The social Network: Il film e la realta’ con le sessioni e CURL

Posted on dicembre 11, 2010
Filed Under Appunti di Php, Protezione Password | Leave a Comment

Il post e’ nato dall’idea del film The social Network di David Fincher quando il baldo giovine crea in “una notte” FaceMash prelevando piu’ o meno correttamente le foto delle studentesse, o quanto meno le url delle immagini da utilizzare per mettere a confronto due ragazze e permettere di scegliere la preferita semplicemente cliccandoci.

Tanti sono i parser presenti su Internet e tanti i sistemi per realizzarli, nel post vedremo come realizzare un sistema di recupero dati automatico tramite l’uso del CURL e ci spingeremo un po’ oltre “contro” dei sistemi che utilizzano le sessioni per proteggere i propri dati dal prelievo che, per chi non lo sapesse, non e’ legale. Allora perche’ il post ? Per puro apprendimento! L’amministratore del sito potrebbe aver messo in piedi delle opportune misure di sicurezza a livello server o via script per limitare il numero di connessioni per IP, usare i cookie per tracciare l’analizzatore o essere in contatto diretto con la Polizia Postale per passargli i dati del tentativo di saturazione della banda a causa delle utility che generano un traffico sospetto.

Il sistema consistera’ in 3 step:
1. Analisi della struttura delle URL
2. Analisi dei contenuti delle pagine per capire i dati da recuperare
3. Realizzazioni delle utility per il recupero dei dati
4. Verifica a campione dei dati recuperati

1. Analisi della struttura delle URL
Molto spesso, ad oggi, i siti Web di un certo livello sono realizzati con alcuni template standard che vengono riempiti in maniera dinamica con i contenuti. Il classico esempio di una directory contenente le varie categorie di lavoro ed il dettaglio dell’offerta di lavoro ne e’ un esempio, cosi’ come i siti turistici che dividono per regione + provincia fino ad arrivare alla scheda del nostro hotel preferito per passare le tanto amate vacanze.

Solitamente nella pagina della regione e della provincia e’ presente un elenco, magari paginato, delle strutture inserite con una struttura delle url che puo’ avere un url SEO oriented o con dei parametri. Ad es.:
- url SEO: http://www.nomedominio.tld/regione/provincia/struttura.php
- url con parametri: http://www.nomedominio.tld/index.php?reg=1&prov=1001
- url semiSEO con parametri: http://www.nomedominio.tld/1234_regione_provincia/

Spesso nelle soluzioni miste basta cambiare l’id e scrivere qualunque cosa affinche’ venga mostrata un’altra pagina ?

L’analisi delle url e’ fondamentale per capire la difficolta’ con la quale andremo a scontrarci. Se una url SEO oriented e’ piu’ difficile da navigare in maniera automatica, le url con parametri sono banali ed il contenuto della pagina che viene mostrata verra’ capita dall’utility che leggera’ la pagina per noi.

2. Analisi dei contenuti delle pagine per capire i dati da recuperare
L’analisi del codice sorgente della pagina e’ fondamentale per scegliere i contenuti da recuperare e come andarli a recuperare. Nell’esempio che faremo potremo pensare di recuperare title, keywords e description ma niente vieta di studiare piu’ approfonditamente la pagina e recuperare i tag H1, particolari porzioni della pagina racchiuse da una classe di un foglio di stile o l’url dell’immagine della bonazza universitaria per realizzare il nostro FaceMash personale.

Per analizzare il codice bastera’ navigare il sito a cui siamo interessati e leggere il codice sorgente generato delle pagine che ci interessano. Vedremo che saranno spesso a gruppi, ossia regione e provincia saranno magari molto simili a livello di contenuto mentre le pagine dettaglio saranno tutte strutturate in maniera analoga. Una volta capita la struttura della pagina e come e’ possibile trovare i dati che ci interessano si puo’ passare a creare delle utility che navighino il sito per noi e prelevino i dati che ci servono magari mettendoli in un database opportunamente creato per il recupero dei dati.

3. Realizzazioni delle utility per il recupero dei dati
Supponendo di aver capito le struttura delle URL, i dati delle pagine andremo a realizzare delle utility sulla base dei template che abbiamo scelto. E’ chiaro che se pensiamo di recuperare i title delle pagine la cosa e’ abbastanza banale e varra’ per tutti i template alla stessa maniera ma se pensiamo di recuperare la foto presente nel dettaglio ed il testo associato alla foto l’analisi diventa un po’ piu’ complessa ma fattibile.

Ecco un esempio pratico della utility che andremo a realizzare:
- Obiettivo: prelievo title, keywords, description da un sito le cui url sono nella forma: http://www.nomedominio.tld/index.php?id=1  – http://www.nomedominio.tld/index.php?id=2 – http://www.nomedominio.tld/index.php?id=3 … – http://www.nomedominio.tld/index.php?id=1000

