下面是一个用 C# 开发简单漏洞扫描器的示例。它包含两个核心功能:
-
端口扫描:快速检测目标主机开放的 TCP 端口。
-
基础 Web 漏洞检测:对 HTTP/HTTPS 服务进行简单的 SQL 注入和 XSS 反射测试。
你可以在此基础上扩展服务识别、漏洞库匹配等高级功能。
1. 项目创建与依赖
建议使用 .NET 6/8 控制台应用。
dotnet new console -n SimpleVulnScanner cd SimpleVulnScanner
无需额外 NuGet 包,仅使用内置 System.Net.Sockets、System.Net.Http。
2. 完整代码
csharp
using System.Net.Sockets;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
namespace SimpleVulnScanner;
class Program
{
static async Task Main(string[] args)
{
Console.WriteLine("=== 简单漏洞扫描器 (C#) ===");
string target = GetTarget(args);
int startPort = 1, endPort = 1024; // 默认扫描常见端口
// 解析端口范围
if (args.Length >= 2)
{
var portParts = args[1].Split('-');
if (portParts.Length == 2 && int.TryParse(portParts[0], out int p1) && int.TryParse(portParts[1], out int p2))
{
startPort = p1;
endPort = p2;
}
else if (int.TryParse(args[1], out int singlePort))
{
startPort = singlePort;
endPort = singlePort;
}
}
Console.WriteLine($"目标: {target}");
Console.WriteLine($"端口范围: {startPort}-{endPort}");
Console.WriteLine("开始端口扫描...\n");
var openPorts = await PortScanner.ScanPortsAsync(target, startPort, endPort);
Console.WriteLine("\n端口扫描完成。");
if (openPorts.Count == 0)
{
Console.WriteLine("未发现开放端口。");
return;
}
Console.WriteLine("开放端口列表:");
foreach (var port in openPorts)
{
string service = PortScanner.GuessService(port);
Console.WriteLine($" {port}/tcp ({service})");
}
// 对常见 Web 端口进行漏洞检测
var webPorts = openPorts.Where(p => p == 80 || p == 443 || p == 8080 || p == 8443).ToList();
if (webPorts.Any())
{
Console.WriteLine("\n开始 Web 漏洞检测...");
foreach (var port in webPorts)
{
string scheme = port == 443 || port == 8443 ? "https" : "http";
string baseUrl = $"{scheme}://{target}:{port}";
await WebVulnScanner.ScanAsync(baseUrl);
}
}
Console.WriteLine("\n扫描结束。按任意键退出...");
Console.ReadKey();
}
static string GetTarget(string[] args)
{
if (args.Length > 0 && !string.IsNullOrEmpty(args[0]))
return args[0];
Console.Write("请输入目标 IP 或域名: ");
return Console.ReadLine()?.Trim() ?? "127.0.0.1";
}
}
// ---------- 端口扫描模块 ----------
public static class PortScanner
{
private const int TimeoutMs = 1000;
private const int MaxConcurrency = 100;
public static async Task<List<int>> ScanPortsAsync(string host, int startPort, int endPort)
{
var openPorts = new List<int>();
var semaphore = new SemaphoreSlim(MaxConcurrency);
var tasks = new List<Task>();
for (int port = startPort; port <= endPort; port++)
{
await semaphore.WaitAsync();
int currentPort = port;
tasks.Add(Task.Run(async () =>
{
try
{
if (await IsPortOpenAsync(host, currentPort))
{
lock (openPorts)
{
openPorts.Add(currentPort);
Console.WriteLine($"[+] 开放: {currentPort}/tcp");
}
}
}
finally
{
semaphore.Release();
}
}));
}
await Task.WhenAll(tasks);
openPorts.Sort();
return openPorts;
}
private static async Task<bool> IsPortOpenAsync(string host, int port)
{
try
{
using var client = new TcpClient();
var connectTask = client.ConnectAsync(host, port);
var timeoutTask = Task.Delay(TimeoutMs);
var completedTask = await Task.WhenAny(connectTask, timeoutTask);
if (completedTask == timeoutTask)
return false;
return client.Connected;
}
catch
{
return false;
}
}
public static string GuessService(int port)
{
return port switch
{
21 => "FTP",
22 => "SSH",
23 => "Telnet",
25 => "SMTP",
80 => "HTTP",
110 => "POP3",
143 => "IMAP",
443 => "HTTPS",
3306 => "MySQL",
3389 => "RDP",
5432 => "PostgreSQL",
8080 => "HTTP-Proxy",
_ => "未知"
};
}
}
// ---------- Web 漏洞检测模块 ----------
public static class WebVulnScanner
{
private static readonly HttpClient _httpClient;
static WebVulnScanner()
{
var handler = new HttpClientHandler
{
ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true // 忽略证书错误
};
_httpClient = new HttpClient(handler);
_httpClient.Timeout = TimeSpan.FromSeconds(10);
_httpClient.DefaultRequestHeaders.Add("User-Agent", "SimpleVulnScanner/1.0");
}
public static async Task ScanAsync(string baseUrl)
{
Console.WriteLine($"\n[*] 扫描 Web 服务: {baseUrl}");
// 1. 检测 SQL 注入(基于错误回显)
await TestSqlInjectionAsync(baseUrl);
// 2. 检测反射型 XSS
await TestReflectedXssAsync(baseUrl);
}
private static async Task TestSqlInjectionAsync(string baseUrl)
{
string[] sqlPayloads = { "'", "\"", "' OR '1'='1", "\" OR \"1\"=\"1", "' OR 1=1--", "\" OR 1=1--" };
var errorPatterns = new[]
{
"SQL syntax", "mysql_fetch", "ORA-", "PostgreSQL", "SQLite", "Microsoft OLE DB",
"Unclosed quotation mark", "You have an error in your SQL syntax"
};
foreach (var payload in sqlPayloads)
{
string testUrl = $"{baseUrl}/?id={Uri.EscapeDataString(payload)}";
try
{
var response = await _httpClient.GetAsync(testUrl);
string content = await response.Content.ReadAsStringAsync();
foreach (var pattern in errorPatterns)
{
if (content.Contains(pattern, StringComparison.OrdinalIgnoreCase))
{
Console.WriteLine($" [!] 可能存在 SQL 注入 (错误回显) - Payload: {payload}");
return; // 仅报告一次
}
}
}
catch (Exception ex)
{
// 忽略网络错误
}
}
}
private static async Task TestReflectedXssAsync(string baseUrl)
{
string xssPayload = "<script>alert('XSS')</script>";
string testUrl = $"{baseUrl}/?q={Uri.EscapeDataString(xssPayload)}";
try
{
var response = await _httpClient.GetAsync(testUrl);
string content = await response.Content.ReadAsStringAsync();
// 检查 payload 是否原样反射在响应中
if (content.Contains(xssPayload))
{
Console.WriteLine($" [!] 可能存在反射型 XSS - Payload 已回显");
}
}
catch
{
// 忽略
}
}
}
3. 使用说明
命令行参数
dotnet run <目标IP/域名> [端口范围]
示例:
# 扫描 127.0.0.1 的 1-1024 端口
dotnet run 127.0.0.1
# 扫描 192.168.1.1 的 80-100 端口
dotnet run 192.168.1.1 80-100
# 扫描单个端口 443
dotnet run example.com 443
若未提供参数,程序会交互式询问目标。
运行截图示意
=== 简单漏洞扫描器 (C#) ===
目标: 192.168.1.1
端口范围: 1-1024
开始端口扫描...
[+] 开放: 80/tcp
[+] 开放: 443/tcp
[+] 开放: 22/tcp
端口扫描完成。
开放端口列表:
22/tcp (SSH)
80/tcp (HTTP)
443/tcp (HTTPS)
开始 Web 漏洞检测...
[*] 扫描 Web 服务: http://192.168.1.1:80
[!] 可能存在 SQL 注入 (错误回显) - Payload: '
[!] 可能存在反射型 XSS - Payload 已回显
[*] 扫描 Web 服务: https://192.168.1.1:443
扫描结束。按任意键退出...
4. 功能说明与局限性
| 功能 | 实现方式 | 说明 |
|---|---|---|
| 端口扫描 | TCP Connect 异步扫描 | 超时 1 秒,并发 100,速度快且准确 |
| 服务猜测 | 静态映射表 | 根据常见端口号推测服务名称 |
| SQL 注入检测 | 发送 ' 等 payload,匹配错误关键词 |
仅检测错误回显型,不适用于盲注 |
| XSS 检测 | 发送 <script>alert('XSS')</script> 并检查回显 |
仅检测反射型,不适用于 DOM 型 |
局限性与改进方向
-
端口扫描:容易被防火墙拦截,可改用 SYN 半开扫描(需更高权限)。
-
Web 漏洞检测:非常基础,实际环境中应集成更全面的 payload 和智能分析(如基于 DOM 的变化)。
-
服务识别:目前仅靠端口猜测,可增加 Banner 抓取。
-
多线程安全 :已使用
SemaphoreSlim控制并发,避免资源耗尽。
5. 扩展建议
如果你想增强这个扫描器,可以考虑以下方向:
-
Banner 抓取:在端口开放后发送特定协议探测包(如 HTTP GET、SMTP EHLO),获取服务版本信息。
-
漏洞库匹配:将识别到的服务版本与 CVE 数据库对比。
-
爬虫与表单扫描:对发现的 Web 服务进行爬取,自动填充表单进行 SQLi / XSS 测试。
-
报告生成:将扫描结果输出为 JSON 或 HTML 报告。
-
插件化架构:使用 MEF 或反射加载自定义检测模块。