-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Implements RDP Relay Server #2101
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
|
Very nice work! |
|
GG |
|
I found small bug in RDP relay server: Also, to relay to LDAP with |
Thanks a lot for reporting this and for the PoC, it was very helpful ! The issue with the RDP cookie on the second connection from the same dialog is now fixed in my patch. For the |
gabrielg5
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey hello @azoxlpf!
Thank you for this PR!! Adding one more guest to the Relay party :D that's great!
I'll be checking functionality, probably submitting a new comment later today with my outcome
Added some tiny details in the review pane regarding logging to keep it clean.
Also, think that would be better align the RDPRelayServer with the other relays (check the HTTP, ie). I mean, having a similar class structure like:
- RDPRelayServer
- class RDPServer
- class RDPHandler
- def init
- def run
for better code / feature alignment across all the relay servers
- ipv6 support
- allow reusing address
Let me know your insights and if need any help
Enhancements ideas while checking the code:
- Adding a parameter to specify the certificate? (use that one instead than the self signed autogenerated if set...)
Thanks @AndreySolod also for your reply here! A couple of doubts on that last changeset
- Why are we managing the active clients like that? closing socket if receiving another req in less than 2 secs
- The
cr_tpdu['Type'] == 67is matching the letter "C" (in "Cookie") as if CR_TPDU was not parsing right message containing cookie... perhaps just the second part of the condition is enough. Will take a more detailed look to this later on as well but wanted to share a first comment on this
Thank you!
|
@gabrielg5 Thanks for the review ! I just pushed the requested changes:
Regarding the certificate, I'm not sure this is strictly necessary. The current auto-generated self-signed certificate works perfectly for our goal: decrypting the TLS handshake to extract NTLM messages (since we hold the private key). Adding an option for a custom certificate might just add complexity to the code without providing a significant benefit for this specific attack vector. As for changes to how active clients are managed, this is because an RDP connection triggers two distinct authentication flows back-to-back (as shown in the screenshot). If we relay both, it duplicates the attack actions (e.g., dumping the SAM on an SMB target twice), which is bad for OPSEC. Closing the second connection prevents this.
Idea: I was actually thinking we could potentially exploit this to relay the second authentication to a second target (getting 2 relays from 1 connection). However, I'm unsure if I should implement that logic here in the RDP server or if it requires modifying ntlmrelayx core to handle multi-target dispatching. Let me know your thoughts ! |
|
Been talking that with other teammates as well If you have multiple targets, the second connection will be relayed to the next target in the list. Does that make sense? |
|
A little bit about certificates: when a client uses NLA, he does NOT verify the validity (trust) of the certificate, he just uses the certificate in order to encrypt his data. This behavior differs from, for example, LDAPS, because in this case the client simply will not connect to the host with a certificate signed by an untrusted authentication authority. |





Hello !
I've been doing R&D on RDP relaying for a few weeks and have implemented an RDP relay server for
ntlmrelayx. This will be useful in scenarios where an administrator sees an unusual machine with the RDP port open and tries to connect to verify what it is, or other scenarios I haven’t thought of yet.What works
What doesn't work
RDP → LDAP: Not possible because the RDP client always requests signing in the NTLMSSP NEGOTIATE message.
SMB/HTTP → RDP (client): Not possible due to CredSSP's anti-relay protection. The CredSSP protocol includes a
pubKeyAuthmessage exchange that acts as a proof-of-possession mechanism. During this exchange :In a relay scenario, we only have the NTLM messages (NEGOTIATE, CHALLENGE, AUTHENTICATE) but not the actual password or NT hash. The NTLM session key is computed from the NT hash, so without it, we cannot encrypt the
pubKeyAuthresponse correctly. The server will reject the authentication. This is an intentional security feature of CredSSP designed to prevent relay attacks.Screenshots
Authentication of an admin on the NTLMRelayx RDP server :
Relay of NTLM authentication to SMB on a server where SMB signing is not required :
Or alternatively, relay to ESC8 :