La challengepermette all'utente di inserire un URL, a cui il programma remoto si collegherà e farà richieste.
Essendo il binario compilato con vb.net si disassembla facilmente usando software come dotPeek o dnSpy. Analizzando il sorgente si vede come il programma genera una stringa random come User-Agent e la invia al server specificato. In seguito ottiene la risposta ed effettua i seguenti controlli:
- Esiste un header "Server-Type" con valore "Frontdoor-Server-1.0"
- Esiste un header "C&c" il cui valore è verificato con il seguente algoritmo: ogni carattere viene xorato con la stringa generata in precedenza, poi i valori sono sommati a coppie, e infine viene controllato se questi valori sono uguali a quelli fissati all'interno del codice. Superando questi controlli il programma comunica nuovamente con il server e invia la prima flag nell'header "Flag".
Per ottenere la seconda flag bisogna analizzare la logica di comunicazione della backdoor. Infatti il programma richiede /command.txt al server, ed effettua diverse operazioni a seconda del contenuto. In particolare inserendo "rdir;." si ottengono i files locali, mentre inserendo "rfile;< nomefile >" si ottiene il contenuto del file. Il programma però cifra la risposta usando AES, analizzando la funzione di cifratura si recupera la chiave fissa e si decifra il traffico. Richiedendo il file superhiddensecret.txt e decifrando la risposta si ottiene la seconda flag.
#!/usr/bin/env python
from pwn import xor
import base64
from Crypto.Cipher import AES
import hashlib
secret=[0x57, 0x47, 0xb3, 0xa9, 0x9a, 0x45, 0x5b, 0xd9, 0xb9, 0xae, 0x45, 0x2c, 0x3f, 0xdf, 0xed, 0x2f, 0x14, 0x3e, 0xd7, 0x2f, 0x3, 0x59, 0x36, 0xff, 0x50, 0xef, 0xb5, 0x82, 0x4e, 0x39, 0xba, 0x5b]
file = open('command.txt','w+')
file.write("rfile;superhiddensecret.txt")
file.close()
try:
# Python 3
from http.server import HTTPServer, SimpleHTTPRequestHandler, test as test_orig
import sys
def test (*args):
test_orig(*args, port=int(sys.argv[1]) if len(sys.argv) > 1 else 8000)
except ImportError: # Python 2
from BaseHTTPServer import HTTPServer, test
from SimpleHTTPServer import SimpleHTTPRequestHandler
class CORSRequestHandler (SimpleHTTPRequestHandler):
def do_POST(self):
content_length = int(self.headers['Content-Length'])
post_data = base64.b64decode(self.rfile.read(content_length))
key = b'\x0c8/\x14\r\xd5\xea\xe52@\x02m$\xa3\xc1\x0c8/\x14\r\xd5\xea\xe52@\x02m$\xa3\xc1\xec\x00'
cipher = AES.new(key, AES.MODE_ECB)
print(cipher.decrypt(post_data))
self.wfile.write("POST request for {}".format(self.path).encode('utf-8'))
def end_headers (self):
if(self.path=="/command.txt"):
print(self.headers)
SimpleHTTPRequestHandler.end_headers(self)
return
ua=self.headers["User-Agent"]
res=[secret[0]-1]+[0]*31
for x in range(1, 32):
res[x]=(secret[x-1]-res[x-1])%256
print(res)
res=bytes(res)
res=xor(res, ua.encode())
ua=ua.encode()
self.send_header("Server-Type", "Frontdoor-Server-1.0")
self.send_header('C&c', base64.b64encode(res).decode())
SimpleHTTPRequestHandler.end_headers(self)
if __name__ == '__main__':
test(CORSRequestHandler, HTTPServer)