solution
level3@srv-public:~$ python /tmp/lvl3.py
mot de passe
You entered: YOU>are\A^tRuE[ 33 z
Ciphered: 2:8vytm&*9|)].l(ol;a
We want: 2:8vytm&*9|)].l(ol;a
Good Job!
YOU>are\A^tRuE[ 33 z
[89, 79, 85, 62, 97, 114, 101, 92, 65, 94, 116, 82, 117, 69, 91, 17, 51, 51, 23, 122]
résolution
Commencons par lister le répertoirelevel3@srv-public:~$ ls -allle crackme ne peut pas être lu, seulement exécuté. Un petit essai pour voir.
total 32
dr-xr-x--- 2 level3 level3 4096 24 juin 13:24 .
drwxr-x--x 24 root root 4096 18 juin 18:19 ..
lrwxrwxrwx 1 root root 9 28 mai 16:09 .bash_history -> /dev/null
-rw-r--r-- 1 root root 220 12 mai 2008 .bash_logout
-rw-r--r-- 1 root root 3116 12 mai 2008 .bashrc
---s--x--- 1 level4 level3 5966 16 juin 09:55 crackme
-r--r----- 1 level3 level3 7 1 janv. 2008 passwd
-rw-r--r-- 1 root root 675 12 mai 2008 .profile
level3@srv-public:~$ ./crackme 00000000000000000000Utilisons la méthode de cryptanalyse différentielle sur les caractères du clair
You entered: 00000000000000000000
Ciphered: YE]|(68JYW8K8[!'ni>+
We want: 2:8vytm&*9|)].l(ol;a
It's incorrect n00b!
You entered: 01111111111111111111Nous remarquons que le premier caractère "Y" du chiffré est conservé. Voyons si ca marche encore pour le second:
Ciphered: YD\{)79KZV9J9Z"(mj=,
You entered: 00111111111111111111Un dernier essai avec le 3ème
Ciphered: YE\{)79KZV9J9Z"(mj=,
You entered: 00011111111111111111Visiblement nous avons affaire à un chiffrement de César ou de Vigenere, c'est à dire une substitution pour chaque caractère. Vérifions si nous pouvons lancer un script python:
Ciphered: YE]{)79KZV9J9Z"(mj=,
level3@srv-public:~$ python
Python 2.5.5 (r255:77872, Apr 21 2010, 08:44:16)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
Et vérifions si le répertoire /tmp peut être utilisé:
level3@srv-public:~$ echo "print 'coucou'" > /tmp/essai
level3@srv-public:~$ python /tmp/essai
coucou
Nous allons donc créer un script python qui bruteforce chaque caractère en utilisant la sortie du programme comme oracle. Nous testerons notre script python sur un programme en local:
$ cat essai.shVoici notre script
#!/bin/bash
echo "You entered: $1"
echo "Ciphered: $1"
echo "We want: 2:8vytm&*9|)].l(ol;a"
echo "It's incorrect n00b!"
#!/bin/python
# solution level3 wargame NDH 2010 par t0ka7a
import string, os
clair = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
cipher = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
solution = [ord('2'),ord(':'),ord('8'),ord('v'),ord('y'),ord('t'),ord('m'),ord('&'),ord('*'),ord('9'),ord('|'),ord(')'),ord(']'),ord('.'),ord('l'),ord('('),ord('o'),ord('l'),ord(';'),ord('a')]
cipher_string = ''
# pour chaque caractere de la solution
for i in range(20):
# pour chaque entier de la table ASCII sauf 0
for j in range(1,256):
# exclure LF et '
if j==10: j+=1
if j==39: j+=1
clair[i] = j
# construction de l'entree de la commande
cmd = "./essai.sh '"
# pour chaque caractere du clair
for k in range(20):
cmd += chr(clair[k])
cmd += "'"
out = os.popen(cmd).readlines()
# pour reperer quand la sortie de la commande change
if out[0].split(' ')[0] == "You":
# cipher_string = 2eme mot de la 2eme ligne de la sortie de la commande
cipher_string = out[1].split(' ')[1]
# si le caractere cipher est un retour chariot, la longueur de la chaine sera plus petite
if len(cipher_string) == 21:
for k in range(20):
cipher[k] = ord(cipher_string[k])
if cipher[i] == solution [i]:
break
else:
for line in out:
print line
break
# affichage du clair pour faire joli
sortie = ''
for k in range(20):
sortie += chr(clair[k])
print sortie
Sans oublier de remplacer essai.sh par crackme, nous le placons dans un fichier dans le répertoire /tmp
$ vim /tmp/lvl3.py
i
SHIFT-INSERT
ESC
:wq
Merci pour les solutions !
RépondreSupprimerÇa permet au noob que je suis de découvrir des trucs !
Simple petit truc : c'est moche d'utiliser python pour faire ça : solution = [ord('2'),ord(':'),ord('8'),ord('v'),ord('y'),ord('t'),ord('m'),ord('&'),ord('*'),ord('9'),ord('|'),ord(')'),ord(']'),ord('.'),ord('l'),ord('('),ord('o'),ord('l'),ord(';'),ord('a')]
=> solution = map(ord, "2:8vytm&*9|)].l(ol;a")
:-)
Beau boulot pour le brute force.
RépondreSupprimerY'avait d'autres manière de résoudre dont celle de guessing ;).
On remarque après quelques manipulations que ça ressemble à une crypto symmétrique.
Donc on entre le "hash" attendu :
"2:8vytm&*9|)].l(ol;a"
On fini avec une partie de la solution.
Certains caractères sont à deviner ou bruteforce ;).
J'ai fini par devoir bruteforce 2 caractères :].