From 21399e07baf95d49a7c2b089c9d578a8344175f5 Mon Sep 17 00:00:00 2001 From: Leonardo Stern Date: Fri, 6 May 2016 12:12:07 -0300 Subject: [PATCH] implementing the parse from pcap feature --- SWParser.py | 103 -------------------------------------------- SWParser/gui/gui.py | 3 +- SWProxy.py | 94 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 94 insertions(+), 106 deletions(-) delete mode 100755 SWParser.py diff --git a/SWParser.py b/SWParser.py deleted file mode 100755 index d7fd2d8..0000000 --- a/SWParser.py +++ /dev/null @@ -1,103 +0,0 @@ -#!/usr/bin/env python - -from SWParser import parse_login_data, parse_visit_data -from SWParser.smon_decryptor import decrypt_request, decrypt_response -import sys -import dpkt -import json - -VERSION = "0.99" - -def parse_pcap(filename): - streams = dict() # Connections with current buffer - with open(filename, "rb") as f: - pcap = dpkt.pcap.Reader(f) - for ts, buf in pcap: - eth = dpkt.ethernet.Ethernet(buf) - if eth.type != dpkt.ethernet.ETH_TYPE_IP: - continue - ip = eth.data - if not isinstance(ip, dpkt.ip.IP): - try: - ip = dpkt.ip.IP(ip) - except: - continue - if ip.p != dpkt.ip.IP_PROTO_TCP: - continue - tcp = ip.data - - if not isinstance(tcp, dpkt.tcp.TCP): - try: - tcp = dpkt.tcp.TCP(tcp) - except: - continue - - tupl = (ip.src, ip.dst, tcp.sport, tcp.dport) - if tupl in streams: - streams[tupl] = streams[tupl] + tcp.data - else: - streams[tupl] = tcp.data - - if (tcp.flags & dpkt.tcp.TH_FIN) != 0 and \ - (tcp.dport == 80 or tcp.sport == 80) and \ - len(streams[tupl]) > 0: - other_tupl = (ip.dst, ip.src, tcp.dport, tcp.sport) - stream1 = streams[tupl] - del streams[tupl] - try: - stream2 = streams[other_tupl] - del streams[other_tupl] - except: - stream2 = "" - if tcp.dport == 80: - requests = stream1 - responses = stream2 - else: - requests = stream2 - responses = stream1 - - while len(requests): - try: - request = dpkt.http.Request(requests) - #print request.method, request.uri - except: - request = '' - requests = '' - try: - response = dpkt.http.Response(responses) - #print response.status - except: - response = '' - responses = '' - requests = requests[len(request):] - responses = requests[len(responses):] - - if len(request) > 0 and len(response) > 0 and \ - request.method == 'POST' and \ - request.uri == '/api/gateway.php' and \ - response.status == '200': - try: - req_plain = decrypt_request(request.body) - resp_plain = decrypt_response(response.body) - req_json = json.loads(req_plain) - resp_json = json.loads(resp_plain) - if resp_json['command'] == 'HubUserLogin' or resp_json['command'] == 'GuestLogin': - parse_login_data(resp_json) - elif resp_json['command'] == 'VisitFriend': - parse_visit_data(resp_json) - except: - import traceback - e = sys.exc_info()[0] - traceback.print_exc() - - elif (tcp.flags & dpkt.tcp.TH_FIN) != 0: - del streams[tupl] - -if __name__ == "__main__": - print "SWParser v%s - Summoners War Data Parser and Extractor" % VERSION - print "\tWritten by KaKaRoTo\n\nLicensed under LGPLv3 and available at : \n\thttps://github.com/kakaroto/SWParser" - - if len(sys.argv) != 2: - print "Usage :\n\t%s input.pcap" % (sys.argv[0]) - sys.exit(-1) - parse_pcap(sys.argv[1]) diff --git a/SWParser/gui/gui.py b/SWParser/gui/gui.py index 52649b1..1a9217f 100644 --- a/SWParser/gui/gui.py +++ b/SWParser/gui/gui.py @@ -45,7 +45,8 @@ def about(self): QtGui.QMessageBox.about(self, "About", "SWProxy: Summoners War Proxy Tool\nWritten by KaKaRoTo\n\nLicensed under LGPLv3 and available at : \n\thttps://github.com/kakaroto/SWParser\n") def openPCAP(self): - QtGui.QMessageBox.about(self, "Open PCAP", "Not yet implemented") + pcap_file = QtGui.QFileDialog.getOpenFileName() + SWProxy.parse_pcap(pcap_file) def log(self, str): self.ui.logWindow.addItem(str) diff --git a/SWProxy.py b/SWProxy.py index 13e16cb..3e3ccbe 100755 --- a/SWProxy.py +++ b/SWProxy.py @@ -10,6 +10,8 @@ import sys import argparse import struct +import dpkt + VERSION = "0.99" GITHUB = 'https://github.com/kakaroto/SWProxy' @@ -30,7 +32,6 @@ def handle(self, client): class SWProxyCallback(object): - def __init__(self): self.request = None @@ -123,7 +124,6 @@ def resource_path(relative_path): def start_proxy_server(options): - my_ip = get_external_ip() try: @@ -134,6 +134,96 @@ def start_proxy_server(options): pass +def parse_pcap(filename): + streams = dict() # Connections with current buffer + with open(filename, "rb") as f: + pcap = dpkt.pcap.Reader(f) + for ts, buf in pcap: + eth = dpkt.ethernet.Ethernet(buf) + if eth.type != dpkt.ethernet.ETH_TYPE_IP: + continue + ip = eth.data + if not isinstance(ip, dpkt.ip.IP): + try: + ip = dpkt.ip.IP(ip) + except: + continue + if ip.p != dpkt.ip.IP_PROTO_TCP: + continue + tcp = ip.data + + if not isinstance(tcp, dpkt.tcp.TCP): + try: + tcp = dpkt.tcp.TCP(tcp) + except: + continue + + tupl = (ip.src, ip.dst, tcp.sport, tcp.dport) + if tupl in streams: + streams[tupl] = streams[tupl] + tcp.data + else: + streams[tupl] = tcp.data + + if (tcp.flags & dpkt.tcp.TH_FIN) != 0 and \ + (tcp.dport == 80 or tcp.sport == 80) and \ + len(streams[tupl]) > 0: + other_tupl = (ip.dst, ip.src, tcp.dport, tcp.sport) + stream1 = streams[tupl] + del streams[tupl] + try: + stream2 = streams[other_tupl] + del streams[other_tupl] + except: + stream2 = "" + if tcp.dport == 80: + requests = stream1 + responses = stream2 + else: + requests = stream2 + responses = stream1 + + while len(requests): + try: + request = dpkt.http.Request(requests) + #print request.method, request.uri + except: + request = '' + requests = '' + try: + response = dpkt.http.Response(responses) + #print response.status + except: + response = '' + responses = '' + requests = requests[len(request):] + responses = requests[len(responses):] + + if len(request) > 0 and len(response) > 0 and \ + request.method == 'POST' and \ + request.uri == '/api/gateway.php' and \ + response.status == '200': + try: + req_plain = decrypt_request(request.body) + resp_plain = decrypt_response(response.body) + req_json = json.loads(req_plain) + resp_json = json.loads(resp_plain) + + if 'command' not in resp_json: + return + + try: + SWPlugin.call_plugins('process_request', (req_json, resp_json)) + except Exception as e: + logger.exception('Exception while executing plugin : {}'.format(e)) + except: + import traceback + e = sys.exc_info()[0] + traceback.print_exc() + + elif (tcp.flags & dpkt.tcp.TH_FIN) != 0: + del streams[tupl] + + if __name__ == "__main__": parser = argparse.ArgumentParser(description='SWParser') parser.add_argument('-d', '--debug', action="store_true", default=False)