-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathsqliAttackTest.py
More file actions
152 lines (143 loc) · 6.55 KB
/
sqliAttackTest.py
File metadata and controls
152 lines (143 loc) · 6.55 KB
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
import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin
from threading import Thread
# Initiation de la session HTTP
response = requests.Session()
class sqliAttackTest(Thread):
def __init__(self, pageList):
Thread.__init__(self)
self.pageList = pageList
self.vulnerablepages = []
def join(self):
Thread.join(self)
return self.vulnerablepages
def run(self):
for link in self.pageList:
self.try_sql_injection(link)
def get_soup(self,url):
"""
Cette fonction nous permet d'obtenir le contenu qui se trouve dans une URL
grâce notamment à la librairie BeautifuSoup
:param: L’URL dont on veut avoir le contenu
:return: Tout le contenu de l'URL grâce à la librairie BeautifulSoup
"""
return BeautifulSoup(response.get(url).content, "html.parser")
def get_all_forms(self,url):
"""
Cette fonction nous resort tous les formulaire qui existe sur la page web
:param: L’URL dont on veut avoir tous les formulaires
:return: Tous les formulaires de l'URL en param
"""
return self.get_soup(url).find_all("form")
def get_informations_form(self,form):
"""
Cette fonction nous permet d'extraire toutes les informations
possibles et utiles sur un `formulaire` HTML
:param: On lui donne un formulaire en paramètre (form)
:return: La fonction nous retourne une liste avec les actions,
méthodes et inputs d'une balise form
"""
informationForm = {}
# On va récupérer l'action du formulaire en param
try:
action = form.attrs.get("action").lower()
except:
action = None
# On va récupérer la méthode du formulaire en param
method = form.attrs.get("method", "get").lower()
# On va récupérer les inputs du formulaire en param
inputs = []
for input in form.find_all("input"):
type = input.attrs.get("type", "text")
name = input.attrs.get("name")
value = input.attrs.get("value", "")
inputs.append({"type": type, "name": name, "value": value})
# put everything to the resulting dictionary
informationForm["action"] = action
informationForm["method"] = method
informationForm["inputs"] = inputs
return informationForm
def test_vulnerable(self,response):
"""
Cette fonction booléenne permet de détermine si
une page est vulnérable à une injection SQL à partir de sa "réponse".
:param: On entre la réponse (response) lors de l'essai de l'injection SQL
:return: Le booléen
"""
errors = {
# MySQL
"you have an error in your sql syntax;",
"mysqli",
"warning: mysql",
# Oracle
"quoted string not properly terminated",
# PostgreSQL
"PostgreSQL",
}
for error in errors:
# Si on trouve l'une de ces erreurs (bien sur il y'en a beaucoup d'autres,
# mais pour eviter de faire un trop gros code, alors on a choisi de vous en mettre
# que quelques unes), ça retourne "True"
if error in response.content.decode().lower():
return True
# Sinon ça retourne false (il n'y a pas eu d'erreurs détectées)
return False
def try_sql_injection(self,url):
# On test l'injection SQL sur l'URL
for injection in "\"'":
# On ajoute une apostrophe/apostrophe double à l'URL
new_url = url + injection
print("*** Test sur : ", new_url, " ***")
# On fait une requête HTTP avec le nouveau lien
resp = response.get(new_url)
if self.test_vulnerable(resp):
# Si on rentre dans cette condition, cela veut dire que
# c'est vulnérable à une injection SQL,
# On a donc pas besoin d'extraire tous les formulaires et de faire le test sur eux
print("")
print("!!!!!!! Une vulnérabilité à été détectée de type injection SQL, voici le lien :")
print("-->", new_url)
print("")
self.vulnerablepages.append(url)
return
# On test l'injection SQL sur les formulaires
forms = self.get_all_forms(url)
print("*** Nous avons detecté ", len(forms), " formulaire dans cet URL : ", url)
for form in forms:
form_informations = self.get_informations_form(form)
for injection in "\"'":
# On prépare la requête avec les données (dans le body) que nous voulons envoyer
data = {}
for input in form_informations["inputs"]:
if input["type"] == "hidden" or input["value"]:
# Quand un formulaire est caché ou bien à une certaine valeur,
# alors il suffit simplement de l'utiliser dans le body du formulaire
try:
data[input["name"]] = input["value"] + injection
except:
pass
elif input["type"] != "submit":
# On ajoute un caractère spécial à la fin de la donnée inutile
# sauf pour le submit
data[input["name"]] = "donnéeInutile" + injection
# On join l'URL à l'action
url = urljoin(url, form_informations["action"])
if form_informations["method"] == "post":
resp = response.post(url, data=data)
elif form_informations["method"] == "get":
resp = response.get(url, params=data)
# On test maintenant si la page est vulnérable avec le formulaire
if self.test_vulnerable(resp):
print("")
print("!!!!!!! Une vulnérabilité à été détectée de type injection SQL, voici le lien :")
print("-->", url)
print("--> Et voici le formulaire :")
print("Action : " ,form_informations["action"])
print("Methode : ", form_informations["method"])
print("Inputs :")
for input in form_informations["inputs"]:
print(" ",input)
print("")
self.vulnerablepages.append(url)
break