簡體   English   中英

Scapy python腳本在嗅探時消耗了太多的CPU

[英]Scapy python script consuming too much cpu while sniffing

我用python + scapy編寫了一個無線探針嗅探器。 我想在openwrt路由器中使用這個腳本。

每次它從附近的設備捕獲探測請求時,信息都會發送到Web服務。 (mac,power和probe)。

我的問題是CPU的高消耗。 這個腳本在我的筆記本電腦上運行得非常好(需要50-70%的cpu),但是當我在一個openwrt路由器(400mhz cpu,16 ram)中運行它需要99%。 這是一個眾所周知的錯誤,因為丟失了高負載的數據包(我同時測試了我的筆記本電腦和路由器中的腳本以及路由器沒有捕獲空中的所有可用數據包)

我已經對代碼做了一些優化,但我認為還有更多的改進空間。

這是腳本。

#!/usr/bin/python
from scapy.all import *
import time
import thread
import requests
from datetime import datetime

PROBE_REQUEST_TYPE=0
PROBE_REQUEST_SUBTYPE=4
buf={'arrival':0,'source':0,'dest':0,'pwr':0,'probe':0}
uuid='1A2B3'

def PacketHandler(pkt):
    global buf
    if pkt.haslayer(Dot11):
        if pkt.type==PROBE_REQUEST_TYPE and pkt.subtype == PROBE_REQUEST_SUBTYPE:
            arrival= int(time.mktime(time.localtime()))
            try:
                extra = pkt.notdecoded
            except:
                extra=None

            if extra!=None:
                signal_strength = -(256-ord(extra[-4:-3]))
            else:
                signal_strength = -100

            source = pkt.addr2
            dest= pkt.addr3
            pwr=signal_strength
            probe=pkt.getlayer(Dot11).info

            if buf['source']!=source and buf['probe']!=probe:
                print 'launch %r %r %r' % (source,dest,probe)
                buf={'arrival':arrival,'source':source,'dest':dest,'pwr':pwr,'probe':probe}

                try:
                    thread.start_new_thread(exporter,(arrival,source,dest,pwr,probe))
                except:
                    print 'Error launching the thread %r' % source

def exporter (arrival,source,dest,pwr,probe):
    global uuid
    urlg='http://webservice.com/?arrival='+str(arrival)+'&source='+str(source)+'&dest='+str(dest)+'&pwr='+str(pwr)+'&probe='+str(probe)+'&uuid='+uuid
    try:
        r=requests.get(urlg)
        print r.status_code
        print r.content
    except:
        print 'ERROR in Thread:::::: %r' % source







def main():
    print "[%s] Starting scan"%datetime.now()
    sniff(iface=sys.argv[1],prn=PacketHandler,store=0)

if __name__=="__main__":
    main()

[UPDATE]

經過大量的閱讀和深度搜索(似乎沒有多少人找到完全解決同一問題或類似的東西)。 我發現你可以直接從sniff函數中過濾,所以我添加了一個過濾器來捕獲探測請求。

def main():
    print "[%s] Starting scan"%datetime.now()
    sniff(iface=sys.argv[1],prn=PacketHandler, filter='link[26] = 0x40',store=0)

在我的筆記本電腦運行非常順利,使用1%-3%的CPU和捕獲大部分空閑的可用數據包。

但是當我在路由器上運行它時,腳本會拋出錯誤並崩潰。

Traceback (most recent call last):
  File "snrV2.py", line 66, in <module>
    main()
  File "snrV2.py", line 63, in main
    sniff(iface=sys.argv[1],prn=PacketHandler, filter='link[26] = 0x40',store=0)
  File "/usr/lib/python2.7/site-packages/scapy/sendrecv.py", line 550, in sniff
    s = L2socket(type=ETH_P_ALL, *arg, **karg)
  File "/usr/lib/python2.7/site-packages/scapy/arch/linux.py", line 460, in __init__
    attach_filter(self.ins, filter)
  File "/usr/lib/python2.7/site-packages/scapy/arch/linux.py", line 132, in attach_filter
    s.setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, bpfh)
  File "/usr/lib/python2.7/socket.py", line 224, in meth
    return getattr(self._sock,name)(*args)
socket.error: [Errno 99] Protocol not available

我已經嘗試使用bpf過濾器語法(在tcpdump http://biot.com/capstats/bpf.html中使用相同)並且它應該也可以在scapy中使用它,但是我得到了一個過濾器語法錯誤。

嗅覺功能:

def main():                                                                                                                                           
    print "[%s] Starting scan"%datetime.now()                                                                                                         
    sniff(iface=sys.argv[1],prn=PacketHandler, filter='type mgt subtype probe-req', store=0) 

錯誤:

Traceback (most recent call last):
  File "snrV2.py", line 66, in <module>
    main()
  File "snrV2.py", line 63, in main
    sniff(iface=sys.argv[1],prn=PacketHandler, filter='type mgt subtype probe-req', store=0)
  File "/usr/lib/python2.7/site-packages/scapy/sendrecv.py", line 550, in sniff
    s = L2socket(type=ETH_P_ALL, *arg, **karg)
  File "/usr/lib/python2.7/site-packages/scapy/arch/linux.py", line 460, in __init__
    attach_filter(self.ins, filter)
  File "/usr/lib/python2.7/site-packages/scapy/arch/linux.py", line 120, in attach_filter
    raise Scapy_Exception("Filter parse error")
NameError: global name 'Scapy_Exception' is not defined

在路由器中我安裝了最新版本的scapy和tcpdump。 現在我真的不知道該怎么做。

當我嘗試在我的NETGEAR WNDR4300上使用帶過濾器的sniff() ,我遇到了類似的錯誤(socket.error:[Errno 99]協議不可用)。

經過大量的Google搜索,我發現原因是我的路由器的Linux內核沒有啟用CONFIG_PACKET。 Scapy安裝指南中提到如下:

  • 確保您的內核已選擇數據包套接字(CONFIG_PACKET)
  • 如果你的內核<2.6,請確保選擇Socket過濾CONFIG_FILTER)

如果在編譯內核時設置CONFIG_PACKET=y ,那么它將為底層套接字啟用BPF。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM