2010-04-24 8 views
6

In quale direzione devo andare (librerie, documenti)?Come dirottare tutta la richiesta http locale ed estrarre l'url usando c?

UPDATE

Qualcuno può illustrare come utilizzare WinPcap per fare il lavoro?

UPDATE 2

Come faccio a verificare se un pacchetto è un HTTP uno?

+2

Non è necessario scrivere alcun software per eseguire questa operazione. Utilizzare un [proxy] (http://www.squid-cache.org/) con [logging] (http://www.squid-cache.org/Doc/config/access_log/). –

+0

Si noti che le risposte fornite consentono di registrare o monitorare gli URL ma di certo non dirottano: "Per modificare le impostazioni del software senza che l'utente ne sia a conoscenza in modo da costringere l'utente a visitare un determinato sito Web" (wiki). Potresti aver usato male il termine o ne hai inteso un altro. –

+0

Mi spiace contestare Matt, ma il calamaro effettivamente "dirotta". Con ciò intendo che ti permette di sostituire un URL diverso per quello che l'utente ha inserito (se è questo che vuoi fare come programmatore). La funzione principale è quella di archiviare le cose, ma può fare più che se lo desideri. – Hotei

risposta

15

Se per "dirottare" si intende intercettare i pacchetti allora che cosa si dovrebbe fare per farlo con WinPcap è la seguente:

  1. Trovare il dispositivo che si desidera utilizzare - See WinPcap tutorial.

  2. Aprire un dispositivo utilizzando pcap_open

    // Open the device 
    char errorBuffer[PCAP_ERRBUF_SIZE]; 
    pcap_t *pcapDescriptor = pcap_open(source,    // name of the device 
                snapshotLength,  // portion of the packet to capture 
                      // 65536 guarantees that the whole packet will be captured on all the link layers 
                attributes,   // 0 for no flags, 1 for promiscuous 
                readTimeout,   // read timeout 
                NULL,     // authentication on the remote machine 
                errorBuffer);   // error buffer 
    
  3. utilizza una funzione che legge i pacchetti dal descrittore come pcap_loop

    int result = pcap_loop(pcapDescriptor, count, functionPointer, NULL); 
    

    Questo ciclo volontà fino a quando qualcosa di sbagliato è successo o il ciclo era rotto usando una chiamata al metodo speciale. Chiamerà il functionPointer per ogni pacchetto.

  4. Nella funzione di rilevare implementare qualcosa che analizza i pacchetti, dovrebbe apparire come un pcap_handler:

    typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *, 
         const u_char *); 
    
  5. Ora tutto quello che hai lasciato è quello di analizzare i pacchetti che la loro buffer è nel const u_char* e la loro la lunghezza è nel campo pcap_pkthdr della struttura caplen.

    Supponendo di avere HTTP GET su TCP su IPv4 su pacchetti Ethernet, è possibile:

    • Skip 14 byte di intestazione Ethernet.
    • Salta 20 byte dell'intestazione IPv4 (presupponendo che non ci siano opzioni IPv4, se si sospetta che le opzioni IPv4 siano possibili, è possibile leggere i 5-8 bit dell'intestazione IPv4, moltiplicare per 4 e questo sarebbe il numero di byte che prende l'intestazione IPv4).
    • Salta 20 byte dell'intestazione TCP (presupponendo che non ci siano opzioni TCP, se si sospetta che le opzioni TCP siano possibili, è possibile leggere i 96-99 bit dell'intestazione TCP, moltiplicare per 4 e questo sarebbe il numero di byte che prende l'intestazione TCP).
    • Il resto del pacchetto dovrebbe essere il testo HTTP. Il testo tra il primo e il secondo spazio dovrebbe essere l'URI. Se è troppo lungo, potrebbe essere necessario eseguire una ricostruzione TCP, ma la maggior parte degli URI è abbastanza piccola da stare in un unico pacchetto.

      UPDATE: In codice di questo sarebbe simile che (l'ho scritto senza prove):

      int tcp_len, url_length; 
      uchar *url, *end_url, *final_url, *tcp_payload; 
      
      ... /* code in http://www.winpcap.org/docs/docs_40_2/html/group__wpcap__tut6.html */ 
      
      /* retireve the position of the tcp header */ 
      ip_len = (ih->ver_ihl & 0xf) * 4; 
      
      /* retireve the position of the tcp payload */ 
      tcp_len = (((uchar*)ih)[ip_len + 12] >> 4) * 4; 
      tcpPayload = (uchar*)ih + ip_len + tcp_len; 
      
      /* start of url - skip "GET " */ 
      url = tcpPayload + 4; 
      
      /* length of url - lookfor space */ 
      end_url = strchr((char*)url, ' '); 
      url_length = end_url - url; 
      
      /* copy the url to a null terminated c string */ 
      final_url = (uchar*)malloc(url_length + 1); 
      strncpy((char*)final_url, (char*)url, url_length); 
      final_url[url_length] = '\0'; 
      

È inoltre possibile filtrare solo il traffico HTTP utilizzando la creazione e l'impostazione di un BPF. See WinPcap tutorial. Probabilmente dovresti usare il filtro "tcp and dst port 80" che ti darebbe solo la richiesta che il tuo computer invia al server.

Se non ti dispiace usare C#, puoi provare a utilizzare Pcap.Net, che farebbe tutto ciò per te molto più facilmente, incluso l'analisi di parti Ethernet, IPv4 e TCP del pacchetto.

+1

È possibile automatizzare il passaggio 1? Sembra che il tutorial richieda di specificare un dispositivo manualmente. – Gtker

+0

Ovviamente, devi ancora sceglierne uno o farlo semplicemente per tutti i dispositivi. Molte volte avrai un solo dispositivo, quindi puoi semplicemente scegliere il primo. Puoi anche automatizzare la scelta usando le loro proprietà (come il loro IP). Guarda un'altra parte del tutorial di WinPcap: http://www.winpcap.org/docs/docs_411/html/group__wpcap__tut2.html – brickner

+0

@ brickner, puoi anche capire come verificare se un pacchetto è un pacchetto HTTP in 'pcap_handler' ? – Gtker

0

Si consiglia di guardare il codice sorgente del tcpdump per vedere come funziona. tcpdump è un'utilità della riga di comando di Linux che monitora e stampa l'attività di rete. Tuttavia, per utilizzarlo è necessario l'accesso come root alla macchina.

+0

Funziona anche per Windows? – Gtker

+0

@Runner: se ti interessano le soluzioni solo per Windows, puoi aggiungere un tag [windows]. –

+0

Non solo Windows, ma sia Windows che Linux. – Gtker

1

Può sembrare eccessivo, ma il server proxy Web/cache Squid fa esattamente questo. Qualche anno fa la mia azienda l'ha usato e ho dovuto modificare localmente il codice per fornire alcuni avvisi speciali quando sono stati raggiunti determinati URL, quindi so che può fare quello che vuoi. Hai solo bisogno di trovare il codice che desideri e tirarlo fuori per il tuo progetto. Ho usato la versione 2.X e vedo che ora sono fino a 3.X ma sospetto che l'aspetto del codice non sia cambiato molto internamente.

Non hai detto se Windows è un "requisito" o una "preferenza" ma secondo il sito: http://www.squid-cache.org/ possono fare entrambe le cose.

+0

No, voglio implementarlo da solo. – Gtker

+2

Non voglio iniziare una guerra di fiamme ma il fatto che tu abbia appena chiesto a qualcun altro come farlo nel commento del winpcap mi chiedo ... – Hotei