Python實現抓取訪問特定URL的數據包

這篇文章緊接着《使用Python來分離或者直接抓取pcap抓包文件中的HTTP流》展開,那篇文章是昨天寫的,今天早上突然又想實現一個直接抓包的程序,於是天沒亮就又爬起來了...

本文的代碼以及前文的代碼在github的地址:https://github.com/marywangran/Python-Http-cap-demux/tree/master

        Python有很多庫可以實現抓包和分析包,典型就是pypcap用來抓包,dpkt用來分析,關於這兩個庫的安裝,我有一些隨筆,雖然這些對於一個Python老手而言似乎是信手拈來可以吹着口哨搞定的事,但是對於新手而言,似乎必然會遇到這樣那樣的問題,因此我先分享一些關於安裝方面的事情。
        Python的庫太過豐富,但是前提是你必須可以隨意安裝它,我比較推薦使用pip安裝,它就像apt-get,yum這樣,甚至語法都一樣:
apt-get/yum/pip install aaaaa
但是pip要真的用起來似乎還是要花點時間的。我首先下載了setuptool:
wget https://pypi.python.org/packages/source/s/setuptools/setuptools-3.0.tar.gz
然後解壓,進入其主目錄後執行:
python ./setup.py build
python ./setup.py install

然後在我瞭解到pip本身也是一個Python庫的時候,我執行了:
easy_install pip
隨後得到了令人遺憾的錯誤提示,說什麼”unknown url type: https“,然後我問了度娘,解決了該問題,很簡單,執行下面的步驟即可:
1.yum install openssl-devel
2.重新編譯Python並install

接下來就可以easy_install pip了,然後就可以:
pip install pypcap
pip install dpkt

最後,代碼就可以隨便寫了...

我主要還是想在直接抓包的時候就過濾好我想要的包,而不是先抓一個超級大的pcap文件,然後再慢慢解析分流。只要腦子裏面有清晰的邏輯,並且手邊有一個得心應手的編程語言,模擬任何事情都不是難事,把昨天的代碼一改,把分析pcap的邏輯改成pypcap/dpkt抓包解包的邏輯,一切似乎就是那麼簡單。代碼如下:
[python] view plain copy
  1. #!/usr/local/bin/python  
  2.   
  3. import pcap  
  4. import dpkt  
  5.   
  6. cap = pcap.pcap('eth3')      
  7. cap.setfilter('tcp port 80')  
  8. files4out = {}  
  9. url = 'www.baidu.com'  
  10.   
  11. for ptime,pktdata in cap:    
  12.     pkt = dpkt.ethernet.Ethernet(pktdata)  
  13.     if pkt.data.data.__class__.__name__ <> 'TCP':  
  14.         continue  
  15.     ipsrc_tag = 0  
  16.     ipdst_tag = 0  
  17.     sport_tag = 0  
  18.     dport_tag = 0  
  19.   
  20.     ipdata = pkt.data  
  21.     sip='%d.%d.%d.%d'%tuple(map(ord,list(ipdata.src)))  
  22.     dip='%d.%d.%d.%d'%tuple(map(ord,list(ipdata.dst)))  
  23.   
  24.     tcpdata = pkt.data.data  
  25.     sport = tcpdata.sport  
  26.     dport = tcpdata.dport  
  27.       
  28.     src_tag = sip  
  29.     dst_tag = dip  
  30.     sp_tag = str(sport)  
  31.     dp_tag = str(dport)  
  32.     if ord(list(ipdata.src)[0]) > ord(list(ipdata.dst)[0]):  
  33.         temp = dst_tag  
  34.         dst_tag = src_tag  
  35.         src_tag = temp  
  36.               
  37.     if sport > dport:  
  38.         temp = sp_tag  
  39.         sp_tag = dp_tag  
  40.         dp_tag = temp  
  41.   
  42.     content = url  
  43.     FLAG = 0  
  44.       
  45.     appdata = tcpdata.data  
  46.     if appdata.find(content) <> -1:  
  47.         print 'find'  
  48.         FLAG = 1  
  49.       
  50.     name = src_tag + '_' + dst_tag + '_' + sp_tag + '_' + dp_tag  
  51.     if (name) in files4out:  
  52.         item = files4out[name]  
  53.         fi = 0  
  54.         cnt = item[1]  
  55.         if cnt < 6 and item[3] <> 1:  
  56.             item[1] += 1  
  57.             item[2].append(pktdata)  
  58.             if FLAG == 1:  
  59.                 item[3] = 1  
  60.         elif item[3] == 1:  
  61.             for index in range(cnt+1):  
  62.                 pktdatai = item[2][index]  
  63.                 pkti = dpkt.ethernet.Ethernet(pktdatai)  
  64.                 ipdatai = pkti.data  
  65.                 tcpdatai = pkti.data.data  
  66.                 sipi='%d.%d.%d.%d'%tuple(map(ord,list(ipdatai.src)))  
  67.                 dipi='%d.%d.%d.%d'%tuple(map(ord,list(ipdatai.dst)))  
  68.                 sporti = tcpdatai.sport  
  69.                 dporti = tcpdatai.dport  
  70.                 print '[datai]' + sipi + ':' + str(sporti) + '-' + dipi + ':' + str(dporti)  
  71.             item[1] = -1  
  72.               
  73.             print '[data]' + sip + ':' + str(sport) + '-' + dip + ':' + str(dport)  
  74.         else  
  75.             # 這裏優化空間巨大!  
  76.             # 爲了不讓隨意的五元組無情地侵佔字典空間,這裏有幾個策略:  
  77.             # 1.發現FIN的時候,再容許這個流在字典中存在固定的時間段或者在允許此流來回5個包,之後刪除字典的索引  
  78.             # 2.如果超過6個包都沒有等到GET /$url,那麼在timewait的時間內,此流不允許佔據字典空間  
  79.             del files4out[name]  
  80.               
  81.               
  82.     else:  
  83.         item = [00, [], 00]  
  84.   
  85.         item[2].append(pktdata)  
  86.         files4out[name] = item  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章