Andremo a creare la nostra tabella MySQL in locale con questi campi:
- key_rec – Intero chiave primaria autoincrement
- title TEXT
- keywords TEXT
- description TEXT
- url TEXT

Ecco il codice SQL per creare la tabella:
CREATE TABLE `recuperodati` (

`key_rec` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`title` TEXT NULL ,
`keywords` TEXT NULL ,
`description` TEXT NULL ,
`url` TEXT NOT NULL

) ENGINE = MYISAM ;

Una volta creata la tabella andremo a realizzare il nostro script PHP per il recupero dei dati cosi’ fatto:<?php
// Connessione al database…
$dbhost = ‘localhost’;        // Indirizzo del server MySQL
$dbusername = ‘root’;        // Inserisci l’utente che ha i privilegi di gestione del database
$dbpasswd = ”;                // Se necessario inserisci la psw dell’utente che puo’ accedere al database!
$database_name = ‘test’;    // Cambiala con il nome del tuo database!!!

$connection = mysql_connect(“$dbhost”,”$dbusername”,”$dbpasswd”) or die (“Impossibile collegarsi al server.”);
$db = mysql_select_db(“$database_name”, $connection) or die(“Impossibile selezionare il database.”);

// Ciclo di recupero dati…
$inizio = 1;
$fine = 1001;
$urlRecupero = “http://www.nomedominio.tld/index.php?id=”;
$nomeFile     = “appoggio.txt”;    // File usato per depositare la pagina prelevata…
$nomeTabella = “recuperodati”;    // Tabella ove deposito i dati…

for ($i=$inizio;$i<$fine;$i++);
{
// CURL…
$urlRecuperoInCorso = $urlRecupero.$i;    // Url che sto analizzando…
$ch = curl_init($urlRecuperoInCorso);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);

// Svuoto i dati precedentemente prelevati…
$title    = “”;
$kes    = “”;
$desc    = “”;

// Deposito la pagina prelevata in un file…
file_put_contents($nomeFile,$output);

// Leggo la pagina…
$handle = fopen($nomeFile,”r”);
while(!feof($handle))
{
$riga = fgets($handle);

// Se la riga analizzata soddisfa la ricerca recupero il dato…
if (strpos(strtolower($riga),”title>”)>0)
$title = strip_tags($riga);
if (strpos(strtolower($riga),’ name=”keywords”‘)>0)
{
$kws = substr($riga,strpos(trim($riga),”content=”)+9);
$kws = substr($kws,0,-3);
}
if (strpos(strtolower($riga),’name=”description”‘)>0)
{
$desc = substr($riga,strpos(trim($riga),”content=”)+9);
$desc = substr($desc,0,-3);
}
}

// Inserisco i dati in database…
$queryIns = “INSERT INTO $nomeTabella (title, keywords, description, url) VALUES (‘$title’,'$kws’,'$desc’,'$urlRecuperoInCorso’)”;
$sqlIns = @mysql_query($queryIns);
}
?>

Lo script, dopo essersi collegato al database dove e’ presente la tabella di appoggio imposta i parametri necessari alla navigazione e tramite la CURL legge la pagina di destinazione. Dopodiche’ deposita il contenuto su un file di appoggio (appoggio.txt) presente nella stessa cartella dello script e poi analizza il file riga per  riga. Se il parser trova la riga giusta la analizza e preleva il contenuto: per il title semplicemente elimina i tags <title> e </title> prendendo il contenuto mentre per keywords e description analizza il contenutno prelevando la parte interna al parametro content

Chiaramente se dovessimo prelevare le immagini delle nostre studentesse dovremo capire template per templete sui vari siti dove e’ posizionata l’immagine e prelevare l’url dell’immagine da poter utilizzare nel contest.

Talvolta ci si potrebbe “scontrare” con sistemi di protezione da questi script basati sulle sessioni come fare ad accorgersene ? Semplicemente navigando il sito si riesce a vedere tutto il contenuto di tutte le pagine ma se per caso noi prelevassimo un URL specifico di una pagina interna al sito e la incollassimo su un altro browser potremo non leggere il contenuto di tale pagina. Questa forma di protezione e’ spesso basata sulla sessione.
L’utente che naviga arrivando in Home Page od in una pagina specifica riceve una o piu’ variabili di sessione che gli permettono la navigazione; l’utente che arriva alla url specifica senza tali parametri non puo’ vederne il contenuto.

Il sistema seppur “comodo” per evitare furti di contenutni non e’ il massimo della protezione visto che e’ possibile far navigare il nostro script facendolo passare dalla pagina che rilascia la sessione e poi farlo arrivare alla pagina con il contenuto. E’ inoltre assai fastidioso per l’utente medio che consiglia ad un amico la visualizzazione dell’url e non si spiega come mai lui lo vede ed il collega magari contattato via IM (Skype, MSN, etc. etc.) non vede la pagina.

