#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('') b2 = hstr.find('') 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()