Initial commit of NomadScanner stealth portscanner

This commit is contained in:
django88
2025-04-25 16:38:50 +02:00
commit e5cc940a86
6 changed files with 538 additions and 0 deletions
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 Tamás Péter
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
+31
View File
@@ -0,0 +1,31 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.13.35919.96 d17.13
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NomadScanner", "NomadScanner\NomadScanner.vcxproj", "{CEFA4CC0-6A8F-4B20-8C75-1FB0335AB2CD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{CEFA4CC0-6A8F-4B20-8C75-1FB0335AB2CD}.Debug|x64.ActiveCfg = Debug|x64
{CEFA4CC0-6A8F-4B20-8C75-1FB0335AB2CD}.Debug|x64.Build.0 = Debug|x64
{CEFA4CC0-6A8F-4B20-8C75-1FB0335AB2CD}.Debug|x86.ActiveCfg = Debug|Win32
{CEFA4CC0-6A8F-4B20-8C75-1FB0335AB2CD}.Debug|x86.Build.0 = Debug|Win32
{CEFA4CC0-6A8F-4B20-8C75-1FB0335AB2CD}.Release|x64.ActiveCfg = Release|x64
{CEFA4CC0-6A8F-4B20-8C75-1FB0335AB2CD}.Release|x64.Build.0 = Release|x64
{CEFA4CC0-6A8F-4B20-8C75-1FB0335AB2CD}.Release|x86.ActiveCfg = Release|Win32
{CEFA4CC0-6A8F-4B20-8C75-1FB0335AB2CD}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D6151507-4368-4EDD-BE69-D00AB6F1ACE0}
EndGlobalSection
EndGlobal
+137
View File
@@ -0,0 +1,137 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.c" />
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>17.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{cefa4cc0-6a8f-4b20-8c75-1fb0335ab2cd}</ProjectGuid>
<RootNamespace>NomadScanner</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
+22
View File
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>
+101
View File
@@ -0,0 +1,101 @@
# 🕵️ NomadScanner - Stealth Portscanner for Red Teams
**NomadScanner** is a stealthy, memory-only Windows port scanner designed for red team operations, evasion testing, and internal assessments. It uses randomized HTTP probes, domain fronting, in-memory result handling, and optional payloads for scanning without dropping files or generating noisy output.
---
## ✨ Features
- 🔧 **Memory-only output** (no stdout or file writes)
- 🥟 **Multithreaded scanning** with jittered delays
- 🌐 **IPv4 & IPv6** support via getaddrinfo
- 🔎 **Randomized HTTP probes** (GET, HEAD, OPTIONS)
- 👥 **Domain fronting** (custom Host headers)
- 📁 **Custom payload support** (HTTP template style)
- 📄 **Banner grabbing** for fingerprinting
- 📊 **Port exclusion** and range support
- 👚 **Hostname spoofing**
- 🔬 **MAC spoof stub** (for later extension)
- 🔐 **XOR-based string obfuscation function**
- 📊 **No console window** — results shown via `MessageBoxA`
---
## 🚀 Usage
```bash
NomadScanner.exe <target_ip> <ports> [payload.txt] [exclude_ports] [fronting_host]
```
### 🔍 Examples
```bash
# Basic scan
NomadScanner.exe 127.0.0.1 80,443
# Scan port range with exclusions
NomadScanner.exe 10.0.0.1 1-1024 payload.txt 135,445
# Domain fronting example
NomadScanner.exe 10.0.0.5 80-90 payload.txt 135,445 www.microsoft.com
```
---
## 📆 Payload Template (Optional)
If using a `payload.txt` file, use placeholders:
```http
GET /status HTTP/1.1\r\nHost: %s\r\nUser-Agent: %s\r\n\r\n
```
Where:
- `%s` → replaced with fronting domain or IP
- `%s` → replaced with randomized `User-Agent`
---
## 💠 Build Instructions
### 💻 Visual Studio (Recommended)
- Open `NomadScanner.sln`
- Set configuration to `Release x64`
- Build → Output: `x64\Release\NomadScanner.exe`
### 🔧 MinGW (alternative)
```bash
gcc -mwindows -s -O3 -o NomadScanner.exe main.c -lws2_32 -liphlpapi
```
---
## 📁 Recommended Files to Include
```
NomadScanner/
├── main.c
├── NomadScanner.sln
├── NomadScanner.vcxproj
├── NomadScanner.vcxproj.filters
├── payload.txt # optional
├── .gitignore
├── LICENSE
└── README.md
```
> 🔒 Exclude: `.vs/`, `*.exe`, `*.obj`, `x64/`, `Debug/`, `Release/`
---
## ⚖️ Legal & Ethical Use
NomadScanner is for **authorized use only** — including red teaming, pentesting, lab research, and education. **Do not use this on systems without explicit permission.**
---
## 📄 License
MIT License – see [LICENSE](LICENSE)
+226
View File
@@ -0,0 +1,226 @@
#define _CRT_SECURE_NO_WARNINGS
#include <WinSock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <iphlpapi.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <iptypes.h>
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "iphlpapi.lib")
#define MAX_THREADS 64
WSADATA wsa;
int totalScanned = 0, totalOpen = 0, totalClosed = 0;
int timeout = 1000, threadCount = 20;
int delayMin = 100, delayMax = 2000;
char payloadTemplate[1024] = { 0 };
char* excludedPortsStr = NULL;
char* domainFront = NULL;
char outputBuffer[8192] = { 0 };
const char* user_agents[] = {
"Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
"curl/7.68.0",
"Wget/1.20.3 (linux-gnu)",
"python-requests/2.25.1"
};
const char* http_methods[] = { "GET", "HEAD", "OPTIONS" };
void xor (char* data, size_t len, char key) {
for (size_t i = 0; i < len; i++) {
data[i] ^= key;
}
}
BOOL IsExcludedPort(int port) {
if (!excludedPortsStr) return FALSE;
char* copy = _strdup(excludedPortsStr);
char* token = strtok(copy, ",");
while (token) {
if (strchr(token, '-')) {
int start, end;
sscanf(token, "%d-%d", &start, &end);
if (port >= start && port <= end) {
free(copy);
return TRUE;
}
}
else {
if (atoi(token) == port) {
free(copy);
return TRUE;
}
}
token = strtok(NULL, ",");
}
free(copy);
return FALSE;
}
void SetHostnameSpoof() {
SetComputerNameA("CORP-WINPC01");
}
void SetMacSpoof() {
// Stub — requires driver-level tools or registry patch with reboot
}
void AppendToBuffer(const char* format, ...) {
va_list args;
va_start(args, format);
size_t len = strlen(outputBuffer);
vsnprintf(outputBuffer + len, sizeof(outputBuffer) - len - 1, format, args);
va_end(args);
}
int InitWSAContext() {
return WSAStartup(MAKEWORD(2, 2), &wsa);
}
BOOL IsAlive(const char* ip, DWORD port) {
struct addrinfo hints, * res = NULL;
char portStr[8];
SOCKET s;
if (IsExcludedPort(port)) return FALSE;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
snprintf(portStr, sizeof(portStr), "%lu", port);
if (getaddrinfo(ip, portStr, &hints, &res) != 0) return FALSE;
s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (s == INVALID_SOCKET) {
freeaddrinfo(res);
return FALSE;
}
setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(timeout));
setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (const char*)&timeout, sizeof(timeout));
if (connect(s, res->ai_addr, (int)res->ai_addrlen) != 0) {
closesocket(s);
freeaddrinfo(res);
return FALSE;
}
const char* method = http_methods[rand() % (sizeof(http_methods) / sizeof(http_methods[0]))];
const char* ua = user_agents[rand() % (sizeof(user_agents) / sizeof(user_agents[0]))];
const char* host = domainFront ? domainFront : ip;
char message[1024];
if (strlen(payloadTemplate) > 0) {
snprintf(message, sizeof(message), payloadTemplate, ip, port, ua);
}
else {
snprintf(message, sizeof(message), "%s / HTTP/1.1\r\nHost: %s\r\nUser-Agent: %s\r\n\r\n", method, host, ua);
}
send(s, message, strlen(message), 0);
char banner[256];
int len = recv(s, banner, sizeof(banner) - 1, 0);
if (len > 0) {
banner[len] = '\0';
AppendToBuffer("[+] Banner from %s:%lu -> %.50s\n", ip, port, banner);
}
closesocket(s);
freeaddrinfo(res);
return TRUE;
}
DWORD WINAPI ScanPort(LPVOID param) {
DWORD port = *(DWORD*)param;
CHAR ip[128];
strncpy(ip, (CHAR*)((char*)param + sizeof(DWORD)), 127);
InterlockedIncrement((volatile LONG*)&totalScanned);
if (IsAlive(ip, port)) {
InterlockedIncrement((volatile LONG*)&totalOpen);
AppendToBuffer("[+] %s:%lu is open\n", ip, port);
}
else {
InterlockedIncrement((volatile LONG*)&totalClosed);
AppendToBuffer("[-] %s:%lu is closed\n", ip, port);
}
Sleep(delayMin + rand() % (delayMax - delayMin));
free(param);
return 0;
}
void Scan(char* ip, char* port_list) {
char* token = strtok(port_list, ",");
HANDLE threads[MAX_THREADS];
int active = 0;
while (token) {
int start, end;
if (strchr(token, '-')) {
sscanf(token, "%d-%d", &start, &end);
}
else {
start = end = atoi(token);
}
for (int port = start; port <= end; port++) {
if (IsExcludedPort(port)) continue;
DWORD* data = malloc(sizeof(DWORD) + 128);
*data = port;
strncpy((char*)(data + 1), ip, 127);
threads[active++] = CreateThread(NULL, 0, ScanPort, data, 0, NULL);
if (active >= threadCount) {
WaitForMultipleObjects(active, threads, TRUE, INFINITE);
for (int i = 0; i < active; i++) CloseHandle(threads[i]);
active = 0;
}
}
token = strtok(NULL, ",");
}
if (active > 0) {
WaitForMultipleObjects(active, threads, TRUE, INFINITE);
for (int i = 0; i < active; i++) CloseHandle(threads[i]);
}
}
int main(int argc, char** argv) {
srand((unsigned int)time(NULL));
SetHostnameSpoof();
SetMacSpoof();
if (argc < 3) return 0;
if (argc > 3) {
FILE* f = fopen(argv[3], "r");
if (f) {
fread(payloadTemplate, 1, sizeof(payloadTemplate) - 1, f);
fclose(f);
}
}
if (argc > 4) excludedPortsStr = _strdup(argv[4]);
if (argc > 5) domainFront = _strdup(argv[5]);
if (InitWSAContext() != 0) return 1;
DWORD startTime = GetTickCount();
Scan(argv[1], argv[2]);
DWORD elapsed = GetTickCount() - startTime;
AppendToBuffer("\n=== Scan Summary ===\n");
AppendToBuffer("Total: %d\nOpen: %d\nClosed: %d\nTime: %.2fs\n", totalScanned, totalOpen, totalClosed, elapsed / 1000.0);
MessageBoxA(NULL, outputBuffer, "Scan Results", MB_OK);
WSACleanup();
return 0;
}