烤
用于处理Interactish OAST(带外应用程序安全测试)域的Go库、CLI工具、自托管web服务器和stdio MCP服务器。
概述
roast 解码嵌入在Interactish OAST域名中的元数据。这些域编码了一个12字节的XID前导码,其中包含时间戳、机器ID、进程ID和计数器值,可用于威胁情报关联和活动跟踪。
回溯和OAST分析
烘焙中使用的方法基于John Jarocki的LABSCon演示 “从OAST到OAST追踪网络空间幽灵”.
本文描述了存储在OAST完全限定域名中的数据,这些域名用作带外测试工具(如Project Discovery的Nuclei)的唯一标签,以验证测试成功。
基于原始假设的分析
| 幻灯片 | 索赔 | 验证 |
|---|---|---|
| 17 | XID是一个12字节结构的“K可排序唯一标识符” | 已确认: id.go 定义 type ID [rawLen]byte 哪里 rawLen = 12 |
| 17 | 前导码以base32hex编码,随机数以z-base-32编码 | 已确认:前导码使用 0123456789abcdefghijklmnopqrstuv,nonce使用 ybndrfg8ejkmcpqxot1uwisza345h769 |
| 19 | 字节布局:TS(4)+MID(3)+PID(2)+计数器(3) | 已确认:匹配 id.go 精确的场偏移 |
| 21 | MID使用平台机器ID的SHA-256 | 已确认适用于xid v1.5.0+(当前版本) |
| 21 | 平台来源:Linux /etc/machine-id,macOS sysctl kern.uuid,Windows注册表 MachineGuidFreeBSD sysctl kern.hostuuid | 已确认:匹配项 hostid_*.go 平台文件 |
| 21 | 回退到主机名或随机字节 | 已确认: readMachineID() 回退链 |
| 22 | z基-32 y =0,生产 yyy 在v1.0.1 nonces中运行 | 已确认:z-base-32字母以开头 y 映射到0 |
| 22 | v1.0.2(2022-03-20)修复了随机数使用随机字节的问题 | 已确认:提交 0166128 切换到 crypto/rand |
| 22 | Web客户端对前导码和随机数都使用z-base-32 | 已确认:Web客户端JavaScript在整个过程中都使用z-base-32 |
| 37 | “时间戳与交互客户端的时区设置有关” | 已确认:XID编码 time.Now().Unix() 它使用客户端的本地挂钟,而不是UTC |
演示文稿中缺少
以下细节在演示文稿中没有,但对以下内容很重要 法医分析:
| 主题 | 缺少什么 | 为什么重要 |
|---|---|---|
| 哈希进化 | 演示文稿显示了SHA-256(幻灯片21),但没有提到旧版本使用MD5,也没有提到转换发生的时间 | 一位分析师在2023年4月之前/之后的域中比较MID,会发现同一台机器的MID不同,并可能错误地得出结论,它们是不同的运算符 |
| 精确的xid版本映射 | 没有交互式版本到xid版本的映射 | 没有这个,分析师就无法确定哪种哈希算法产生了给定的MID |
XID_MACHINE_ID env 是 | 未提及(在演示后于2025年5月添加) | 操作员现在可以通过设置此环境变量来欺骗他们的MID,从而破坏机器相关性 |
| Linux回退路径 | /sys/class/dmi/id/product_uuid 作为Linux上的辅助源 | 在容器化环境中 /etc/machine-id 可能不存在,则使用DMI UUID |
| 大规模自动时区估计 | 演示文稿演示了差分技术(GA cookie与XID时间戳,幻灯片36),并指出时间戳是本地的(幻灯片37),但并没有将其正式化为跨活动批量时区估计的系统管道 | Roast EstimateTimezone() 和 ConsensusTimezone() 通过信心评分在多个领域实现自动化 |
| 计数器初始化 | 计数器从以下位置播种 crypto/rand,不是从0开始 | 对于计数器间隙分析很重要——进程中的第一个域不会有计数器=0(与v1.0.1 nonce不同) |
| PID截断 | PID存储为 os.Getpid() % 65536 (2字节) | 在具有高PID(>65535)的Linux上,不同进程可以产生相同的PID字段 |
安装
go install codeberg.org/hrbrmstr/go-roast/cmd/roast@latest或者从源代码构建:
# To install from Bob Rudis' original repo:
# git clone https://codeberg.org/hrbrmstr/go-roast
# To install from this fork:
git clone https://github.com/jarocki/go-roast
cd go-roast
go build -o roast ./cmd/roastCLI使用情况
快速参考
| 命令 | 目的 |
|---|---|
roast decode | 解码OAST域(每行一个) |
roast extract | 从文本/日志中提取OAST域 |
roast analyze | 分析活动模式的域 |
roast pipe | 用于DuckDB集成的逐行NDJSON输出 |
roast serve | 启动web UI服务器 |
roast mcp | 启动MCP stdio服务器 |
全球旗帜
-o, --output-输出格式:JSON、CSV、表格、markdown(默认:JSON)-q, --quiet-抑制非必要输出-h, --help-显示任何命令的帮助-v, --version-显示版本信息
解码OAST域
从文件或stdin中解码一个或多个OAST域。
# Decode from stdin
echo "c58bduhe008dovpvhvugcfemp9yyyyyyn.oast.pro" | roast decode
# Decode from file (one domain per line)
roast decode -f domains.txt
# Output as CSV
roast decode -f domains.txt -o csv
# Output as table
roast decode -f domains.txt -o table
# Quiet mode (suppress counts)
roast decode -f domains.txt -q旗帜:
-f, --file-包含OAST域的文件(每行一个)
从文本中提取OAST域
从文本文件或stdin中提取OAST域。
# Extract from file
roast extract -f logfile.txt
# Extract and decode in one step
roast extract -f logfile.txt --decode
# Extract from stdin
cat logs.txt | roast extract --decode -o json
# Extract with CSV output
roast extract -f logfile.txt -o csv
# Extract and decode with table output
roast extract -f logfile.txt --decode -o table旗帜:
-f, --file-从中提取OAST域的文件(如果未提供,则从stdin读取)--decode-还解码提取的域
分析OAST活动
从文件或stdin分析OAST域并生成活动统计信息。自动提取和解码找到的所有域。
# Analyze domains from a file (markdown report)
roast analyze -f domains.txt -o markdown
# Analyze from stdin
cat logs.txt | roast analyze -o markdown
# Output as JSON
roast analyze -f domains.txt -o json
# Include raw JSON data with markdown report
roast analyze -f domains.txt -o markdown --include-json旗帜:
-f, --file-要分析的文件(如果没有提供,则从stdin读取)--include-json-在markdown输出中包含原始JSON数据
活动分析提供:
- 载有高级别调查结果的执行摘要
- 总体统计数据(总域、有效/无效、唯一活动/机器/PID)
- 活动的时间跨度(首次出现、最后出现、持续时间)
- 分类细分(客户端类型、服务器版本),包括每个活动的详细信息
- v1.0.1版本的会话分析(会话年龄、域生成速度)
- 交叉引用发现(跨同一机器域的证实或警告)
- 每个活动的叙述,包括随机时间戳范围、计数器范围和会话时间
- 所有活动的活动时间线
- 威胁情报的相关数据
示例输出
解码输出(JSON):
[
{
"original": "c58bduhe008dovpvhvugcfemp9yyyyyyn.oast.pro",
"timestamp": "2021-09-26T18:07:54Z",
"machine_id": "2e:00:10",
"pid": 56447,
"counter": 4165629,
"nonce": "cfemp9yyyyyyn",
"ksort": "c58bdu",
"campaign": "he008",
"valid": true,
"classification": {
"client_type": "cli",
"server_version": "v1.0.1",
"confidence": "high",
"reasoning": [
"preamble contains digits — CLI client (base32hex)",
"nonce decodes to valid timestamp 2021-09-26T18:07:56Z — v1.0.1",
"nonce counter=1 (domain sequence in process)"
],
"decodable": true,
"nonce_analysis": {
"nonce_timestamp": "2021-09-26T18:07:56Z",
"nonce_counter": 1,
"session_age": "2 seconds",
"session_age_secs": 2,
"domain_sequence": 1,
"timestamp_reliable": true,
"commentary": [
"session_age=2 seconds: short client session",
"nonce_counter=1: first domain generated in this process"
]
}
},
"nonce_timestamp": "2021-09-26T18:07:56Z",
"nonce_counter": 1
}
]活动分析输出(Markdown):
# OAST Campaign Analysis
## Executive Summary
Analysis of 15 domains across 3 campaigns spanning 2.2 days.
Found 2 machine IDs and 1 PIDs. Classification: v1.0.1 (15).
## Overall Statistics
- **Total Domains Found:** 15
- **Valid Domains:** 15
- **Unique Campaigns:** 3
- **Unique Machine IDs:** 2
- **Unique PIDs:** 1
## Session Analytics
v1.0.1 nonce-derived session data:
**Campaign `he008`:**
- Nonce Timestamp Range: 2024-01-15T10:30:45Z to 2024-01-15T15:02:12Z
- Session Age Range: 2s to 16200s
- Domain Generation Velocity: 1.8 domains/hour
## Campaign Details
### Campaign: `he008`
- **Count:** 8 domains
- **Duration:** 4.5 hours
- **Counter Range:** 5678 - 5801
- **Machine IDs (1):** `12:34:56`
- **PIDs (1):** `1234`
Campaign he008 was active for 4.5 hours across 1 machines, generating 8 domains.
## Timeline
Activity observed from 2024-01-15T10:30:45Z to 2024-01-17T14:22:33Z (2.2 days).
15 domains decoded across 3 campaigns from 2 unique machines.MCP服务器
启动模型上下文协议stdio服务器:
roast mcp有关Claude Desktop的详细配置,请参阅 CLAUDE_DESKTOP.md
提示
oast-expert-全面的OAST领域知识库和分析指导(加载/oast-expert在克劳德桌面)
资源
oast://info-OAST域及其结构概述oast://format-详细的格式规范,包括编码细节oast://domains-已知OAST域后缀列表oast://intel-来自主动维护的威胁情报源的外部OAST域情报
工具
岩心分析工具
decode_oast-解码一个或多个OAST域extract_oast-从文本中提取OAST域extract_oast_file-从文件中提取OAST域validate_oast-检查字符串是否为有效的OAST域oast_campaign_analysis-从文件中分析OAST域,并以markdown格式生成活动分析摘要
增强的实时智能工具
fetch_interactsh_domains_live-通过缓存和条件请求对400多个交互式域进行实时HTTP获取fetch_burp_collaborator_domains_live-使用缓存对Burp Collaborator域进行实时HTTP获取check_domain_updates-使用带有ETag/Last Modified支持的HEAD请求进行高效的更新检查validate_domain_advanced-具有归因和威胁情报背景的高级域验证validate_domain_batch_advanced-使用统计数据和组织归因进行批量域验证oast_cache_stats-缓存统计信息,包括TTL、性能指标和清理状态
传统威胁情报工具
fetch_interactsh_domains-有关Interactish域的基本信息(使用实时版本以增强功能)fetch_burp_collaborator_domains-Burp Collaborator域的基本信息(使用实时版本增强功能)oast_threat_intel-关于OAST域和基础设施的全面威胁情报背景
增强功能
实时数据获取
- HTTP客户端集成:直接从darses/cti GitHub存储库获取
- 条件请求:使用ETag和Last Modified标头来最小化带宽
- 错误处理:优雅的回退和详细的错误报告
- 用户代理:标识为“烘焙/1.0.0(OAST域分析器)”
智能高速缓存
- 基于TTL的缓存:1小时默认TTL,可配置过期时间
- 内容哈希:SHA256哈希检测实际内容更改
- 稳定性检测:缓存90%过期时提前刷新
- 背景清理:每15分钟自动删除过期条目
更新通知
- 变化检测:跟踪ETag、上次修改时间和内容哈希
- 高效检查:HEAD请求在不下载的情况下检查更新
- 更新警示:更新外部列表时的通知
- 缓存统计:缓存性能和命中率的详细指标
高级域验证
- 多源验证:交叉引用内置+400+外部域
- 归因引擎:确定组织所有权(NetSPI、Rapid7、研究人员)
- 威胁分类:将合法测试与潜在威胁区分开来
- 信心评分:验证结果的高/中/低置信水平
- 批处理:使用摘要统计信息验证多个域
MCP配置
基本配置
添加到您的Claude桌面配置(~/Library/Application Support/Claude/claude_desktop_config.json 在macOS上):
{
"mcpServers": {
"roast": {
"command": "/path/to/roast",
"args": ["mcp"]
}
}
}替换 /path/to/roast 带有您的烤肉二进制文件的完整路径。
使用OAST专家提示
Claude Desktop支持MCP提示。要自动提供OAST领域专业知识上下文,请执行以下操作:
- 添加上述MCP服务器配置后,重新启动Claude Desktop
- 开始对话并键入
/oast-expert加载全面的OAST知识库 - Claude将有权访问以下详细信息:
- OAST域结构和编码 - 解码算法和字段布局 - 活动分析技术 - 机器ID推导 - 版本检测模式 - 分析最佳做法
该提示为OAST域的智能分析提供了上下文,而无需手动读取资源。
提示中包含的内容:
- 完整的OAST域结构文档
- Base32hex和z-base-32编码规范
- 具有字节级详细信息的字段布局
- 所有平台的机器ID推导
- K-sort和活动标识符解释
- 版本检测技术(v1.0.1通过“y”模式检测)
- 威胁情报关联策略
- 活动跟踪方法
- 分析技巧和最佳实践
- 所有已知的OAST域后缀
这种丰富的上下文允许Claude在使用OAST域时提供专家级的分析和指导。
网页用户界面
启动交互式域分析的web界面:
# Start on default port (8080)
roast serve
# Custom address and port
roast serve --addr 0.0.0.0 --port 9090web UI提供:
- 粘贴或上传 --直接粘贴域或拖放CSV文件
- 解码/分类/提取/分析 --浏览器中的所有CLI功能
- 分类徽章 --客户端类型(CLI/web)、服务器版本(v1.0.1/1.0.2+)和置信度(高/中/低)的视觉指标
- Nonce分析显示 --解码的时间戳、计数器、会话时间和注释
- 保存CSV --将任何结果集导出为CSV文件
- 下载报告 --下载活动分析作为降价报告
领域分类
roast 按以下方式对OAST域进行分类 客户类型 和 服务器版本 使用字符集启发式和随机数分析。
客户端类型检测
| 客户 | 信号 | 信心 |
|---|---|---|
| 命令行界面 | 前言包含数字 [0-9] (基座32hex) | 高 |
| 网络 | 序言包含 [w-z] (外底32hex) | 高 |
| 未知 | 序言就是全部 [a-v] (模棱两可) | 低 |
服务器版本检测
| 版本 | 信号 | 置信度 |
|---|---|---|
| v1.0.1 | Nonce zbase32解码为有效的时间戳(2020-2030) | 高 |
| v1.0.1 | 有效的时间戳,但在未来 | 中等 |
| v1.0.1 | 有效的时间戳,但比CID早>5分钟 | 低 |
| v1.0.2+ | Nonce解码到超出范围的时间戳 | 中等 |
| 未知 | Nonce包含非zbase32个字符(l/v/0/2) | 高(网络随机数) |
Nonce分析(v1.0.1)
当检测到v1.0.1随机数时, roast 提取物:
- Nonce时间戳 --域生成时(可靠时升级为顶级JSON字段)
- Nonce计数器 --进程中的域序列号
- 会话年龄 --CID创建和域生成之间的时间
- 评论 --自动化分析(启动域、长会话、大容量生成等)
- 时间戳可靠性 --在未来或CID之前标记为不可靠
交叉引用验证
当批量解码多个域时, roast 跨共享相同机器ID的域交叉引用v1.0.1分类:
- 全部一致 --信心升级,领域相互印证
- 混合版本 --警告补充说,某些分类可能不可靠
- 单个域 --无法证实,分类按原样进行
图书馆使用情况
核心类型
// DecodedOAST contains the decoded metadata from an OAST domain
type DecodedOAST struct {
Original string // Original subdomain/FQDN
Timestamp time.Time // Decoded timestamp
MachineID string // Format: "xx:xx:xx" (3 hex bytes)
PID uint16 // Process ID
Counter uint32 // Counter value (24-bit)
Nonce string // The nonce portion (if present)
KSort string // First 6 chars of preamble (for K-sorting)
Campaign string // Chars 7-11 of preamble (campaign identifier)
Valid bool // Whether decoding succeeded
Error string // Error message if invalid
Classification *Classification // Client type, server version, and nonce analysis
NonceTimestamp *time.Time // Promoted from nonce analysis (when reliable)
NonceCounter *uint32 // Promoted from nonce analysis (when reliable)
}
// OASTMatch represents an extracted OAST domain from text
type OASTMatch struct {
Full string // Full matched string
Subdomain string // Just the subdomain portion
Domain string // The OAST domain (e.g., "oast.fun")
StartIndex int // Position in source text
EndIndex int // End position in source text
}
// CampaignAnalysis contains the full analysis of OAST domains
type CampaignAnalysis struct {
TotalDomains int
ValidDomains int
InvalidDomains int
UniqueCampaigns int
FirstSeen time.Time
LastSeen time.Time
TimeSpan string
UniqueMachines int
UniquePIDs int
MachineIDs []string
PIDs []uint16
Campaigns map[string]*CampaignStats
}解码功能
import "codeberg.org/hrbrmstr/go-roast/pkg/roast"
// Decode a single domain
decoded, err := roast.Decode("c58bduhe008dovpvhvugcfemp9yyyyyyn.oast.pro")
if err != nil {
log.Fatal(err)
}
fmt.Printf("Timestamp: %s\n", decoded.Timestamp)
fmt.Printf("Machine ID: %s\n", decoded.MachineID)
fmt.Printf("PID: %d\n", decoded.PID)
fmt.Printf("Counter: %d\n", decoded.Counter)
fmt.Printf("Campaign: %s\n", decoded.Campaign)
// Decode multiple domains at once
domains := []string{"domain1.oast.pro", "domain2.oast.fun"}
results := roast.DecodeBatch(domains)
for _, result := range results {
if result.Valid {
fmt.Printf("%s: %s\n", result.Campaign, result.Timestamp)
}
}提取功能
// Extract domains from a string
matches := roast.ExtractFromString("Found: c58bduhe008dovpvhvug.oast.pro")
for _, match := range matches {
fmt.Printf("Found: %s at position %d\n", match.Full, match.StartIndex)
}
// Extract from a reader (e.g., file, HTTP response)
file, _ := os.Open("logs.txt")
matches, err := roast.ExtractFromReader(file)
// Extract from a file
matches, err := roast.ExtractFromFile("logs.txt")
// Extract and decode in one step
text := "Logs contain c58bduhe008dovpvhvug.oast.pro"
matches, decoded := roast.ExtractAndDecode(text)
// Extract and decode from a reader
matches, decoded, err := roast.ExtractAndDecodeFromReader(file)
// Extract and decode from a file
matches, decoded, err := roast.ExtractAndDecodeFromFile("logs.txt")活动分析功能
// Analyze domains from a file
analysis, err := roast.AnalyzeCampaignFromFile("domains.txt")
if err != nil {
log.Fatal(err)
}
fmt.Printf("Total domains: %d\n", analysis.TotalDomains)
fmt.Printf("Unique campaigns: %d\n", analysis.UniqueCampaigns)
fmt.Printf("Time span: %s\n", analysis.TimeSpan)
// Generate markdown report
markdown := analysis.FormatMarkdown()
fmt.Println(markdown)
// Analyze domains from a string
text := "log with c58bduhe008dovpvhvug.oast.pro domains"
analysis := roast.AnalyzeCampaignFromString(text)验证功能
// Check if a string is a valid OAST subdomain
if roast.IsValidOASTSubdomain("c58bduhe008dovpvhvugcfemp9yyyyyyn") {
fmt.Println("Valid subdomain")
}
// Validate that a 20-char string is valid base32hex
if roast.IsValidPreamble("c58bduhe008dovpvhvug") {
fmt.Println("Valid preamble")
}
// Get list of known OAST domain suffixes
domains := roast.KnownOASTDomains()
// Returns: ["oast.pro", "oast.live", "oast.site", ...]
// Check if a domain is a known OAST domain
if roast.IsKnownOASTDomain("oast.pro") {
fmt.Println("Known OAST domain")
}OAST域格式
交互式FQDN看起来像:
c58bduhe008dovpvhvugcfemp9yyyyyyn.oast.pro
|------ preamble ------||- nonce -|前言(20个字符)
Base32hex编码的12字节XID包含:
- 字节0-3: Unix时间戳(从纪元开始的秒数,大端序)
- 字节4-6: 机器ID(哈希平台UUID的前3个字节)
- 字节7-8: 进程ID(大端序)
- 字节9-11: 计数器(大端序,从随机值开始)
Nonce(13+个字符)
z-base-32编码随机值(用于会话唯一性)
已知OAST域
内置域:
- oast.pro
- oast.live
- oast.site
- oast.online
- oast.fun
- oast.me
- interact.sh
- 互动网站
扩展域列表
为了全面覆盖OAST域, roast 提供 实时访问 积极维护威胁情报列表:
- 552+互动域名: darses/cti互动门户.txt -带缓存的实时HTTP获取
- 316+Burp协作者域名: darses/cti burpsuit-domains.txt -带缓存的实时HTTP获取
这些列表由以下人员维护 达塞斯 并通过自动Shodan查询定期更新:
交互式发现:
product:"Interactsh SMTP Server" port:25- `http.html:"
Interactsh Server "`
Burp协作者发现:
port:25 "Burp Collaborator Server ready"
增强功能:
- 实时HTTP获取:实时访问当前域列表
- 智能高速缓存:带条件请求的1小时TTL(ETag/上次修改)
- 更新检测:列表更改时自动通知
- 归因引擎:确定组织所有权(NetSPI、Rapid7、研究人员)
- 高级验证:交叉引用868多个威胁情报领域
注: roast 将尝试解码与Interactish前导码格式匹配的任何域,而不管后缀如何。增强的验证为威胁情报相关性提供了归因背景。
用例
- 威胁情报: 将不同安全事件中的OAST回调与归因上下文相关联
- 活动跟踪: 通过机器ID和活动标识符识别相关的扫描活动
- 法医: 从日志中的OAST域中提取时间戳和源信息
- 安全研究: 分析交互式使用模式和扫描行为
- 归因分析: 将合法的安全测试(NetSPI、Rapid7)与潜在威胁区分开来
- 基础设施监控: 使用实时域智能跟踪新的OAST部署
- 事件响应: 根据已知的合法基础设施与可疑基础设施验证OAST回调
主要业绩及成果
企业级智能
- 868+域名总数:8个内置+552个Interactish+316个Burp Collaborator域
- 实时数据获取:实时HTTP访问darses/cti存储库
- 智能高速缓存:1小时TTL的亚秒级响应时间
- 归因引擎:自动组织识别和威胁分类
性能和可靠性
- 100%缓存命中率:用于TTL窗口内的请求
- 条件请求:ETag和上次修改的优化
- 后台处理:每15分钟自动清理一次缓存
- 螺纹安全设计:完全并发访问支持
高级能力
- 更新通知:外部列表更改时自动检测
- 批处理:使用全面的统计数据验证多个域
- 信心评分:验证结果的高/中/低置信水平
- 威胁背景:区分安全公司、研究人员和潜在威胁
测试
# Run all tests
go test ./...
# Run with verbose output
go test -v ./pkg/roast/...
# Run with coverage
go test -cover ./...参考文献
- Base32hex(RFC 4648)
- z-base-32
- MCP规范
- darses/cti -积极维护OAST域基础架构列表
致谢
此更新由 约翰·加洛基 (@加洛基)以及 克劳德代码没有这个是不可能的 人民村——我永远感激这次惊人的合作。
- 鲍勃·鲁迪斯 (@hrbrmstr)——原创的创造者
烤 和 烤mcp 代码库。他在OAST领域的工作 解码和MCP服务器集成是本项目的基础。
- 伊恩·坎贝尔 --为了就OAST域分析技术进行协作和讨论,
2026年初在Mastodon上讨论过。
- 达塞斯 (@darses)——为了不懈的工作维护
darses/cti,积极策划的Interactish和 Burp Collaborator域为烤肉的实时威胁情报功能提供动力。
- 克劳德系统 通过 胡安·安德烈斯·格雷罗·萨德 (@贾格斯) —
这 Claude代码配置 马具起到了关键作用 在编排此更新时,提供代理基础架构、钩子和工作流 使这样的多问题实现成为可能的护栏。
许可证
麻省理工学院
