#python #buffer #scapy #pcap #bytesio
#python #буфер #scapy #pcap #bytesio
Вопрос:
У меня возникли проблемы с записью pcap в файловый буфер, важно, чтобы я не касался диска для этих записей 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
Обычно это происходит, когда вы открываете (Нет), это ошибка в функции PcapWriter в Scapy Utils?
Я также пробовал это с помощью: buf.seek(0)
перед написанием, и это все еще не удается.
Комментарии:
1. Я проверил в коде —
wrpcap
ожидает имя файла. Вы не можете использовать какой-либо буфер.2. Интересно, могу ли я каким-либо образом перенести данные pcap в буфер, хм.
3. если в
utils.py
вы могли бы изменить строкуself.f = [open,gzip.open]...
наself.f = your_buffer
, то, вероятно, вы могли бы получитьpcap
доступ к памяти. Вы можете получитьwrpcap
код и написать собственную версию с помощью собственногоself.f
.4. Да, я мог бы попробовать изменить
utils.py
файл, однако я обнаружил, что могу это сделать:buf = io.BytesIO() for i in range(0, len(cap)-1): buf.write(str(cap[i]))
единственным недостатком является то, что это все необработанные пакетные данные, а не формат pcap. однако ‘text2pcap’ из утилит WireShark оказывается сложным с этими данными. Итак, да, вы можете удалить данные в виде буфера, но, похоже, это только необработанные пакетные данные, а не в формате pcap.5. кстати. короче и более pythonic
for x in cap: buf.write(str(x))
Ответ №1:
Вы должны использовать последнюю версию 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 🙂 И, похоже, вы добавили эту модификацию 🙂
2. Однако я сделал это, объединил более 7 месяцев назад, так что это не совсем ново 😉
3. Похоже, мне придется получить версию scapy Kali для Github, должно быть, устаревшую, lol!
4. Да, Kali устарел, я пробовал wrpcap, однако после этого все равно нужно открыть буфер, чтобы манипулировать им. Однако второй набор кода с более новой версией работает нормально.
Ответ №2:
Я получил код из scapy
( utils.py
) и создал memwrpcap
который может записывать в io.BytesIO
.
buf = io.BytesIO()
memwrpcap(buf, cap)
(после записи буфер не закрывается, и вы можете перейти к началу чтения из буфера.)
После этого я использовал стандартные open()
и write()
для сохранения данных из io.BytesIO
и сравнил этот файл с файлом, созданным с 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())
Комментарии:
1. Я собираюсь немного рассказать об этом: я смог использовать файловый буфер для записи каждого пакета в виде raw hex, затем взять их и преобразовать в полезный pcap, выполнив:
for f in *.hex; do od -Ax -tx1 -v $f >> cap.dump; done amp;amp; text2pcap -n cap.dump cap.pcap
проблема, с которой я столкнулся при повторной сборке данных, заключалась в том, что text2pcap должен знать длину каждого пакета, прежде чем его можно будет должным образом обработать. Я расскажу об этом позже, если это сработает, это должно быть преобразовано в запрос на извлечение в scapy.2. В качестве дополнительного примечания, это может быть из-за того, что моя версия
utils.py
старше, если у кого-то есть проблемы с выполнением этой работы, просто измените наMemoryPcapWriter(filename, *args, **kargs) as fdesc: fdesc.write(pkt)
наMemoryPcapWriter(filename, *args, **kargs).write(pkt)
, кроме того, что это работает как шарм, вы собираетесь создать запрос на извлечение этого для проекта scapy?3. Я проверил новейший код в репозитории, и он был добавлен 8 марта. Теперь вы можете использовать
PcapWriter()
вместоwrpcap()
:buf = io.BytesIO() ; PcapWriter(buf).write(cap)