xbase-util 0.4.2__tar.gz → 0.4.4__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. {xbase_util-0.4.2 → xbase_util-0.4.4}/PKG-INFO +1 -1
  2. {xbase_util-0.4.2 → xbase_util-0.4.4}/setup.py +1 -1
  3. xbase_util-0.4.4/xbase_util/dangerous_util.py +101 -0
  4. {xbase_util-0.4.2 → xbase_util-0.4.4}/xbase_util/es_db_util.py +0 -1
  5. xbase_util-0.4.4/xbase_util/packet_util.py +171 -0
  6. {xbase_util-0.4.2 → xbase_util-0.4.4}/xbase_util.egg-info/PKG-INFO +1 -1
  7. {xbase_util-0.4.2 → xbase_util-0.4.4}/xbase_util.egg-info/SOURCES.txt +1 -0
  8. xbase_util-0.4.2/xbase_util/packet_util.py +0 -93
  9. {xbase_util-0.4.2 → xbase_util-0.4.4}/README.md +0 -0
  10. {xbase_util-0.4.2 → xbase_util-0.4.4}/setup.cfg +0 -0
  11. {xbase_util-0.4.2 → xbase_util-0.4.4}/xbase_util/__init__.py +0 -0
  12. {xbase_util-0.4.2 → xbase_util-0.4.4}/xbase_util/add_column_util.py +0 -0
  13. {xbase_util-0.4.2 → xbase_util-0.4.4}/xbase_util/db/__init__.py +0 -0
  14. {xbase_util-0.4.2 → xbase_util-0.4.4}/xbase_util/db/bean/ConfigBean.py +0 -0
  15. {xbase_util-0.4.2 → xbase_util-0.4.4}/xbase_util/db/bean/CurrentConfigBean.py +0 -0
  16. {xbase_util-0.4.2 → xbase_util-0.4.4}/xbase_util/db/bean/FlowBean.py +0 -0
  17. {xbase_util-0.4.2 → xbase_util-0.4.4}/xbase_util/db/bean/TaskTemplateBean.py +0 -0
  18. {xbase_util-0.4.2 → xbase_util-0.4.4}/xbase_util/db/bean/__init__.py +0 -0
  19. {xbase_util-0.4.2 → xbase_util-0.4.4}/xbase_util/db/dao/ConfigDao.py +0 -0
  20. {xbase_util-0.4.2 → xbase_util-0.4.4}/xbase_util/db/dao/CurrentConfigDao.py +0 -0
  21. {xbase_util-0.4.2 → xbase_util-0.4.4}/xbase_util/db/dao/FlowDao.py +0 -0
  22. {xbase_util-0.4.2 → xbase_util-0.4.4}/xbase_util/db/dao/TaskTemplateDao.py +0 -0
  23. {xbase_util-0.4.2 → xbase_util-0.4.4}/xbase_util/db/dao/__init__.py +0 -0
  24. {xbase_util-0.4.2 → xbase_util-0.4.4}/xbase_util/db/initsqlite3.py +0 -0
  25. {xbase_util-0.4.2 → xbase_util-0.4.4}/xbase_util/esreq.py +0 -0
  26. {xbase_util-0.4.2 → xbase_util-0.4.4}/xbase_util/geo_util.py +0 -0
  27. {xbase_util-0.4.2 → xbase_util-0.4.4}/xbase_util/handle_features_util.py +0 -0
  28. {xbase_util-0.4.2 → xbase_util-0.4.4}/xbase_util/pcap_util.py +0 -0
  29. {xbase_util-0.4.2 → xbase_util-0.4.4}/xbase_util/xbase_constant.py +0 -0
  30. {xbase_util-0.4.2 → xbase_util-0.4.4}/xbase_util/xbase_util.py +0 -0
  31. {xbase_util-0.4.2 → xbase_util-0.4.4}/xbase_util.egg-info/dependency_links.txt +0 -0
  32. {xbase_util-0.4.2 → xbase_util-0.4.4}/xbase_util.egg-info/not-zip-safe +0 -0
  33. {xbase_util-0.4.2 → xbase_util-0.4.4}/xbase_util.egg-info/top_level.txt +0 -0
  34. {xbase_util-0.4.2 → xbase_util-0.4.4}/xbase_util_assets/GeoLite2-City.mmdb +0 -0
  35. {xbase_util-0.4.2 → xbase_util-0.4.4}/xbase_util_assets/arkimeparse.js +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: xbase_util
