FlowAnalyzer 0.4.5__tar.gz → 0.4.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {flowanalyzer-0.4.5 → flowanalyzer-0.4.6}/FlowAnalyzer/PacketParser.py +10 -4
- {flowanalyzer-0.4.5 → flowanalyzer-0.4.6}/FlowAnalyzer.egg-info/PKG-INFO +1 -1
- {flowanalyzer-0.4.5 → flowanalyzer-0.4.6}/PKG-INFO +1 -1
- {flowanalyzer-0.4.5 → flowanalyzer-0.4.6}/setup.py +1 -1
- flowanalyzer-0.4.6/tests/test_parser.py +52 -0
- flowanalyzer-0.4.5/tests/test_parser.py +0 -47
- {flowanalyzer-0.4.5 → flowanalyzer-0.4.6}/FlowAnalyzer/FlowAnalyzer.py +0 -0
- {flowanalyzer-0.4.5 → flowanalyzer-0.4.6}/FlowAnalyzer/Models.py +0 -0
- {flowanalyzer-0.4.5 → flowanalyzer-0.4.6}/FlowAnalyzer/Path.py +0 -0
- {flowanalyzer-0.4.5 → flowanalyzer-0.4.6}/FlowAnalyzer/PcapSplitter.py +0 -0
- {flowanalyzer-0.4.5 → flowanalyzer-0.4.6}/FlowAnalyzer/__init__.py +0 -0
- {flowanalyzer-0.4.5 → flowanalyzer-0.4.6}/FlowAnalyzer/logging_config.py +0 -0
- {flowanalyzer-0.4.5 → flowanalyzer-0.4.6}/FlowAnalyzer.egg-info/SOURCES.txt +0 -0
- {flowanalyzer-0.4.5 → flowanalyzer-0.4.6}/FlowAnalyzer.egg-info/dependency_links.txt +0 -0
- {flowanalyzer-0.4.5 → flowanalyzer-0.4.6}/FlowAnalyzer.egg-info/top_level.txt +0 -0
- {flowanalyzer-0.4.5 → flowanalyzer-0.4.6}/LICENSE +0 -0
- {flowanalyzer-0.4.5 → flowanalyzer-0.4.6}/README.md +0 -0
- {flowanalyzer-0.4.5 → flowanalyzer-0.4.6}/setup.cfg +0 -0
- {flowanalyzer-0.4.5 → flowanalyzer-0.4.6}/tests/test.py +0 -0
- {flowanalyzer-0.4.5 → flowanalyzer-0.4.6}/tests/test_split.py +0 -0
|
@@ -20,7 +20,7 @@ class PacketParser:
|
|
|
20
20
|
4: tcp.payload
|
|
21
21
|
5: frame.time_epoch
|
|
22
22
|
6: exported_pdu.exported_pdu
|
|
23
|
-
7: http.request.full_uri
|
|
23
|
+
7: http.request.full_uri
|
|
24
24
|
8: tcp.segment.count
|
|
25
25
|
"""
|
|
26
26
|
frame_num = int(row[3])
|
|
@@ -48,9 +48,11 @@ class PacketParser:
|
|
|
48
48
|
headerEnd = file_data.find(b"\r\n\r\n")
|
|
49
49
|
if headerEnd != -1:
|
|
50
50
|
return file_data[: headerEnd + 4], file_data[headerEnd + 4 :]
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
|
|
52
|
+
headerEnd = file_data.find(b"\n\n")
|
|
53
|
+
if headerEnd != -1:
|
|
54
|
+
return file_data[: headerEnd + 2], file_data[headerEnd + 2 :]
|
|
55
|
+
|
|
54
56
|
return b"", file_data
|
|
55
57
|
|
|
56
58
|
@staticmethod
|
|
@@ -73,6 +75,10 @@ class PacketParser:
|
|
|
73
75
|
raise ValueError("Not chunked data")
|
|
74
76
|
|
|
75
77
|
size_line = file_data[cursor:newline_idx].strip()
|
|
78
|
+
# Handle chunk extension: ignore everything after ';'
|
|
79
|
+
if b";" in size_line:
|
|
80
|
+
size_line = size_line.split(b";", 1)[0].strip()
|
|
81
|
+
|
|
76
82
|
if not size_line:
|
|
77
83
|
cursor = newline_idx + 1
|
|
78
84
|
continue
|
|
@@ -7,7 +7,7 @@ with open(os.path.join(os.path.dirname(__file__), "README.md"), encoding="utf-8"
|
|
|
7
7
|
|
|
8
8
|
setup(
|
|
9
9
|
name="FlowAnalyzer",
|
|
10
|
-
version="0.4.
|
|
10
|
+
version="0.4.6",
|
|
11
11
|
description="FlowAnalyzer是一个流量分析器,用于解析和处理tshark导出的JSON数据文件",
|
|
12
12
|
author="Byxs20",
|
|
13
13
|
author_email="97766819@qq.com",
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import binascii
|
|
2
|
+
import gzip
|
|
3
|
+
import unittest
|
|
4
|
+
from urllib import parse
|
|
5
|
+
|
|
6
|
+
from FlowAnalyzer.PacketParser import PacketParser
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class TestPacketParserOptimization(unittest.TestCase):
|
|
10
|
+
def test_gzip_decompression(self):
|
|
11
|
+
# Construct a fake HTTP response with GZIP body
|
|
12
|
+
content = b"Hello, Gzip World!"
|
|
13
|
+
compressed = gzip.compress(content)
|
|
14
|
+
header = b"HTTP/1.1 200 OK\r\nContent-Encoding: gzip\r\n\r\n"
|
|
15
|
+
full_response = header + compressed
|
|
16
|
+
|
|
17
|
+
full_request_hex = binascii.hexlify(full_response)
|
|
18
|
+
|
|
19
|
+
# Test extract_http_file_data
|
|
20
|
+
extracted_header, extracted_body = PacketParser.extract_http_file_data(full_request_hex)
|
|
21
|
+
|
|
22
|
+
self.assertEqual(extracted_header, header)
|
|
23
|
+
self.assertEqual(extracted_body, content)
|
|
24
|
+
|
|
25
|
+
def test_basic_extraction(self):
|
|
26
|
+
# Case: Simple text body, no chunking
|
|
27
|
+
content = b"Simple Body"
|
|
28
|
+
header = b"HTTP/1.1 200 OK\r\n\r\n"
|
|
29
|
+
full_response = header + content
|
|
30
|
+
full_request_hex = binascii.hexlify(full_response)
|
|
31
|
+
|
|
32
|
+
extracted_header, extracted_body = PacketParser.extract_http_file_data(full_request_hex)
|
|
33
|
+
self.assertEqual(extracted_body, content)
|
|
34
|
+
|
|
35
|
+
def test_chunked_decoding(self):
|
|
36
|
+
# Case: Chunked body
|
|
37
|
+
# 5\r\nHello\r\n0\r\n\r\n
|
|
38
|
+
chunked_body = bytes.fromhex(
|
|
39
|
+
"333b577644436167386f6a6d41707950734d36456d590d0a6e616d0d0a323b5052457a347a3678686b797875775656506d645a7757700d0a653d0d0a333b30544350750d0a6868680d0a333b4271694b6e7056486c4338750d0a2532370d0a333b4562636d544855354b6a58485976725575615074414d0d0a2537430d0a313b6a694f4542774c44624b3267620d0a250d0a333b376c6447726b3663350d0a3743250d0a313b3232424d6c5838426f360d0a320d0a333b684d61354547593339740d0a3853450d0a313b41723843390d0a4c0d0a333b31693052423453360d0a4543540d0a313b444968514d3164633870560d0a250d0a333b4d73736a630d0a3230250d0a323b4a77756d74324636440d0a32370d0a323b37654844337a30646430454d55643353636c0d0a52430d0a323b797549574643783137377330476630530d0a75470d0a323b6552794878625735625175485a64575832450d0a25320d0a313b5a7145444c32690d0a370d0a333b346a637a720d0a2532300d0a333b39627a59497650544b39714655376f6a6d374d664d305976480d0a46524f0d0a313b5556477645615749584e62784f0d0a4d0d0a323b4b503748426f7a6f687530744e514a6c59634a44417156630d0a25320d0a313b3458467945466a3347366f765869694f650d0a300d0a333b696a3054754c3578595768705049390d0a4455410d0a313b595730494f0d0a4c0d0a323b4e3567485a4861504d3233346b50564b4b4f45464e390d0a25320d0a313b495254683876435468625137334a773669397a0d0a300d0a333b414635416a7265585977356e35496b67453952513252420d0a5748450d0a313b67565846465a586b547074313752574d580d0a520d0a323b614e7a5947754948774339790d0a45250d0a313b3076757a444f43446e36613162313269424c73796b616e65430d0a320d0a323b41666e524d716447540d0a30390d0a333b427a3773504a534d370d0a3736360d0a333b34544757775458484a51687a7666596238326a6c6b39440d0a2533440d0a323b48334b35646c4c0d0a39370d0a323b7362517563480d0a36360d0a333b326c6f45534c79684f32495535306865756f300d0a2532300d0a333b65415169345751456e4c4d30446d39636d537836430d0a414e440d0a333b65556a4c6b4a6635635441364c346c3731305547376c67570d0a2532300d0a333b63416f4d546771444c590d0a3937390d0a323b523778364233616167387648310d0a39250d0a333b7765764b577a52530d0a3344490d0a323b527344505845754a517563314c54434d0d0a46250d0a313b45617431624b354c4e76365465384c0d0a320d0a313b48725072376d6c7231666265446c7353454d6f4d550d0a380d0a313b634137714b43516e5671387155794d7046367a4c38665058650d0a250d0a323b4f664c343252727364356f4d6855644548336878745459720d0a32380d0a333b70336e437046720d0a4f52440d0a323b4972505332386b344f42416b414b306d6e7769724156370d0a25320d0a323b7476674d72366363670d0a384d0d0a323b317a4f77623045774256516641486a7266386858576d6946710d0a49440d0a323b3779366b7077375a304b6a46777a724e0d0a25320d0a323b5259684b71336e4853656d786b564952514b53444877346d0d0a38250d0a333b3264365a4d3643674451700d0a3238530d0a323b4d61443468473772496b59336c565a476f6d0d0a454c0d0a323b31476336376e6f46750d0a45430d0a333b746774754b0d0a5425320d0a313b6549464d676a594b6b4b4f487143654169540d0a300d0a313b327530776264486f5363737536327370757076580d0a490d0a333b716d733841370d0a464e550d0a333b78563962414232630d0a4c4c250d0a313b3733507567370d0a320d0a333b454b4e6268326a316271415635440d0a3843410d0a313b52787738716c78454f4a6d6d700d0a530d0a323b6a337954446476564d516372714f360d0a54250d0a333b4e47566976674144590d0a3238660d0a323b5954615959654b474c564b41536e78650d0a6c610d0a323b6272557a796e324179304d667a6c6f6e0d0a67250d0a323b684870416876446c706f570d0a32300d0a323b6172786778475938714c51655677503931687453344d456c530d0a41530d0a313b4a52304472594a69427972794b74646d31666950340d0a250d0a313b546835467a0d0a320d0a313b6d6c366d39774b514435745841725059750d0a300d0a313b314a484a690d0a430d0a313b6c524b5531477152466e6e454d46754e64780d0a480d0a313b61447071630d0a410d0a313b6d7a65557152486455337a756a730d0a520d0a333b474e4d375164436f4a3042696d0d0a2532390d0a323b7655686967646f3373727739456f67547a4c0d0a25320d0a323b34576a6d747a394c5744384d77434831567175786d7a706d350d0a43300d0a313b343831656f4c5a720d0a780d0a333b456e64787155527049734372540d0a3230250d0a313b63797356646954553537510d0a320d0a323b4e447159334557710d0a39250d0a323b776d44496a4f0d0a32300d0a333b535839487375573269476247440d0a46524f0d0a333b4d7636616e53516e586a3072714337487936536b576558570d0a4d25320d0a323b5441674444626d6437480d0a30740d0a333b784f346a79584f677251676f390d0a6573740d0a333b6b5766563469557466430d0a2e666c0d0a323b6d334b4d416565430d0a61670d0a333b6a6141744d4631576d540d0a2532300d0a313b3150596e30506e75570d0a4f0d0a333b683638724e36554a684f6a476a65450d0a5244450d0a313b4f51316c736a6e344b337049540d0a520d0a333b7257625142566452613868464b4c7352780d0a2532300d0a333b3941694b4d4454596976647476423561347642676739440d0a4259250d0a323b66626d764c5475434855505064644d796d320d0a32300d0a313b716933793571563066467a63556166643245770d0a660d0a313b524b424673594f3574694342360d0a6c0d0a323b6d494343414c0d0a61670d0a313b6c4b4236585632384b72316e33750d0a250d0a333b6d77794e6765520d0a32304c0d0a333b4849337031346574450d0a494d490d0a333b425836546a4a68306e43754c6a6b4d7436646c760d0a5425320d0a333b356e363078326d4b6f5a7063484f6b654f5a7861386774594d0d0a3030250d0a313b39753457534e655a0d0a320d0a323b77536e544967446b0d0a43310d0a323b3372446f630d0a25320d0a333b32636f744f4759700d0a3925320d0a333b35464f6d34706b636346376a5a7973304e776a750d0a4334320d0a313b686f645257386c6a776c6e5a47675a6d4e4c690d0a250d0a323b624e6d784c0d0a32430d0a333b66374e6931536d6c0d0a3125320d0a313b4d46466e573043645637340d0a390d0a313b774b4e4645454445747a4a537075325a4c626d78656a49304c0d0a250d0a333b636e595a5843373633767a5343636c6b5936790d0a3239250d0a323b343731684f545179580d0a33450d0a333b5166684944494c4a675556754937616244410d0a3125320d0a323b753442385358704742536e0d0a39250d0a323b4f374c73474b775169324b30330d0a32430d0a313b6b375639414951544d4661713879745541540d0a530d0a313b6533336944690d0a4c0d0a323b6f75386d44324343504e4870316232474f0d0a45450d0a323b6e4b6f644d0d0a50250d0a323b4b45584b6b43750d0a32380d0a333b495357635771784f39507750724244766772370d0a3125320d0a323b42596b4a4948704c62623147760d0a39250d0a333b783347786e434b776e48370d0a3243390d0a313b7837396f49670d0a370d0a323b734634364168736c7968547a667a756f32520d0a39390d0a333b5a786e37734e69534d7356386d51685244637872594953490d0a2532390d0a333b416e586f37345071447531500d0a2532390d0a323b6f7164664144327247580d0a25370d0a313b39384f494f4358644a6d66664f386c770d0a430d0a333b47565a6e593965457769584a0d0a2537430d0a323b614e376c4b6147544c77735172786342410d0a25320d0a333b6563585745797364467679474162306f61515a7966327239660d0a3726700d0a333b6e7878464c545a65527779646639310d0a6173730d0a323b4952463149314a36490d0a3d780d0a323b3567327643664e0d0a78780d0a300d0a0d0a"
|
|
40
|
+
)
|
|
41
|
+
header = b"HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"
|
|
42
|
+
full_response = header + chunked_body
|
|
43
|
+
full_request_hex = binascii.hexlify(full_response)
|
|
44
|
+
extracted_header, extracted_body = PacketParser.extract_http_file_data(full_request_hex)
|
|
45
|
+
self.assertEqual(
|
|
46
|
+
parse.unquote_to_bytes(extracted_body), # 手动url解码一下
|
|
47
|
+
b"name=hhh'||(SELECT 'RCuG' FROM DUAL WHERE 9766=9766 AND 9799=IF((ORD(MID((SELECT IFNULL(CAST(flag AS CHAR),0x20) FROM test.flag ORDER BY flag LIMIT 0,1),42,1))>1),SLEEP(1),9799))||'&pass=xxx",
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
if __name__ == "__main__":
|
|
52
|
+
unittest.main()
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import binascii
|
|
2
|
-
import gzip
|
|
3
|
-
import unittest
|
|
4
|
-
|
|
5
|
-
from FlowAnalyzer.PacketParser import PacketParser
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class TestPacketParserOptimization(unittest.TestCase):
|
|
9
|
-
def test_gzip_decompression(self):
|
|
10
|
-
# Construct a fake HTTP response with GZIP body
|
|
11
|
-
content = b"Hello, Gzip World!"
|
|
12
|
-
compressed = gzip.compress(content)
|
|
13
|
-
header = b"HTTP/1.1 200 OK\r\nContent-Encoding: gzip\r\n\r\n"
|
|
14
|
-
full_response = header + compressed
|
|
15
|
-
|
|
16
|
-
full_request_hex = binascii.hexlify(full_response)
|
|
17
|
-
|
|
18
|
-
# Test extract_http_file_data
|
|
19
|
-
extracted_header, extracted_body = PacketParser.extract_http_file_data(full_request_hex)
|
|
20
|
-
|
|
21
|
-
self.assertEqual(extracted_header, header)
|
|
22
|
-
self.assertEqual(extracted_body, content)
|
|
23
|
-
|
|
24
|
-
def test_basic_extraction(self):
|
|
25
|
-
# Case: Simple text body, no chunking
|
|
26
|
-
content = b"Simple Body"
|
|
27
|
-
header = b"HTTP/1.1 200 OK\r\n\r\n"
|
|
28
|
-
full_response = header + content
|
|
29
|
-
full_request_hex = binascii.hexlify(full_response)
|
|
30
|
-
|
|
31
|
-
extracted_header, extracted_body = PacketParser.extract_http_file_data(full_request_hex)
|
|
32
|
-
self.assertEqual(extracted_body, content)
|
|
33
|
-
|
|
34
|
-
def test_chunked_decoding(self):
|
|
35
|
-
# Case: Chunked body
|
|
36
|
-
# 5\r\nHello\r\n0\r\n\r\n
|
|
37
|
-
chunked_body = b"5\r\nHello\r\n0\r\n\r\n"
|
|
38
|
-
header = b"HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"
|
|
39
|
-
full_response = header + chunked_body
|
|
40
|
-
full_request_hex = binascii.hexlify(full_response)
|
|
41
|
-
|
|
42
|
-
extracted_header, extracted_body = PacketParser.extract_http_file_data(full_request_hex)
|
|
43
|
-
self.assertEqual(extracted_body, b"Hello")
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
if __name__ == "__main__":
|
|
47
|
-
unittest.main()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|