恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

theHarvester 中的 ASN 组织归属持久化:基于来源证据的规范化 SQLite 关系设计

  • 首页
  • 资讯中心
  • /
  • theHarvester 中的 ASN 组织归属持久化:基于来源证据的规范化 SQLite 关系设计

相关资讯

mold 中的 mimalloc vcpkg 集成:自定义 port、覆盖安装与 CMake 使用指南 2026/9/14 12:33:44
PHP实现生辰八字排盘系统:从农历转换到四柱计算详解 2026/9/14 12:33:44
LangChain Agent结构化输出实战:从原理到应用 2026/9/14 12:28:43

最新资讯

【2016-10-18】C语言HTTP开源框架libghttp的网址记录
JavaWeb小区物业管理系统:MVC分层、Servlet/JSP与MySQL实践解析
Vite热更新失效?这个配置让我debug到怀疑人生
2026重庆瓶装水选购指南:看懂水源地与执行标准,选对适合你的那瓶水
Java Stream处理大集合,我的内存怎么就炸了
uni-app脚手架与框架的本质区别:启动器vs操作系统

今日推荐

ASP+Access库存管理系统源码部署与IIS配置实战指南
基于SSM框架的毕业季旧物分类处理系统设计与实现
MATLAB FFT频谱仿真:从DFT原理到参数设置与窗函数选择

本周热门

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验
Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化
Flutter应用改名全指南:从Android到iOS的配置与工具实践

本月精选

自研推理加速器Redwood:两周内实现PyTorch模型高效部署的实战教程
V4L2摄像头采集实战:从camera_client.rar到出图全流程解析
从“谁发明了钢琴键”到知识问答智能体:RAG与记忆工程实践

theHarvester 中的 ASN 组织归属持久化:基于来源证据的规范化 SQLite 关系设计

