Tag Archives: PHP

Brute-force verso Google e codice PHP per le disposizioni

Nel precedente articolo sui servizi nascosti o segreti di Google, Fabio Schenone aveva chiesto nei commenti quando avrei svolto un attacco brute-force.

Ho accolto il suggerimento di Fabio ed ho cercato URL di Google nella seguente forma, assegnando al parametro “tbm” tutte le possibili stringhe di tre o di quattro caratteri basate sull’alfabeto inglese:

http://www.google.com/search?q=test&hl=en&prmd=ivnsfd&source=lnms&tbm=XXXX&sa=X&oi=mode_link&ct=mode&cd=4

(per maggiori informazioni sull’URL sopra indicato vi invito a leggere le spiegazioni nel post precedente)

Quantità delle interrogazioni

Disposizioni con ripetizione (permutations)
Le possibili stringhe di testo lunghe tre caratteri, ciascuno dei quali può essere uno qualunque dei simboli dell’alfabeto inglese sono esattamente 17576 (26^3).

Le possibili stringhe di testo lunghe quattro caratteri, ciascuno dei quali può essere uno qualunque dei simboli dell’alfabeto inglese sono esattamente 456976 (26^4).

In totale ho dunque fatto 474552 interrogazioni, che non sono servite ad un fico secco perché non ho scoperto ulteriori servizi nascosti. Gli unici individuati rimangono dunque quelli osservati e pubblicati nel post precedente.

Codice PHP per le disposizioni

Oltre a disporre di una batteria di Xenu, per produrre tutte le stringhe/URL da interrogare ho sviluppato una semplice funzione PHP che produce l’elenco di disposizioni (con ripetizione) ottenibili. Non ho idea se mai mi servirà ancora in futuro, quindi ve la fornisco nella speranza che possa un giorno essere utile a qualcuno di voi.

Per esempio, chiamando la funzione con i seguenti parametri: permutations(“ab”, 3); si ottiene in output un array contenente le stringhe: aaa, aab, aba, abb, baa, bab, bba, bbb.

  /**
   * Permutations
   *
   * Returns an array of strings containing all the
   * ($alphabet ^ $output_length) permutations
   *
   * @alphabet (string|array) set of at least two elements to choose from
   * @output_length (int) the number of elements in each output string
   */
  function permutations ($alphabet, $output_length=1) {

    $output = array();

    if ($alphabet AND ($output_length > 0)) {

      // Handles both string alphabets and array alphabets
      if (is_string ($alphabet)) {
        $alphabet_length = strlen ($alphabet);
        $symbol = str_split ($alphabet);
      } elseif (is_array ($alphabet)) {
        $alphabet_length = count ($alphabet);
        $symbol = $alphabet;
      } else {
        return $output;
      }

      if ($alphabet_length < 2) return $output;


      // Creates a -1 index in order to avoid the out-of-bounds
      // warning during the last loop of the do-while structure
      $pointer = array_fill (-1, $output_length+1, 0);
      
      // How much iterations to perform
      $iterations = pow ($alphabet_length, $output_length);
  
      // To avoid all the "- 1"...
      $alphabet_length--;
      $output_length--;
  
      // Do the job
      for ($i=0; $i < $iterations; $i++) {
        $permutation = "";
        for ($c = 0; $c <= $output_length; $c++) {
          $permutation .= $symbol[$pointer[$c]];
        }
        $output[] = $permutation;
  
  
        // Updates the pointers
        $c = $output_length;
  
        do {
          $pointer[$c]++;
          if ($pointer[$c] <= $alphabet_length) {
            break;
          } else {
            $pointer[$c] = 0;
            $c--;
          }
        } while (TRUE);
      }
    }
    
    return $output;
  }

Un proxy PHP per il querybot

Dopo aver pubblicato l’articolo sul querybot per la simulazione di ricerche degli utenti, alcune persone mi hanno chiesto se l’emulazione umana avrebbe previsto anche il cambio di IP durante le richieste.

PHP proxyLa risposta è sì. Se non ne ho parlato nell’articolo è perché, senza pensarci, ho dato per scontata tale caratteristica, visto che da tempo uso un proxy PHP che mi permette di cambiare facilmente IP. Ma ugualmente scontato per i lettori non lo è e quindi vi spiego un po’ come funziona il proxy.

