利用scapy,需安装WinPcap
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

127 lines
4.7 KiB

4 years ago
#encoding=utf-8
from scapy.sendrecv import sniff
from scapy.all import scapy,TCPSession
from scapy.layers.http import HTTPRequest, HTTPResponse, HTTP
from datetime import datetime
import re
import configparser
import os
class hcap:
packageBody = ''
packageType = ''
def __init__(self,host,port,iface):
self.host = host
self.port = port
self.iface = iface
def hcap(self):
hoststr = "host "+self.host+" and tcp port "+self.port
data = sniff(filter=hoststr,iface=self.iface,prn=self.__get_HTTP,session=TCPSession)
def __get_HTTP(self, pkt):
if pkt.haslayer('TCP'):
try:
http = pkt.getlayer('TCP').load
if len(http) > 6:
self.__handle_pack(http)
except:
if self.packageBody:
self.__close_pack(self.packageType)
def __handle_pack(self, http_bytes):
try:
if http_bytes.find(b'HTTP/1.1') > 0:
# Request & Response package are together
resp_beg = http_bytes.find(b'HTTP/1.1')
if http_bytes.find(b'GET') == 0 or http_bytes.find(b'POST') == 0:
# split the request part
self.packageType = 'Request'
self.packageBody = http_bytes[:resp_beg]
self.__close_pack(self.packageType)
if http_bytes[-4:] == b'\r\n\r\n':
# if response is over write it
self.packageType = 'Response'
self.packageBody = http_bytes[resp_beg:]
self.__close_pack(self.packageType)
else:
self.packageType = 'Response'
self.packageBody = http_bytes[resp_beg:]
elif http_bytes.find(b'GET') == 0 or http_bytes.find(b'POST') == 0:
self.packageType = 'Request'
self.packageBody = http_bytes
self.__close_pack(self.packageType)
elif http_bytes.find(b'HTTP/1.1') == 0:
self.packageType = 'Response'
self.packageBody = http_bytes
if http_bytes[-4:] == b'\r\n\r\n' or http_bytes[-4:] == b'0000':
self.packageBody = self.packageBody + http_bytes
self.__close_pack(self.packageType)
elif http_bytes.find(b'0000') > 0:
self.packageBody = self.packageBody + http_bytes
self.__close_pack(self.packageType)
else:
self.packageBody += http_bytes
except:
pass
def __close_pack(self, type=None):
# end of package and send to txt file
try:
txtBody = self.packageBody.decode('utf-8')
txtF = re.sub(r'\r\n\r\n[0-9a-f]{4}\r\n\r\n', '', txtBody)
self.__write_log('###### '+type+' ######')
self.__write_log(txtF.replace('0000', '').replace('\r\n\r\n', ''))
self.packageBody = ''
except:
pass
def __write_log(self, txtBody):
try:
fname = 'xlog' + datetime.strftime(datetime.now(), '%Y%d%m') + '.txt'
with open(fname, 'a') as f:
f.write(txtBody+'\r\n')
except:
pass
def __get_ENCODE(self,httpbytes):
code = ''
if httpbytes:
try:
char_beg = str(httpbytes).find('charset')
char_end = str(httpbytes[char_beg:]).find('\"')
if char_beg >= 0:
code = str(httpbytes)[char_beg+8:char_end].replace('\\r','').replace('\\n','')
except:
pass
return code
def __get_HTML(self,httpbytes):
html = ''
if self.__get_TYPE(httpbytes) == 'resp':
encode = self.__get_ENCODE(httpbytes)
if encode:
hstr = bytes(httpbytes).decode(encode)
b1 = hstr.find('<!DOCTYPE html>')
b2 = hstr.find('<html>')
try:
if b1 >= 0:
html = hstr[b1:]
elif b2 >= 0:
html = hstr[b2:]
except:
print('Getting HTML Error!')
return html
if __name__ == "__main__":
cfgpath = os.path.join(os.getcwd(), "settings.ini")
print(cfgpath)
conf = configparser.ConfigParser()
conf.read(cfgpath, encoding="utf-8")
iface = conf.get('settings', 'iface')
ip = conf.get('settings', 'ip')
port = conf.get('settings', 'port')
h = hcap(ip, port, iface)
h.hcap()