NotesSecurity

Solutions challenges Bandit OverTheWire (1-24)

J’ai commencé à m’amuser avec les « challenges » du site OverTheWire. Ce site propose des exercices pour s’exercer à la sécurité sous Linux. Pour le moment, je n’en ai fait que quelques exercices, je vais poster les solutions que je trouve au fur et à mesure que j’avance.

Challenges Bandits

On se connecte tout d’abord en SSH sur l’adresse bandit.labs.overthewire.org avec bandit0:bandit0.

Niveau 0 -> 1
Le mot de passe est stocké dans le fichier readme. Il suffit de lister le répertoire.


[email protected]:~$ ls
readme
[email protected]:~$ cat readme
boJ9jbbUNNfktd78OOpsqOltutMc3MY1

Niveau 1 -> 2
Le mot de passe est ici stocké dans un fichier nommé « -« , hors « – » étant utilisé pour les arguments des commandes, pour lire ce fichier il est nécessaire d’ajouter ./ ou la location absolue pour l’afficher.


[email protected]:~$ ls
-
[email protected]:~$ cat ./-
CV1DtqXWVFXTvM2F0k09SHz0YwRINYA9

Niveau 2 -> 3
Pour cet exercice, le mot de passe est stocké dans un fichier contenant des espaces, on a juste à les échapper avec des « / ».


[email protected]:~$ ls
spaces in this filename
[email protected]:~$ cat spaces\ in\ this\ filename"
UmHadQclWmgdLOKQ3YNgjWxGoRMb5luK

Niveau 3 -> 4
Le mot de passe est stocké dans un fichier caché. On affiche avec l’argument « -a » de ps.


[email protected]:~$ ls
inhere
[email protected]:~$ cd inhere
[email protected]:~/inhere$ ls -la
total 12
drwxr-xr-x 2 root    root    4096 2012-05-10 23:51 .
drwxr-xr-x 3 root    root    4096 2012-05-10 23:51 ..
-rw-r----- 1 bandit4 bandit3   33 2012-05-10 23:51 .hidden
[email protected]:~/inhere$ cat .hidden
pIwrPrtPN36QITSp3EQaw936yaFoFgAB

Niveau 4 -> 5
Le mot de passe est stocké dans le seul fichier lisible par un « humain » à comprendre, le seul fichier contenant des caractères ASCII ou Unicode. On utilise donc la commande « file ».


[email protected]:~$ cd inhere
[email protected]:~/inhere$ file ./-*
./-file00: data
./-file01: data
./-file02: data
./-file03: data
./-file04: data
./-file05: data
./-file06: data
./-file07: ASCII text
./-file08: data
./-file09: data
[email protected]:~/inhere$ cat ./-file07
koReBOKuIDDepwhWk7jZC0RTdopnAYKh

Niveau 5 -> 6
Le mot de passe est stocké dans un fichier de 1033 bytes. On utilise donc la commande find avec l’attribue « size »


[email protected]:~$ find inhere -size 1033c
./-file00: data
./-file01: data
./-file02: data
./-file03: data
./-file04: data
./-file05: data
./-file06: data
./-file07: ASCII text
./-file08: data
./-file09: data
[email protected]:~/inhere$ cat ./-file07
koReBOKuIDDepwhWk7jZC0RTdopnAYKh

Niveau 6 -> 7
Cette fois-ci, on ne sait pas où se trouve le fichier contenant le mot de passe sur le serveur.On sait par contre qu’il appartient à l’utilisateur bandit7 et au groupe bandit6. On le trouve donc avec la commande find et les options « -user » et « -group »


[email protected]:~$ find / -user bandit7 -group bandit6 2>/dev/null
/var/lib/dpkg/info/bandit7.password
[email protected]:~$ cat /var/lib/dpkg/info/bandit7.password
HKBPTKQnIay4Fw76bEy8PVxKEDQRKTzs

