lundi 9 août 2010

lvl3 wargame NDH2010 - crypto bruteforce substitution of characters

level3 wargame NDH2010 - crypto characters substitution

This article describes the NDH2010 wargame level3 solution. The interest stands in the search of a password generated by a substitution of the user characters.


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]

howto


first list the current directory.
    level3@srv-public:~$ ls -all
    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

crackme can't be read, only executed. Try it:

level3@srv-public:~$ ./crackme 00000000000000000000
You entered: 00000000000000000000
Ciphered: YE]|(68JYW8K8[!'ni>+
We want: 2:8vytm&*9|)].l(ol;a
It's incorrect n00b!

Use a differential cryptanalysis on the plain characters:
You entered: 01111111111111111111
Ciphered: YD\{)79KZV9J9Z"(mj=,

You can observe that first character "Y" of the cipher is not modified. See if it is still true for next chars:
You entered: 00111111111111111111
Ciphered: YE\{)79KZV9J9Z"(mj=,

Last attempt with third char:
You entered: 00011111111111111111
Ciphered: YE]{)79KZV9J9Z"(mj=,

It looks like a Vigenere or Cesar encryption, ie a substitution of each character independently from the others.

See if Python can be used:
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.
>>>

See if /tmp can be used:
level3@srv-public:~$ echo "print 'coucou'" > /tmp/essai
level3@srv-public:~$ python /tmp/essai
coucou

Here is a Python script to bruteforce each character using the output of the program as oracle. Test the script on a local program:

$ cat essai.sh
#!/bin/bash
echo "You entered: $1"
echo "Ciphered: $1"
echo "We want: 2:8vytm&*9|)].l(ol;a"
echo "It's incorrect n00b!"

Here is the script:

#!/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

Do not forget to replace essai.sh by crackme and copy the script in /tmp
$ vim /tmp/lvl3.py
i
SHIFT-INSERT
ESC
:wq

Aucun commentaire:

Enregistrer un commentaire