C#教程

关注公众号 jb51net

关闭
首页 > 软件编程 > C#教程 > C#漏洞扫描器

基于C#实现一个简单的漏洞扫描器

作者:JQLvopkk

本文介绍了使用C#开发一个简单的漏洞扫描器,具备端口扫描和基础Web漏洞检测功能,如SQL注入和XSS检测,文章提供了项目创建方法、完整代码、使用说明以及功能说明,还提到了局限性和改进方向,最后建议了功能拓展方向,需要的朋友可以参考下

下面是一个用 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. 完整代码

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 型

局限性与改进方向

5. 扩展建议

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

  1. Banner 抓取:在端口开放后发送特定协议探测包(如 HTTP GET、SMTP EHLO),获取服务版本信息。
  2. 漏洞库匹配:将识别到的服务版本与 CVE 数据库对比。
  3. 爬虫与表单扫描:对发现的 Web 服务进行爬取,自动填充表单进行 SQLi / XSS 测试。
  4. 报告生成:将扫描结果输出为 JSON 或 HTML 报告。
  5. 插件化架构:使用 MEF 或反射加载自定义检测模块。

以上就是基于C#实现一个简单的漏洞扫描器的详细内容,更多关于C#漏洞扫描器的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文