C#实现的简单的漏洞扫描器

下面是一个用 C# 开发简单漏洞扫描器的示例。它包含两个核心功能:

  1. 端口扫描:快速检测目标主机开放的 TCP 端口。

  2. 基础 Web 漏洞检测:对 HTTP/HTTPS 服务进行简单的 SQL 注入和 XSS 反射测试。

你可以在此基础上扩展服务识别、漏洞库匹配等高级功能。


1. 项目创建与依赖

建议使用 .NET 6/8 控制台应用。

dotnet new console -n SimpleVulnScanner cd SimpleVulnScanner

无需额外 NuGet 包,仅使用内置 System.Net.SocketsSystem.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. 扩展建议

如果你想增强这个扫描器,可以考虑以下方向:

  1. Banner 抓取:在端口开放后发送特定协议探测包(如 HTTP GET、SMTP EHLO),获取服务版本信息。

  2. 漏洞库匹配:将识别到的服务版本与 CVE 数据库对比。

  3. 爬虫与表单扫描:对发现的 Web 服务进行爬取,自动填充表单进行 SQLi / XSS 测试。

  4. 报告生成:将扫描结果输出为 JSON 或 HTML 报告。

  5. 插件化架构:使用 MEF 或反射加载自定义检测模块。

相关推荐
小小仙。2 小时前
IT自学第三十八天
java·开发语言
Lyyaoo.2 小时前
【JAVA基础面经】JMM(Java内存模型)
java·开发语言
XMYX-02 小时前
05 - Go 的循环与判断:语法、用法与最佳实践
开发语言·golang
fengci.2 小时前
php反序列化(复习)(第三章)
android·开发语言·学习·php
echome8882 小时前
Python 装饰器详解:从入门到精通的 7 个实用案例
开发语言·python
竹之却2 小时前
【Agent-阿程】openclaw v2026.4.9更新内容介绍
开发语言·php·openclaw·openclaw 更新
米优2 小时前
qt+vlc实现解码h264/h265裸码流播放
开发语言·qt·vlc
xyq20242 小时前
W3C CSS 活动
开发语言
Han_han9193 小时前
案例二:交通工具调度系统(核心:继承 + 多态 + final + 方法重写)
java·开发语言