Go 语言开发的资产探测器 sma11sCan
sma11sCan:基于 Go 的高并发端口扫描与资产探测工具开发记录
最近用 Go 写了一个安全工具项目:sma11sCan。
这是一个偏命令行风格的资产探测工具,第一版主要聚焦在端口扫描、Banner 抓取、HTTP 探测、Web 指纹识别、Favicon 识别、服务识别、子域名收集、CDN 检测以及源站 IP 找回这些能力上。
这一版还没有接入 Gin,也没有做 Web API、任务队列、MySQL 入库、Redis 缓存这些后端平台化能力。它更像是一个单机 CLI 工具:用户通过命令行传入目标,程序完成扫描、探测、识别并在终端输出结果。
项目地址:
1 | https://github.com/shen060606/sma11sCan |
一、为什么写这个工具
一开始写这个项目的原因很简单:想把平时学到的一些安全开发能力串起来。
单独写一个端口扫描器并不难,单独写一个 HTTP Title 获取器也不难,单独做 CNAME 判断 CDN 也不复杂。但是如果把这些能力组合起来,就会涉及到很多工程问题:
比如:
1 | 1. 如何控制扫描并发,避免 goroutine 无限增长? |
所以 sma11sCan 的目标不是只写一个简单端口扫描 demo,而是尝试做成一个较完整的资产探测工具。
二、项目整体能力
目前第一版主要支持这些功能:
1 | 端口扫描 |
命令行使用方式大概是:
1 | go run ./cmd/sma11scan/ -ip 192.168.1.1 -module fast |
如果要开启 Banner 和指纹识别:
1 | go run ./cmd/sma11scan/ -ip 192.168.1.1 -module top -banner |
如果输入的是域名,程序会先尝试解析域名,同时进行 CDN 检测:
1 | go run ./cmd/sma11scan/ -ip www.example.com -module fast -banner |
如果目标是网段:
1 | go run ./cmd/sma11scan/ -ip 192.168.1.0/24 -banner |
子域名收集:
1 | go run ./cmd/sma11scan/ -domain example.com |
三、端口扫描设计
端口扫描部分是整个工具的基础能力。
目前支持三种扫描模式:
1 | fast:常用端口 |
端口扫描采用的是 TCP Connect 方式,也就是通过 net.DialTimeout 尝试建立 TCP 连接。
为了避免每个端口都启动一个 goroutine 导致资源失控,项目中使用了 Worker Pool 模型进行并发控制。扫描任务通过 channel 分发给固定数量的 Worker,目前默认是 100 个 Worker 并发执行。
大致流程是:
1 | 生成扫描任务 |
这种设计的好处是并发可控,不会因为全端口扫描而瞬间创建几万个 goroutine。
同时,为了让扫描过程更直观,项目中还使用原子计数器统计进度,并在终端实时刷新扫描进度。
四、域名、IP、CIDR 的统一处理
工具支持三种输入形式:
1 | 单个 IP |
如果用户输入的是 IP,直接扫描该 IP。
如果用户输入的是 CIDR,例如:
1 | 192.168.1.0/24 |
程序会先解析出网段内的所有 IP,再逐个执行扫描。
如果用户输入的是域名,例如:
1 | www.example.com |
程序会先通过 DNS 解析得到 IP,再进行扫描。
这里有一个细节:如果目标是域名,HTTP/HTTPS 探测时不能简单地把域名解析成 IP 后就完全丢掉原域名。因为 HTTPS 请求涉及 TLS SNI,如果 TLS 握手时没有设置正确的 ServerName,很多站点会返回错误证书或握手失败。
所以项目里处理域名扫描时,会保留原始域名。在 TCP 层连接 IP,但 TLS 握手时仍然使用原域名作为 SNI。
简单说就是:
1 | TCP 连接:连 IP |
这个细节对安全探测工具很重要。