Come superare questo inghippo ? Supponiamo che sia l’Home Page a rilasciare la variabile di sessione. In tal caso il nostro script andrebbe modificato in questo modo:
<?php
// Connessione al database…
$dbhost = ‘localhost’;        // Indirizzo del server MySQL
$dbusername = ‘root’;        // Inserisci l’utente che ha i privilegi di gestione del database
$dbpasswd = ”;                // Se necessario inserisci la psw dell’utente che puo’ accedere al database!
$database_name = ‘test’;    // Cambiala con il nome del tuo database!!!

$connection = mysql_connect(“$dbhost”,”$dbusername”,”$dbpasswd”) or die (“Impossibile collegarsi al server.”);
$db = mysql_select_db(“$database_name”, $connection) or die(“Impossibile selezionare il database.”);

// Ciclo di recupero dati…
$inizio = 1;
$fine = 1001;
$UrlSessione = “http://www.nomedominio.tld/”;
$urlRecupero = “http://www.nomedominio.tld/index.php?id=”;
$nomeFile     = “appoggio.txt”;    // File usato per depositare la pagina prelevata…
$nomeTabella = “recuperodati”;    // Tabella ove deposito i dati…

function CURL_ParseHeader($Response,$StartHeaders=200,$EndHeaders=299)
{
$HttpHeaders = false;
$Response=strip_tags($Response);
$Strip =explode(“\n”,$Response);
foreach($Strip as $k=>$v)
{
if(preg_match(“/^[HTTP\/]/”,$v)==true)
{
$ValHttp =explode(” “,$v);
if (($ValHttp[1] >= $StartHeaders) AND  ($ValHttp[1] <= $EndHeaders))
$HttpHeaders = true;
}
}
//verifico se è positiva la risposta
if($HttpHeaders == true)
return true;
else
return false;
}

function CURL_GetIDSession($Header=”")
{
if($Header!=”")
{
if(CURL_ParseHeader($Header)==true)
{
$s=explode(“\n”,$Header);
foreach($s as $key=>$value)
{
if(preg_match(“/^Set-Cookie: PHPSESSID=[\w\W\d]+;/”,$value,$y))
{
//Se trovo il +OK setto a true la variabile di controllo del flusso
$Exp=explode(“=”,$y[0]);
$SSID=substr($Exp[1],0,-1);
}
}
if($SSID!=”")
return $SSID;
else
return false;
}
else
return false;
}
else
return false;
}

// Prelevo la variabile di sessione…
// Imposto la variabile di sessione grabbata…
$ch = curl_init($UrlSessione);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

$output = curl_exec($ch);
curl_close($ch);
$PHPSESSID=CURL_GetIDSession($output);

for ($i=$inizio;$i<$fine;$i++);
{
// CURL…
$urlRecuperoInCorso = $urlRecupero.$i;    // Url che sto analizzando…
$ch = curl_init($urlRecuperoInCorso);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIE,”PHPSESSID=”.$PHPSESSID);
$output = curl_exec($ch);
curl_close($ch);

// Svuoto i dati precedentemente prelevati…
$title    = “”;
$kes    = “”;
$desc    = “”;

// Deposito la pagina prelevata in un file…
file_put_contents($nomeFile,$output);

// Leggo la pagina…
$handle = fopen($nomeFile,”r”);
while(!feof($handle))
{
$riga = fgets($handle);

// Se la riga analizzata soddisfa la ricerca recupero il dato…
if (strpos(strtolower($riga),”title>”)>0)
$title = strip_tags($riga);
if (strpos(strtolower($riga),’ name=”keywords”‘)>0)
{
$kws = substr($riga,strpos(trim($riga),”content=”)+9);
$kws = substr($kws,0,-3);
}
if (strpos(strtolower($riga),’name=”description”‘)>0)
{
$desc = substr($riga,strpos(trim($riga),”content=”)+9);
$desc = substr($desc,0,-3);
}
if (strpos(strtolower($riga),’sorry’)>0)
$kws=”sorry”;
}

// Inserisco i dati in database…
$queryIns = “INSERT INTO $nomeTabella (title, keywords, description, url) VALUES (‘$title’,'$kws’,'$desc’,'$urlRecuperoInCorso’)”;
$sqlIns = @mysql_query($queryIns);
}
?>

In questo modo andremo a prelevare la variabile di sessione che permettera’ al sito di riconoscerci e mostrarci il contenuto della pagina.
Analogamente per i siti che invece di utilizzare la PHPSESSID utilizzano la JSESSIONID bastera’ variariare di poco la funzione di prelievo della variabile per permettere al nostro script di operare per conto nostro.

Others Script adv

Leave a Reply