2016-10-22 26 views
1

파일 버퍼에 pcap을 쓰는 데 문제가 있습니다.이 pcap 캡처를 위해 디스크를 만지지 않아야합니다. 그렇습니다. 열려 (없음)을 할 수 없을 때 일반적으로Scapy로 버퍼에 pcap 작성하기

sudo scapy 
>>> import io 
>>> cap = sniff(timeout=30) 
>>> buf = io.BytesIO() 
>>> wrpcap(buf, cap) 
Traceback (most recent call last): 
    File "<console>", line 1, in <module> 
    File "/usr/lib/python2.7/dist-packages/scapy/utils.py", line 524, in wrpcap 
    with PcapWriter(filename, *args, **kargs) as fdesc: 
    File "/usr/lib/python2.7/dist-packages/scapy/utils.py", line 682, in __init__ 
    self.f = [open,gzip.open][gz](filename,append and "ab" or "wb", gz and 9 or bufsz) 
TypeError: coercing to Unicode: need string or buffer, _io.BytesIO found 

이 발생,이 Scapy의 Utils에서 PcapWriter 기능의 버그?

나는 이것을 쓰기 전에 buf.seek(0)으로 시도했지만 여전히 실패합니다.

+0

내가 코드를 체크 - 'wrpcap'는 파일 이름을 요구합니다. 버퍼는 사용할 수 없습니다. – furas

+0

궁금하다면 어쨌든 나는 버퍼에 pcap 데이터를 얻을 수있다. – lillypad

+0

'utils.py'에서'self.f = [open, gzip.open] ...'을'self.f = your_buffer'로 바꿀 수 있다면, 아마도 여러분은 메모리에'pcap'을 얻을 수있을 것입니다. 'wrpcap' 코드를 받아서 자신의'self.f'로 자신의 버전을 작성할 수 있습니다. – furas

답변

-1

scapy (utils.py)에서 코드를 얻었으며 io.BytesIO에 쓸 수있는 memwrpcap을 만들었습니다.

buf = io.BytesIO() 
memwrpcap(buf, cap) 

내가 io.BytesIO에서 데이터를 저장하는 표준 open()write()을 사용 그 후

(. 그것은 당신이 버퍼에서 읽을 시작에 가깝지 않은 버퍼로 이동할 수 있습니다 않습니다 작성 후)이 파일과 비교 파일 wrpcap

diff -c test-std.pcap test-mem.pcap 

로 만든 그렇게 io.BytesIO는 PCAP 형식의 데이터가 그들이 동일 보인다.

전체 코드 - memwrpcam, MemoryPcapWriter 및 테스트에 사용한 코드.

# 
# from: scapy/utils.py 
# 

from scapy.all import * 

def memwrpcap(filename, pkt, *args, **kargs): 
    """Write a list of packets to a pcap file 
    gz: set to 1 to save a gzipped capture 
    linktype: force linktype value 
    endianness: "<" or ">", force endianness""" 

    # use MemoryPcapWriter instead of PcapWriter 
    with MemoryPcapWriter(filename, *args, **kargs) as fdesc: 
     fdesc.write(pkt) 


class MemoryPcapWriter(PcapWriter): 
    """A stream PCAP writer with more control than wrpcap()""" 
    def __init__(self, filename, linktype=None, gz=False, endianness="", append=False, sync=False): 
     """ 
     linktype: force linktype to a given value. If None, linktype is taken 
        from the first writter packet 
     gz: compress the capture on the fly 
     endianness: force an endianness (little:"<", big:">"). Default is native 
     append: append packets to the capture file instead of truncating it 
     sync: do not bufferize writes to the capture file 
     """ 

     self.linktype = linktype 
     self.header_present = 0 
     self.append=append 
     self.gz = gz 
     self.endian = endianness 
     self.filename=filename 
     self.sync=sync 
     bufsz=4096 
     if sync: 
      bufsz=0 

     # use filename or file-like object 
     if isinstance(self.filename, str): 
      self.f = [open,gzip.open][gz](filename,append and "ab" or "wb", gz and 9 or bufsz) 
     else: # file-like object 
      self.f = filename 

    def __exit__(self, exc_type, exc_value, tracback): 
     self.flush() 
     if isinstance(self.filename, str): 
      self.close() # don't close file-like object 


# --- main --- 

# 
# run script with sudo 
# 
# compare results (on Linux) 
# diff -s test-std.pcap test-mem.pcap 
# 

from scapy.all import * 

import io 

cap = sniff(timeout=5) 

# save to pcap file 
wrpcap('test-std.pcap', cap) 

# save to buffer 
buf = io.BytesIO() 
memwrpcap(buf, cap) 

# move to beginning and save to file 
#print('current position:', buf.tell()) 
buf.seek(0) 
#print('current position:', buf.tell()) 

with open('test-mem.pcap', 'wb') as fp: 
    fp.write(buf.read()) 
+0

나는이 파일을 조금씩 짤 것이다. 파일 버퍼를 사용하여 각 패킷을 raw 16 진수로 쓸 수 있었다. 그 다음에 그것들을 가져 와서 유용한 pcap으로 변환하십시오.'for f in * .hex; od -Ax -tx1 -v $ f >> cap.dump; done && text2pcap -n cap.dump cap.pcap' 데이터를 다시 어셈블하는 문제는 제대로 처리되기 전에 text2pcap이 각 패킷의 길이를 알아야한다는 것입니다. 나는 여기에 여기에 한 발을 던지겠다. 만약에 이것이 작동한다면, 이것은 scapy에 풀 요청을해야만한다. – lillypad

+0

추가 정보로,'utils.py'의 제 버전이 누군가이 작업을하는 데 문제가 있다면'MemoryPcapWriter (filename, * args, ** kargs)를 fdesc : fdesc.write pkt)''MemoryPcapWriter (filename, * args, ** kargs) .write (pkt)'이것은 매력처럼 작동한다는 것 이외에, scapy 프로젝트를위한 pull 요청을 생성 할 예정입니까? – lillypad

+0

나는 repo에서 최신 코드를 검사했고 3 월 8 일에 추가되었습니다.이제'wrpcap()'대신'PcapWriter()'를 사용할 수 있습니다 :'buf = io.BytesIO(); PcapWriter (buf) .write (cap)' – furas

2
당신은 Scapy의 최신 버전을 사용한다

, 그것은 상자 밖으로 작동합니다

Welcome to Scapy (2.3.3) 
>>> import io 
>>> cap = sniff(timeout=30) 
>>> buf = io.BytesIO() 
>>> wrpcap(buf, cap) 
>>> 

당신이 buf 개방을 유지해야하는 경우

, 그냥 수행

Welcome to Scapy (2.3.3) 
>>> import io 
>>> cap = sniff(timeout=30) 
>>> buf = io.BytesIO() 
>>> PcapWriter(buf).write(cap) 
>>> buf.seek(0) 
0L 
>>> rdpcap(buf) 
<No name: TCP:736 UDP:0 ICMP:0 Other:0> 
+1

그냥 GitHub의 코드에서 찾았습니다. :) 그리고이 수정을 추가 한 것으로 보입니다 :) – furas

+0

나는 7 개월 전에 합병 했으므로 정말 새로운 것은 아닙니다.) – Pierre

+0

내가 scapy Kali의 Github 판을 구식이어야하는 것처럼보아야 할 것처럼 보인다! – lillypad