-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcommon_vulnerability.py
executable file
·156 lines (130 loc) · 5.39 KB
/
common_vulnerability.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
#!/var/ossec/framework/python/bin/python3
######## common_vulnerability.py #######
#
# This is based on original work from Juan C. Tello
# Description:
# This wodle (Wazuh module) gives Wazuh the capability to query the manager's
# API to gather information on the vulnerability information from all agents.
# It is accompannied by the common_vulnerability.xml rule file which goes to
# /var/ossec/etc/rules/
#
# Configuration:
#
#
# <wodle name="command">
# <disabled>no</disabled>
# <tag>test</tag>
# <command>/var/ossec/framework/python/bin/python3 /var/ossec/wodles/vuln_report.py --manager WAZUH_MANAGER_IP_ADDRESS --user WAZUH_API_USER --password WAZUH_API_PASSWORD</command>
# <interval>1d</interval>
# <ignore_output>yes</ignore_output>
# <run_on_start>yes</run_on_start>
# <timeout>0</timeout>
# <!--
# <verify_sha256></verify_sha256>
# -->
# </wodle>
#
#
###############################
import logging
logging.basicConfig(format='%(asctime)s %(message)s',filename='common_vulnerability.log', encoding='utf-8', level=logging.DEBUG)
logging.info('Started common_vulnerability.py')
logging.info('Loading libraries')
import requests, urllib3, json, argparse
from socket import socket, AF_UNIX, SOCK_DGRAM
logging.info('Libraries loaded')
requests.packages.urllib3.disable_warnings()
HEADERS={}
VERIFY=False
socketAddr = '/var/ossec/queue/sockets/queue'
def get_token():
"""
Function to retrieve the Wazuh JWST token for the API
This was built for Wazuh 4.3.10. For Wazuh 4.4.0 this is expected to change
to a POST request: https://github.com/wazuh/wazuh/issues/12793
"""
request_result = requests.get(WAZUH_API + "/security/user/authenticate", auth=(WAZUH_USER, WAZUH_PASS), verify=VERIFY,timeout=5)
if request_result.status_code == 200:
token = json.loads(request_result.content.decode())['data']['token']
HEADERS['Authorization'] = f'Bearer {token}'
else:
raise Exception(f"Error obtaining response: {request_result.json()}")
def get_pages(URL,limit=500):
"""
Function to get navigate all pages of a result in the Wazuh API
"""
result = []
offset = 0
finished = False
while not finished:
request = requests.get(URL + f"?limit={limit}&offset={offset}", headers=HEADERS, verify=VERIFY,timeout=5)
if request.status_code == 200:
items = json.loads(request.content.decode())['data']
for i in items['affected_items']:
result.append(i)
# If there are more items to be gathered, iterate the offset
if items['total_affected_items'] > (limit + offset):
offset = offset + limit
if (offset + limit) > items['total_affected_items']:
limit = items['total_affected_items'] - offset
else:
finished = True
else:
if request.status_code == 401:
get_token() # Renew token
else:
raise Exception(f"Error obtaining response: {request.json()}")
return result
def get_vulnerability(agents):
"""
Function to retrieve the vulnerability of every agent
https://documentation.wazuh.com/current/user-manual/api/reference.html#tag/Syscollector
This function returns a dictionary with an vulnerability for each agent
"""
vulnerability = {}
for a in agents:
ID=a['id']
reply = get_pages(WAZUH_API + "/vulnerability/" + ID )
if len(reply) > 0:
vulnerability[str(ID)] = []
for i in range(0,len(reply)):
vulnerability[str(ID)].append({
'name': reply[i]['name'],
'version': reply[i]['version'],
'architecture': reply[i]['architecture'],
'cve': reply[i]['cve'],
'severity': reply[i]['severity'],
'status': reply[i]['status'] })
else:
vulnerability[str(ID)] = [ 'empty' ]
return vulnerability
def send_event(msg,agentId,agentName):
string = f'1:[{agentId}] ({agentName}) any->vulnerability:{msg}'
sock = socket(AF_UNIX, SOCK_DGRAM)
sock.connect(socketAddr)
sock.send(string.encode())
sock.close()
if __name__ == "__main__":
# Parsing arguments
logging.info('Reading Arguments')
parser = argparse.ArgumentParser()
parser.add_argument('-m', '--manager', type=str, default='127.0.0.1', help='*Wazuh API IP or DNS name.(def. "127.0.0.1").')
parser.add_argument('-u', '--user', type=str, default='wazuh-wui', help='*Wazuh API user (def. "wazuh-wui").')
parser.add_argument('-p', '--password', type=str, default='wazuh-wui', help='*Wazuh API user password (def. "wazuh-wui").')
args = parser.parse_args()
WAZUH_IP = args.manager
WAZUH_USER = args.user
WAZUH_PASS = args.password
WAZUH_PORT = 55000
WAZUH_API=f"https://{WAZUH_IP}:{WAZUH_PORT}"
logging.info('Getting agents (paged)')
agents = get_pages(WAZUH_API + f"/agents")
logging.info('Getting vulnerabilities from agents')
vulnerability = get_vulnerability(agents)
logging.info('Pushing data to Wazuh Socket')
for a in agents:
ID=a['id']
NAME=a['name']
if len(vulnerability[ID]) > 0:
for i in range(len(vulnerability[ID])):
send_event(json.dumps(vulnerability[ID][i]),ID,NAME)