Introduction to Lantern:

This write-up will explore the “Lantern” machine from Hack The Box, categorized as a Hard difficulty challenge. This walkthrough will cover the reconnaissance, exploitation, and privilege escalation steps required to capture the flag.

Objective:

The goal of this walkthrough is to complete the “Lantern” machine from Hack The Box by achieving the following objectives:

User Flag:

Exploiting the HTB Lantern Machine: A Multi-Vector Attack

The HTB Lantern Machine presents a multifaceted attack surface, primarily due to vulnerabilities in its underlying technologies. By exploiting Server-Side Request Forgery (SSRF) in the Skipper proxy, attackers can bypass security measures and gain access to the internal Blazor admin panel. Once inside, a range of attack vectors becomes feasible, including SQL injection, reverse-engineering DLLs, and uploading malicious Razor components. These techniques can ultimately lead to remote code execution and full system compromise.

Root Flag:

Exploiting ProcMon Logs for Root Password Extraction

By gaining access to the ProcMon SQLite database, I intend to meticulously examine the logged events. This analysis will focus on identifying any instances of root password input or exposure, which could potentially provide a valuable foothold for further exploitation.

Enumerating the Machine

Reconnaissance:

Nmap Scan:

Begin with a network scan to identify open ports and running services on the target machine.


     nmap -sC -sV -oN nmap_initial.txt 10.10.11.29

Nmap Output:

┌─[darknite@parrot]─[~/Documents/htb/Lantern]
└──╼ $nmap -sC -sV 10.10.11.29 -oA initial
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-11-29 21:34 EST
Nmap scan report for lantern.htb (10.10.11.29)
Host is up (0.016s latency).
Not shown: 997 closed tcp ports (conn-refused)
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-server-header: Skipper Proxy
|_http-title: Lantern
| fingerprint-strings: 
|   FourOhFourRequest: 
|     HTTP/1.0 404 Not Found
|     Content-Length: 207
|     Content-Type: text/html; charset=utf-8
|     Date: Sat, 30 Nov 2024 02:20:57 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: Sat, 30 Nov 2024 02:20:51 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: GET, OPTIONS, HEAD
|     Content-Length: 0
|     Content-Type: text/html; charset=utf-8
|     Date: Sat, 30 Nov 2024 02:20:51 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: Sat, 30 Nov 2024 02:20:56 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: Sat, 30 Nov 2024 02:21:01 GMT
|     Server: Kestrel
|   Help: 
|     HTTP/1.1 400 Bad Request
|     Content-Length: 0
|     Connection: close
|     Date: Sat, 30 Nov 2024 02:20:56 GMT
|     Server: Kestrel
|   RTSPRequest: 
|     HTTP/1.1 505 HTTP Version Not Supported
|     Content-Length: 0
|     Connection: close
|     Date: Sat, 30 Nov 2024 02:21:01 GMT
|     Server: Kestrel
|   SSLSessionReq, TerminalServerCookie: 
|     HTTP/1.1 400 Bad Request
|     Content-Length: 0
|     Connection: close
|     Date: Sat, 30 Nov 2024 02:21:16 GMT
|_    Server: Kestrel
2 services unrecognized despite returning data. If you know the service/version, please submit the following fingerprints at https://nmap.org/cgi-bin/submit.cgi?new-service :
==============NEXT SERVICE FINGERPRINT (SUBMIT INDIVIDUALLY)==============
SF-Port80-TCP:V=7.94SVN%I=7%D=11/29%Time=674A79BC%P=x86_64-pc-linux-gnu%r(
SF:GetRequest,18F,"HTTP/1\.0\x20302\x20Found\r\nContent-Length:\x20225\r\n
SF:Content-Type:\x20text/html;\x20charset=utf-8\r\nDate:\x20Sat,\x2030\x20
SF:Nov\x202024\x2002:20:51\x20GMT\r\nLocation:\x20http://lantern\.htb/\r\n
SF:Server:\x20Skipper\x20Proxy\r\n\r\n<!doctype\x20html>\n<html\x20lang=en
SF:>\n<title>Redirecting\.\.\.</title>\n<h1>Redirecting\.\.\.</h1>\n<p>You
SF:\x20should\x20be\x20redirected\x20automatically\x20to\x20the\x20target\
SF:x20URL:\x20<a\x20href=\"http://lantern\.htb/\">http://lantern\.htb/</a>
SF:\.\x20If\x20not,\x20click\x20the\x20link\.\n")%r(HTTPOptions,A5,"HTTP/1
SF:\.0\x20200\x20OK\r\nAllow:\x20GET,\x20OPTIONS,\x20HEAD\r\nContent-Lengt
SF:h:\x200\r\nContent-Type:\x20text/html;\x20charset=utf-8\r\nDate:\x20Sat
SF:,\x2030\x20Nov\x202024\x2002:20:51\x20GMT\r\nServer:\x20Skipper\x20Prox
SF:y\r\n\r\n")%r(RTSPRequest,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nCon
SF:tent-Type:\x20text/plain;\x20charset=utf-8\r\nConnection:\x20close\r\n\
SF:r\n400\x20Bad\x20Request")%r(FourOhFourRequest,162,"HTTP/1\.0\x20404\x2
SF:0Not\x20Found\r\nContent-Length:\x20207\r\nContent-Type:\x20text/html;\
SF:x20charset=utf-8\r\nDate:\x20Sat,\x2030\x20Nov\x202024\x2002:20:57\x20G
SF:MT\r\nServer:\x20Skipper\x20Proxy\r\n\r\n<!doctype\x20html>\n<html\x20l
SF:ang=en>\n<title>404\x20Not\x20Found</title>\n<h1>Not\x20Found</h1>\n<p>
SF:The\x20requested\x20URL\x20was\x20not\x20found\x20on\x20the\x20server\.
SF:\x20If\x20you\x20entered\x20the\x20URL\x20manually\x20please\x20check\x
SF:20your\x20spelling\x20and\x20try\x20again\.</p>\n")%r(GenericLines,67,"
SF:HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-Type:\x20text/plain;\x20c
SF:harset=utf-8\r\nConnection:\x20close\r\n\r\n400\x20Bad\x20Request")%r(H
SF:elp,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-Type:\x20text/pla
SF:in;\x20charset=utf-8\r\nConnection:\x20close\r\n\r\n400\x20Bad\x20Reque
SF:st")%r(SSLSessionReq,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-
SF:Type:\x20text/plain;\x20charset=utf-8\r\nConnection:\x20close\r\n\r\n40
SF:0\x20Bad\x20Request")%r(TerminalServerCookie,67,"HTTP/1\.1\x20400\x20Ba
SF:d\x20Request\r\nContent-Type:\x20text/plain;\x20charset=utf-8\r\nConnec
SF:tion:\x20close\r\n\r\n400\x20Bad\x20Request");
==============NEXT SERVICE FINGERPRINT (SUBMIT INDIVIDUALLY)==============
SF-Port3000-TCP:V=7.94SVN%I=7%D=11/29%Time=674A79C2%P=x86_64-pc-linux-gnu%
SF:r(GetRequest,114E,"HTTP/1\.1\x20500\x20Internal\x20Server\x20Error\r\nC
SF:onnection:\x20close\r\nContent-Type:\x20text/plain;\x20charset=utf-8\r\
SF:nDate:\x20Sat,\x2030\x20Nov\x202024\x2002:20:56\x20GMT\r\nServer:\x20Ke
SF:strel\r\n\r\nSystem\.UriFormatException:\x20Invalid\x20URI:\x20The\x20h
SF:ostname\x20could\x20not\x20be\x20parsed\.\n\x20\x20\x20at\x20System\.Ur
SF:i\.CreateThis\(String\x20uri,\x20Boolean\x20dontEscape,\x20UriKind\x20u
SF:riKind,\x20UriCreationOptions&\x20creationOptions\)\n\x20\x20\x20at\x20
SF:System\.Uri\.\.ctor\(String\x20uriString,\x20UriKind\x20uriKind\)\n\x20
SF:\x20\x20at\x20Microsoft\.AspNetCore\.Components\.NavigationManager\.set
SF:_BaseUri\(String\x20value\)\n\x20\x20\x20at\x20Microsoft\.AspNetCore\.C
SF:omponents\.NavigationManager\.Initialize\(String\x20baseUri,\x20String\
SF:x20uri\)\n\x20\x20\x20at\x20Microsoft\.AspNetCore\.Components\.Server\.
SF:Circuits\.RemoteNavigationManager\.Initialize\(String\x20baseUri,\x20St
SF:ring\x20uri\)\n\x20\x20\x20at\x20Microsoft\.AspNetCore\.Mvc\.ViewFeatur
SF:es\.StaticComponentRenderer\.<InitializeStandardComponentServicesAsync>
SF:g__InitializeCore\|5_0\(HttpContext\x20httpContext\)\n\x20\x20\x20at\x2
SF:0Microsoft\.AspNetCore\.Mvc\.ViewFeatures\.StaticC")%r(Help,78,"HTTP/1\
SF:.1\x20400\x20Bad\x20Request\r\nContent-Length:\x200\r\nConnection:\x20c
SF:lose\r\nDate:\x20Sat,\x2030\x20Nov\x202024\x2002:20:56\x20GMT\r\nServer
SF::\x20Kestrel\r\n\r\n")%r(HTTPOptions,6F,"HTTP/1\.1\x20200\x20OK\r\nCont
SF:ent-Length:\x200\r\nConnection:\x20close\r\nDate:\x20Sat,\x2030\x20Nov\
SF:x202024\x2002:21:01\x20GMT\r\nServer:\x20Kestrel\r\n\r\n")%r(RTSPReques
SF:t,87,"HTTP/1\.1\x20505\x20HTTP\x20Version\x20Not\x20Supported\r\nConten
SF:t-Length:\x200\r\nConnection:\x20close\r\nDate:\x20Sat,\x2030\x20Nov\x2
SF:02024\x2002:21:01\x20GMT\r\nServer:\x20Kestrel\r\n\r\n")%r(SSLSessionRe
SF:q,78,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-Length:\x200\r\nCon
SF:nection:\x20close\r\nDate:\x20Sat,\x2030\x20Nov\x202024\x2002:21:16\x20
SF:GMT\r\nServer:\x20Kestrel\r\n\r\n")%r(TerminalServerCookie,78,"HTTP/1\.
SF:1\x20400\x20Bad\x20Request\r\nContent-Length:\x200\r\nConnection:\x20cl
SF:ose\r\nDate:\x20Sat,\x2030\x20Nov\x202024\x2002:21:16\x20GMT\r\nServer:
SF:\x20Kestrel\r\n\r\n");
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 95.72 seconds

Analysis:

  • Port 22 (SSH): OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (ECDSA, ED25519 keys)
  • Port 80 (HTTP): Skipper Proxy web server (Lantern)
  • Port 3000 (PPP?): Potential web application/API with Kestrel server (various HTTP responses)

Web Enumeration:

Perform web enumeration to discover potentially exploitable directories and files.

Exploitation

Web Application Exploration:

Navigating to http://lantern.htb opens a web portal focused on IT solutions.

Accessing http://lantern.htb/vacancies reveals a recruitment page seeking engineers aligned with their application needs.

A resume can be uploaded at the bottom of the page.

In addition to the earlier evidence, I discovered the presence of a Server Skipper Proxy.

What is Skipper Proxy?

Skipper Proxy is a reverse proxy and HTTP router developed in Go that is designed to handle traffic in modern web environments. It provides key functionalities to manage and route HTTP requests effectively:

  • Traffic Routing: Routes HTTP requests to backend services or microservices based on predefined or dynamic rules.
  • Load Balancing: Distributes requests across multiple servers to improve performance and reduce strain on individual systems.
  • Redirection: Manages HTTP redirects, as evidenced by scan results showing traffic forwarded to http://lantern.htb/, indicating a configuration for domain-specific routing.
  • Security: Includes features like SSL/TLS termination, access control, and authentication for secure traffic management.

Skipper versions before v0.13.236 are susceptible to SSRF attacks. To exploit CVE-2022-38580 on http://lantern.htb:80, we can leverage BurpSuite to inject the X-Skipper-Proxy header into HTTP requests

A screenshot of a computer

Description automatically generated

The website 3000 redirects to LanternAdmin, which requires credentials for access. Unfortunately, we don’t have any credentials to proceed.

The source code indicates that the application is built using the Blazor framework. We did cover this on the Blazorized machine which can be found here

The login page’s source code indicates a server-side Blazor implementation. Blazor, a Microsoft framework, enables the development of interactive web UIs using C#. Unlike client-side Blazor, this application likely runs its logic on the server, sending rendered HTML to the client.

The script will follow a structure similar to the one illustrated above.

Enemuerate the DLL file extension

Blazor applications typically listen on port 5000. The framework exposes internal files through specific paths, including _framework/blazor.boot.json and _framework/blazor.webassembly.js.

Analyzing blazor.boot.json reveals a detailed list of these exposed files

Let’s download the DLL file and save it on our computer. Due to the limitations of dnSpy’s decompilation capabilities, we were forced to utilize dotPeek. This alternative tool enabled us to uncover base64-encoded employee data.

This alternative tool enabled us to uncover base64-encoded employee data.

Let’s try logging into LanternAdmin using the username and password we found earlier.

The dashboard interface will follow a structure similar to the one illustrated above.

We should create one malicious file to be used for our attack.

Let’s add our malicious file to the application’s file system

Blazor Application enumeration on Lantern Machine

Blazor applications rely on MessagePack for data serialization, but the specific format used adheres to the Blazor Hub Protocol. Generic MessagePack parsers are insufficient for this purpose. The BTP BurpSuite extension is designed to intercept and deserialize Blazor’s custom MessagePack format, enabling us to manipulate requests and responses. For instance, we can modify file upload requests to include path traversal attacks by altering the target file path.

The serialized data appears in JSON format. To interpret it, we’ll need to deserialize it. We’ll use the BTP BurpSuite extension for this task

We should get an SSH public key that we can use to log into the machine remotely.

However, the machine looks unstable for some reason

Obtaining the Username for the access Lantern Machine

The /PrivacyAndPolicy route suffers from a file disclosure vulnerability. The lack of proper input validation for the lang and file_ext parameters can be exploited to trigger path traversal attacks, potentially revealing unauthorized files

The /PrivacyAndPolicy route is vulnerable to path traversal attacks. By carefully crafting the lang and ext parameters, we can bypass directory boundaries and access sensitive files like /etc/passwd

After some effort, we were able to identify a possible username.

We can view the user flag by running the command cat user.txt in the terminal.

Escalate To Root Privileges Access on Lantern Machine

Privilege Escalation:

The sudo -l is a command that can be used to identify potential privilege escalation vectors

What is Procmon?

Procmon is a robust tool from Microsoft’s Sysinternals suite designed to monitor system activities in real time. It’s especially valuable for penetration testers and cybersecurity professionals, enabling them to track and analyze various system activities, including file system, registry, and process/thread actions.

Key features of Procmon include:

  • Real-time monitoring: Captures and displays system activities as they happen, essential for detecting and investigating security incidents.
  • Filtering: Allows setting filters to focus on specific events related to particular processes, files, or registry keys.
  • Detailed event information: Provides comprehensive details for each event, such as process name, operation type, result, and additional forensic analysis aids.
  • Boot logging: This can be configured to start logging from the system boot, capturing all activities from the beginning.

Procmon is commonly used for:

  • Incident response: Investigate security incidents by tracking system activities that may indicate a compromise.
  • Penetration testing: Monitoring the impact of exploits and understanding how they interact with the system.
  • Malware analysis: Analyzing the behaviour of malicious software to understand its capabilities and effects.

To use Procmon effectively, administrative privileges are typically required on the system being monitored. It’s an indispensable tool in the cybersecurity professional’s toolkit for its ability to provide deep insights into system behaviour.

An email might have been sent to Tomas requesting verification of a shell script named ‘automation.sh’ in the root directory (/root). Although the script seems unreadable, it’s worth checking Tomas’ sudo privileges for any connection to this script.

SQLite3 enumeration on the Lantern Machine

We can use the ps aux | grep automation command to see which processes are currently running that are related to the ‘automation’ script. To capture file write operations of the suspicious process, note its PID and execute the command sudo procmon -p <PID> -e write.

Allow sufficient time for data writes to occur, then export the logs by pressing F6 and terminate the process monitor with F9.”

We have successfully acquired the database file and can now proceed with local analysis.

Let’s use the SCP command to copy the database file from the remote machine to our computer.

We found some data encoded in hexadecimal format. We’ll need to convert it back to its original form.

The password for the root account seems to be the same as the one visible in the image. We can use this password to switch to the root user by running the command su root from Tomas’ shell.

We can view the root flag by running the command cat root.txt in the terminal.