Niveau 7 -> 8
Le mot de passe est contenu dans data.txt, à coté du mot « millionth », on filtre donc avec « grep » le contenu du fichier.


[email protected]:~$ grep millionth data.txt
millionth       cvX2JJa4CFALtqS87jk27qwqGhBM9plV

Niveau 8 -> 9
Le mot de passe est contenu dans data.txt sur la seule ligne unique du fichier. On trie le fichier à l’aide « sort » et on affiche uniquement les lignes uniques à l’aide de « uniq -u ».


[email protected]:~$ cat data.txt | sort | uniq -u
UsvVyFSfZZWbi6wgC7dAFyFuR6jQQUhR

Niveau 9 -> 10
Le fichier data.txt contenant le mot de passe est un binaire. J’ai essayé avec « grep -a « = » data.txt mais cela ne m’a pas donné le résultat que j’escomptais, j’ai donc utilisé la commande « strings » qui affiche les chaines de caractères contenues dans un binaire et « grep » pour filtrer les lignes commençant par « = ».


[email protected]:~$ strings data.txt | grep =
Rj=G
========== the
=qy9g
,========== passwordc
========== is
=9-5
O=p~
#r=t!
7e}=eG
========== truKLdjsbJ5g7yyJ2X2R0o3a5HQJFuLk
uXI/{I=VPO=
6'Q|_=Vt
:={!
yd=6

Niveau 10 -> 11
Dans cet exercice, le texte contenu dans le fichier data.txt était codé en base64. Il a donc fallu le décoder à l’aide de la commande base64 et de l’argument « -d »


[email protected]:~$ base64 -d data.txt
The password is IFukwKGsFW8MOq3IRFqrxE1hxTNEbUPR

Niveau 11 -> 12
Dans cet exercice, le texte contenu dans le fichier data.txt était codé à l’aide du Rot13. Toute les lettres avaient été décalées de 13 positions. Il a donc fallu faire les rotations nécessaire à l’aide de la commande tr.


[email protected]:~$ cat data.txt |tr a-zA-Z n-za-mN-ZA-M
The password is 5Te8Y4drgCRfCx8ugdwuEX8KFC6k2EUu

Niveau 12 -> 13
Dans cet exercice, on dispose d’un dump hexadécimal d’un fichier compressé de multiple fois, on va donc renverser le dump à l’aide de « xxd -r » pour récupérer l’archive puis à l’aide de la commande file combinés aux commandes d’archives, on va décompresser le fichier.


[email protected]:~$ mkdir /tmp/lince ; cd /tmp/lince
[email protected]:/tmp/lince$ xxd -r ~/data.txt > data2
[email protected]:/tmp/lince$ file data2
data2: bzip2 compressed data, block size = 900k
[email protected]:/tmp/lince$ bzip2 -d data2
bzip2: Can't guess original name for data2 -- using data2.out
[email protected]:/tmp/lince$ file data2.out
data2.out: gzip compressed data, was "data4.bin", from Unix, last modified: Thu Jun  6 13:59:43 2013, max compression
[email protected]:/tmp/lince$ mv data2.out data2.gz
[email protected]:/tmp/lince$ gzip -d data2.gz
[email protected]:/tmp/lince$ ls
data.txt  data2
[email protected]:/tmp/lince$ file data2
data2: POSIX tar archive (GNU)
[email protected]:/tmp/lince$ tar -xvf data2
data5.bin
[email protected]:/tmp/lince$ file data5.bin
data5.bin: POSIX tar archive (GNU)
[email protected]:/tmp/lince$ tar -xvf data5.bin
data6.bin
[email protected]:/tmp/lince$ file data6.bin
data6.bin: bzip2 compressed data, block size = 900k
[email protected]:/tmp/lince$ tar -xvf data6.bin
data8.bin
[email protected]:/tmp/lince$ file data8.bin
data8.bin: gzip compressed data, was "data9.bin", from Unix, last modified: Thu Jun  6 13:59:43 2013, max compression
[email protected]:/tmp/lince$ mv data8.bin data8.gz
[email protected]:/tmp/lince$ gzip -d data8.gz
[email protected]:/tmp/lince$ file data8
data8: ASCII text
[email protected]:/tmp/lince$ cat data8
The password is 8ZjyCRiBWFYkneahHwxCv3wb2a1ORpYL
[email protected]:/tmp/lince$ cd ~ ; rm /tmp/lince

Niveau 13 -> 14
Dans cet exercice, on dispose d’une clé ssh privée appartenant à bandit14. On spécifie donc le fichier contenant la clé à l’aide de l’option -i, on se connecte et on affiche le fichier contenant le mot de passe.


[email protected]:~$ ssh -i [email protected] -i sshkey.private
[email protected]:~$ cat /etc/bandit_pass/bandit14
4wcYUJFw0k0XLShlDzztnTBHiqxU3b3e

Niveau 14 -> 15
Dans cet exercice, on doit écrire le mot de passe du niveau 14 sur le port 30000 de la machine courante. « echo » combiné à « nc » suffisent à obtenir ce résultat.


[email protected]:~$ echo 4wcYUJFw0k0XLShlDzztnTBHiqxU3b3e | nc localhost 30000
Correct!
BfMYroe26WYalil77FoDi9qh59eK5xNr

Niveau 15 -> 16
Dans cet exercice, on doit écrire le mot de passe du niveau 15 sur le port 30001 de la machine courante. Contrairement à l’exercice précédent, il est nécessaire d’établir une connexion SSL. On utilise donc la commande openssl s_client. Le problème est que par défaut, s_client démarre un client interactif. Pour obtenir le mot de passe, il suffit de lui coller dans le pseudo shell. Comme j’avais commencé de la même manière que le précédent exercice avec « echo », j’ai du rajouter -quiet comme option.


[email protected]:/$ echo BfMYroe26WYalil77FoDi9qh59eK5xNr | openssl s_client -quiet -connect localhost:30001
depth=0 CN = localhost
verify error:num=18:self signed certificate
verify return:1
depth=0 CN = localhost
verify return:1
Correct!
cluFn7wTiGryunymYOu4RcffSxQluehd

read:errno=0

Niveau 16 -> 17
Dans cet exercice, on doit écrire le mot de passe du niveau 16 sur un port contenu entre 31000 et 32000. On réutilise l’exercice précédent auquel on ajoute un scan de port. J’aurais bien voulu éviter un bruteforce des ports, mais je n’ai pas trouvé d’option me permettant d’isoler le bon serveur. j’ai donc testé toute la liste à l’aide d’une boucle for et de la commande de l’exercice précédent.
On obtient alors la clé privée que l’on doit stocker dans un fichier puis réutiliser. J’ai bloqué sur la syntax de sed pour les multi-lignes, car je voulais stocker la clé automatique dans un fichier puis lancer ssh sur ce fichier, j’ai donc juste enlevé les lignes qui me dérangeaient puis j’ai recrée les délimiteurs de clé RSA. Ce qui me fait la commande trop longue suivante.


[email protected]:~$ if [ ! -x /tmp/lince2 ] ; then mkdir /tmp/lince2 ; chmod 777  /tmp/lince2  ; fi ; for i in $(nmap localhost -p 31000-32000 | grep tcp | sed -e "s/\(.*\)\/.*/\1/" | tr "\n" " ") ; do echo "Test $i" >&2 ; echo $(echo cluFn7wTiGryunymYOu4RcffSxQluehd | ( openssl s_client -quiet -connect localhost:$i 2>/dev/null) & sleep 2; kill -9 $! 2>/dev/null) >> /tmp/lince2/temp ;  done ; echo -e "-----BEGIN RSA PRIVATE KEY-----\n$(cat /tmp/lince2/temp | tr " " "\n" | sed "1,8d" | tac | sed "1,5d" |tac)\n-----END RSA PRIVATE KEY-----\n" > /tmp/lince2/sshkey.priv ; rm /tmp/lince2/temp ; chmod 700 /tmp/lince2/sshkey.priv ; ssh -i /tmp/lince2/sshkey.priv [email protected]
Test 31046
Test 31518
Test 31691
Test 31790
Test 31960
Could not create directory '/home/bandit16/.ssh'.
The authenticity of host 'localhost (127.0.0.1)' can't be established.
ECDSA key fingerprint is 91:b4:28:0b:9a:4d:0c:b6:39:1f:8f:68:89:4a:ce:92.
Are you sure you want to continue connecting (yes/no)?

La clé RSA de cet exercice est la suivante:

-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAvmOkuifmMg6HL2YPIOjon6iWfbp7c3jx34YkYWqUH57SUdyJ
imZzeyGC0gtZPGujUSxiJSWI/oTqexh+cAMTSMlOJf7+BrJObArnxd9Y7YT2bRPQ
Ja6Lzb558YW3FZl87ORiO+rW4LCDCNd2lUvLE/GL2GWyuKN0K5iCd5TbtJzEkQTu
DSt2mcNn4rhAL+JFr56o4T6z8WWAW18BR6yGrMq7Q/kALHYW3OekePQAzL0VUYbW
JGTi65CxbCnzc/w4+mqQyvmzpWtMAzJTzAzQxNbkR2MBGySxDLrjg0LWN6sK7wNX
x0YVztz/zbIkPjfkU1jHS+9EbVNj+D1XFOJuaQIDAQABAoIBABagpxpM1aoLWfvD
KHcj10nqcoBc4oE11aFYQwik7xfW+24pRNuDE6SFthOar69jp5RlLwD1NhPx3iBl
J9nOM8OJ0VToum43UOS8YxF8WwhXriYGnc1sskbwpXOUDc9uX4+UESzH22P29ovd
d8WErY0gPxun8pbJLmxkAtWNhpMvfe0050vk9TL5wqbu9AlbssgTcCXkMQnPw9nC
YNN6DDP2lbcBrvgT9YCNL6C+ZKufD52yOQ9qOkwFTEQpjtF4uNtJom+asvlpmS8A
vLY9r60wYSvmZhNqBUrj7lyCtXMIu1kkd4w7F77k+DjHoAXyxcUp1DGL51sOmama
+TOWWgECgYEA8JtPxP0GRJ+IQkX262jM3dEIkza8ky5moIwUqYdsx0NxHgRRhORT
8c8hAuRBb2G82so8vUHk/fur85OEfc9TncnCY2crpoqsghifKLxrLgtT+qDpfZnx
SatLdt8GfQ85yA7hnWWJ2MxF3NaeSDm75Lsm+tBbAiyc9P2jGRNtMSkCgYEAypHd
HCctNi/FwjulhttFx/rHYKhLidZDFYeiE/v45bN4yFm8x7R/b0iE7KaszX+Exdvt
SghaTdcG0Knyw1bpJVyusavPzpaJMjdJ6tcFhVAbAjm7enCIvGCSx+X3l5SiWg0A
R57hJglezIiVjv3aGwHwvlZvtszK6zV6oXFAu0ECgYAbjo46T4hyP5tJi93V5HDi
Ttiek7xRVxUl+iU7rWkGAXFpMLFteQEsRr7PJ/lemmEY5eTDAFMLy9FL2m9oQWCg
R8VdwSk8r9FGLS+9aKcV5PI/WEKlwgXinB3OhYimtiG2Cg5JCqIZFHxD6MjEGOiu
L8ktHMPvodBwNsSBULpG0QKBgBAplTfC1HOnWiMGOU3KPwYWt0O6CdTkmJOmL8Ni
blh9elyZ9FsGxsgtRBXRsqXuz7wtsQAgLHxbdLq/ZJQ7YfzOKU4ZxEnabvXnvWkU
YOdjHdSOoKvDQNWu6ucyLRAWFuISeXw9a/9p7ftpxm0TSgyvmfLF2MIAEwyzRqaM
77pBAoGAMmjmIJdjp+Ez8duyn3ieo36yrttF5NSsJLAbxFpdlc1gvtGCWW+9Cq0b
dxviW8+TFVEBl1O4f7HVm6EpTscdDxU+bCXWkfjuRb7Dy9GOtt9JPsX8MBTakzh3
vBgsyi/sN3RqRBcGU40fOoZyfAMT8s1m/uYv52O6IgeuZ/ujbjY=
-----END RSA PRIVATE KEY-----

Niveau 17 -> 18
Dans cet exercice, on doit trouver la ligne de différente entre le fichier passwords.old et passwords.new. La ligne du passwords.new nous donne accès au niveau 18.


[email protected]:~$ diff -u passwords.new passwords.old | grep -E "^-[[:alpha:]]"
-kfBf3eYk5BPBRzwjqutbbfE887SVc5Yd

Niveau 18 -> 19
Le mot de passe de ce niveau est contenu dans le fichier readme du répertoire de bandit18. Dès le chargement de la session, vous êtes déconnectés suite à une commande inclue dans le .bashrc. Il suffit de lancer directement la commande pour afficher le mot de passe directement avec ssh.


[email protected]:~$ ssh [email protected] "cat readme"
The authenticity of host 'localhost (127.0.0.1)' can't be established.
ECDSA key fingerprint is 91:b4:28:0b:9a:4d:0c:b6:39:1f:8f:68:89:4a:ce:92.
Are you sure you want to continue connecting (yes/no)? yes
Failed to add the host to the list of known hosts (/home/bandit17/.ssh/known_hosts).

This is the OverTheWire game server. More information on http://www.overthewire.org/wargames

Please note that wargame usernames are no longer levelX, but wargamenameX
e.g. vortex4, semtex2, ...

Note: at this moment, blacksun and drifter are not available.

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0640 for '/home/bandit17/.ssh/id_rsa' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
bad permissions: ignore key: /home/bandit17/.ssh/id_rsa
[email protected]'s password:
IueksS7Ubh8G3DCwVzrTd8rAVOwq3M5x

Niveau 19 -> 20
Le mot de passe de ce niveau est contenu dans le /ect/bandit_pass/bandit20. Un binaire appartenant à bandit20 et ayant le bit de setuid est stocké dans le répertoire de bandit19. En utilisant ce binaire, on peut lancer des commandes comme bandit20. Il suffit donc d’afficher le mot de passe à l’aide de ce binaire.


[email protected]:~$ ./bandit20-do cat /etc/bandit_pass/bandit20
GbKksEFF4yrVs6il55v6gwY5aVje5f0j

Niveau 20 -> 21
Le script fournit dans le répertoire de bandit20 effectue une connexion sur le port passé en argument et lit les données envoyées dans ce port. Si ces données sont égale au mot de passe de bandit20, il renvoie le mot de passe de bandit 21.
On a donc besoin d’utiliser nc pour ouvrir un port et envoyer sur ce port le mot de passe de bandit20 puis lancer le binaire fournis sur le même port pour obtenir le mot de passe. Cela peut être effectué à l’aide de la commande suivante.


[email protected]:~$  echo GbKksEFF4yrVs6il55v6gwY5aVje5f0j | nc -l -k localhost 11112 & ./suconnect 11112
[2] 12044
Read: GbKksEFF4yrVs6il55v6gwY5aVje5f0j
Password matches, sending next password
gE269g2h3mw3pwgrj0Ha9Uoqen1c9DGr

Niveau 21 -> 22
Dans ce niveau, un job crontab est activé pour bandit22, on va donc regarder la commande lancée dans /etc/cron.d/cronjob_bandit22, on récupère la location du script lancé par la commande, on affiche le script ce qui nous donne la manière d’obtenir le mot de passe. Ici, il suffit d’afficher un fichier existant dans /tmp.


[email protected]:~$ cat /etc/cron.d/cronjob_bandit22
* * * * * bandit22 /usr/bin/cronjob_bandit22.sh &> /dev/null
[email protected]:~$ cat /usr/bin/cronjob_bandit22.sh
#!/bin/bash
chmod 644 /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv
cat /etc/bandit_pass/bandit22 > /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv
[email protected]:~$ cat /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv
Yk7owGAcWjwMVRwrTesJEwB7WVOiILLI

Niveau 22 -> 23
Dans ce niveau, un job crontab est activé pour bandit23, on va donc regarder la commande lancée dans /etc/cron.d/cronjob_bandit23, on récupère la location du script lancé par la commande, on affiche le script ce qui nous donne la manière d’obtenir le mot de passe. Ici, le script écrit encore un fichier dans temp, mais avec un nom non explicite généré par une commande. On rééxecute la commandeavec le bon paramètre et on récupère le mot de passe dans le fichier.


[email protected]:~$ cat /usr/bin/cronjob_bandit23.sh
#!/bin/bash

myname=$(whoami)
mytarget=$(echo I am user $myname | md5sum | cut -d ' ' -f 1)

echo "Copying passwordfile /etc/bandit_pass/$myname to /tmp/$mytarget"

cat /etc/bandit_pass/$myname > /tmp/$mytarget
[email protected]:~$ echo I am user bandit23 | md5sum | cut -d ' ' -f 1
8ca319486bfbbc3663ea0fbe81326349
[email protected]:~$ cat /usr/bin/cronjob_bandit23.sh
#!/bin/bash

myname=$(whoami)
mytarget=$(echo I am user $myname | md5sum | cut -d ' ' -f 1)

echo "Copying passwordfile /etc/bandit_pass/$myname to /tmp/$mytarget"

cat /etc/bandit_pass/$myname > /tmp/$mytarget
[email protected]:~$ echo I am user bandit23 | md5sum | cut -d ' ' -f 1
8ca319486bfbbc3663ea0fbe81326349
[email protected]:~$ cat /tmp/8ca319486bfbbc3663ea0fbe81326349
jc1udXuA1tiHqjIsL8yaapX5XIAI6i0n

Niveau 23 -> 24
Dans ce niveau, un job crontab est activé pour bandit24, on va donc regarder la commande lancée dans /etc/cron.d/cronjob_bandit24, on récupère la location du script lancé par la commande, on affiche le script. On voit alors que tout les binaires exécutable contenus dans


[email protected]:~$ cat /etc/cron.d/cronjob_bandit23
* * * * * bandit23 /usr/bin/cronjob_bandit23.sh  &> /dev/null
[email protected]:~$ cat /usr/bin/cronjob_bandit23.sh
#!/bin/bash

myname=$(whoami)
mytarget=$(echo I am user $myname | md5sum | cut -d ' ' -f 1)

echo "Copying passwordfile /etc/bandit_pass/$myname to /tmp/$mytarget"

cat /etc/bandit_pass/$myname > /tmp/$mytarget
[email protected]:~$ cat /usr/bin/cronjob_bandit24.sh
#!/bin/bash

myname=$(whoami)

cd /var/spool/$myname
echo "Executing and deleting all scripts in /var/spool/$myname:"
for i in *;
do
    echo "Handling $i"
    ./$i
    rm -f $i
done

[email protected]:~$ vim /var/spool/bandit24/.lince.sh
[email protected]:~$ cat /var/spool/bandit24/.lince.sh
#!/bin/bash
cat /etc/bandit_pass/bandit24 > /tmp/lince/bandit24
chown 777 /tmp/lince/bandit24
[email protected]:~$ chmod +x /var/spool/bandit24/.lince.sh
[email protected]:~$ cp /var/spool/bandit24/.lince.sh /var/spool/bandit24/lince.sh
[email protected]:~$ cat /tmp/lince/bandit24
UoMYTrfrBFHyQXmg6gzctqAwOmw1IohZ