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.
bandit0@melinda:~$ ls
readme
bandit0@melinda:~$ 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.
bandit1@melinda:~$ ls
-
bandit1@melinda:~$ 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 « / ».
bandit2@melinda:~$ ls
spaces in this filename
bandit2@melinda:~$ 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.
bandit3@melinda:~$ ls
inhere
bandit3@melinda:~$ cd inhere
bandit3@melinda:~/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
bandit3@melinda:~/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 ».
bandit4@melinda:~$ cd inhere
bandit4@melinda:~/inhere$ file ./-*
./-file00: data
./-file01: data
./-file02: data
./-file03: data
./-file04: data
./-file05: data
./-file06: data
./-file07: ASCII text
./-file08: data
./-file09: data
bandit4@melinda:~/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 »
bandit5@melinda:~$ 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
bandit5@melinda:~/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 »
bandit6@melinda:~$ find / -user bandit7 -group bandit6 2>/dev/null
/var/lib/dpkg/info/bandit7.password
bandit6@melinda:~$ 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.
bandit7@melinda:~$ 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 ».
bandit8@melinda:~$ 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 « = ».
bandit9@melinda:~$ 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 »
bandit10@melinda:~$ 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.
bandit11@melinda:~$ 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.
bandit12@melinda:~$ mkdir /tmp/lince ; cd /tmp/lince
bandit12@melinda:/tmp/lince$ xxd -r ~/data.txt > data2
bandit12@melinda:/tmp/lince$ file data2
data2: bzip2 compressed data, block size = 900k
bandit12@melinda:/tmp/lince$ bzip2 -d data2
bzip2: Can't guess original name for data2 -- using data2.out
bandit12@melinda:/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
bandit12@melinda:/tmp/lince$ mv data2.out data2.gz
bandit12@melinda:/tmp/lince$ gzip -d data2.gz
bandit12@melinda:/tmp/lince$ ls
data.txt data2
bandit12@melinda:/tmp/lince$ file data2
data2: POSIX tar archive (GNU)
bandit12@melinda:/tmp/lince$ tar -xvf data2
data5.bin
bandit12@melinda:/tmp/lince$ file data5.bin
data5.bin: POSIX tar archive (GNU)
bandit12@melinda:/tmp/lince$ tar -xvf data5.bin
data6.bin
bandit12@melinda:/tmp/lince$ file data6.bin
data6.bin: bzip2 compressed data, block size = 900k
bandit12@melinda:/tmp/lince$ tar -xvf data6.bin
data8.bin
bandit12@melinda:/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
bandit12@melinda:/tmp/lince$ mv data8.bin data8.gz
bandit12@melinda:/tmp/lince$ gzip -d data8.gz
bandit12@melinda:/tmp/lince$ file data8
data8: ASCII text
bandit12@melinda:/tmp/lince$ cat data8
The password is 8ZjyCRiBWFYkneahHwxCv3wb2a1ORpYL
bandit12@melinda:/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.
bandit13@melinda:~$ ssh -i bandit14@localhost -i sshkey.private
bandit14@melinda:~$ 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.
bandit14@melinda:~$ 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.
bandit15@melinda:/$ 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.
bandit16@melinda:~$ 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 bandit17@localhost
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.
bandit17@melinda:~$ 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.
bandit17@melinda:~$ ssh bandit18@localhost "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
bandit18@localhost'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.
bandit19@melinda:~$ ./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.
bandit20@melinda:~$ 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.
bandit21@melinda:~$ cat /etc/cron.d/cronjob_bandit22
* * * * * bandit22 /usr/bin/cronjob_bandit22.sh &> /dev/null
bandit21@melinda:~$ cat /usr/bin/cronjob_bandit22.sh
#!/bin/bash
chmod 644 /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv
cat /etc/bandit_pass/bandit22 > /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv
bandit21@melinda:~$ 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.
bandit22@melinda:~$ 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
bandit22@melinda:~$ echo I am user bandit23 | md5sum | cut -d ' ' -f 1
8ca319486bfbbc3663ea0fbe81326349
bandit22@melinda:~$ 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
bandit22@melinda:~$ echo I am user bandit23 | md5sum | cut -d ' ' -f 1
8ca319486bfbbc3663ea0fbe81326349
bandit22@melinda:~$ 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
bandit23@melinda:~$ cat /etc/cron.d/cronjob_bandit23
* * * * * bandit23 /usr/bin/cronjob_bandit23.sh &> /dev/null
bandit23@melinda:~$ 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
bandit23@melinda:~$ 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
bandit23@melinda:~$ vim /var/spool/bandit24/.lince.sh
bandit23@melinda:~$ cat /var/spool/bandit24/.lince.sh
#!/bin/bash
cat /etc/bandit_pass/bandit24 > /tmp/lince/bandit24
chown 777 /tmp/lince/bandit24
bandit23@melinda:~$ chmod +x /var/spool/bandit24/.lince.sh
bandit23@melinda:~$ cp /var/spool/bandit24/.lince.sh /var/spool/bandit24/lince.sh
bandit23@melinda:~$ cat /tmp/lince/bandit24
UoMYTrfrBFHyQXmg6gzctqAwOmw1IohZ