-
Notifications
You must be signed in to change notification settings - Fork 11
/
sql_injection_detector.py
145 lines (132 loc) · 4.63 KB
/
sql_injection_detector.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
import requests,sys,time
# import re # uncomment this for DVWA
from bs4 import BeautifulSoup as bs
from urllib.parse import urljoin
from pprint import pprint
s = requests.Session()
s.headers["User-Agent"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36"
# below code is for logging to your local DVWA
# uncomment it if you want to use this on DVWA
# login_payload = {
# "username": "admin",
# "password": "password",
# "Login": "Login",
# }
# # change URL to the login page of your DVWA login URL
# login_url = "http://localhost:8080/DVWA-master/login.php"
# # login
# r = s.get(login_url)
# token = re.search("user_token'\s*value='(.*?)'", r.text).group(1)
# login_payload['user_token'] = token
# s.post(login_url, data=login_payload)
print('''\033[92m
___ ___ _ ___ ___ _ _
/ __|/ _ \| | |_ _| | \ ___| |_ ___ __| |_ ___ _ _
\__ \ (_) | |__ | | | |) / -_) _/ -_) _| _/ _ \ '_|
|___/\__\_\____||___| |___/\___|\__\___\__|\__\___/_|
example : python sql_injection_detector.py <url>
coded by R3DHULK
Github Page : https://github.com/R3DHULK
''')
try:
def slowprint(s):
for c in s + '\n' :
sys.stdout.write(c)
sys.stdout.flush()
time.sleep(10. / 100)
def get_all_forms(url):
"""Given a `url`, it returns all forms from the HTML content"""
soup = bs(s.get(url).content, "html.parser")
return soup.find_all("form")
def get_form_details(form):
"""
This function extracts all possible useful information about an HTML `form`
"""
details = {}
# get the form action (target url)
try:
action = form.attrs.get("action").lower()
except:
action = None
# get the form method (POST, GET, etc.)
method = form.attrs.get("method", "get").lower()
# get all the input details such as type and name
inputs = []
for input_tag in form.find_all("input"):
input_type = input_tag.attrs.get("type", "text")
input_name = input_tag.attrs.get("name")
input_value = input_tag.attrs.get("value", "")
inputs.append({"type": input_type, "name": input_name, "value": input_value})
# put everything to the resulting dictionary
details["action"] = action
details["method"] = method
details["inputs"] = inputs
return details
def is_vulnerable(response):
"""A simple boolean function that determines whether a page
is SQL Injection vulnerable from its `response`"""
errors = {
# MySQL
"you have an error in your sql syntax;",
"warning: mysql",
# SQL Server
"unclosed quotation mark after the character string",
# Oracle
"quoted string not properly terminated",
}
for error in errors:
# if you find one of these errors, return True
if error in response.content.decode().lower():
return True
# no error detected
return False
def scan_sql_injection(url):
# test on URL
for c in "\"'":
# add quote/double quote character to the URL
new_url = f"{url}{c}"
print("\033[93m [!] Trying", new_url)
# make the HTTP request
res = s.get(new_url)
if is_vulnerable(res):
# SQL Injection detected on the URL itself,
# no need to preceed for extracting forms and submitting them
print("\033[92m [+] SQL Injection vulnerability detected, link:", new_url)
return
# test on HTML forms
forms = get_all_forms(url)
slowprint(f"\033[92m [+] Detected {len(forms)} forms on {url}.")
for form in forms:
form_details = get_form_details(form)
for c in "\"'":
# the data body we want to submit
data = {}
for input_tag in form_details["inputs"]:
if input_tag["value"] or input_tag["type"] == "hidden":
# any input form that has some value or hidden,
# just use it in the form body
try:
data[input_tag["name"]] = input_tag["value"] + c
except:
pass
elif input_tag["type"] != "submit":
# all others except submit, use some junk data with special character
data[input_tag["name"]] = f"test{c}"
# join the url with the action (form request URL)
url = urljoin(url, form_details["action"])
if form_details["method"] == "post":
res = s.post(url, data=data)
elif form_details["method"] == "get":
res = s.get(url, params=data)
# test whether the resulting page is vulnerable
if is_vulnerable(res):
slowprint("\033[92m [+] SQL Injection vulnerability detected, link:", url)
slowprint("\033[92m [+] Form:")
pprint(form_details)
break
if __name__ == "__main__":
import sys
url = sys.argv[1]
scan_sql_injection(url)
except KeyboardInterrupt:
slowprint("\n\033[91m [-] Exiting...")