In presenza di sito click-through (vedasi la pagina precedente) può capitare di incontrare un'altra tecnica di offuscamento, che consiste nell'uso del javascript. In pratica la pagina click-through non contiene, bello chiaro ed evidente, il link al sito vero e proprio, ma contiene una procedura scritta, per l'appunto, in javascript. Quando la pagina click-through viene caricata in un browser che sia in grado di eseguire il javascript, la procedura in questione viene eseguita e produce, come output, delle righe di codice html che di fatto sostituiscono l'iniziale codice html della pagina. Nella pagina così riscritta è presente il link da nascondere, oppure possono esserci ulteriori script che, alla fine, faranno giungere alla url che lo spammer intende far visitare. Normalmente guardando il javascript non si capisce nulla, perché quello che dovrà diventare il nuovo sorgente html della pagina non è scritto in chiaro, ma risiede in costanti codificate, che è compito della procedura decodificare. Inoltre, il comando "View source" disponibile in tutti i browser non è di alcuna utilità, poiché mostra solo l'originario contenuto codificato della pagina. Comunque anche per questi casi, come vedremo tra un attimo, c'è rimedio.
Al solo scopo di evitare confusione ricordiamo che, a differenza dei programmi CGI, che vengono eseguiti entro il web server, le procedure javascript vengono eseguite dal browser sul computer dell'utente. Il browser trova tali procedure sempre in formato sorgente all'interno di appositi tag della pagina html.
Sulla decrittazione dei javascript non ho un caso pratico mio, ragion per cui ne prendo uno che ho visto segnalare su news.admin.net-abuse.email e che mi pare consenta di capire abbastanza chiaramente di cosa si tratta. I casi che si incontreranno nella pratica potranno magari essere differenti ma saranno da affrontare in maniera analoga.
Prima di procedere è doverosa una premessa: io di javascript non me ne intendo. Alla data di creazione della presente pagina, se io guardo una routine scritta in javascript arrivo al massimo ad intuire vagamente quello che fa. Dubito fortemente di volermi documentare sull'argomento in futuro, in quanto il javascript mi sta cordialmente antipatico: come utente web lo tengo nei miei browser disabilitato e, come si può ben immaginare, non intendo usarlo sulle mie pagine. Ho fatto questa precisazione soprattutto per uno scopo: far vedere che non occorre affatto essere un esperto di javascript per rendere inutile anche questa ennesima trovata degli spammer.
L'esempio che vediamo ora fa uso di una soluzione commerciale, abbastanza diffusasi tra gli spammer, che promette di rendere il proprio sito accessibile ma, al tempo stesso, non rintracciabile e di conseguenza al riparo dalle segnalazioni degli antispammer.
La soluzione basata sul javascript che vediamo qui non è opera di spammer, ma di abili programmatori che vendono il loro software agli spammer (per esempio, HayWyre è il nome commerciale di una di queste soluzioni). Fa sempre un certo senso vedere qualcuno che fa soldi vendendo piedi di porco e calzamaglie a ladri e rapinatori. Chi vende spamware (software di supporto alla attività degli spammer) fa esattamente la stessa cosa.
La url pubblicizzata nello spam, debitamente cammuffata con i trucchetti che già conosciamo, faceva giungere ad una pagina il cui contenuto può venire schematizzato così:
<html>
<head>
<meta HTTP-EQUIV="Expires" CONTENT="SECURE HTML">
</head>
<script src="z"></script>
<script language="Javascript">
<!--
function rm(){
var rmt="1O8__$E**__nED)]V$RX_.....stringone lunghissimo di caratteri senza senso...",
rmv=1,rms=196,rmr=28;
document.write((rmo)((rmt),(rms),(rmr),(rmv)));
}
(rm());
//-->
</script>
</html>
Ho riarrangiato il testo della pagina mettendo le andate a capo e le indentazioni in modo da rendere il tutto più leggibile; la pagina originale (anche per via del fatto che lo stringone che inizializza la variabile rmt è lungo 4600 byte e passa) appare decisamente più confusa e scomoda da leggere.
Analizzando quanto sopra si vede che, al momento del caricamento della pagina, va in esecuzione
lo script e che il primo statement effettivamente eseguibile è quell'(rm()); evidenziato
in grassetto. rm() è
una funzione (il cui codice è disponibile subito sopra) che inizializza alcune variabili per poi
eseguire una document.write(), ossia l'istruzione che scrive nuove righe di html entro la
pagina che il browser sta visualizzando. Argomento della document.write() è il
valore di ritorno della funzione (rmo), cui vengono passati come argomenti le variabili
poc'anzi inizializzate.
C'è un solo problema: il codice della funzione (rmo) dove lo troviamo?
La risposta sta in una delle prime righe, ove si trova: <script src="z"></script>,
ossia il riferimento ad un ulteriore script, distribuito in un file a parte il cui nome è "z". In pratica,
se la pagina ove avete trovato quel codice html ha la url http://sito.dello.spammer.com/path/pagina.html
dovrete usare il vostro browser per prelevare il file http://sito.dello.spammer.com/path/z
Disponendo del file "z" avrete tutto il necessario per far funzionare lo script. Il fatto che una parte del codice sia fornita in un file separato è certamente per fare in modo che la pagina html, quand'anche venisse prelevata, da sola non sia sufficiente per ricavare le informazioni nascoste. Guardiamo dunque il contenuto del file "z", che è già più leggibile:
<!-- version 1.0 -->
function rmo(rm1,rm3,rm4,rmv) {
if (rmv!=1){return "File mismatch, please update you dec file";}
var rm2="PqE@9;Q\\>gMb-T%Fn`p0/GmCiV.Zl?jXz6r +hKoS$_e)tJaA4*3R!\"uN2}kU]H=\twLcW#Oy:s<xI,(5D18fB[|~&v\n7dY^{'",
rmf="",
rmp=0;
rm3/=rm4;
rm4/=2;
for(var rml1=0;rml1<rm4;rml1++){
for(var rml2=rml1;rml2<rm1.length;rml2+=rm4){
rmp=rm2.indexOf(rm1.charAt(rml2))-rm3;
if(rmp<0){rmp+=rm2.length;}
rmf+=rm2.charAt(rmp);
}
}
return rmf;
}
Come ci aspettavamo, ecco dunque la funzione rmo(). Del resto, doveva esserci per forza, se no
lo script non avrebbe potuto funzionare. Potrei sbagliare, ma mi sembrerebbe che la funzione rmo()
non sia altro che una routine di decifrazione, in cui si ha una chiave (quella inizializzata nella variabile
rm2) e il ciclo con i due for nidificati che trasforma, in base ai caratteri della
chiave, i vari byte di quello stringone che avevamo visto nel pezzo di codice precedente.
A questo punto è tutto chiaro: quando il browser carica la pagina iniziale, manda in esecuzione lo script, il che provoca il prelievo (non notato dall'utente) del file "z". A quel punto il browser lavora per diversi secondi, eseguendo la routine di decifrazione. Quando ha finito, appare una pagina dalla quale si potrà finalmente accedere al sito dello spammer.
Vi interessa provare questa trafila sul vostro computer? È molto semplice. Come si può ben immaginare, non metto tra le pagine di questo sito quelle originali dello spammer, tuttavia potete scaricare questo file zippato, che contiene la versione originale della pagina iniziale e dello script "z", oltre ad una immagine gif utilizzata durante il funzionamento. Per fare la prova basta unzippare i file nella stessa directory, poi aprire la pagina html con un browser in cui il javascript sia abilitato. Suggerisco che facciate la prova quando NON siete collegati in rete, anche se mi risulta che i link referenziati dalla pagina in questione siano ormai morti.
Quando il browser finisce di eseguire la routine di decifrazione, il testo che ci interessa vedere è stato dunque ricostruito e ha dato luogo a ciò che compare nella finestra del browser. Riuscire a salvarsi in chiaro tale testo non è però così semplice. Non è semplice perché il comando "View source" non mostra l'html quale risulta dopo la document.write, ma mostra in ogni caso l'html come scritto nella pagina originale. Altrettanto dicasi se qualcuno pensa di provare a usare il menù "File"/"Salva con nome": almeno sul Netscape con cui ho fatto la prova io, si riottiene il sorgente originale. Anche nella cache di Netscape si può poi rintracciare solo la versione originale.
E allora? Dobbiamo alterare lo script, cosa per cui abbiamo da provare varie soluzioni.
Prima soluzione. Facciamo in modo che lo script produca, in testa al suo normale output,
una riga con un tag <XMP> e, al termine, il corrispondente tag
</XMP>. Ciò significa alterare lo script della pagina originale
come segue:
<html>
<head>
<meta HTTP-EQUIV="Expires" CONTENT="SECURE HTML">
</head>
<script src="z"></script>
<script language="Javascript">
<!--
document.write("<XMP>");
function rm(){var rmt="1O8__$E**__nED)]V$RX_DO $_H_R_XX)... lo stringone continua ma a noi non interessa...
document.write("</XMP>");
//-->
</script>
</html>
Si notino, in grassetto, le due document.write() che sono state aggiunte in modo da aprire un
tag XMP prima che inizi l'output originale dello script, e chiuderlo al termine. Il tag XMP dice al browser di
considerare tutte le righe comprese al suo interno come semplice testo da visualizzare così com'è, trattando come
testo anche eventuali tag che vi si trovassero. Il tag XMP è deprecato da tempo, tuttavia i browser ancora lo
supportano e questa è quindi una soluzione che può funzionare. Tuttavia non escluderei che in futuro, eventualmente,
i programmatori che hanno escogitato i trucchi che stiamo esaminando trovassero modo di neutralizzare questa soluzione,
magari iniziando il loro output con un </XMP>.
Seconda soluzione. Rielaboriamo l'output prodotto dallo script in modo da sostituire tutti
i caratteri "<" e ">" in esso contenuti con le rispettive sequenze
"<" e ">" (cosa che trasforma tutti i tag in innocui elementi
di testo che saranno visualizzati così come sono). Bisogna tuttavia trovare un rimedio al fatto che,
venendo meno l'effetto dei tag originali, il sorgente verrebbe sì visualizzato ma senza andate a capo
e senza spaziature, divenendo pertanto poco leggibile. Diventa quindi opportuno costruire, con alcune
document.write(), una semplice pagina html attorno all'output modificato, facendo sì di
comprenderlo entro un tag <PRE> </PRE>, che mantiene la originaria
formattazione. Questa soluzione ha, rispetto alla precedente, il vantaggio che l'html che viene prodotto, una
volta salvato in un file, può essere visualizzato da qualunque tipo di browser.
Resta solo da vedere come si fa a operare la sostituzione dei caratteri. A questo proposito, si
consideri che lo script nella sua versione originale deve per forza avere da qualche parte una
document.write() e che tale funzione deve per forza avere un argomento, il cui valore
sarà il testo da scrivere nel documento. Nel nostro caso abbiamo una document.write()
in fondo al lungo stringone:
<html> <head> <meta HTTP-EQUIV="Expires" CONTENT="SECURE HTML"> </head> <script src="z"></script> <script language="Javascript"> <!-- function rm()...stringone...;document.write((rmo)((rmt),(rms),(rmr),(rmv)));}(rm()); //--> </script> </html>
Andremo quindi a modificare l'argomento della document.write() e ad aggiungere
altri tag prima e dopo, in modo da trasformare la pagina come segue:
<html>
<head>
<meta HTTP-EQUIV="Expires" CONTENT="SECURE HTML">
</head>
<script src="z"></script>
<script language="Javascript">
<!--
document.write("<HTML><HEAD><TITLE>Pagina Decodificata</TITLE></HEAD><BODY><PRE>");
function rm()...stringone...;document.write((rmo)((rmt),(rms),(rmr),(rmv)).split("<").join("<").split(">").join(">"));}(rm());
document.write("</PRE></BODY></HTML>");
//-->
</script>
</html>
Si notino le parti aggiunte, che sono in grassetto. È importante la posizione della catena di funzioni:
.split("<").join("<").split(">").join(">")
che deve essere collocata nella posizione giusta, dopo l'argomento della document.write() che
è, nel nostro caso, la chiamata di funzione (rmo)(...).
Sia seguendo questa soluzione che quella precedente, il codice che ci interessa viene visualizzato in chiaro nella finestra del browser. Non si riesce a salvarlo in un file dal menù File/Salva con nome, tuttavia si riesce a selezionarlo tutto e a copiarlo in clipboard.
A volte possono capitare dei javascript contenenti vari trucchi volti a neutralizzare soluzioni come quelle appena viste. In questi casi, si tratta semplicamente di ricorrere a soluzioni più complicate, eventualmente da cercarsi al momento o da adattarsi. Sono in particolare interessanti le soluzioni escogitate da un frequentatore del newsgroup news.admin.net-abuse.email, conosciuto per interventi tecnici assai profondi postati con lo pseudonimo di spamless@Nil.nil. L'idea principale portata da Spamless alla decrittazione dei javascript consiste nell'aggiungere istruzioni per far sì che il codice decodificato venga scritto nel campo di input di un form, per la precisione in una TEXTAREA, dove può essere letto, selezionato e copiato in clipboard senza difficoltà. Avendo chiaro che, se si evita di lasciare il proprio computer in balia del codice dello spammer, la cosa riesce senz'altro meglio, Spamless ha suggerito di modificare nel seguente modo la originale pagina crittografata:
// define my variable zzx23ymy="";Ovviamente il nome zzx23ymy può anche essere scelto differente, basta che non sia una variabile già usata nello script.
document.write(qualchecosa) vengano trasformati come segue:
//document.write(qualchecosa) zzx23ymy+=qualchecosa
Vale a dire, la document.write viene trasformata in un commento e ciò che sarebbe stato scritto nel documento da visualizzare nel browser viene invece concatenato nel valore della variabile zzx23ymy. Questa modifica è importante anche perché, neutralizzando la document.write originale, si evita che il browser interpreti il codice dello spammer. Nel caso del nostro esempio avremo che
...,rmr=28;document.write((rmo)((rmt),(rms),(rmr),(rmv)));}(...ecc..
diventa:
...,rmr=28;zzx23ymy+=(rmo)((rmt),(rms),(rmr),(rmv));}(...ecc..
<FORM NAME="spam"> <TEXTAREA NAME="src" COLS="100" ROWS="38"></TEXTAREA> <INPUT VALUE="Decoder" NAME="Decoder" TYPE="button" onClick="spam.src.value=zzx23ymy;"> </FORM>In effetti, non essendoci più la document.write, l'intera pagina rimarrebbe vuota ed il relativo spazio può quindi essere usato per contenere un'ampia TEXTAREA (le dimensioni COLS="100" ROWS="38" possono essere ovviamente scelte da ciascuno a proprio gusto, in base alla risoluzione dello schermo).
Dopo aver compiuto queste modifiche, si caricherà la pagina nel browser, si cliccherà il bottone Decoder e si vedrà apparire il codice decodificato. Spamless fa comunque presente che qualche caso potrebbe richiedere la decodifica in più riprese e che, se è vero che una soluzione si può sempre trovare, è anche vero che non è semplice fornire una soluzione universale, che valga sempre.
Per chi preferisse non fare la prova pratica con il nostro esempio, la pagina decodificata è disponibile qui in formato zippato. Comunque vediamone velocemente le caratteristiche più significative.
L'html che doveva rimanere nascosto (nelle intenzioni dello spammer e del suo programmatore) fa uso di ulteriori routine in Javascript. Per esempio cerca di settare un cookie e, se si accorge che il cookie è stato rifiutato, ridirige il browser su Excite (un sito come un altro, tanto per far finire lontani dal loro). Ci sono poi alcune routine che hanno il compito di impedire all'utente di usare il tasto destro del mouse.
Si nota, a questo proposito, un messaggio (che comunque nelle prove che ho effettuato non ho mai
visto comparire) che dice: "Sorry, you don't have permission to right-click.". Questa arrogante presa di
possesso del computer dell'utente da parte dello spammer e del suo programmatore, al punto da stabilire
quando l'utente ha o non ha il diritto di usare un tasto del mouse, si adatta benissimo a ciò che gli spammer
fanno di solito (ossia appropriarsi di risorse altrui per conseguire il proprio profitto), quindi non stupisce.
Stupisce di più un altro particolare: quando l'utente cerca di usare il tasto destro del mouse, la procedura
esegue una istruzione parent.window.close(), che significa chiudere la finestra principale del browser.
Mentre MS Internet Explorer, almeno alla versione 4, chiede conferma all'utente prima di chiudersi, quel susinone di
Netscape si chiude invece senza tanti complimenti (quasi che i browser venissero installati a beneficio dei webmaster
dei siti che vengono visitati e non degli utenti che se ne servono).
Come si vede dal codice, in centro alla pagina compare un bottone ENTER che serve per entrare nel sito principale dello spammer. Tale bottone non aziona un link qualsiasi, ma fa partire una ennesima funzione javascript la quale apre, entro una nuova finestra del browser, la url del sito da raggiungere. Naturalmente la nuova finestra viene configurata in modo da non avere né menù né toolbar né campo di input per la url, così da togliere all'utente ogni possibilità di controllo:
window.open('http://3538297410/tmsm/info2kcate.html','','toolbar=no,menubar=no,resizable=yes,scrollbars=yes,location=no,fullscreen');
Superfluo dire che il solito Netscape esegue alla lettera queste prescrizioni e non lascia all'utente alcuna possibilità di alterare le caratteristiche della finestra: gli è solo consentito (bontà loro) di chiuderla. MS Internet Explorer versione 4 fa pure di peggio: apre la nuova finestra a pieno schermo, senza neppure fornire la barra del titolo da cui poterla chiudere (e a quel punto non è semplice liberarsene).
È ora ovvio che si tratterà di vedere chi ha in hosting il sito la cui url compare nella window.open()
(come direbbero i matematici, ci siamo ricondotti al caso precedente).
Tirando le conclusioni, si può dire che non esiste nessun metodo sicuro per nascondere i siti, anche se in certe pagine simili a quella che abbiamo qui preso in esame compaiono pittoreschi messaggi come il seguente:
<!--//©1997, 1998, 1999 MasterAgents "we invent the technology..." - ...and We ARE the technology! For your secure page needs, call 1-505-202-xxxx for $100 u.s. per page - . - ... - ;::::; - ;::::; :; - ;:::::' :; - ;:::::; ;. - ,:::::' ; OOO\ - ::::::; ; OOOOO\ - ;:::::; ; MOOOOOOO - ,;::::::; ;' / AOOOOOO - ;:::::::::`. ,,,;. / / SOOOOOO - .';:::::::::::::::::;, / / TOOOO - ,::::::;::::::;;;;::::;, / / EOOO - ;`::::::`'::::::;;;::::: ,#/ / ROOO - :`:::::::`;::::::;;::: ;::# / AOOO - ::`:::::::`;:::::::: ;::::# / GOO - `:`:::::::`;:::::: ;::::::#/ EO - :::`:::::::`;; ;:::::::::## NO - ::::`:::::::`;::::::::;:::# T - `:::::`::::::::::::;'`:;::# S - `:::::`::::::::;' / / `:# - We created the 'No Dot' IP - We created the 'Hexidecimal links' - We created the 'Stealth Link' - We created the 'Stealth Frame' - We created the 'No-Right Click' for Netscape - Don't F*ck With MasterAgents! You WILL Lose! - - Ayn Rand Rules!!! Read Atlas Shrugged to find out why you should be living instead of trying to crack my codes//-->
Il tipo che ha scritto queste righe sta combattendo una battaglia persa in partenza: potrà inventare di tanto in tanto nuovi trucchi, certamente più ingegnosi di quelli che potrei inventare io, ma dopo un paio di giorni sarà già di dominio pubblico il modo per aggirarli. Quanto allo spammer, continuerà a perdere l'account, il sito e tutto il resto, con la differenza che stavolta avrà anche speso 100 dollari per un inutile prodotto di offuscamento delle pagine web.
Indice << Precedente Successiva >>
Ultimo aggiornamento: 14 agosto 2002
Leonardo Collinelli