An unsuccessful attempt to use
netsh to make RoguePotato work.
Recently, I was faced with an interesting situation where I had code execution as a Windows service account, with SeImpersonatePrivilege. My first thought was to use one of the Potato family of exploits - the box was running on Windows Server 2019, meaning that JuicyPotato would not work. My next option was to use RoguePotato - a similar exploit, but with a requirement that you are able to gain control of port 135 on another box.
Normally this is simple, and I simply start a
socat relay on my host machine to echo any connections to port 135 back to the victim machine. However, this wasn’t possible, as I was tunnelling into the victim via a Domain Controller I had SYSTEM code execution on - meaning port 135 was permanently in use by the RPC endpoint mapper service. So, how to proceed?
Attempt 1: Kill the service
“How important is this service anyway?” I thought, and began searching for ways to perform this. First, I used the Windows Service manager to track down the service - I found it, but every single option was greyed out, which makes sense, but then why list it in the dialogue at all? So, maybe a more direct approach was required.
netstat to track down the PID of the process listening on port 135, and navigated to it in Task Manager. However, clicking the end task button presented me with a popup explaining that killing this service could affect stability - and gave me the option to ‘cancel’ or ‘shut down’ (apparently, “quite important” is the answer to that question.)
“Affect stability” - I took this to mean that the box would keep chugging along as best it could, but would run into issues doing anything using RPC. Sounds fine, right? All I need is to relay one connection anyway - if the box crashed a minute or so later then that was good enough for me. With this thought, I entered
taskill /f /pid <pid> - and immediately lost several shells and my RDP session. Presumably, either some important service immediately triggered and wasn’t able to communicate, leading to a crash - or Windows just constantly checks if the service is up, and panics if not. Either way, if Windows won’t let you stop a service, there’s probably a good reason why!
Attempt 2: Rebind the service to only listen locally
This was a short lived attempt - some blog posts and docs implied that the service could bind to only localhost - this would mean that the box should still be able to communicate internally, meaning it wouldn’t crash, and I could bind my listener to the external interface. I wasn’t able to get this working, and some closer reading revealed it meant that the temporary high ports that RPC uses for communication could be modified to only listen locally - which obviously wouldn’t help.
Attempt 3: Sidestep the service entirely
During my research into Windows networking related topics, I came across an interesting utility -
netsh portproxy. This is an on-box firewall-level port forwarding tool. It allowed specifying a ‘listen’ address and port, and a connect address/port. Connections to
<listenaddr>:<port> would be instead sent to
<connectaddr>:<port>. Sounded promising, so I setup an experiment. Listening on the publicly accessible IP, I forwarded 6000 to 7000 (also on the box), and setup listeners on both ports. I then connected from my host box to 6000 on the DC and - the port 7000 listener receives a connection! This meant that due to being a firewall-level forwarder, the active listener on port 6000 was entirely bypassed.
All seemed ready, so I setup the 135->7000 forwarder, connected to 135 and… nothing. I ran an
nmap scan, the listening port was still reported to be the RPCSS service. I tried again, with port 445 to test, and got the same result. I also checked forwarding 136 (making sure the failure reason wasn’t due to it being a < 1024 port). This worked as expected.
Why does this happen exactly? I don’t know, but I believe I can take some educated guesses. Perhaps these system-critical services listen at the firewall level (somehow?), and the RPC service is hit before the
netsh check. Alternatively, (and more likely), certain ports are blacklisted for
netsh by Windows, and the rules are silently dropped. This makes sense as it would make MITM attacks like this significantly harder to perform.
As a closing thought, it’s possible that this blacklist does not apply to port 5985, meaning attacking using RogueWinRM would be possible. Either way, I moved on and found another route, but I’d love to know if anyone has any thoughts/knowledge on this subject!