3
- Version: 0.4.2
3
+ Version: 0.4.4
4
4
  Summary: 网络安全基础工具
5
5
  Home-page: https://gitee.com/jimonik/xbase_util.git
6
6
  Author: xyt
@@ -3,7 +3,7 @@ from distutils.core import setup
3
3
  from setuptools import find_packages
4
4
 
5
5
  setup(name="xbase_util",
6
- version="0.4.2",
6
+ version="0.4.4",
7
7
  description="网络安全基础工具",
8
8
  long_description="包含提取,预测,训练的基础工具",
9
9
  author="xyt",
@@ -0,0 +1,101 @@
1
+ import splunklib.client as client
2
+ from splunklib import results
3
+
4
+
5
+ def get_splunk_pa(start_time, end_time, splunk_host,
6
+ splunk_port,
7
+ splunk_username,
8
+ splunk_password,
9
+ splunk_scheme="https",
10
+ splunk_filter="THREAT AND NOT informational"):
11
+ """
12
+ 获取PA威胁信息
13
+ :param splunk_filter:
14
+ :param start_time:
15
+ :param end_time:
16
+ :param splunk_host:
17
+ :param splunk_port:
18
+ :param splunk_username:
19
+ :param splunk_password:
20
+ :param splunk_scheme:
21
+ :return:
22
+ """
23
+ service = client.connect(
24
+ host=splunk_host,
25
+ port=splunk_port,
26
+ scheme=splunk_scheme,
27
+ username=splunk_username,
28
+ password=splunk_password
29
+ )
30
+ job = service.jobs.oneshot(
31
+ """search index=idx_pa
32
+ FILTER_TEXT
33
+ | rex field=_raw "THREAT,(?P<LOG_TYPE>.+?),.*?,(?P<PA_DATE>.*?),(?P<SIP>.*?),(?P<DIP>.*?),(?:.*?,.*?,.*?){7},(?P<S_PORT>.*?),(?P<D_PORT>.*?),.*?,.*?,.*?,(?P<PROTOCOL>.*?),(?P<DENY_METHOD>.*?),(?P<THREAT_SUMMARY>.*?),(?P<SEVERITY>medium|high|critical|low),"
34
+ | eval RAW_BAK=_raw
35
+ | eval THREAT_TIME = strftime(strptime(PA_DATE, "%Y/%m/%d %H:%M:%S"), "%Y-%m-%d %H:%M:%S")
36
+ | rex mode=sed field=_raw "s/.*?,\w{8}-\w{4}-\w{4}-\w{4}-\w{12},/start_ama_flag,/g"
37
+ | rex field=_raw "start_ama_flag,.*?,.*?,(?<XFF_IP>.*?),"
38
+ | eval _raw=RAW_BAK
39
+ | table THREAT_TIME,SIP,S_PORT, DIP, D_PORT,XFF_IP,PROTOCOL, DENY_METHOD, THREAT_SUMMARY, SEVERITY
40
+ | dedup THREAT_TIME,SIP,S_PORT, DIP, D_PORT,XFF_IP,PROTOCOL
41
+ """.replace("FILTER_TEXT", splunk_filter), **{
42
+ "earliest_time": start_time.strftime('%Y-%m-%dT%H:%M:%S'),
43
+ "latest_time": end_time.strftime('%Y-%m-%dT%H:%M:%S'),
44
+ "output_mode": "json",
45
+ "count": 20000
46
+ })
47
+ return [item for item in results.JSONResultsReader(job) if isinstance(item, dict)]
48
+
49
+
50
+ def get_splunk_waf(start_time, end_time, splunk_host,
51
+ splunk_port,
52
+ splunk_username,
53
+ splunk_password,
54
+ splunk_scheme="https"):
55
+ # splunk里面用这个
56
+ """
57
+ sourcetype=changting:waf
58
+ | rex field=_raw (?P<THREAT_TIME>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\+\d{2}:\d{2})
59
+ | rex field=_raw "\"src_ip\":\"(?<SIP>[^\"]+)\""
60
+ | rex field=_raw "\"protocol\":\"(?<PROTOCOL>[^\"]+)\""
61
+ | rex field=_raw "\"src_port\":(?<S_PORT>\d+)"
62
+ | rex field=_raw "\"dest_ip\":\"(?<DIP>[^\"]+)\""
63
+ | rex field=_raw "\"dest_port\":(?<D_PORT>\d+)"
64
+ | rex field=_raw "\"risk_level\":\"(?<SEVERITY>[^\"]+)\""
65
+ | rex field=_raw "\"action\":\"(?<DENY_METHOD>[^\"]+)\""
66
+ | rex field=_raw "\"reason\":\"(?<THREAT_SUMMARY>[^\"]+)\""
67
+ | rex field=_raw "\"x_forwarded_for\":\"(?<XFF_IP>[^\"]+)\""
68
+ | table THREAT_TIME,SIP,S_PORT,DIP,D_PORT,XFF_IP,PROTOCOL,DENY_METHOD,THREAT_SUMMARY,SEVERITY
69
+ | dedup THREAT_TIME,SIP,S_PORT,DIP,D_PORT,XFF_IP,PROTOCOL
70
+ """
71
+ service = client.connect(
72
+ host=splunk_host,
73
+ port=splunk_port,
74
+ scheme=splunk_scheme,
75
+ username=splunk_username,
76
+ password=splunk_password
77
+ )
78
+ # | rex field=_raw "\\"src_port\\":(?<S_PORT>\d+)"
79
+ # | rex field=_raw "\\"dest_port\\":(?<D_PORT>\d+)"
80
+ exp = """search sourcetype=changting:waf
81
+ | rex field=_raw "(?P<THREAT_TIME>\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\+\\d{2}:\\d{2})"
82
+ | rex field=_raw "\\"dest_ip\\":\\"(?<DIP>[^\\"]+)\\""
83
+ | rex field=_raw "\\"src_ip\\":\\"(?<SIP>[^\\"]+)\\""
84
+ | rex field=_raw "\\"src_port\\":(?<S_PORT>\\d+)"
85
+ | rex field=_raw "\\"dest_port\\":(?<D_PORT>\\d+)"
86
+ | rex field=_raw "\\"protocol\\":\\"(?<PROTOCOL>[^\\"]+)\\""
87
+ | rex field=_raw "\\"x_forwarded_for\\":\\"(?<XFF_IP>[^\\"]+)\\""
88
+ | rex field=_raw "\\"action\\":\\"(?<DENY_METHOD>[^\\"]+)\\""
89
+ | rex field=_raw "\\"reason\\":\\"(?<THREAT_SUMMARY>[^\\"]+)\\""
90
+ | rex field=_raw "\\"risk_level\\":\\"(?<SEVERITY>[^\\"]+)\\""
91
+ | dedup THREAT_TIME,SIP,S_PORT,DIP,D_PORT,XFF_IP,PROTOCOL
92
+ | table THREAT_TIME,SIP,S_PORT,DIP,D_PORT,XFF_IP,PROTOCOL,DENY_METHOD,THREAT_SUMMARY,SEVERITY
93
+ """
94
+ job = service.jobs.oneshot(
95
+ exp, **{
96
+ "earliest_time": start_time.strftime('%Y-%m-%dT%H:%M:%S'),
97
+ "latest_time": end_time.strftime('%Y-%m-%dT%H:%M:%S'),
98
+ "output_mode": "json",
99
+ "count": 20000
100
+ })
101
+ return [item for item in results.JSONResultsReader(job) if isinstance(item, dict)]
@@ -5,7 +5,6 @@ class EsDb:
5
5
  def __init__(self, req, manager):
6
6
  self.req = req
7
7
  self.internals = manager.dict()
8
- print("初始化:Elasticsearch DB")
9
8
 
10
9
  def get_file_by_file_id(self, node, num, prefix=None):
11
10
  key = f'{node}!{num}'
@@ -0,0 +1,171 @@
1
+ import re
2
+
3
+ from scapy.layers.inet import TCP
4
+
5
+ from xbase_util.xbase_constant import plain_content_type_columns, packetKeyname, src_dst_header, statisticHeader, \
6
+ features_key, plain_body_columns
7
+ from xbase_util.xbase_util import firstOrZero
8
+
9
+
10
+ def content_type_is_plain(packet):
11
+ """
12
+ 从单个包(包括header和body)中获取content-type并判断是否为可见类型
13
+ :param packet:
14
+ :return:
15
+ """
16
+ if ":" not in packet:
17
+ return False
18
+ for item in packet.replace("-", "_").replace(" ", "").lower().split("\n"):
19
+ if "content_type" in item:
20
+ if ":" not in item:
21
+ continue
22
+ content_type = item.split(":")[1].replace("\r", "").strip()
23
+ return content_type in plain_content_type_columns
24
+ return False
25
+
26
+
27
+ def filter_visible_chars(data):
28
+ """
29
+ 过滤不可见字符,仅保留可打印的ASCII字符
30
+ :param data:
31
+ :return:
32
+ """
33
+ return ''.join(chr(b) for b in data if 32 <= b <= 126 or b in (9, 10, 13))
34
+
35
+
36
+ def get_all_columns(
37
+ contains_packet_column=False,
38
+ contains_src_dst_column=False,
39
+ contains_statistic_column=False,
40
+ contains_features_column=False,
41
+ contains_plain_body_column=False,
42
+ contains_pcap_flow_text=False
43
+ ):
44
+ result_columns = []
45
+ if contains_packet_column:
46
+ result_columns += packetKeyname
47
+ if contains_src_dst_column:
48
+ result_columns += src_dst_header
49
+ if contains_statistic_column:
50
+ result_columns += statisticHeader
51
+ if contains_features_column:
52
+ result_columns += features_key
53
+ if contains_plain_body_column:
54
+ result_columns += plain_body_columns
55
+ if contains_pcap_flow_text:
56
+ result_columns.append(contains_pcap_flow_text)
57
+ return result_columns
58
+
59
+
60
+ def get_all_packets_by_regx(packets):
61
+ """
62
+ 通过正则pcap获取所有包的数据
63
+ :param packets:
64
+ :return:
65
+ """
66
+ streams = b""
67
+ for pkt in packets:
68
+ if TCP in pkt:
69
+ streams += bytes(pkt[TCP].payload)
70
+ text = filter_visible_chars(streams)
71
+ pattern = r"(GET|POST|HEAD|PUT|DELETE|OPTIONS|PATCH) \/[^\s]* HTTP\/\d\.\d"
72
+ requests = re.split(f"(?={pattern})", text, re.M)
73
+ all_packets = []
74
+ for item in requests:
75
+ if len(re.findall(pattern, item)) != 0:
76
+ request_text = ""
77
+ response_text = ""
78
+ response_text_list = re.findall(r"HTTP/\d\.\d \d{3}[\s\S]*", item)
79
+ if len(response_text_list) != 0:
80
+ # 有响应数据
81
+ response_text = response_text_list[0]
82
+ if response_text == "":
83
+ # 没有响应数据,那么全是请求数据
84
+ request_text = item
85
+ else:
86
+ # 有响应数据,用正则获取请求数据
87
+ request_re = re.search(
88
+ r"(GET|POST|HEAD|PUT|DELETE|OPTIONS|PATCH) \/[^\s]* HTTP\/\d\.\d[\s\S]*?\r\n\r\n", item)
89
+ if request_re:
90
+ request_text = request_re.group(0)
91
+ else:
92
+ request_text = ""
93
+ all_packets.append({"req": request_text, "res": response_text})
94
+ return all_packets
95
+
96
+
97
+ def get_body(param, is_src):
98
+ body = param.split("\r\n\r\n")[1].strip()
99
+ return "" if body is None else body
100
+
101
+
102
+ def get_header_value(header_set, value):
103
+ result = [item for item in header_set if value in item]
104
+ if len(result) != 0:
105
+ return result[0].replace(f"{value}:", "").strip()
106
+ else:
107
+ return ""
108
+
109
+
110
+ def get_detail_by_package(packets_from_pcap, publicField, use_regx):
111
+ """
112
+ 通过pcap的数量分离session并完善相关字段
113
+ :param packets_from_pcap: 通过PcAp解析出的包
114
+ :param publicField: 原始的session单条数据
115
+ :return: 完整的单条数据
116
+ """
117
+ res_field = publicField.copy()
118
+ if use_regx:
119
+ req = packets_from_pcap['req']
120
+ res = packets_from_pcap['res']
121
+ else:
122
+ res = packets_from_pcap["response"]
123
+ req = packets_from_pcap["request"]
124
+ res_field["initRTT"] = firstOrZero(res_field.get("initRTT", 0))
125
+ res_field["length"] = firstOrZero(res_field.get("length", 0))
126
+ request_lines = req.strip().split("\n")
127
+ http_request_lines = [item for item in request_lines if "HTTP" in item]
128
+ if len(http_request_lines) != 0:
129
+ first_line = http_request_lines[0].split(" ")
130
+ res_field['http.clientVersion'] = str(first_line[2]).replace("\n", "").replace("\r", "")
131
+ res_field['http.path'] = first_line[1]
132
+ res_field['http.method'] = first_line[0]
133
+ else:
134
+ res_field['http.clientVersion'] = ''
135
+ res_field['http.path'] = ''
136
+ res_field['http.method'] = ''
137
+ res_field['http.request-referer'] = get_header_value(header_set=request_lines, value="Referer")
138
+ res_field['http.request-content-type'] = get_header_value(header_set=request_lines,
139
+ value="Content-Type")
140
+ res_field['http.hostTokens'] = get_header_value(header_set=request_lines, value="Host")
141
+
142
+ if use_regx:
143
+ res_field['plain_body_src'] = ""
144
+ res_field['plain_body_dst'] = ""
145
+ if content_type_is_plain(req):
146
+ res_field['plain_body_src'] = get_body(req, is_src=True)
147
+ if content_type_is_plain(res):
148
+ res_field['plain_body_dst'] = get_body(res, is_src=False)
149
+
150
+ response_lines = res.strip().split("\n")
151
+ http_response_lines = [item for item in response_lines if "HTTP" in item]
152
+ if len(http_response_lines) != 0:
153
+ first_line = http_response_lines[0].strip().split(" ")
154
+ res_field['http.statuscode'] = first_line[1]
155
+ res_field['http.serverVersion'] = first_line[0].split("/")[1]
156
+ else:
157
+ res_field['http.statuscode'] = ""
158
+ res_field['http.serverVersion'] = ""
159
+ res_field['http.response-server'] = get_header_value(header_set=response_lines, value="Server")
160
+ res_field['http.response-content-type'] = get_header_value(header_set=response_lines,
161
+ value="Content-Type")
162
+ for response in list(set(response_lines + request_lines)):
163
+ key_value = response.replace("\r", "").split(":")
164
+ if len(key_value) == 2:
165
+ key = key_value[0].replace(" ", "").replace("-", "_").lower()
166
+ value = key_value[1].replace(" ", "")
167
+ if f"src_{key}" in src_dst_header:
168
+ res_field[f"src_{key}"] = value
169
+ if f"dst_{key}" in src_dst_header:
170
+ res_field[f"dst_{key}"] = value
171
+ return res_field
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: xbase-util
3
- Version: 0.4.2
3
+ Version: 0.4.4
4
4
  Summary: 网络安全基础工具
5
5
  Home-page: https://gitee.com/jimonik/xbase_util.git
6
6
  Author: xyt
@@ -2,6 +2,7 @@ README.md
2
2
  setup.py
3
3
  xbase_util/__init__.py
4
4
  xbase_util/add_column_util.py
5
+ xbase_util/dangerous_util.py
5
6
  xbase_util/es_db_util.py
6
7
  xbase_util/esreq.py
7
8
  xbase_util/geo_util.py
@@ -1,93 +0,0 @@
1
- import re
2
-
3
- from scapy.layers.inet import TCP
4
-
5
- from xbase_util.xbase_constant import plain_content_type_columns, packetKeyname, src_dst_header, statisticHeader, \
6
- features_key, plain_body_columns
7
-
8
-
9
- def content_type_is_plain(packet):
10
- """
11
- 从单个包(包括header和body)中获取content-type并判断是否为可见类型
12
- :param packet:
13
- :return:
14
- """
15
- if ":" not in packet:
16
- return False
17
- for item in packet.replace("-", "_").replace(" ", "").lower().split("\n"):
18
- if "content_type" in item:
19
- if ":" not in item:
20
- continue
21
- content_type = item.split(":")[1].replace("\r", "").strip()
22
- return content_type in plain_content_type_columns
23
- return False
24
-
25
-
26
- def filter_visible_chars(data):
27
- """
28
- 过滤不可见字符,仅保留可打印的ASCII字符
29
- :param data:
30
- :return:
31
- """
32
- return ''.join(chr(b) for b in data if 32 <= b <= 126 or b in (9, 10, 13))
33
-
34
-
35
- def get_all_columns(
36
- contains_packet_column=False,
37
- contains_src_dst_column=False,
38
- contains_statistic_column=False,
39
- contains_features_column=False,
40
- contains_plain_body_column=False,
41
- contains_pcap_flow_text=False
42
- ):
43
- result_columns = []
44
- if contains_packet_column:
45
- result_columns += packetKeyname
46
- if contains_src_dst_column:
47
- result_columns += src_dst_header
48
- if contains_statistic_column:
49
- result_columns += statisticHeader
50
- if contains_features_column:
51
- result_columns += features_key
52
- if contains_plain_body_column:
53
- result_columns += plain_body_columns
54
- if contains_pcap_flow_text:
55
- result_columns.append(contains_pcap_flow_text)
56
- return result_columns
57
-
58
-
59
- def get_all_packets_by_regx(packets):
60
- """
61
- 通过正则pcap获取所有包的数据
62
- :param packets:
63
- :return:
64
- """
65
- streams = b""
66
- for pkt in packets:
67
- if TCP in pkt:
68
- streams += bytes(pkt[TCP].payload)
69
- text = filter_visible_chars(streams)
70
- pattern = r"(GET|POST|HEAD|PUT|DELETE|OPTIONS|PATCH) \/[^\s]* HTTP\/\d\.\d"
71
- requests = re.split(f"(?={pattern})", text, re.M)
72
- all_packets = []
73
- for item in requests:
74
- if len(re.findall(pattern, item)) != 0:
75
- request_text = ""
76
- response_text = ""
77
- response_text_list = re.findall(r"HTTP/\d\.\d \d{3}[\s\S]*", item)
78
- if len(response_text_list) != 0:
79
- # 有响应数据
80
- response_text = response_text_list[0]
81
- if response_text == "":
82
- # 没有响应数据,那么全是请求数据
83
- request_text = item
84
- else:
85
- # 有响应数据,用正则获取请求数据
86
- request_re = re.search(
87
- r"(GET|POST|HEAD|PUT|DELETE|OPTIONS|PATCH) \/[^\s]* HTTP\/\d\.\d[\s\S]*?\r\n\r\n", item)
88
- if request_re:
89
- request_text = request_re.group(0)
90
- else:
91
- request_text = ""
92
- all_packets.append({"req": request_text, "res": response_text})
93
- return all_packets
File without changes
File without changes