server.py (2846B)
1import os 2import selectors 3import shutil 4import signal 5import socketserver 6import subprocess 7import tempfile 8from os import fdopen 9 10TIMEOUT = 60 * 10 # timeout after ten minutes 11 12 13class Handler(socketserver.BaseRequestHandler): 14 def handle(self): 15 self.request.sendall( 16 f"[?] Please provide the boot disk in hex format.\n".encode() 17 ) 18 self.request.sendall(f'[*] End your input with "EOF"\n'.encode()) 19 20 buffer = b"" 21 while b"EOF" not in buffer: 22 buffer += self.request.recv(1024) 23 buffer = buffer.replace(b"EOF", b"").lower() 24 try: 25 buffer = bytes(list(filter(lambda x: chr(x) in "0123456789abcdef", buffer))) 26 27 data = bytes.fromhex(buffer.decode()) 28 except: 29 self.request.sendall(f"[!] Invalid input... bye!\n".encode()) 30 return 31 32 fd, disk_path = tempfile.mkstemp() 33 with fdopen(fd, "wb") as f: 34 f.write(data) 35 36 # make sure we use the fresh vars every time 37 shutil.copy("OVMF_VARS.fd", "OVMF_VARS_CURRENT.fd") 38 os.chmod("OVMF_VARS_CURRENT.fd", 0o660) 39 40 subprocess.call( 41 ["sh", "-c", "kill -9 $(cat /tmp/qemu)"], 42 stdin=subprocess.DEVNULL, 43 stdout=self.request.fileno(), 44 stderr=self.request.fileno(), 45 ) 46 47 cmd = [ 48 "/usr/bin/qemu-system-x86_64", 49 "-pidfile", "/tmp/qemu", 50 "-s", "-S", 51 "-d", "int,in_asm", 52 "-D", "/tmp/log", 53 "-cpu", 54 "max", 55 "-machine", 56 "q35", 57 "-drive", 58 "if=pflash,format=raw,readonly=on,unit=0,file=OVMF_CODE.fd", 59 "-drive", 60 "if=pflash,format=raw,unit=1,file=OVMF_VARS_CURRENT.fd", 61 "-drive", 62 f"file={disk_path},if=none,id=disk1,format=raw", 63 "-device", 64 "ide-hd,drive=disk1,bootindex=1", 65 "-monitor", 66 "none", 67 "-display", 68 "none", 69 "-nographic", 70 ] 71 72 self.request.sendall(f"[*] Starting qemu, good luck!\n".encode()) 73 74 # signal.signal( 75 # signal.SIGALRM, 76 # lambda _n, _f: [self.request.sendall(b"[!] Timed out..\n"), exit(1)], 77 # ) 78 #signal.alarm(TIMEOUT) 79 subprocess.call( 80 cmd, 81 stdin=subprocess.DEVNULL, 82 stdout=self.request.fileno(), 83 stderr=self.request.fileno(), 84 ) 85 86 87with socketserver.ForkingTCPServer(("0.0.0.0", 1024), Handler) as server: 88 server.allow_reuse_address = True 89 with selectors.PollSelector() as selector: 90 selector.register(server, selectors.EVENT_READ) 91 while True: 92 ready = selector.select(0.5) 93 if ready: 94 server._handle_request_noblock()