五、Banner 抓取和服务识别
开启 -banner 参数后,工具会对开放端口进一步探测。
Banner 抓取逻辑主要是:
1 | 建立 TCP 连接 |
例如 SSH 服务通常会返回类似:
1 | SSH-2.0-OpenSSH_8.2 |
MySQL、Redis、RDP 等服务也可能通过 Banner 或端口特征进行识别。
服务识别采用了三层策略:
1 | 第一层:Banner 关键词匹配 |
这样即使某些服务没有返回明显 Banner,也可以通过端口表进行兜底判断。
六、HTTP/HTTPS 探测
对于 Web 服务,工具会发起 HTTP/HTTPS 请求,提取更多信息:
1 | 状态码 |
HTTP 探测中模拟了常见浏览器请求头,例如:
1 | User-Agent |
这样可以减少部分站点因为请求头过于简单而返回异常页面的情况。
Title 提取通过正则匹配 HTML 中的 <title> 标签完成。虽然这不是最复杂的 HTML 解析方式,但对资产探测工具来说已经比较实用。
七、Web 指纹识别
项目中实现了一个 Web 指纹匹配模块。
识别目标包括:
1 | Web Server |
指纹匹配的位置包括:
1 | header |
为了降低误报,项目不是简单命中一个关键词就直接判定,而是做了一个权重累积机制。
大致分为:
1 | 铁证规则:权重 90-100,单条命中即可基本确认 |
这样做的好处是可以避免一些泛关键词造成误报。
例如单纯在页面里看到某个通用词,不一定能说明目标使用了某个 CMS;但如果 Header、Title、Body 多个位置同时命中,就更可信。
八、Favicon 指纹识别
很多 Web 系统的 favicon 比页面内容更稳定,所以项目也加入了 Favicon 指纹识别。
流程大概是:
1 | 从 HTML 中提取 favicon 路径 |
这里有一个细节:favicon 的路径不一定是完整 URL,可能是:
1 | <link rel="icon" href="/favicon.ico"> |
也可能是:
1 | <link rel="shortcut icon" href="static/favicon.ico"> |
所以项目里使用了 url.Parse 和 ResolveReference 来正确拼接 favicon 地址。
拿到 favicon 内容后,计算 MD5 值,再和内置的 Favicon 指纹库进行匹配。
九、CDN 检测
CDN 检测主要基于 CNAME 规则。
当输入目标是域名时,程序会通过 net.LookupCNAME 获取 CNAME 记录,然后和内置 CDN 规则库进行匹配。
目前覆盖了多家国内外主流 CDN,例如:
1 | Cloudflare |
例如目标 CNAME 中包含:
1 | cloudflare.net |
就可以判断目标大概率使用了 Cloudflare。
这个检测方式不是绝对准确,但对多数常见 CDN 场景比较有效。
十、源站 IP 找回
CDN 检测之后,项目还尝试实现了源站 IP 找回。
当前版本主要通过 VirusTotal API 获取历史 DNS 解析记录。
使用前需要设置环境变量:
1 | export VT_API_KEY="your-api-key" |
Windows PowerShell:
1 | $env:VT_API_KEY = "your-api-key" |
流程大概是:
1 | 检测目标是否使用 CDN |
这里不能只判断候选 IP 是否开放 80/443,因为很多无关服务器也可能开放 Web 服务。
所以项目里使用了两个维度做验证:
1 | 网页 Title |
如果候选 IP 返回的 Title 和 Favicon 与原始域名访问结果一致,则认为它更可能是源站 IP。
如果找回成功,工具会切换到源站 IP 继续扫描。
如果找回失败,也不会中断流程,而是继续扫描 CDN 节点。

十一、子域名收集
子域名模块目前支持两种方式:
1 | DNS 字典爆破 |
字典爆破会读取默认字典文件:
1 | subdomains.txt |
然后拼接成:
1 | www.example.com |
再并发进行 DNS 解析。
为了避免并发过高,子域名爆破使用了信号量限制并发,目前默认 50 并发。
子域名发现后,可以继续联动端口扫描和指纹识别。
例如:
1 | go run ./cmd/sma11scan/ -domain example.com -module top -banner |
这样可以先收集子域名,再对发现的子域名进行资产探测。

十二、项目结构
当前项目结构如下:
1 | ├── cmd/ |
其中:
1 | cmd/sma11scan |
是命令行入口,负责解析参数和组织整体流程。
1 | internal/scanner |
负责端口扫描、Worker Pool、CIDR 解析、域名解析、结果输出。
1 | internal/banner |
负责 Banner 抓取和 HTTP/HTTPS 探测。
1 | internal/cdn |
负责 CDN 检测和源站 IP 找回。
1 | internal/fingerprint |
负责 Web 指纹和 Favicon 指纹识别。
1 | internal/subdomain |
负责子域名收集。
这种拆分方式比把所有逻辑写在 main.go 里更清晰,也方便后续升级成 Web 平台。
十三、第一版的不足
第一版虽然已经实现了不少扫描能力,但它还是一个 CLI 工具,还没有平台化。
目前存在这些不足:
1 | 1. 扫描结果只在终端输出,没有持久化入库 |
也就是说,当前版本更适合作为本地命令行工具使用。如果要做成更接近真实安全平台的项目,还需要继续工程化。
十四、后续计划:从 CLI 工具升级为扫描平台
下一步计划是把 sma11sCan 从 CLI 工具升级为一个后端扫描平台。
大致方向是:
1 | Gin 路由 |
计划中的接口包括:
1 | POST /api/v1/tasks |
创建任务时,API 不直接执行完整扫描,而是立即返回一个 task_id:
1 | { |
后台 Worker 再异步执行端口扫描、Banner 抓取、CDN 检测、指纹识别等任务。扫描完成后,把结果写入 MySQL。
这样可以避免 HTTP 请求长时间阻塞,也方便后续做并发控制、失败重试、任务状态查询和结果管理。
十五、总结
sma11sCan 第一版主要解决的是“扫描能力”的问题。
它实现了:
1 | 高并发端口扫描 |
这一版没有使用 Gin,也没有接入 MySQL、Redis、任务队列这些中间件。它更像是安全开发项目的第一阶段:先把扫描器核心能力做出来。
后续如果要投安全开发实习,仅仅有 CLI 工具还不够。更有竞争力的方向是把它升级成一个完整的资产扫描平台:
1 | 可提交任务 |
所以 sma11sCan 第一版只是开始。下一阶段会重点做 Gin API 层、任务队列、数据库持久化和扫描结果管理,把它从一个命令行工具逐步改造成一个真正的安全扫描平台。
安全声明
本项目仅用于授权资产探测、学习研究和安全开发实践。请勿用于未授权目标扫描或任何非法用途。使用者需要自行遵守当地法律法规,并对自己的行为负责。

.png)
.png)
.png)
.png)

