The first thing you need to do is to capture packets scapy package
install scapy package
pip install scapy
stay python Reference... In the code scapy package
from scapy.all import *
# In order to save trouble , direct import *, You can also import what you want to use according to your needs
Want to analyze packages , First of all, there should be bags , Let's start with bag grabbing
Packet capturing uses scapy Medium sniff() Method
pcaps = sniff(filter="",iface="any", prn=function, count="")
#filter The rules of Berkeley Packet Filter (BPF) grammar
#iface It is used to specify which network interface to capture packets ( Usually all network interfaces are not specified )
#prn Specify the callback function , Whenever a match filter When the message is detected , Will execute the callback function , Usually use lambda Expression to write a callback function
#count Specify the maximum number of packets to sniff ( Compliance filter Conditional message , Not all messages )
among
filter Filter rules for , reference BPF Syntax fill filter rule
for example :filter="ip src www.baidu.com" The source address is www.baidu.com Message of
iface For which network card to grab packets from , Fill in the network card name at the back
for example :iface="WLAN" or iface="eth0"
prn Is a callback function , Simple usage such as :prn=lambda x:x.summary() or prn=lambda x:x[IP].src
prn=lambda x:x.summary() Is the brief information of the printed message
effect :Ether / IP / TCP 192.168.2.204:4963 > 180.97.162.191:8202 A
prn=lambda x:x[IP].src Is the source address of the printed message
effect :192.168.1.1
count To capture how many messages
If you catch a bag and want to save it , So that we can analyze it slowly next time , You can use the following methods to save
wrpcap("pc2.pcap", pcaps)
If you don't want to save , Then go straight to the next step
After catching the bag , Just now we used the method of callback function summary, Shows brief information about each package , There are also many ways to print the information of the bag , Refer to the following code for details
from scapy.all import *
dpkt = sniff(iface="WLAN", count=10)
print(dpkt)
# Print out the total information of the package , Printing effect :
#<Sniffed: TCP:2 UDP:0 ICMP:0 Other:0>
print(dpkt[0])
# Print the first package , In fact, this printing is useless , I can't see anything , Because it's all 16 Base number , That's what the warning means. Printing doesn't make any sense , Printing effect
#WARNING: Calling str(pkt) on Python 3 makes no sense!
#b'X\x00\xe3Df\xfbh\xa8(/\xd7\t\x08\x00E\x00\x01{\xa6)@\x005\x11 \xef=\x97\xb4\xa2\xac\x1c\xdf\x03\[email protected]\x0f\xb1\x01g\x06>\x02:-\x00\x17\xab\r2\xc2o\n\x00\x00\nF.v\x8e+\x80\x0e\x14\xa3/\'\x7f+_\xba%\xd86\xb8\x00\xda\n\x7f\xff\xc16\x13
-#\x15\t\xe4\xb6[U\xdcT\xfb\xf6\xfb\xc5!%~\x92U\xdd\x96\x88\xf6\x12\xc8.\xda9\xd0\x85\x9d{\xd7/,\xf6\xb2\x9a\xe9\xbcg\x1bw\xec-\xab9\xab\x8e\xc0\x94\xef\xdbneT\x8f\xe3c\xa0h=\xc0\n+\xec\xdf\xa2x\xb3\x03\xc7GR\x90~D\xa4\xbe\x8a\xf8\xa
#d\xb9I\x05\x16&%\xa6B\xabM\xd1\x1bh\xa8\xb1\xe8=\xc7HG\x11Qv\xa3\x11\x14\xf0\x98\xb2\x9c\xd3\x94\xd1\xa1&\x99;\x86\xa6.\x10\x1e\x1d\xf5\xa3H(\xa7I\x84\xf9\xa8k\x9f\r\x86\x05\xf9p\x0b\xc0\x8e\xda\xcer\x0e<\xaf\x16\xccT|\xae\xack\x1a\
#xd1\xae\\1\xc9\x98\xb4\xc4Um\xb6\xa1\xdfAoa\xc5\xa6N\xe9\xbd\x9fB\xed\x94\xf2\xe2\xb4\xa4O\xa46,\xbc\xe8\x86h,\x19\x0e\x01\x93\xa9*\\\xd0mW\x03\xb2r\xc6\x8cN\xf8#8\x8e\t\xfc\x08O.\x13\x9er2\x86\x81*[\xb1\xfb\xaaD\xc8\x83\xab\xc9\xda
#`\xac:\x02\xaf\x1a\xf9\xfb\x08\x93,\xd7q\x8b\xaev/\xd3}\xf3t*\xcf\xebUt\xe5[\x06\xe7\xab\x03eg\xe6hd\x81\xe3EH\\\x99MZW\x1c\xb9\x87"\xa4\xff\x03y\xf9Q#\x00B9qK\xbf\x99a"\n75\xc8Z\xa2\x03'
print(dpkt[0].show())
# Show package details , Because each package is different , So the effect of printing may be different , I only showed the printing effect of this kind of package , The effect is as follows :
# ###[ Ethernet ]###
# dst = 68:a8: 28:2
# f: d7:0
# 9
# src = 58:00: e3:44: 66:fb
# type = IPv4
# ###[ IP ]###
# version = 4
# ihl = 5
# tos = 0x4
# len = 58
# id = 19004
# flags = DF
# frag = 0
# ttl = 200
# proto = tcp
# chksum = 0x6875
# src = 172.28.223.3
# dst = 172.31.200.200
# \options \
# ###[ TCP ]###
# sport = 49688
# dport = 9988
# seq = 2674031876
# ack = 3838184596
# dataofs = 5
# reserved = 0
# flags = PA
# window = 513
# chksum = 0xbe17
# urgptr = 0
# options = []
# ###[ Raw ]###
# load = "\x01LVSIs'\\x9e0\n\x00\x00\x00\x00\x00\x00\x00\x00"
#
#
# None
print(dpkt[0].time)
# Print time , The printing effect is as follows :
# 1639643824.65736
print(dpkt[0].fields)
# {'dst': '01:00:5e:7f:ff:fa', 'src': '58:00:e3:44:66:fb', 'type': 2048}
# Print dpkt[0].show() Information in
# For example, print the above IP Inside src
print(dpkt[0][IP].src)
# Such as print TCP Medium sport
print(dpkt[0]["TCP"].sport)
#0 It means the 0 A package , If you want to see the second bag , Can be 0 Change it to 1, If you want to traverse all the packages , You can replace the numbers inside with a loop
# Be careful , Some bags may not have TCP, Not even IP, You need to judge when traversing
I won't talk about it here , Refer to other materials
capture.yp
import Database
from scapy.all import *
def get_all_pcap(ifs, size=10, filter=""):
# Grab the bag
pcaps = sniff(iface=ifs, count=size, filter=filter)
# Save package to file
# wrpcap("pc2.pcap", dpkt)
data = []
for item in pcaps:
if item['Ethernet'].type == 2048:
# ipv4
ethernet_type = 'IPV4'
# Judge tcp still udp
if item["IP"].proto == 6:
sport = item['TCP'].sport
dport = int(re.sub(r'[\(\)\,]', "", str(item['TCP'].dport)))
tcp_udp = 'TCP'
tcp_type = item['TCP'].flags
else:
sport = item['UDP'].sport
dport = re.sub(r'[\(\)\,]', "", str(item['UDP'].dport))
tcp_udp = 'UDP'
tcp_type = 'null'
src_ip = re.sub(r'[\(\)\,]', "", str(item['IP'].src))
dst_ip = re.sub(r'[\(\)\,]', "", str(item['IP'].dst))
elif item['Ethernet'].type == 2054:
# ARP
ethernet_type = 'ARP'
src_ip = item['ARP'].psrc
dst_ip = item['ARP'].pdst
sport = 'null'
dport = 'null'
tcp_udp = 'null'
tcp_type = 'null'
else:
# ipv6
ethernet_type = 'IPV6'
src_ip = item['IPv6'].src
dst_ip = item['IPv6'].dst
sport = 'null'
dport = 'null'
tcp_udp = 'null'
tcp_type = 'null'
time = item.time
# Insert data into the array
data.append([
ethernet_type,
src_ip,
dst_ip,
sport,
dport,
tcp_udp,
str(tcp_type),
int(time)
])
return data
def insertToSQL(data):
field = ['ethernet_type', 'src_ip', 'dst_ip', 'sport', 'dport', 'TCP_UDP', 'tcp_type', 'time']
# insert data
result = Database.Database().insert_all('pack_info', field, data)
if result == 0:
return 'success'
else:
return 'error'
def main():
# Grab the bag
# ifs = 'WLAN' # network card
data = get_all_pcap('WLAN', 100, 'tcp')
# Insert database
result = insertToSQL(data)
print(result)
if __name__ == '__main__':
main()
Datebase.py
import pymysql.cursors
class Database:
connected = False
__conn = None
# Constructors , Connect to the database directly during initialization
def __init__(self):
conf = {
'host': 'ip',
'port': 3306,
'user': ' user name ',
'pw': ' password ',
'db': ' database '}
if type(conf) is not dict:
print(' error : Parameter is not a dictionary type !')
else:
for key in ['host', 'port', 'user', 'pw', 'db']:
if key not in conf.keys():
print(' error : Parameter dictionary is missing %s' % key)
if 'charset' not in conf.keys():
conf['charset'] = 'utf8'
try:
self.__conn = pymysql.connect(
host=conf['host'],
port=conf['port'],
user=conf['user'],
passwd=conf['pw'],
db=conf['db'],
charset=conf['charset'],
cursorclass=pymysql.cursors.DictCursor)
self.connected = True
except pymysql.Error as e:
print(' Database connection failed :', end='')
# Insert a piece of data into the data table
def insert_one(self, table, val_obj):
sql_top = 'INSERT INTO ' + table + ' ('
sql_tail = ') VALUES ('
try:
for key, val in val_obj.items():
sql_top += key + ','
if isinstance(val,int):
sql_tail += str(val) + ','
else:
sql_tail += '\'' + val + '\'' + ','
sql = sql_top[:-1] + sql_tail[:-1] + ')'
# Print sql sentence
# print(sql)
# exit()
with self.__conn.cursor() as cursor:
cursor.execute(sql)
self.__conn.commit()
return self.__conn.insert_id()
except pymysql.Error as e:
self.__conn.rollback()
return False
def insert_all(self,table,field,record):
sql_top = 'INSERT INTO ' + table + ' ('
sql_tail = ') VALUES ('
try:
for val in field:
sql_top += val + ','
for i in record:
for j in i:
if isinstance(j, int):
sql_tail += str(j) + ','
else:
sql_tail += '\'' + j + '\'' + ','
sql_tail = sql_tail[:-1] + '),('
sql = sql_top[:-1] + sql_tail[:-2]
# Print sql sentence
# print(sql)
# exit()
with self.__conn.cursor() as cursor:
cursor.execute(sql)
self.__conn.commit()
return self.__conn.insert_id()
except pymysql.Error as e:
self.__conn.rollback()
return False
# Close database connection when destroying object
def __del__(self):
try:
self.__conn.close()
except pymysql.Error as e:
pass
# Close database connection
def close(self):
self.__del__()
It is purely to record the personal learning process , I'm just beginning to learn python, I feel that there must be something wrong with the above code , If there is something incorrect or unclear , Welcome to correct ..
Some of this knowledge refers to the following links , Thank you, big brother
python Capture and unpack _ Yi Ran -CSDN Blog _python Grab the bag