发布时间:2026/9/14 12:33:44
theHarvester 中的 ASN 组织归属持久化:基于来源证据的规范化 SQLite 关系设计 theHarvester 中的 ASN 组织归属持久化基于来源证据的规范化 SQLite 关系设计【免费下载链接】theHarvesterE-mails, subdomains and names Harvester - OSINT项目地址: https://gitcode.com/GitHub_Trending/th/theHarvester导读本文围绕 theHarvester 仓库中的架构决策记录 ADR-0005Persist ASN organization attribution as sourced evidence 展开讲解项目如何把某组织organization持有/通告某 ASN这一信息从随意的属性标签升级为带来源sourced、类型化typed、可校验canonical的持久化证据。你将掌握归属观察AsnAttributionObservation的数据模型与规范化规则、SQLite 中asn_attributions关系表的存储结构、JSONL 与 API 的投影格式以及它与 RouteViews 网络纵深pivot的衔接边界。读完本文即可在二次开发或审计 thisHarvester 结果数据库时准确理解组织归属数据的写入、读取与校验链路。本文涉及文件均为仓库现有内容可对照 theHarvester/lib/asn_attribution.py、theHarvester/lib/database.py、theHarvester/lib/completed_result.py 等路径深入阅读。背景为什么组织标签不能作为 ASN 的可变属性ADR-0005 首先回答了一个数据建模问题ASN 的组织归属organization attribution应该以什么形态存储Provider 标签本身并不可靠ADR 明确列出的现实约束有三点可能缺失某个数据源source返回的 ASN 结果里并没有组织名会随时间变化组织改名、重组、运营主体变更都会导致同一 ASN 的标签前后不一致跨来源不一致不同 provider如 Onyphe、Shodan、URLScan对同一 ASN 给出的组织名可能互相冲突。如果把组织标签当作 ASN 结果上的一个可变属性直接塞进results.details_json这些冲突会被静默覆盖且无法支撑跨多次运行cross-run查询同一 ASN 的所有组织归属这类需求。因此 ADR-0005 的决策是归一化normalized为独立的、带来源的关系记录每条记录把 ASN 结果、关联的主机名或 IP 结果、以及产生该证据的 source/action 执行三者显式关联起来。同时决策划清了语义边界组织归属只服务于操作者复核operator review它不代表所有权ownership判定不构成授权authorization依据不能扩展目标范围target scope其组织标签本身不能作为过滤条件——但它精确的 IP 主体exact IP subject可以作为自动触发 RouteViews 纵深查证的输入。决策要点类型化证据 归一化关系行ADR 的完整决策是将每条 ASN 组织归属存储为一个类型化的领域观察typed domain observation由一条归一化的 SQLite 关系行支撑该行关联 run、ASN 结果、相关主机名或 IP 结果、以及 source 执行。SQLAlchemy 行对ResultStore保持私有观察通过 JSONL 与 API 投影输出而不是把组织标签当作 ASN 的可变属性。落到代码上这一决策由三层结构落实领域对象层theHarvester/lib/asn_attribution.py 中定义的AsnAttributionObservation冻结数据类存储层theHarvester/lib/database.py 中定义的_AsnAttributionRowSQLAlchemy 模型表名asn_attributions且仅由ResultStore内部使用投影层JSONL 序列化completed_result.py与 API 响应模型run_models.py。领域模型AsnAttributionObservation 及其规范化规则AsnAttributionObservation是 frozen slots 的不可变数据类字段与约束如下asn_attribution.py字段类型规范化规则producer_kindsource/action必须是二者之一producerstr非空、UTF-8 可编码、长度 ≤ 255、不含 Cc/Cf 控制类字符asnstr经normalize_asn归一为ASnumber形式organization_labelstr非空、UTF-8 可编码、长度 ≤ 255MAX_ORGANIZATION_LABEL_LENGTH、不含控制字符subject_kindhostname/ip二者之一subject_valuestrhostname 经normalize_hostnameIP 必须是规范地址拒绝 IPv6 scope 标识%collected_atdatetime必须带时区统一转为 UTC__post_init__中所有字段都在构造时完成校验与规范化任何违规都抛出ValueError体现了**构造即校验、失败即关闭fail closed**的设计。其中asn的规范化实现在 result_values.py去掉AS前缀大小写不敏感、只接受 ASCII 十进制整数、范围0 ≤ ASN ≤ 4_294_967_295最终输出ASnumber规范形式subject的规范化在_normalize_subjectasn_attribution.pyhostname 走域名归一化IP 通过ipaddress.ip_address生成规范字符串且明确拒绝含%的 IPv6 scope 形式_normalize_name校验非空、UTF-8 可编码、长度上限以及 Unicode 控制字符类别unicodedata.category为Cc/Cf的字符一律拒绝。观察对象还提供两个关键方法sort_key()按(asn, producer_kind, producer, organization_label, subject_kind, subject_value, collected_at)排序用于去重与稳定排序detail()输出投影字典结构固定为{ type: organization-attribution, producer_kind: source, # 或 action producer: urlscan, organization_label: Example Transit, subject: {type: ip, value: 192.0.2.10}, collected_at: 2026-09-13T05:11:54Z, # format_utc 输出的 UTC 时间戳 }规范化集合与严格解析模块级函数定义了观察集合的规范化含义asn_attribution.pycanonical_asn_attributions(observations)sorted(set(...), keysort_key)即去重 排序后才算规范化asn_attribution_details(observations)把规范化集合逐一投影为detail()字典列表parse_asn_attribution_details(asn, details)反向解析。它对输入做严格全等校验要求details是非空数组、每个元素必须是恰好包含type / producer_kind / producer / organization_label / subject / collected_at六个键的字典、subject必须恰好包含type / value两个键、collected_at必须是可解析的 UTC 时间戳最终还要求detail ! observation.detail()时直接抛错——即读回来的内容必须与写出的规范化结构完全一致不允许任何变体或多余字段。存储层asn_attributions 关系表的结构与生命周期表结构与外键SQLAlchemy 模型_AsnAttributionRowdatabase.py对应表asn_attributions列类型说明run_idText主键所属运行positionint主键行内序号asn_result_positionint外键 →results(run_id, position)指向该 run 内的 ASN 结果subject_result_positionint外键 →results(run_id, position)指向主机名或 IP 结果execution_positionint外键 →executions(run_id, position)指向产生两者的 source/action 执行organization_labelText组织标签原文collected_atTextISO 格式 UTC 时间戳三条外键约束都带ondeleteCASCADErun、被引用的结果或执行被删除时归属行随之级联删除。行不存 ASN 值本身只存位置指针——ASN 值由results表中对应行承载归属行通过asn_result_position引用这与 ADR 中关系行 linking the run, ASN result, related hostname or IP result, and source execution的描述完全一致。初始化schema 保持 8缺表自动创建ADR 提到当前未发布unreleased的 schema 仍为 8初始化时若缺表则自动创建。代码印证于 database.py 的SCHEMA_VERSION 8初始化流程database.py读取PRAGMA user_version若版本高于 8 直接报错拒绝随后执行_Base.metadata.create_alldatabase.pyasn_attributions作为 metadata 中已注册的表在数据库为空或旧库缺少该表时会被自动创建无需提升 schema 版本——这正是创建额外表而非破坏性迁移的设计意图。写入save_run 的三段引用解析写入逻辑位于ResultStore.save_rundatabase.py。写入前先建立两张查找表result_positions{(kind, value): position}覆盖 run 内全部结果execution_positions{(producer_kind, name): position}覆盖全部 source 与 action 执行。随后每条归属观察被映射为一行_AsnAttributionRow( run_idrun_id, positionposition, asn_result_positionresult_positions[(asn, attribution.asn)], subject_result_positionresult_positions[(attribution.subject_kind, attribution.subject_value)], execution_positionexecution_positions[(attribution.producer_kind, attribution.producer)], organization_labelattribution.organization_label, collected_atattribution.collected_at.isoformat(), )注意归属对象中的asn与subject都是规范化后的值必须能在本 run 的results中找到对应行否则KeyError会让整个事务失败——这就是每条归属必须引用规范的 ASN 结果、精确的主机名/IP 主体、以及产生两者的 source 或 action的强制保证。读取load_run 的反向装配与完整性校验读取时database.pyload_run按position顺序取出全部attribution_rows对每一行执行反向装配通过asn_result_position/subject_result_position/execution_position三处指针分别查出 ASN 结果、主体结果与执行记录任一指针落空即抛出ResultStoreError(Persisted ASN attribution references missing evidence)校验执行记录的producer_kind合法性反推producer_kindsource/action用 ISO 时间戳重建collected_at构造AsnAttributionObservation全部装配完成后调用canonical_asn_attributions与原始列表比较顺序不一致同样抛错。也就是说持久化数据在每次加载时都会被重新规范化并全等校验任何缺失、重复或非规范化noncanonical的关系都会导致 fail closed。这一点在测试 test_completed_persistence.py 中有直接覆盖通过UPDATE asn_attributions SET asn_result_position subject_result_position、INSERT INTO asn_attributions ...等方式注入损坏数据后load_run必须抛错拒绝。投影层JSONL 与 API 如何暴露归属观察ADR 强调 SQLAlchemy 行对ResultStore保持私有观察通过JSONL 与 API对外投影。JSONL 序列化在 completed_result.py 中CompletedResult.to_jsonl()先把归属按 ASN 分组为attribution_by_asn当遇到kind asn且该 ASN 存在归属时向该行记录写入{type: asn, value: AS64500, observations: [{type: organization-attribution, ...}]}反向路径from_jsonlcompleted_result.py则调用parse_asn_attribution_details严格解析失败时以ValueError拒绝整条记录。此外CompletedResult在构造后还有一条全局一致性校验completed_result.py所有归属必须已去重排序collected_at必须落在本次运行的started_at~completed_at区间内且每条归属的(asn, subject)必须真实存在于 run 的结果集合中、其 producer 必须与执行记录吻合——任何一条不满足都拒绝该结果对象。API 响应模型API 侧的投影模型定义在 run_models.pyAsnAttributionSubjectResponsetype限定为hostname | ipvalue为字符串extraforbidAsnAttributionObservationResponsetype限定为organization-attribution字段与detail()一一对应同样extraforbid。请求/响应处理在 run_evidence.py先拒绝含未知字段的输入再调用parse_asn_attribution_details解析最后用asn_attribution_details重新规范化输出。这套解析 → 规范化 → 输出的往返保证了 API 与 JSONL 两个入口看到的归属结构完全一致。边界约束归属不可授权、不可过滤但可触发 RouteViews 纵深ADR 的 Consequences 部分明确了两条安全边界归属可以相互冲突地独立可见不同 provider 标签冲突时归一化关系保留全部冲突记录而不是覆盖其中一方归属不能授权目标范围扩展组织标签本身不是过滤条件也不会自动扩大扫描授权范围。唯一的自动化联动是RouteViews 网络纵深pivot。在 routeviews.py 中enrich_routeviews的文档字符串写明Domain runs automatically pass harvested IPs that have sourced IP-to-ASN attribution. Bare ASN findings are not expanded into complete prefix inventories; that requires an explicit ASN target.即域名类运行中只有带来源的 IP→ASN 归属所对应的精确 IP 才会被自动送入 RouteViews 查询孤立的 ASN 结果无归属关联、无显式 ASN 目标不会被自动展开成完整前缀清单。归属的精确 IP 主体是触发纵深查询的输入但组织标签不参与过滤决策。对应地run_models.py中关于该能力的描述为Enrich discovered IPs with sourced ASN attribution, or an explicitly targeted ASN or IP addressrun_models.py进一步印证要么是带来源的自动归属要么是用户显式指定的 ASN/IP 目标。源码验证路径小结关注点验证位置观察数据类与规范化asn_attribution.pyASN 归一化规则result_values.py关系表定义database.pyschema 版本与建表database.py、database.py写入/读取装配database.py、database.pyJSONL 投影与校验completed_result.py、completed_result.pyAPI 模型与解析run_models.py、run_evidence.pyRouteViews 联动边界routeviews.py损坏数据 fail-closed 测试test_completed_persistence.py来源侧产出归属的测试test_shodan_engine.py、test_onyphe.py、test_urlscan.py、test_source_runner.py总结ADR-0005 为 theHarvester 确立了一条清晰的证据持久化原则组织归属是来源证据不是ASN 属性。它以不可变领域对象 归一化 SQLite 关系行承载通过外键把 run、ASN 结果、主机名/IP 主体和 source/action 执行钉死在一条记录里写入与读取两侧都执行去重、排序、引用完整性与全等校验任何缺失、重复或非规范的关系都会 fail closed。对外它通过 JSONL 与 API 投影为结构固定的organization-attribution观察对内它只作为操作者复核材料与 RouteViews 精确 IP 纵深查证的输入既不充当过滤条件也不构成目标范围授权。这种设计在保留跨来源冲突可见性的同时让 ASN 组织归属成为可查询、可追溯、可复核的结构化证据。【免费下载链接】theHarvesterE-mails, subdomains and names Harvester - OSINT项目地址: https://gitcode.com/GitHub_Trending/th/theHarvester创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号