下面是一个用 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. 完整代码
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 或反射加载自定义检测模块。
以上就是基于c#实现一个简单的漏洞扫描器的详细内容,更多关于c#漏洞扫描器的资料请关注代码网其它相关文章!
发表评论