实现原理:CT 日志与子域枚举
对应代码:
pkg/ctlog.go+pkg/ctenumerate.go· 入口CTSearch/CTSearchByFingerprint/CTEnumerateSubdomains
证书透明度(Certificate Transparency)日志记录了几乎所有公开 CA 签发的证书。cert-skills 用它做历史检索与子域发现。本页讲数据源、解析与归类的细节。
数据源:crt.sh
cert-skills 的 CT 能力全部走 crt.sh(Sectigo 运营的 CT 搜索服务):
| 函数 | URL 模板 |
|---|---|
CTSearch(domain) | https://crt.sh/?q=%25.<domain>&output=json |
CTSearchByFingerprint(fp) | https://crt.sh/?q=<fingerprint>&output=json |
%25.是%.的 URL 编码——crt.sh 后缀通配语法,搜该域名下所有子域证书- User-Agent:
cert-skills/1.0 (certificate security toolkit) - HTTP client Timeout:30 秒
crtshBaseURL变量可被测试覆写指向本地 stub
crtshEntry 结构体(8 字段)
type crtshEntry struct {
IssuerCAID int `json:"issuer_ca_id"`
IssuerName string `json:"issuer_name"`
CommonName string `json:"common_name"`
NameValue string `json:"name_value"` // 所有 SAN,换行分隔
SerialNumber string `json:"serial_number"`
NotBefore string `json:"not_before"`
NotAfter string `json:"not_after"`
FingerprintSHA256 string `json:"sha256"`
}NameValue 一条记录可能含多个域名(\n 分隔),必须拆开。
解析与去重
CTSearchByFingerprint 不去重
CTSearchByFingerprint 不做去重(L222-239 直接全收)——同一张证书在多个 CT 日志里都有副本,返回条目数会大于 1。需要去重请按 cert_sha256 自行聚合。
子域枚举
CTEnumerateSubdomains(ctenumerate.go L28)在 CTSearch 基础上做归类:
3 种时间格式
NotAfter 逐个尝试(第一个成功即 break):
| 格式 | Go layout | 示例 |
|---|---|---|
| ISO-like 无时区 | 2006-01-02T15:04:05 | 2025-12-31T23:59:59 |
| 空格分隔 | 2006-01-02 15:04:05 | 2025-12-31 23:59:59 |
| 仅日期 | 2006-01-02 | 2025-12-31 |
解析后与 time.Now() 比较:Before → ExpiredCerts++,否则 ActiveCerts++。
extractCTOrganization(非正则)
纯字符串分割,非正则。找不到返回 ""。
按 issuer 聚合
cleanIssuerName(L154-165):按 , split,TrimSpace 每段,去空,重新用 ", " join。
输出结构
type CTEnumerationResult struct {
TotalCerts int
UniqueSubdomains []string
WildcardDomains []string
SubdomainCount int
ByIssuer map[string][]string
ByCA map[string]int
ActiveCerts int
ExpiredCerts int
Organizations []string
}CTSearchResult:{Certificates []CTCert, TotalCount int, Error string}。
三种 CT 用法
| 场景 | 命令 | 用途 |
|---|---|---|
| 资产发现 | search-ct | 某域名下所有签发记录 |
| 侦察枚举 | ct-enumerate | 子域清单 + CA 归类 + 活跃/过期 |
| 精确溯源 | search-ct-fingerprint | 一张证何时签发、出现在哪些日志 |
取证场景的串联
CT 日志是公开审计的——攻击者复用一张证到多个钓鱼/C2 域名,CT 会留下全部记录。详见 证书事件应急取证工作流。
错误路径
局限
- 依赖 crt.sh 可用性:crt.sh 偶有不可用或限流,cert-skills 没有备用 CT API(Google/Cloudflare 的 ct-log API 未接入)
- 仅公开 CA 签发:私有 CA / 内网证书不在 CT 日志里
- 有签发延迟:证签发后到入 CT 日志有数小时延迟
下一步
- 取证编排 → 证书事件应急取证工作流
- 测绘三段式里 CT 的位置 → 网络空间测绘