Il proxy è una versione riveduta e corrotta di un software che ho programmato qualche anno fa, per la creazione di alcuni tool SEO e di un proxy web in grado di bypassare certe restrizioni imposte da Google.

Si tratta di uno script PHP che fa da wrapper delle funzioni cURL e che necessita dunque di questa libreria per funzionare, così come di una versione o configurazione di PHP che contempli la presenza di tali funzioni.

Dal punto di vista dello sviluppatore l’uso è molto semplice: esiste una copia esatta delle funzioni previste dalla cURL, con l’aggiunta di alcune opzioni di tipo CURLOPT_ per la gestione dei parametri del proxy.

Per esempio, usando la copia della funzione curl_setopt() è possibile specificare l’URL del proxy che dovrà essere usato per le successive richieste.

All’URL specificato è presente uno script PHP che rappresenta il proxy vero e proprio, ecco come funziona il meccanismo:

  • il client effettua una richiesta come si farebbe normalmente con la cURL
  • il wrapper entra in gioco per codificare la richiesta in un particolare formato
  • il wrapper usa la cURL per inviare la richiesta codificata allo script proxy, nel far questo usa il metodo POST
  • lo script proxy riceve la richiesta codificata e la decodifica
  • lo script proxy usa la cURL per effettuare la richiesta originale esattamente nello stesso modo in cui l’avrebbe fatta il client;
  • ovviamente la richiesta viene effettuata con l’IP dell’host sul quale lo script proxy risiede
  • lo script proxy riceve il risultato della richiesta, lo codifica nuovamente e lo spedisce al client
  • il client riceve e decodifica il risultato della richiesta e lo restituisce al codice chiamante

Tutto il processo sopra indicato viene effettuato in modo assolutamente trasparente per il programmatore. In altre parole, qualsiasi script PHP che usa già la cURL può facilmente essere modificato per aggiungere la capacità di sfruttare uno o più proxy esterni.

Il sistema è comodo perché il sottoscritto, come la maggior parte dei webmaster e dei SEO, possiede più di un host provider per i propri siti web. Uploadare su ciascuno di essi lo script proxy permette dunque di ottenere tanti IP diversi quanti sono gli host su cui si pubblica lo script.

Conflitto tra le opzioni

Un dettaglio di progettazione che trovo interessante e che voglio condividere con voi è il modo in cui ho evitato le collisioni tra le nuove opzioni CURLOPT_ introdotte dal wrapper e le opzioni CURLOPT_ già esistenti.

La cURL prevede già di default un lungo elenco di opzioni attraverso le quali è possibile stabilire il comportamento della libreria. Ciascuna di queste opzioni ha un nome (una costante che inizia con “CURLOPT_”) e un corrispondente valore numerico.

Il wrapper è stato progettato in modo da replicare le opzioni CURLOPT_ e aggiungerne di proprie. Ho dovuto quindi fare attenzione a non definire costanti che avessero gli stessi valori già usati per quelle “ufficiali”. Il problema però sta nel fatto che ad ogni aggiornamento della cURL è possibile che la quantità di opzioni (e quindi delle costanti) aumenti.

Il mio wrapper non poteva quindi definire le nuove costanti in modo statico, perché avrebbe rischiato di usare valori potenzialmente allocabili dalle future versioni della cURL. Ogni aggiornamento della libreria avrebbe potuto scatenare dei conflitti e mettere il wrapper nelle condizioni di produrre malfunzionamenti.

La soluzione che ho trovato è stata quella di definire dinamicamente le costanti che mi serviva aggiungere. Il wrapper fa così ad ogni sua inizializzazione (si legga: lancio dello script):

  • usa la funzione di PHP get_defined_constants() per ottenere la lista delle costanti definite dalla cURL
  • estrae il valore più alto usato dalle costanti “ufficiali”
  • inizia a definire dinamicamente con la funzione define() le nuove costanti, partendo da valori superiori a quello massimo usato dalla cURL

Facendo in questo modo non c’è rischio che le costanti vengano create con valori già in uso o potenzialmente usabili in futuro dalla libreria cURL. 🙂