From e525a6e512de17f4e9848d4a8eef6f4a0687b289 Mon Sep 17 00:00:00 2001 From: nfa Date: Thu, 23 Dec 2021 08:46:17 +0800 Subject: [PATCH] v1 --- httpcap.py | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 httpcap.py diff --git a/httpcap.py b/httpcap.py new file mode 100644 index 0000000..63e9918 --- /dev/null +++ b/httpcap.py @@ -0,0 +1,126 @@ +#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() +