-
Notifications
You must be signed in to change notification settings - Fork 24
/
Copy pathPacketParser.py
157 lines (126 loc) · 4.74 KB
/
PacketParser.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
import xml.etree.ElementTree as ET
import base64
import re
class PacketParser:
def __init__(self, packet_file):
self.packet_file = packet_file
self.headers = {}
self.cookies = {}
self.body = ""
self.method = "GET"
self.url = ""
self.path = ""
self.protocol = "https"
self.is_burp = False
# Parse the file
self._parse_file()
def _parse_file(self):
"""Determine file type and parse accordingly"""
with open(self.packet_file, 'r') as f:
content = f.read()
# Check if it's a Burp file by looking for burpVersion
if 'burpVersion' in content:
self.is_burp = True
self._parse_burp_file()
else:
self._parse_raw_file()
def _parse_burp_file(self):
"""Parse Burp XML file"""
tree = ET.parse(self.packet_file)
root = tree.getroot()
# Get the first item element
item = root.find('item')
if item is None:
return
# Get base request
request_elem = item.find('request')
if request_elem is None:
return
# Check if request is base64 encoded
is_base64 = request_elem.get('base64', 'false') == 'true'
request_data = request_elem.text
if is_base64:
request_data = base64.b64decode(request_data).decode('utf-8')
# Parse the raw request data
self._parse_raw_request(request_data)
# Get URL from Burp file
url_elem = item.find('url')
if url_elem is not None:
self.url = url_elem.text
# Get protocol
protocol_elem = item.find('protocol')
if protocol_elem is not None:
self.protocol = protocol_elem.text
def _parse_raw_file(self):
"""Parse raw request file"""
with open(self.packet_file, 'r') as f:
raw_request = f.read()
self._parse_raw_request(raw_request)
def _parse_raw_request(self, raw_request):
"""Parse raw HTTP request string"""
# Split into lines
lines = raw_request.split('\n')
# Parse first line for method and path
if lines:
first_line = lines[0].strip()
parts = first_line.split(' ')
if len(parts) >= 2:
self.method = parts[0]
self.path = parts[1]
# Parse headers and cookies
header_section = True
body_lines = []
for line in lines[1:]:
line = line.strip()
# Empty line marks end of headers
if not line:
header_section = False
continue
if header_section:
if ':' in line:
key, value = line.split(':', 1)
key = key.strip()
value = value.strip()
# Parse cookies
if key.lower() == 'cookie':
cookies = value.split(';')
for cookie in cookies:
if '=' in cookie:
c_key, c_value = cookie.split('=', 1)
self.cookies[c_key.strip()] = c_value.strip()
self.headers[key] = value
# Check for Host header to construct URL
if key.lower() == 'host':
self.url = f"https://{value.strip()}{self.path}"
else:
body_lines.append(line)
self.body = '\n'.join(body_lines)
def get_headers(self):
"""Return parsed headers without 'Host' header"""
headers_copy = self.headers.copy() # Create a copy of the headers
# Remove the 'Host' header if it exists, regardless of case
headers_copy = {k: v for k, v in headers_copy.items() if k.lower() != 'host'}
return headers_copy
def get_cookies(self):
"""Return parsed cookies"""
if self.cookies:
return self.cookies
return None
def get_body(self):
"""Return request body"""
return self.body
def get_method(self):
"""Return HTTP method"""
return self.method
def get_url(self):
"""Return full URL"""
return self.url
def get_path(self):
"""Return path of the URL"""
return self.path
def get_protocol(self):
"""Return protocol (http/https)"""
return self.protocol
def is_burp_file(self):
"""Return whether file is a Burp file"""
return self.is_burp