ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

theHarvester 结果与本地数据指南:JSONL、SQLite、REST API 与 yield 分析全解析

theHarvester 结果与本地数据指南:JSONL、SQLite、REST API 与 yield 分析全解析 theHarvester 结果与本地数据指南JSONL、SQLite、REST API 与 yield 分析全解析【免费下载链接】theHarvesterE-mails, subdomains and names Harvester - OSINT项目地址: https://gitcode.com/GitHub_Trending/th/theHarvester导读theHarvester 在完成一轮 OSINT 枚举后会产出一批结果数据邮箱、子域名/主机名、IP、URL、ASN、截图等本指南系统讲解如何按“下一步任务”选择最合适的输出通道终端用于交互审查JSONL 用于自动化与来源归因SQLite 用于本地历史与批量流转JSON/XML 用于兼容旧消费方REST API 用于生命周期状态与本地集成。读完本文你将掌握-f报告文件的 JSONL 结构、SQLite 六张证据表的含义、harvest-yields源产出对比方法以及结果的合规处理与分享规范。输出通道总览按任务选格式输出适用场景关键限制Terminal交互式人工审查不是稳定的自动化接口JSONL自动化、单次运行的交换与溯源provenance一条 summary 记录后跟规范化的 findingsSQLite本地历史与已完成运行的批量迁移跨运行包含敏感证据JSON 或 XML兼容旧消费方不保留逐条目的来源归因REST API生命周期状态、规范化结果与本地集成需要 API 认证从源码结构看这些通道共享同一套规范化的证据模型CompletedResult见 completed_result.py负责把运行结果、来源执行、动作执行与各类结构化证据虚拟主机、网络观测、Shodan 主机、接管候选、ASN 归属统一表达再分别投影到终端输出、JSONL、SQLite 与 API。evidence_types.pytheHarvester/lib/evidence_types.py定义了完整的ResultKind集合hostname、ip、email、url、asn、prefix、shodan-host、takeover、dns-recursive-classification、dns-recursive-finding、dns-recursive-summary等二十余种执行状态为completed / partial / failed / rate-limited / skipped证据状态为complete / partial / failed。Terminal 输出CLI 会按结果类型分组打印 findings也可以单独打印富化信息如 Shodan 输出。终端的print_section逻辑见 output.py对每个分组去重、排序后逐行输出。它面向运营人员的交互式审查不应作为稳定的自动化接口——终端文本格式、分组方式与诊断日志可能随版本变化。JSONL 报告推荐的自动化输出生成方式使用-f NAME写入一份持久化的运行报告uv run theHarvester -d example.com -b crtsh,certspotter -f report-f/--filename参数定义在 theHarvester/main.pyWrite NAME.json, NAME.xml, and NAME.jsonl.。也就是同一命令会同时产出三个文件其中report.jsonl是推荐给自动化流水线的格式。文档特别说明网络活动包含“面向提供方的被动发现”与“本地报告写入”两部分因此生成报告本身只涉及本地磁盘写入不会额外发起网络探测。JSONL 的结构约定report.jsonl的约定非常严格由 completed_result.py 的encode_result_jsonl/parse_result_jsonl实现首条记录是 summary汇总本次运行run_id、target、started_at/completed_at、counts、result_count、evidence_status并列出source_executions与action_executions每条含 action/source、status、duration_ms、result_count、error_type、stop_reason以及artifacts文件元数据。其余每条记录是一条规范化 finding必含type、value、sources、actions四个键hostname/prefix/asn可带observationsshodan-host/takeover可带detailsprefix固定带scope: external-relationship。校验器会拒绝未知类型、空 value、非规范化值如非 canonical 的 hostname/IP/ASN/prefix并强制sources、actions排序去重——这意味着 JSONL 文件必须由 theHarvester 生成或严格按规范构造才能被 API 导入。查看汇总之外的 findings只提取关键字段jq -c select(.type ! summary) | {type, value, sources, actions} report.jsonl因为每条 finding 自带sources数组JSONL 能在不执行发现流程的情况下由 API 直接导入并重建来源归因。Action evidence 示例合成数据文档提供的这些示例使用保留名、保留 ASN 与保留地址段如example.com、192.0.2.0/24、AS64500、2001:db8::1每条记录块都以 summary 开头并且能通过与导入完全相同的 JSONL 解析器。DNS 解析、反向解析与爆破Resolutiondns-resolve贡献 IP findings反向解析dns-lookup贡献主机名爆破dns-brute两者皆可贡献{action_executions:[{action:dns-brute,duration_ms:25.0,error_type:null,result_count:2,status:completed,stop_reason:null},{action:dns-lookup,duration_ms:31.0,error_type:null,result_count:1,status:completed,stop_reason:null},{action:dns-resolve,duration_ms:18.0,error_type:null,result_count:1,status:completed,stop_reason:null}],artifacts:[],completed_at:2026-08-17T12:01:00Z,counts:{hostname:3,ip:2},evidence_status:complete,result_count:5,run_id:123e4567-e89b-12d3-a456-426614174101,source_executions:[{duration_ms:12.0,error_type:null,result_count:1,source:crtsh,status:completed,stop_reason:null},{duration_ms:15.0,error_type:null,result_count:1,source:rapiddns,status:completed,stop_reason:null}],started_at:2026-08-17T12:00:00Z,target:example.com,type:summary} {actions:[dns-brute],sources:[],type:hostname,value:admin.example.com} {sources:[crtsh],type:hostname,value:api.example.com} {actions:[dns-lookup],sources:[],type:hostname,value:ptr.example.com} {actions:[dns-resolve],sources:[rapiddns],type:ip,value:192.0.2.10} {actions:[dns-brute],sources:[],type:ip,value:192.0.2.20}注意api.example.com由crtsh来源发现没有actions而192.0.2.10同时带actions:[dns-resolve]与sources:[rapiddns]表示该 IP 先被被动来源发现、再经解析动作验证。每条 finding 的actions数组标识产生它的动作。递归 DNSRecursive DNS递归 DNS 产出普通 hostname/IP findings同时它的结构化记录保留父名parent、返回地址addresses、PTR 值、深度depth、查询计数query_count与停止原因stop_reason。结构化value字段内是 JSON 字符串用jq读取时需fromjson{action_executions:[{action:dns-recursive,duration_ms:40.0,error_type:null,result_count:5,status:completed,stop_reason:depth-limit}],artifacts:[],completed_at:2026-08-17T12:01:00Z,counts:{dns-recursive-classification:1,dns-recursive-finding:1,dns-recursive-summary:1,hostname:2,ip:1},evidence_status:complete,result_count:6,run_id:123e4567-e89b-12d3-a456-426614174102,source_executions:[{duration_ms:12.0,error_type:null,result_count:1,source:crtsh,status:completed,stop_reason:null}],started_at:2026-08-17T12:00:00Z,target:example.com,type:summary} {actions:[dns-recursive],sources:[],type:dns-recursive-classification,value:{\addressability\:\not-currently-addressable\,\addresses\:[],\cnames\:[\missing.vendor.test\],\hostname\:\unused.api.example.com\,\parent\:\api.example.com\,\ptrs\:[\legacy-ptr.example.net\]}} {actions:[dns-recursive],sources:[],type:dns-recursive-finding,value:{\addresses\:[\192.0.2.21\],\hostname\:\dev.api.example.com\,\parent\:\api.example.com\,\ptrs\:[\ptr.example.net\]}} {actions:[dns-recursive],sources:[],type:dns-recursive-summary,value:{\depth_reached\:1,\query_count\:24,\stop_reason\:\depth-limit\,\zero_yield_batches\:0}} {sources:[crtsh],type:hostname,value:api.example.com} {actions:[dns-recursive],sources:[],type:hostname,value:dev.api.example.com} {actions:[dns-recursive],sources:[],type:ip,value:192.0.2.21}Shodan 主机富化shodan-hostfinding 以 IP 地址为 valueJSONL 把服务详情整体放在details中而不是拆成多个独立结果类型{action_executions:[{action:shodan,duration_ms:22.0,error_type:null,result_count:1,status:completed,stop_reason:null}],artifacts:[],completed_at:2026-08-17T12:01:00Z,counts:{ip:1,shodan-host:1},evidence_status:complete,result_count:2,run_id:123e4567-e89b-12d3-a456-426614174103,source_executions:[{duration_ms:15.0,error_type:null,result_count:1,source:rapiddns,status:completed,stop_reason:null}],started_at:2026-08-17T12:00:00Z,target:example.com,type:summary} {sources:[rapiddns],type:ip,value:192.0.2.10} {actions:[shodan],details:{asn:AS64500,domains:[example.com],hostnames:[api.example.com],organization:Example Network,services:[{http:{components:[nginx],server:nginx,title:Example},observed_at:2026-08-17T11:58:00Z,port:443,product:nginx,transport:tcp,version:1.24.0}]},sources:[],type:shodan-host,value:192.0.2.10}RouteViews 路由证据RouteViews 把 ASN 保留为标量 finding同时把 origin、BGP 路由与 RPKI 观测挂到一条 canonical prefix 上。该 prefix 只是外部关系scope: external-relationship不会扩展目标授权范围{action_executions:[{action:routeviews,duration_ms:55.0,error_type:null,result_count:1,status:completed,stop_reason:null}],artifacts:[],completed_at:2026-08-17T12:01:00Z,counts:{asn:1,prefix:1},evidence_status:complete,result_count:2,run_id:123e4567-e89b-12d3-a456-426614174104,source_executions:[],started_at:2026-08-17T12:00:00Z,target:AS64500,type:summary} {sources:[],type:asn,value:AS64500} {actions:[routeviews],observations:[{action:routeviews,collected_at:2026-08-17T12:01:00Z,origin_asn:AS64500,type:observed-origin},{action:routeviews,as_path:64496 64500,collected_at:2026-08-17T12:01:00Z,collector:route-views.example,communities:64496:100 64500:200,observed_at:2026-08-17T11:59:00Z,origin_asn:AS64500,peer_address:2001:db8::1,peer_asn:AS64496,type:bgp-route},{action:routeviews,collected_at:2026-08-17T12:01:00Z,observed_at:2026-08-17T11:59:00Z,origin_asn:AS64500,state:valid,type:rpki-validation}],scope:external-relationship,sources:[],type:prefix,value:192.0.2.0/24}对应的结构化模型在 network_evidence.pyPrefixOriginObservation、BgpRouteObservation、RpkiValidationObservationCompletedResult.__post_init__会强制校验BGP 路由与 RPKI 观测必须引用对应的 observed-origin 证据prefix/ASN 必须同时存在于 results 中。虚拟主机 JSONL finding完整的 virtual-host JSONL finding 展示了一个已确认的主机名如何在多个端点观测中保留证据results中只存一条hostname行details_json承载所有端点的观测数组。这是“一个结果、多条观测”的统一模型。兼容性文件同一个-f report命令还会创建report.json与report.xml兼容性报告。JSON 与 XML 兼容性报告JSON是单个对象包含更广的结果集。cmd、hosts、shodan始终存在其他字段在非空时才出现。XML包含命令、邮箱、主机与虚拟主机其他结果类型请改用 JSON。JSON 与 XML 报告不记录每个条目由哪个来源发现——这是它们与 JSONL、API 的关键差异。当运行了虚拟主机发现时JSON 的vhosts数组与 XML 的vhost条目只包含已确认的主机名不含端点或基线证据这类结构化数据请使用 JSONL 或 API 运行详情。主机值可能是纯主机名启用 DNS 解析时也可以使用hostname:IP形式。SQLite 数据库本地历史与批量流转存储位置与权限主机、邮箱、IP 及相关记录存储在~/.local/share/theHarvester/stash.sqlite数据库跨运行持久存在因此必须纳入授权测试engagement的清理与留存流程。从源码看database.py 中_DEFAULT_DATABASE定义了该路径初始化时会把父目录权限设为0700、数据库文件chmod(0o600)见 run_store.py 的initialize并启用外键约束与 WAL 日志模式。运行记录的写入方式完成的 CLI 执行会以 run UUID 为键存储一条规范化终端记录API 执行默认使用同一数据库并可用环境变量THEHARVESTER_RUN_DB覆盖路径。生命周期行与终端证据分离队列、取消、worker 状态由run_records/run_worker_leases两张运行级表保存与六张证据表解耦对应 database.py 中的RunLifecycleStore与ResultStore。导入 JSONL 不执行发现POST /api/v1/runs/import直接解析上传的.jsonl上限 10 MiB经RunStore.import_evidence校验后持久化并从每条 finding 的sources数组重建来源归因runs.py。SQLite 导入/导出为批量流转POST /api/v1/runs/import-database上传.sqlite/.sqlite3/.db校验 SQLite 魔数SQLite format 3\0大小由THEHARVESTER_MAX_DATABASE_IMPORT_BYTES控制GET /api/v1/runs/export-database下载便携数据库。批量迁移会校验源库、复制每一个已完成运行并保留原始 run ID同时剔除队列/取消/worker-lease 状态_PORTABLE_DATABASE_DROP_STATEMENTS会删除legacy_observations、run_records、run_worker_leases三张运行表。HarvestView 调度数据库HarvestView调度/认领/分发预留使用另一套独立的、权限0600的 SQLite 数据库由 SQLAlchemy 管理~/.local/share/theHarvester/stash.schedules.sqlite可通过THEHARVESTER_SCHEDULE_DB切换路径。它是本地控制状态不包含在便携式 SQLite 证据导出中。六张证据表runs一次有限的枚举运行run_id、target、started_at、completed_at、evidence_status。executions每个被动来源或主动动作producer_kind 区分source/action含 status、duration_ms、result_count、error_type、stop_reason。results去重后的 hostnames、IPs、emails、URLs 与结构化输出(run_id, kind, value)唯一约束details_json存结构化细节。result_origins每个结果由哪个执行产生result 与 execution 的多对多关联。asn_attributions带来源的组织标签把 ASN 结果精确关联到同一次执行提供的 hostname 或 IP。artifacts截图等文件元数据链接到创建它的动作与主体结果含size_bytes 0与 SHA-256 十六进制校验约束。虚拟主机证据复用同一模型results存一条hostname行result_origins把它链接到vhost动作执行details_json保存端点观测。一个主机名即使分布在多个不同 IP 端点上仍是一条结果、多条观测。运行期收集会记录被动来源执行以及 DNS、takeover、Shodan、API 端点扫描等执行及其来源关联截图动作把文件元数据挂到捕获的 hostname/URL 上但不创建 screenshot 类型的 finding截图 artifact 的kind为screenshot结果类型则是它所属的hostname/url。结构化证据的语义约束RouteViews创建prefix结果scope: external-relationshiprouteviews动作溯源观测区分 ASN-prefix 的 origin 声明、collector/peer 的 BGP 路由与 RPKI 校验状态。它们应被当作路由证据不代表注册、所有权、授权、可达性也不扩展目标范围。ASN 组织归属URLScan、ONYPHE、Shodan 可以把提供方组织标签挂到 ASN。SQLite 把每条关系存在asn_attributionsJSONL、API、CLI 输出与 HarvestView 暴露同样的类型化观测。这些标签是有时间界限的提供方证据缺失或冲突的值保持分离不会被单一“ASN 所有者”属性替换。Shodan 的org字段提供组织标签其isp字段仍是 Shodan 载荷的一部分不等价。URL 统一为url结果类型来源或动作溯源标明它来自 BuiltWith、GitLab、RocketReach、API 扫描或其他生产者不再存储提供方专属的 URL 类型。主机名/IP 统一为hostname/ip类型在 SQLite、JSONL、API 与 HarvestView 中一致。hostname 可能是授权目标本身或其下属名称因此结果类型不声明每个值都是子域名。运行级辅助表与升级run_records存储队列与生命周期状态run_worker_leases防止两个本地 worker 认领同一队列租约超时 30 秒见 run_store.py 的WORKER_LEASE_TIMEOUT_SECONDS。无运行的旧观测存在legacy_observations。SQLite 在正常初始化时自动升级受支持的 schema当前SCHEMA_VERSION 8并会对历史 result kind 别名如vhost→hostname、ip-address→ip、api-endpoint→url做规范化归并见 database.py。截图uv run theHarvester -d example.com -b crtsh --screenshot /path/to/dir--screenshot DIR把浏览器捕获写入所选目录。即使未使用任何凭据截图也可能包含认证页、内部名称或其他敏感可视数据——需要按敏感数据管理。从 theHarvester/main.py 的截图执行逻辑看截图动作会记录screenshot动作执行状态含completed / partial / failed / skipped每个成功文件生成带sha256的 artifact并且截图只支持直连传输不能与--proxies同用文档还建议截图应配合 DNS 解析使用。REST API 结果GET /api/v1/runs/{run_id}返回生命周期状态加一个规范化的results数组每个结果含type、value、sources、actions通过vhost动作发现的hostname自带端点观测native endpoint observations通过 RouteViews 发现的prefix自带 origin、route、RPKI 观测scope 固定为external-relationship运行级的来源/动作结果保留在source_executions/action_executions文件元数据经artifacts返回JSONL 导入/导出按单次运行进行SQLite 导入与GET /api/v1/runs/export-database则批量迁移已完成运行不携带队列、取消与 worker-lease 状态。运行时的/docs、/redoc与 OpenAPI 文档是请求与响应结构的精确参考。相关路由实现见 runs.py数据组装逻辑见 run_store.py 的_rowdetail 模式会加载 evidence、source_yields、artifacts与screenshots。对比来源主机名产出source yields指标定义运行详情中的source_yields由持久化的规范化主机名溯源推导每个被选中的来源含以下字段observed_result_count归属于该来源的不同主机名数量unique_result_count本次运行中没有任何其他来源报告过的主机名数量shared_result_count至少还有其他一个来源也报告过的主机名数量resolved_hostname_count该来源归属的主机名中本次运行的dns-resolve动作保留了 A、AAAA 或 CNAME 答案的数量unique_resolved_hostname_count仅此来源归属的、且有当前 DNS 证据的主机名数量。unique_result_count衡量来源的边际覆盖marginal coverage不依赖来源顺序unique_resolved_hostname_count进一步限定为有现时 DNS 证据的主机名。需要明确这两个计数都不能证明提供方是权威或独立的DNS 答案也不能证明服务可达。对比前的纪律必须结合对应的来源执行状态与 stop_reason 阅读计数失败、被限流、被跳过或停在提供方边界provider boundary的来源不能与“零结果但已完成”的来源直接比较。同一证书透明CT或被动 DNS 家族的来源可能重叠因为它们依赖相同的上游证据。跨运行对比时固定以下变量授权目标、来源集合、请求的 limit、发布版本、解析器集合与收集时间窗。仅在对比不应有共享本地结果上限时把 limit 设为0。把已完成运行保存在 SQLite并在多个授权目标与日期上重复测试对比中位 unique 计数、中位 unique-resolved 计数、解析率与成功运行率。把提供方与适配器的上限记录为执行证据不要把截断的运行当作零产出。不提交目标结果只有积累到足够多可比的运行后才添加跨运行聚合。用 harvest-yields 分析 SQLite 中的产出随包安装的harvest-yields命令直接读取已有的结果数据库。默认读取~/.local/share/theHarvester/stash.sqlite并报告 hostname 产出如果所选数据库不存在命令直接退出而不会创建它。常用用法harvest-yields harvest-yields --database results.sqlite harvest-yields --database results.sqlite --kind hostname harvest-yields --database results.sqlite --kind ip harvest-yields --database results.sqlite --kind asn harvest-yields --database results.sqlite --run-id 11111111-1111-4111-8111-111111111111 harvest-yields --database results.sqlite --format json各参数的解析逻辑见 source_yields.py--database选择数据库文件默认即~/.local/share/theHarvester/stash.sqlite命令会先检查args.database.is_file()--kind在全部RESULT_KINDS中选要对比的结果类型默认hostname--run-id只报告一个已完成运行而不是聚合所有运行--formattable默认或json。不带--run-id时命令把每次运行的来源产出累加。顶层的run_count显示选中的运行数每个来源行有自己的run_count包含产出了零结果的执行。UNIQUE/RUN用来源的求和 unique 计数除以该来源运行数是默认排序键JSON 中对应字段为unique_result_count_per_run。“Unique”永远表示单次运行内的 unique因此聚合总计是各次运行 per-run 计数的相加而不是跨目标/日期重新计算唯一性。hostname 输出还包含 resolved 与 unique-resolved 计数以及UNIQUE-RESOLVED/RUNJSON 字段unique_resolved_hostname_count_per_run其他结果类型省略这些 DNS 专属字段。表格输出以UNIQUE/RUN降序、再按UNIQUE、OBSERVED、来源名排序见 source_yields.py。处理与分享规范只在授权测试允许的地点存储结果。留存期到期时删除报告、截图与 SQLite 数据库。不要把收集到的输出提交到 theHarvester 仓库也不要把原始目标数据附加到公开 issue。只分享复现问题所需的最小脱敏输出。移除凭据、私有目标、账户细节与不必要的提供方响应内容。相关文档虚拟主机发现含完整 JSONL 示例REST API 参考HarvestView 架构运行证据架构配置与 API Keys【免费下载链接】theHarvesterE-mails, subdomains and names Harvester - OSINT项目地址: https://gitcode.com/GitHub_Trending/th/theHarvester创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表