-
Notifications
You must be signed in to change notification settings - Fork 0
/
xss_scan.py
93 lines (82 loc) · 3.1 KB
/
xss_scan.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
import requests
from pprint import pprint
from bs4 import BeautifulSoup as bs
from urllib.parse import urljoin
def get_all_forms(url):
"""l'url donnee est lu puis bs retourne la page html"""
soup = bs(requests.get(url).content, "html.parser")
return soup.find_all("form")
def get_form_details(form):
"""
extrait toutes les informations utiles d'un formulaire
"""
details = {}
# retourne l'action du formulaire
action = form.attrs.get("action").lower()
# retourne la méthode du formaulire
method = form.attrs.get("method", "get").lower()
# retourne tout les inputs du formaulire ansi que leurs nom et leurs types
inputs = []
for input_tag in form.find_all("input"):
input_type = input_tag.attrs.get("type", "text")
input_name = input_tag.attrs.get("name")
inputs.append({"type": input_type, "name": input_name})
# créer un dictionnaire
details["action"] = action
details["method"] = method
details["inputs"] = inputs
return details
def submit_form(form_details, url, value):
"""
valide le formulaire donne
Params:
form_details (list): le dictionnaire contenant les informations du formulaire
url (str): l'url original donné en paramètre
value (str): cette variable remplace les inputs
Retourne la réponse HTTP une fois les informations entrée
"""
# retourne l'URL en entier
target_url = urljoin(url, form_details["action"])
# retourne les inputs
inputs = form_details["inputs"]
data = {}
for input in inputs:
# remplace tout le texte et les valeurs par `value`
if input["type"] == "text" or input["type"] == "search":
input["value"] = value
input_name = input.get("name")
input_value = input.get("value")
if input_name and input_value:
# si l'attribut name et value ne sont pas NULL
# envoie les informations pour validation
data[input_name] = input_value
if form_details["method"] == "post":
#Retourne les information en méthode POST si le formulaire utilise cette méthode
return requests.post(target_url, data=data)
else:
# Si le formulaire utilise la méthode GET
return requests.get(target_url, params=data)
def scan_xss(url):
"""
Analyse et recupere tout les formulaires d'une url donnee
"""
# Obtenir tous les formulaires de la page du site vise
forms = get_all_forms(url)
print(f"[+] Detection de {len(forms)} formulaire sur {url}.")
js_script = "<Script>alert('hi')</scripT>"
# on retourne
is_vulnerable = False
# recommence pour chaque formulaire detecte
for form in forms:
form_details = get_form_details(form)
content = submit_form(form_details, url, js_script).content.decode()
if js_script in content:
print(f"[+] Faille XSS detectee a {url}")
print(f"[*] detail du formulaire :")
pprint(form_details)
is_vulnerable = True
return is_vulnerable
if __name__ == "__main__":
import sys
url = sys.argv[1]
scan_xss(url)