Smap输出格式深度剖析:XML、JSON与Grepable实战指南
Smap依托Shodan数据引擎,为安全研究人员提供了Nmap的现代化替代方案。本文深入探讨其三种核心输出格式的技术特性、应用场景及最佳实践,助力高效处理网络扫描数据。
XML格式:企业级报告首选
XML输出位于internal/output/xml.go,完整保留扫描会话的元数据与结果细节,与Nmap生态工具链无缝兼容。
核心优势
- 遵循标准化Nmap XML Schema,支持XSLT样式转换生成可视化报告
- 完整记录扫描参数、时间戳、主机存活状态及操作系统指纹
- 集成CPE(通用平台枚举)标识,便于漏洞关联分析
执行指令
smap -oX enterprise_scan.xml 192.168.1.0/24
关键节点说明
| 元素 | 功能描述 |
|---|---|
<nmaprun> | 根元素,承载扫描器版本、启动参数及执行时间 |
<hosthint> | 目标主机提示信息,优化大规模扫描性能 |
<portused> | 用于OS检测的端口状态样本 |
<osclass> | 操作系统分类置信度与CPE绑定 |
JSON格式:自动化流水线基石
JSON模块实现于internal/output/json.go,采用流式序列化设计,可高效处理大规模扫描结果集。
技术特性
- 原生支持
jq、gron等命令行JSON处理器 - 数组结构优化,便于导入Elasticsearch、MongoDB等文档数据库
- 支持Pretty Print与紧凑模式切换
执行指令
smap -oJ api_data.json --min-rate 1000 10.0.0.0/8
数据模型示例
{
"scan_info": {
"tool": "smap",
"version": "0.1.12",
"started": "2024-01-15T09:23:17Z"
},
"targets": [
{
"addr": "203.0.113.45",
"status": "up",
"services": [
{
"port": 443,
"proto": "tcp",
"state": "open",
"banner": "nginx/1.24.0",
"tls": true,
"cert_subject": "CN=*.example.org"
}
],
"vulns": ["CVE-2023-44487"]
}
]
}
Grepable格式:终端效率利器
Grepable输出由internal/output/grep.go实现,采用紧凑的键值对格式,专为Shell文本处理工具链设计。
设计哲学
- 单主机单行的扁平化结构,规避多行记录解析复杂度
- 字段定界符统一为
/,与awk -F'/'模式高度契合 - 省略XML/JSON的层级嵌套,降低正则提取难度
执行指令
smap -oG live_hosts.gnmap -sn 172.16.0.0/16
字段解析规范
Host: 198.51.100.7 (edge-router.lab.local) Status: Up
Host: 198.51.100.7 () Ports: 22/open/tcp//ssh/OpenSSH_9.2/; 161/filtered/udp//snmp/// Ignored State: closed (998)
典型处理模式
# 提取存活主机IP
awk '/Status: Up/{print $2}' scan.gnmap | cut -d: -f2
# 筛选特定服务端口
grep '/http/' scan.gnmap | grep -oP 'Host: \K[^ ]+'
多格式并行输出策略
Smap支持单次扫描多目标格式输出,满足异构下游系统的数据消费需求:
smap -oX audit/$(date +%Y%m%d)_full.xml \
-oJ siem/import_$(date +%s).json \
-oG - 10.0.0.0/22 | tee >(grep 'open/tcp' > quick_check.txt)
格式选型决策矩阵
| 下游系统 | 推荐格式 | 关键考量 |
|---|---|---|
| DefectDojo、Dradis | XML | 原生支持Nmap XML导入 |
| Splunk、ELK Stack | JSON | 无需自定义解析规则 |
| Ansible Inventory | Grepable | 快速生成动态主机清单 |
| CI/CD流水线 | JSON | 结构化退出码与结果断言 |
| 手工分析报告 | XML+HTML转换 | 浏览器可读性与打印友好 |
高级过滤与转换技巧
JSON流式处理
smap -oJ - target | jq -c '.targets[] | select(.services | length > 0) | {ip: .addr, ports: [.services[].port]}'
XML转CSV快速转换
xmllint --xpath '//host/address/@addr|//port/@portid|//service/@name' scan.xml | \
paste - - - | tr '="' ',' | sed 's/addr,//;s/portid,//;s/name,//'
Grepable状态码批量统计
cut -d: -f3 scan.gnmap | sort | uniq -c | sort -rn