<?xml version="1.0" encoding="utf-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><title>UzzzzZ</title><link>https://uzzju.com/</link><description>wish</description><item><title>CodeOrion：从代码图到 Agentic 代码审计</title><link>https://uzzju.com/post/88.html</link><description>&lt;p&gt;AI Agent 对代码审计的影响正在变得越来越明显。&lt;/p&gt;
&lt;p&gt;过去做白盒审计时，工具更多是先通过规则、污点分析、数据流分析或代码图查询发现疑似问题，再由安全人员继续确认入口、参数来源、调用链、过滤逻辑、依赖版本和可利用条件。这个流程长期有效，但也有一个现实问题：真正判断一个漏洞是否成立，往往不只看某个危险函数是否被调用，而是要把代码上下文、框架行为、业务逻辑、第三方依赖和验证结果串成一条完整证据链。&lt;/p&gt;
&lt;p&gt;AI Agent 的出现，让这件事有了新的可能。它不只是帮人解释一条扫描告警，也不只是把源码总结成自然语言，而是可以像审计员一样持续追问：这个接口是否外部可达？参数是否来自用户输入？中间有没有鉴权、校验或清洗？调用是否进入第三方组件？组件内部是否存在敏感逻辑？这个风险能不能构造请求验证？最终结论有没有证据支撑？&lt;/p&gt;
&lt;p&gt;但这也带来一个新的问题：如果直接把大量源码丢给 Agent，让它凭上下文自由推理，它很容易受到上下文窗口、幻觉、路径遗漏和过早下结论的影响。代码审计不能只依赖模型直觉，它需要稳定、可查询、可复核的结构化事实。&lt;/p&gt;
&lt;p&gt;这也是我做 CodeOrion 的原因。CodeOrion 不是想再做一个传统规则扫描器，而是想探索一种更适合 AI Agent 的代码审计底座：先把源码、符号、入口、调用关系和依赖边界整理成代码图，再让 Agent 基于这些事实进行查询、推理、取证和验证。换句话说，CodeOrion 负责把代码变成 Agent 能可靠使用的结构事实，codeorion-agent 负责把这些事实组织成审计证据链。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202607012126354.png&quot; alt=&quot;hunter-diamond&quot;&gt;&lt;/p&gt;
&lt;p&gt;传统白盒代码扫描已经发展了很多年。CodeQL、Semgrep、Joern 这类工具证明了一件事：代码不能只被当成文本扫描，必须被还原成结构。&lt;/p&gt;
&lt;p&gt;Joern 的 Code Property Graph 把程序表示成带属性的有向图，并把语法结构、控制流、数据流放到统一的图模型中查询。CodeQL 和 Semgrep 的数据流、污点分析也都离不开 source（输入来源）、propagator（传播规则）、sanitizer（过滤逻辑）和 sink（危险操作）这些基础模型。&lt;/p&gt;
&lt;p&gt;这些方向都非常重要。但我在真实代码审计里遇到的问题是：只靠静态规则和固定建模，往往很难以低成本走完整条漏洞判断链路，尤其是跨框架、跨文件、跨依赖和需要业务上下文时。&lt;/p&gt;
&lt;p&gt;传统工具可以通过数据流、污点分析和图查询回答一部分问题，但这些能力高度依赖 source、sink、sanitizer、框架和依赖模型的完整度。真实项目里，剩下的大量判断仍然需要上下文推理和证据验证：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;这个 sink（危险调用）是否真的能从 HTTP 入口到达？&lt;/li&gt;&lt;li&gt;参数是否来自用户输入？&lt;/li&gt;&lt;li&gt;中间有没有鉴权、校验、清洗、格式约束？&lt;/li&gt;&lt;li&gt;风险是否藏在第三方组件内部？&lt;/li&gt;&lt;li&gt;这个 finding（风险结论）是否能构造出可复现请求？&lt;/li&gt;&lt;li&gt;报告里的结论是否有可追溯证据？&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;所以我做 CodeOrion 时，没有把它设计成“又一个规则扫描器”。我更希望它成为一个面向 AI Agent 的代码图底座：CodeOrion 负责把代码变成可查询的结构事实，codeorion-agent 负责基于这些事实完成审计推理、evidence（证据）登记、finding（风险结论）输出和 PoC 验证。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202607012149457.png&quot; alt=&quot;image-20260701214935402&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202607012116858.png&quot; alt=&quot;image-20260701211552186&quot;&gt;&lt;/p&gt;
&lt;h1 id=&quot;h1--agent-&quot;&gt;&lt;a name=&quot;一、白盒扫描正在从“规则命中”走向“图谱、证据和 Agent”&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;一、白盒扫描正在从“规则命中”走向“图谱、证据和 Agent”&lt;/h1&gt;&lt;p&gt;在写 CodeOrion 之前，我先看的是白盒代码审计工具过去十几年的演进路线。这个领域并不是从 LLM 出现后才开始做自动化，相反，SAST、数据流分析、污点分析、代码属性图、软件成分分析都已经积累了很长时间。&lt;/p&gt;
&lt;p&gt;如果把这条路线压缩成几个阶段，大致是这样：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202607012116319.png&quot; alt=&quot;image-20260701211621212&quot;&gt;&lt;/p&gt;
&lt;p&gt;这条路线说明了一件事：白盒扫描的核心矛盾一直没有变。工具要尽可能覆盖全仓，又要尽可能减少误报；要足够自动化，又要理解复杂业务上下文；要能发现已知模式，又不能被规则库限制住。&lt;/p&gt;
&lt;h2 id=&quot;h2-1-code-property-graph-&quot;&gt;&lt;a name=&quot;1、Code Property Graph：代码图路线已经被长期验证&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;1、Code Property Graph：代码图路线已经被长期验证&lt;/h2&gt;&lt;p&gt;Code Property Graph 不是一个新概念。Joern 文档里把 CPG 定义为一种用于在大型代码库中挖掘编程模式的数据结构，它以节点、带标签的有向边、键值属性来表示程序构造。Joern 也明确提到，早期 CPG 工作的核心思想是把语法、控制流、过程内数据流等经典程序表示合并到一个属性图里，再通过图遍历 DSL 查询漏洞模式。&lt;/p&gt;
&lt;p&gt;这对 CodeOrion 的启发很直接：如果要让 Agent 审计代码，不能只把源码切片塞给模型。源码文本太长、太散、太依赖局部上下文。更合理的方式是先把代码变成图，让 Agent 通过工具查询图。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202607012116245.png&quot; alt=&quot;image-20260701211635188&quot;&gt;&lt;/p&gt;
&lt;p&gt;CodeOrion 和 Joern 的目标并不完全相同。Joern 更成熟地围绕 CPGQL、CPG schema 和多语言前端构建静态分析平台；CodeOrion 当前更聚焦在“面向 Agent 消费”的工程形态上：统一 IR、SQLite 存储、MCP 工具、自然语言查询、跨边界依赖追踪、证据输出。&lt;/p&gt;
&lt;p&gt;换句话说，CodeOrion 当前不是完整意义上的 Joern CPG 实现，而是一个面向 Agent 消费的代码图底座。它借鉴 CPG 的统一图思想，但现阶段重点落在 CST、符号、框架入口、依赖边界和可查询证据上。&lt;/p&gt;
&lt;h2 id=&quot;h2-2-codeql-semgrep-source-sink-&quot;&gt;&lt;a name=&quot;2、CodeQL 和 Semgrep 证明了 source / sink 模型的价值，也暴露了规则维护成本&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;2、CodeQL 和 Semgrep 证明了 source / sink 模型的价值，也暴露了规则维护成本&lt;/h2&gt;&lt;p&gt;CodeQL 的官方文档把数据流分析描述为计算变量在程序不同位置可能持有的值，以及这些值如何传播、在哪里使用。很多安全查询都依赖数据流分析，用来判断潜在恶意或不安全数据是否以危险方式被使用。CodeQL 也区分普通数据流和污点传播：前者关注值是否保持，后者关注值是否受到不安全输入影响。&lt;/p&gt;
&lt;p&gt;Semgrep 的污点模式则更直观。一个污点规则需要定义 source（输入来源）、propagator（传播方式）、sanitizer（过滤逻辑）和 sink（危险操作）。Semgrep 文档里也提到，污点会从 source 经过赋值和函数调用传播到 sink；如果中间没有被 sanitizer 处理，就会报告 finding。&lt;/p&gt;
&lt;p&gt;这套模型很强，但它天然依赖建模质量：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;source 要覆盖所有入口&lt;/li&gt;&lt;li&gt;sink 要覆盖所有敏感 API&lt;/li&gt;&lt;li&gt;sanitizer 要避免过度信任或过度怀疑&lt;/li&gt;&lt;li&gt;propagator 要理解框架、库、容器对象、ORM、模板引擎&lt;/li&gt;&lt;li&gt;跨函数、跨文件分析要在准确率和性能之间取舍&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Semgrep 文档里还提到，跨文件分析需要更多内存资源，实际效果依赖语言和规则配置。CodeQL 文档也明确列出数据流图完整性挑战：标准库源码不可见、运行时行为不确定、别名问题、全局数据流图巨大且计算昂贵。&lt;/p&gt;
&lt;p&gt;这说明传统规则和污点分析不是“不好”，而是它们在复杂业务项目里需要大量工程建模。CodeOrion 的思路不是抛弃这些能力，而是把 source、sink、sanitizer 从“命中即漏洞”的最终判定降级为“候选事实”和“审计线索”，再由 Agent 结合调用链、数据流证据、框架入口、依赖路径、配置和验证结果进行二次判断。&lt;/p&gt;
&lt;h2 id=&quot;h2-3-sca-&quot;&gt;&lt;a name=&quot;3、SCA 解决了组件可见性，但还不等于组件风险可达性&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;3、SCA 解决了组件可见性，但还不等于组件风险可达性&lt;/h2&gt;&lt;p&gt;OWASP Top 10:2021 把 Vulnerable and Outdated Components 放在 A06。OWASP 的描述很清楚：如果不知道自己使用的所有组件版本，包括直接依赖和嵌套依赖，就很可能处于风险中；组织应该持续 inventory 组件版本，使用 OWASP Dependency Check、retire.js、SCA 等工具自动化这个过程。&lt;/p&gt;
&lt;p&gt;SCA 也要区分不同层次。比较基础的 SCA 通常主要看依赖清单、SBOM、包名和版本，输出“项目用了某个有漏洞的组件”。更进一步的 SCA 已经开始判断：漏洞相关方法是否真的被应用调用路径触达。&lt;/p&gt;
&lt;p&gt;但“方法可达”仍然不是最终风险结论。&lt;/p&gt;
&lt;p&gt;真实审计还要继续问：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;这个漏洞对应的方法是否被项目调用？&lt;/li&gt;&lt;li&gt;从外部入口是否能到达这个方法？&lt;/li&gt;&lt;li&gt;项目使用方式是否满足漏洞触发条件？&lt;/li&gt;&lt;li&gt;是否存在配置、参数、Feature、版本分支上的限制？&lt;/li&gt;&lt;li&gt;这个组件是否被 shading、clone、重命名或隐藏依赖绕过普通 SBOM 识别？&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;近几年的 SCA 研究也在往这个方向走。比如漏洞方法分析关注的就是“漏洞方法是否从应用执行路径可达”，而不是只看组件版本。关于 SBOM 和 SCA 的研究也指出，隐藏依赖、组件变体、代码克隆、依赖重打包会导致漏洞报告不一致或漏报。&lt;/p&gt;
&lt;p&gt;CodeOrion 的 &lt;code&gt;dependency_callgraph&lt;/code&gt; 和 &lt;code&gt;trace_dependency_calls&lt;/code&gt; 就是沿着这个方向做的：我不只想知道项目依赖了什么，更想把项目调用点、依赖方法、依赖内部调用链和 Agent 证据验证串起来。&lt;/p&gt;
&lt;h2 id=&quot;h2-4-llm-agent-&quot;&gt;&lt;a name=&quot;4、LLM Agent 正在进入告警研判，但不能只做“告警解释器”&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;4、LLM Agent 正在进入告警研判，但不能只做“告警解释器”&lt;/h2&gt;&lt;p&gt;2025 到 2026 年，LLM 结合 SAST 的研究明显增多。很多工作关注 false positive reduction（误报过滤）：先让传统 SAST 产出候选告警，再让 LLM 或多 Agent 根据代码上下文判断哪些告警更可信。&lt;/p&gt;
&lt;p&gt;例如 QASecClaw 这类多 Agent SAST 误报过滤研究，把传统 SAST 和代码专用 LLM 结合起来，由不同 Agent 负责测试规划、安全验证、证据关联、过滤和报告。另一些研究也在讨论 LLM Agent 对 CodeQL、Semgrep 等工具告警进行 triage（告警研判）的能力。&lt;/p&gt;
&lt;p&gt;这些研究说明 LLM Agent 正在进入 SAST 的告警研判和验证环节，但整体仍处于快速探索阶段。现阶段更现实的路线不是让 LLM 替代静态分析，而是让 LLM 基于静态分析、代码图、证据和可控验证环境做辅助判断。&lt;/p&gt;
&lt;p&gt;但我不希望 codeorion-agent 只是一个“告警解释器”。如果流程是：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;SAST 先吐告警 -&amp;gt; LLM 再解释告警&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;那 LLM 仍然被传统规则的召回边界限制住。CodeOrion 的路线更接近：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;代码图提供结构事实 -&amp;gt; Agent 自己选择入口、路径、依赖、数据流、证据 -&amp;gt; 输出风险结论&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这就是 CodeOrion 和 codeorion-agent 组合的关键差异：Agent 不是站在告警后面做客服，而是站在代码图前面做审计员。&lt;/p&gt;
&lt;h1 id=&quot;h1--&quot;&gt;&lt;a name=&quot;二、传统白盒扫描的几个痛点&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;二、传统白盒扫描的几个痛点&lt;/h1&gt;&lt;p&gt;我把传统 SAST 的问题分成三类。&lt;/p&gt;
&lt;h2 id=&quot;h2-1-&quot;&gt;&lt;a name=&quot;1、规则硬编码问题&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;1、规则硬编码问题&lt;/h2&gt;&lt;p&gt;大部分 SAST 的底层逻辑依然离不开规则：哪些函数是 source（输入来源），哪些函数是 sink（危险操作），哪些调用算 sanitizer（过滤逻辑），哪些赋值和函数调用算 propagator（传播规则）。规则是必要的，但规则越多，维护成本越高。框架、组件、业务封装稍微变化，规则就可能失效、漏报或误报。&lt;/p&gt;
&lt;p&gt;例如同样是 SQL 注入，在真实项目里可能经过 Controller 参数绑定、DTO 转换、Service 封装、动态查询构造、ORM wrapper、XML mapper、注解 SQL、分页插件、租户插件。单独写一个 “字符串拼接 SQL” 规则，很容易只能覆盖最表层的样例。&lt;/p&gt;
&lt;h2 id=&quot;h2-2-&quot;&gt;&lt;a name=&quot;2、上下文不足问题&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;2、上下文不足问题&lt;/h2&gt;&lt;p&gt;静态分析要准确理解数据流，本身就很难。标准库源码不可见、运行时分派不确定、别名关系复杂、全局数据流计算成本高，这些都是长期存在的问题。真实业务项目还会叠加框架路由、依赖注入、权限中间件、配置文件、消息队列、异步任务等上下文。&lt;/p&gt;
&lt;p&gt;这会导致很多扫描结果停在“疑似”。它命中了 source 和 sink，但没有证明入口是否可达，也没有证明中间是否经过 sanitizer，更没有说明这个漏洞在业务语义上是否真的成立。&lt;/p&gt;
&lt;h2 id=&quot;h2-3-&quot;&gt;&lt;a name=&quot;3、组件风险深入困难&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;3、组件风险深入困难&lt;/h2&gt;&lt;p&gt;现代应用大量风险不在业务代码的最后一行，而在“业务代码如何调用组件”。反序列化、模板渲染、表达式执行、文件解析、服务端请求、ORM 拼接、日志组件、鉴权框架，这些问题经常藏在第三方依赖的使用方式里。&lt;/p&gt;
&lt;p&gt;传统扫描如果只看到项目源码，很容易停在“用了某个包”或“调用了某个 API”。但安全审计真正需要的是：从外部入口到项目调用点，再到依赖方法，再到依赖内部危险行为，这条链路是否成立。&lt;/p&gt;
&lt;h1 id=&quot;h1--codeorion-&quot;&gt;&lt;a name=&quot;三、CodeOrion 的定位：不直接判漏洞，而是提供结构事实&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;三、CodeOrion 的定位：不直接判漏洞，而是提供结构事实&lt;/h1&gt;&lt;p&gt;CodeOrion 的核心定位是多语言代码图系统。它基于 Tree-sitter 把源代码解析成统一 IR，构建 CST 图、框架端点图、依赖调用图，并存入 SQLite。CodeOrion 核心引擎不做“命中即漏洞”的最终判定，而是提供可解释、可查询、可组合的结构事实；漏洞判断由 codeorion-agent 结合 Skill、图查询、源码证据和验证结果完成。&lt;/p&gt;
&lt;p&gt;我希望 CodeOrion 回答的是这些基础问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;项目里有哪些文件、类、函数、调用点？&lt;/li&gt;&lt;li&gt;哪些位置是 HTTP 入口？&lt;/li&gt;&lt;li&gt;某个符号的调用者和被调用者是谁？&lt;/li&gt;&lt;li&gt;某个入口能否到达某个危险 API？&lt;/li&gt;&lt;li&gt;某个项目调用点是否解析到第三方依赖方法？&lt;/li&gt;&lt;li&gt;从项目代码能否继续追进依赖内部调用链？&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;整体扫描链路如下：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202607012116242.png&quot; alt=&quot;image-20260701211656192&quot;&gt;&lt;/p&gt;
&lt;p&gt;当前 CodeOrion 的主扫描流程包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Grammar Registry 注册语言 Grammar&lt;/li&gt;&lt;li&gt;LanguageDetector 识别文件语言&lt;/li&gt;&lt;li&gt;ParserRuntime 调用 Tree-sitter 解析源码&lt;/li&gt;&lt;li&gt;CstGraphBuilder 把 CST 转成统一 IR 节点和边&lt;/li&gt;&lt;li&gt;GraphStore 把节点、边、诊断、符号信息写入 SQLite&lt;/li&gt;&lt;li&gt;可选启用 &lt;code&gt;--framework-facts&lt;/code&gt; 提取 HTTP 入口&lt;/li&gt;&lt;li&gt;可选启用 &lt;code&gt;--dependency-callgraph&lt;/code&gt; 展开依赖和跨边界调用&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;这里最关键的不是“扫描出一个告警”，而是把源码变成 Agent 可以反复检索的图谱。&lt;/p&gt;
&lt;p&gt;一个传统规则扫描器通常输出的是结论：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;发现危险函数 Runtime.exec
疑似命令执行&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;CodeOrion 更关注过程事实：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;POST /api/task/run
  -&amp;gt; TaskController.run
  -&amp;gt; TaskService.execute
  -&amp;gt; CommandRunner.run
  -&amp;gt; Runtime.exec&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这条链路比单点命中更接近真实审计的工作方式。&lt;/p&gt;
&lt;h1 id=&quot;h1--mcp-agent-&quot;&gt;&lt;a name=&quot;四、MCP：让代码图成为 Agent 的工具&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;四、MCP：让代码图成为 Agent 的工具&lt;/h1&gt;&lt;p&gt;代码图本身不是最终产品。真正有价值的是，Agent 能不能低成本地查询它、组合它、验证它。&lt;/p&gt;
&lt;p&gt;CodeOrion 通过 FastMCP 暴露图查询能力。Agent 可以通过 MCP 工具完成项目扫描、符号搜索、入口枚举、调用图遍历、数据流追踪、依赖分析和自然语言探索。&lt;/p&gt;
&lt;p&gt;其中我最看重的是 &lt;code&gt;trace_dependency_calls&lt;/code&gt;。它支持从 HTTP 入口、项目方法或依赖方法出发，做正向或反向追踪。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202607012117766.png&quot; alt=&quot;image-20260701211706713&quot;&gt;&lt;/p&gt;
&lt;p&gt;这解决的是传统 SAST / SCA 在真实项目里成本较高的问题：组件不是只看“有没有依赖”，而是要看“项目是否调用了相关依赖方法、调用链是否从外部入口可达、用户输入是否真的流向危险参数、可利用条件是否满足”。&lt;/p&gt;
&lt;p&gt;例如某个 Java 项目使用了 Fastjson。传统依赖扫描可能告诉我“这个版本存在历史风险”，传统代码扫描可能告诉我“这里调用了 parseObject”。但真正的白盒审计还要继续问：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;这个 parseObject 是否接收外部输入？&lt;/li&gt;&lt;li&gt;从哪个 HTTP 入口进入？&lt;/li&gt;&lt;li&gt;中间是否限制了类型、字段或 Feature？&lt;/li&gt;&lt;li&gt;是否调用到了危险反序列化路径？&lt;/li&gt;&lt;li&gt;这个调用是否在真实业务路径里可达？&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;CodeOrion 的依赖追踪不是为了替代人工判断，而是把这些问题变成可查询的图路径。&lt;/p&gt;
&lt;h1 id=&quot;h1--0day-&quot;&gt;&lt;a name=&quot;五、更理想化的目标：从业务漏洞走向组件 0day 风险链路&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;五、更理想化的目标：从业务漏洞走向组件 0day 风险链路&lt;/h1&gt;&lt;p&gt;我做 CodeOrion 和 codeorion-agent，还有一个更理想化的目标：传统静态代码审计通常更关注“业务代码本身是否写出了漏洞”，但真实攻击面并不只存在于业务代码。&lt;/p&gt;
&lt;p&gt;有时候业务代码本身确实存在漏洞，例如把用户输入直接拼接 SQL、直接传给命令执行、直接传给反序列化 API。这个场景传统 SAST、污点分析、人工审计都比较熟悉。&lt;/p&gt;
&lt;p&gt;但还有另一类更难的问题：业务代码看起来没有明显漏洞，甚至代码写法在当时的公开知识里是“正常调用”，但它调用的第三方组件内部存在一个非公开 0day，或者存在一个只有在特定参数、特定配置、特定版本、特定运行环境下才触发的深层缺陷。这时真正的问题就变成：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;外部输入能否到达这个组件方法？&lt;/li&gt;&lt;li&gt;业务代码是否把高危数据类型、表达式、模板、URL、文件名、对象 key、序列化数据传给组件？&lt;/li&gt;&lt;li&gt;组件内部是否继续进入解析器、解释器、反射、类加载、模板渲染、网络请求、文件系统等敏感逻辑？&lt;/li&gt;&lt;li&gt;如果未来披露一个组件 0day，我能否快速回答“我的哪些业务入口暴露在这条路径上”？&lt;/li&gt;&lt;li&gt;即使 0day 尚未公开，我能否基于组件内部调用链发现异常复杂、异常危险、异常暴露的风险路径？&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;这不是说 CodeOrion 能凭空“发现所有 0day”。这句话必须讲清楚。0day 的本质是未知缺陷，任何工具都不应该宣称可以自动完整发现。但 CodeOrion 想做的是把组件风险分析从“有没有这个依赖”推进到“业务入口如何调用这个依赖、用户输入如何进入组件、组件内部走向哪些敏感逻辑”。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202607012117440.png&quot; alt=&quot;image-20260701211716395&quot;&gt;&lt;/p&gt;
&lt;p&gt;从审计视角看，这里其实有两条线：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;场景&lt;/th&gt;
&lt;th&gt;传统关注点&lt;/th&gt;
&lt;th&gt;CodeOrion 更想补的部分&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;业务代码本身有漏洞&lt;/td&gt;
&lt;td&gt;确认用户输入是否进入危险 API&lt;/td&gt;
&lt;td&gt;用代码图和 Agent 把入口、数据流、调用链、证据、PoC 串起来&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;业务代码本身无明显漏洞，但调用了高风险组件&lt;/td&gt;
&lt;td&gt;组件版本、公开 CVE、是否使用危险 API&lt;/td&gt;
&lt;td&gt;追踪业务入口到组件方法，再继续观察组件内部是否进入解析、反射、类加载、模板、网络、文件等敏感路径&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;组件存在非公开 0day&lt;/td&gt;
&lt;td&gt;传统工具通常没有规则或 CVE 可匹配&lt;/td&gt;
&lt;td&gt;先回答可达性和影响范围：哪些入口、参数、调用点、组件方法可能受影响&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;这种能力在真实安全运营里很有价值。&lt;/p&gt;
&lt;p&gt;当某个组件 0day 刚被披露时，很多团队第一反应是查 SBOM 或 Maven / npm / PyPI / Go module 版本，看“我有没有用这个包”。但这只是第一步。更关键的问题是：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;我是否调用了漏洞相关方法？
这个调用是否从外部入口可达？
用户输入是否进入了关键参数？
有没有配置或运行条件让漏洞触发？
影响哪些接口、哪些业务、哪些租户？&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;CodeOrion 的理想路径是：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202607012117850.png&quot; alt=&quot;image-20260701211728798&quot;&gt;&lt;/p&gt;
&lt;p&gt;如果 0day 尚未公开，CodeOrion 也可以做更偏研究型的组件风险挖掘：从业务入口出发，找那些“外部可控输入进入复杂组件解析器”的路径，再让 Agent 结合 Skill 做人工可复核的风险排序。例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;外部 JSON 进入反序列化组件&lt;/li&gt;&lt;li&gt;外部模板进入模板引擎&lt;/li&gt;&lt;li&gt;外部 URL 进入 HTTP client / cloud SDK&lt;/li&gt;&lt;li&gt;外部文件名进入压缩包、图片、Office、PDF、XML 解析器&lt;/li&gt;&lt;li&gt;外部表达式进入规则引擎、脚本引擎、SpEL、OGNL、MVEL&lt;/li&gt;&lt;li&gt;外部对象 key 进入对象存储 SDK&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;这类路径不一定马上就是漏洞，但它们是高价值审计入口。传统 SAST 更擅长在业务代码里寻找已知模式；CodeOrion 更希望把“业务代码 + 第三方组件 + 组件内部敏感逻辑”的路径暴露出来，让 Agent 和人工审计员能围绕这些路径做更深入的验证。&lt;/p&gt;
&lt;p&gt;所以我对 CodeOrion 的长期想法不是“再写一套规则库”，而是做一个面向漏洞研究和安全审计的代码图雷达：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;已知漏洞：快速确认是否使用、是否可达、影响面多大
未知漏洞：找出外部输入进入复杂组件敏感逻辑的候选路径
验证阶段：把候选路径变成审计证据、风险结论、PoC 或待复核项&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这件事比较理想化，也一定需要长期工程投入。它依赖更强的依赖方法展开、更好的框架建模、更准确的数据流、更丰富的组件风险知识库，以及 Agent 与人工审计员之间更好的协作。但我认为这是 CodeOrion 最值得做的方向之一。&lt;/p&gt;
&lt;h1 id=&quot;h1--fastjson-&quot;&gt;&lt;a name=&quot;六、一个具体例子：Fastjson 反序列化链路可以怎么追&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;六、一个具体例子：Fastjson 反序列化链路可以怎么追&lt;/h1&gt;&lt;p&gt;这里用 Fastjson 举一个更具体的例子。&lt;/p&gt;
&lt;p&gt;假设项目里有一个接口：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;@PostMapping(&amp;quot;/fastjson/deserialize&amp;quot;)
public Object deserialize(@RequestBody String params) {
    return JSON.parseObject(params);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;传统扫描器通常能看到两类信息。&lt;/p&gt;
&lt;p&gt;第一，依赖扫描会告诉我项目用了 &lt;code&gt;com.alibaba:fastjson:1.2.x&lt;/code&gt;，这个版本可能存在历史反序列化风险。&lt;/p&gt;
&lt;p&gt;第二，代码扫描会告诉我业务代码里调用了 &lt;code&gt;JSON.parseObject(params)&lt;/code&gt;，而 &lt;code&gt;params&lt;/code&gt; 可能来自 HTTP body。&lt;/p&gt;
&lt;p&gt;但这还不够。因为我真正关心的是完整风险路径：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;外部 HTTP 请求
  -&amp;gt; Controller 参数绑定
  -&amp;gt; JSON.parseObject(params)
  -&amp;gt; fastjson 依赖方法
  -&amp;gt; DefaultJSONParser
  -&amp;gt; ParserConfig / JavaBeanDeserializer / TypeUtils
  -&amp;gt; 可能进入类型解析、类加载或反序列化敏感逻辑&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里必须强调一个边界：调用到 &lt;code&gt;parseObject&lt;/code&gt; 或类型解析路径，只代表风险候选，不等于漏洞成立。Fastjson 是否可利用仍然取决于版本、AutoType、safeMode、Feature、目标类型、gadget、JDK、黑白名单和运行环境。&lt;/p&gt;
&lt;p&gt;白盒审计里至少要分三层：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;层级&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;th&gt;是否等于漏洞&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;调用链可达&lt;/td&gt;
&lt;td&gt;A 函数能调用到 B 函数&lt;/td&gt;
&lt;td&gt;不等于&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;数据流可达&lt;/td&gt;
&lt;td&gt;用户输入能传播到危险参数&lt;/td&gt;
&lt;td&gt;还不一定&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;可利用条件满足&lt;/td&gt;
&lt;td&gt;版本、配置、参数、gadget、权限和环境都满足&lt;/td&gt;
&lt;td&gt;才接近漏洞成立&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;CodeOrion 追这条链路时，会分成几个阶段。&lt;/p&gt;
&lt;h2 id=&quot;h2-1-&quot;&gt;&lt;a name=&quot;1、扫描项目并打开框架入口和依赖调用图&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;1、扫描项目并打开框架入口和依赖调用图&lt;/h2&gt;&lt;p&gt;我会让 CodeOrion 扫描项目，同时启用框架事实和依赖调用图：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;codeorion scan --path . \
  --framework-facts \
  --dependency-callgraph \
  --dependency-source-mode auto \
  --dependency-depth 10&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里发生了几件事：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--framework-facts&lt;/code&gt; 会把 Spring MVC 的 &lt;code&gt;&lt;a href=&quot;https://github.com/PostMapping&quot; title=&quot;&amp;#64;PostMapping&quot; class=&quot;at-link&quot;&gt;@PostMapping&lt;/a&gt;(&amp;quot;/fastjson/deserialize&amp;quot;)&lt;/code&gt; 提取成 HTTP 入口节点&lt;/li&gt;&lt;li&gt;&lt;code&gt;--dependency-callgraph&lt;/code&gt; 会解析 Maven / Gradle 依赖，识别 &lt;code&gt;com.alibaba:fastjson&lt;/code&gt;&lt;/li&gt;&lt;li&gt;JVM 侧车会按需分析被项目调用触达的 fastjson artifact&lt;/li&gt;&lt;li&gt;项目调用点会通过 &lt;code&gt;resolves_to_dependency_method&lt;/code&gt; 边连接到依赖方法&lt;/li&gt;&lt;li&gt;fastjson 内部方法会以 &lt;code&gt;dependency_method&lt;/code&gt; 节点和 &lt;code&gt;calls&lt;/code&gt; 边进入同一个图&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;这一步的关键是“按需展开”。我不需要一开始把所有依赖全量反编译到爆炸，而是先从项目中出现的外部调用目标出发，例如 &lt;code&gt;com.alibaba.fastjson.JSON.parseObject&lt;/code&gt;，再去展开相关 artifact。&lt;/p&gt;
&lt;h2 id=&quot;h2-2-http-&quot;&gt;&lt;a name=&quot;2、从 HTTP 入口开始追踪&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;2、从 HTTP 入口开始追踪&lt;/h2&gt;&lt;p&gt;扫描完成后，Agent 可以通过 MCP 先拿入口：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;codeorion_get_endpoints()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;它会看到类似这样的入口：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;POST /fastjson/deserialize
handler: FastJsonController.deserialize
framework: spring_mvc&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后从这个 HTTP 入口正向追踪：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;codeorion_trace_dependency_calls(
  http_method=&amp;quot;POST&amp;quot;,
  route=&amp;quot;/fastjson/deserialize&amp;quot;,
  max_hops=12,
  include_project=true,
  include_dependency=true
)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;期望得到的链路不是一句“发现 parseObject”，而是一组可解释的调用路径步骤：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;POST /fastjson/deserialize                                      [HTTP 入口]
  -&amp;gt; FastJsonController.deserialize(String params)               [project]
  -&amp;gt; JSON.parseObject(params)                                    [项目调用点]
  -&amp;gt; com.alibaba.fastjson.JSON.parseObject(String, Class, ...)   [dependency_method]
  -&amp;gt; DefaultJSONParser.parseObject(Type)                         [dependency_method]
  -&amp;gt; ParserConfig.getDeserializer(Type)                          [dependency_method]
  -&amp;gt; JavaBeanDeserializer.deserialze(...)                        [dependency_method]
  -&amp;gt; TypeUtils.loadClass(String, ...)                            [dependency_method]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这条追踪结果的含义是：从 HTTP 入口到 fastjson 相关依赖方法存在调用路径。它还不能单独证明反序列化漏洞成立。接下来 Agent 必须继续检查数据流和利用条件：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用户输入是否真的进入 &lt;code&gt;JSON.parseObject&lt;/code&gt; 的 JSON 字符串参数&lt;/li&gt;&lt;li&gt;是否存在 &lt;code&gt;&lt;a href=&quot;https://github.com/type&quot; title=&quot;&amp;#64;type&quot; class=&quot;at-link&quot;&gt;@type&lt;/a&gt;&lt;/code&gt; 或等价类型控制点进入反序列化逻辑&lt;/li&gt;&lt;li&gt;是否启用了 AutoType 或绕过了限制&lt;/li&gt;&lt;li&gt;是否存在 &lt;code&gt;ParserConfig.getGlobalInstance().setAutoTypeSupport(true)&lt;/code&gt;&lt;/li&gt;&lt;li&gt;是否使用了危险 Feature&lt;/li&gt;&lt;li&gt;是否升级到了安全版本或启用了 safeMode&lt;/li&gt;&lt;li&gt;是否存在黑白名单配置&lt;/li&gt;&lt;li&gt;当前 JDK、gadget、依赖版本和运行环境是否满足触发条件&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;用图表示就是：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202607012117613.png&quot; alt=&quot;image-20260701211741560&quot;&gt;&lt;/p&gt;
&lt;p&gt;这张图里，前半段是业务代码可达性，中间是用户输入到依赖方法的路径，后半段是组件内部风险候选和利用条件验证。基础的 SCA 常常告诉我“fastjson 版本有风险”，传统规则扫描常常告诉我“parseObject 被调用”。CodeOrion 想补齐的是中间这条可查询、可复核的证据路径。&lt;/p&gt;
&lt;h2 id=&quot;h2-3-&quot;&gt;&lt;a name=&quot;3、从依赖方法反向追踪谁在用它&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;3、从依赖方法反向追踪谁在用它&lt;/h2&gt;&lt;p&gt;Fastjson 这种组件风险还有一个常见审计方式：不是从 HTTP 入口正向追，而是先从依赖危险方法反向问“谁在调用它”。&lt;/p&gt;
&lt;p&gt;Agent 可以先搜索依赖方法：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;codeorion_search_dependency_methods(method_name=&amp;quot;parseObject&amp;quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;找到 &lt;code&gt;com.alibaba.fastjson.JSON.parseObject&lt;/code&gt; 后，再反向追踪：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;codeorion_trace_dependency_calls(
  start_node_id=&amp;quot;&amp;lt;dependency_method_node_id&amp;gt;&amp;quot;,
  direction=&amp;quot;backward&amp;quot;,
  max_hops=12
)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样可以得到：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;com.alibaba.fastjson.JSON.parseObject
  &amp;lt;- JSON.parseObject(params)
  &amp;lt;- FastJsonController.deserialize
  &amp;lt;- POST /fastjson/deserialize&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个能力适合做组件风险排查。比如我想知道项目里所有 Fastjson、Jackson、SnakeYAML、XStream、ObjectInputStream、JNDI、表达式引擎相关入口，不需要先猜每个 Controller，而是可以从依赖方法或危险 API 反推业务入口。反向追踪仍然只是候选收敛手段，后续还要继续确认用户输入、配置条件和可利用性。&lt;/p&gt;
&lt;h2 id=&quot;h2-4-agent-&quot;&gt;&lt;a name=&quot;4、Agent 不是直接报漏洞，而是登记证据&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;4、Agent 不是直接报漏洞，而是登记证据&lt;/h2&gt;&lt;p&gt;追到链路之后，codeorion-agent 还不会直接写“存在漏洞”。它会继续把 MCP 结果登记成证据：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;register_evidence(
  summary=&amp;quot;POST /fastjson/deserialize 到 JSON.parseObject 的跨依赖调用链&amp;quot;,
  mcp_tools=[&amp;quot;codeorion_trace_dependency_calls&amp;quot;],
  entrypoint_id=&amp;quot;&amp;lt;endpoint_node_id&amp;gt;&amp;quot;,
  sink_symbol_id=&amp;quot;&amp;lt;dependency_method_node_id&amp;gt;&amp;quot;
)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后再输出风险结论：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;emit_finding(
  vuln_type=&amp;quot;deserialization&amp;quot;,
  title=&amp;quot;Fastjson parseObject 接收外部 JSON 导致反序列化风险&amp;quot;,
  input_entry={file, line, route, parameter},
  dangerous_method={dependency_coordinate, method},
  dataflow_path=[
    &amp;quot;HTTP body 进入 params&amp;quot;,
    &amp;quot;params 传入 JSON.parseObject&amp;quot;,
    &amp;quot;跨边界进入 fastjson JSON.parseObject&amp;quot;,
    &amp;quot;进入 DefaultJSONParser / TypeUtils.loadClass&amp;quot;
  ],
  evidence_refs=[&amp;quot;ev-...&amp;quot;],
  raw_request=&amp;quot;POST /fastjson/deserialize HTTP/1.1 ...&amp;quot;
)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里的 &lt;code&gt;dataflow_path&lt;/code&gt; 不能只写“函数调用到了哪里”，还要写清楚用户输入如何进入危险参数。如果只能证明调用链，结论应该标成候选或待复核；只有数据流和利用条件都有证据时，才应提升为确认。&lt;/p&gt;
&lt;p&gt;最后，如果目标环境可运行，再由验证子 Agent 或沙箱去验证 PoC。这样一条 Fastjson 风险结论最终包含三类证据：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;入口证据：HTTP 入口和参数来源&lt;/li&gt;&lt;li&gt;路径证据：项目调用点到依赖内部方法的追踪结果&lt;/li&gt;&lt;li&gt;条件证据：版本、AutoType、safeMode、Feature、gadget、JDK 和黑白名单&lt;/li&gt;&lt;li&gt;验证证据：原始请求、沙箱响应、人工复核结论&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;这就是我想表达的“追得深”：不是只看到 &lt;code&gt;JSON.parseObject&lt;/code&gt;，也不是把调用链直接当成漏洞，而是把入口、项目调用、依赖边界、数据流、组件内部风险候选、利用条件和证据落盘串起来。&lt;/p&gt;
&lt;h1 id=&quot;h1--python-go-&quot;&gt;&lt;a name=&quot;七、Python 和 Go 的组件依赖怎么做&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;七、Python 和 Go 的组件依赖怎么做&lt;/h1&gt;&lt;p&gt;Fastjson 是 Java 生态的例子。Java 的优势是 Maven / Gradle 坐标明确，JAR 可通过 JVM 侧车做字节码分析，SootUp 可以提供 Jimple、CHA、RTA、Qilin 等不同精度的调用图模式。&lt;/p&gt;
&lt;p&gt;但 CodeOrion 不是只为 Java 写的。Python 和 Go 的依赖处理方式不一样，因为它们的包管理、源码分发和调用模型都不同。&lt;/p&gt;
&lt;h2 id=&quot;h2-1-python-requirements-pyproject-site-packages-&quot;&gt;&lt;a name=&quot;1、Python：从 requirements / pyproject 到 site-packages 源码展开&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;1、Python：从 requirements / pyproject 到 site-packages 源码展开&lt;/h2&gt;&lt;p&gt;Python 项目常见依赖来源包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;requirements.txt&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;pyproject.toml&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;setup.cfg&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;setup.py&lt;/code&gt;&lt;/li&gt;&lt;li&gt;当前虚拟环境的 &lt;code&gt;site-packages&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;CodeOrion 的 Python 依赖解析会先生成 BuildManifest，识别 PyPI 包、版本和本地路径。对于被项目调用链触达的包，会在 &lt;code&gt;site-packages&lt;/code&gt; 中定位包目录，然后按需解析源码。&lt;/p&gt;
&lt;p&gt;解析策略是：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202607012117587.png&quot; alt=&quot;image-20260701211753509&quot;&gt;&lt;/p&gt;
&lt;p&gt;举一个 Python 反序列化例子：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;from flask import request
import yaml

@app.post(&amp;quot;/load&amp;quot;)
def load():
    data = request.data
    return yaml.load(data, Loader=yaml.Loader)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;传统规则会提示 &lt;code&gt;yaml.load&lt;/code&gt; 危险。CodeOrion 更希望追出：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;POST /load
  -&amp;gt; Flask handler load()
  -&amp;gt; request.data
  -&amp;gt; yaml.load(data, Loader=yaml.Loader)
  -&amp;gt; dependency_method: yaml.load
  -&amp;gt; PyYAML constructor / loader 内部路径&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;再比如：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;import pickle

def restore(blob):
    return pickle.loads(blob)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Agent 可以从 &lt;code&gt;pickle.loads&lt;/code&gt; 反向追踪谁传入了外部 blob，也可以从 HTTP route 正向追踪到 &lt;code&gt;pickle.loads&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;Python 的难点在于动态性更强：运行时替换、动态导入、装饰器、框架魔法、运行时对象类型都可能影响精度。所以 Python 侧的策略不是声称“静态全精确”，而是尽量把依赖包源码、函数节点、调用边、入口参数和证据组织起来，让 Agent 能继续读关键源码和做验证。&lt;/p&gt;
&lt;h2 id=&quot;h2-2-go-go-mod-gomodcache-&quot;&gt;&lt;a name=&quot;2、Go：从 go.mod 到 GOMODCACHE，按需展开模块函数&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;2、Go：从 go.mod 到 GOMODCACHE，按需展开模块函数&lt;/h2&gt;&lt;p&gt;Go 的依赖入口相对清晰，核心是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;go.mod&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;go.sum&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;go.work&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;replace&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;$GOMODCACHE&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;CodeOrion 的 Go 依赖解析会读取 &lt;code&gt;go.mod&lt;/code&gt;，处理 &lt;code&gt;require&lt;/code&gt;、&lt;code&gt;replace&lt;/code&gt;、&lt;code&gt;indirect&lt;/code&gt;，再从 &lt;code&gt;$GOMODCACHE/pkg/mod&lt;/code&gt; 定位模块源码。对于命中的依赖函数，会按需展开模块中的导出函数和方法，并生成 &lt;code&gt;dependency_module&lt;/code&gt;、&lt;code&gt;dependency_function&lt;/code&gt;、&lt;code&gt;dependency_method&lt;/code&gt; 节点。&lt;/p&gt;
&lt;p&gt;Go 侧有三级降级策略：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Level 1：tree-sitter-go，完整解析和调用链追踪&lt;/li&gt;&lt;li&gt;Level 2：go/parser 子进程，提取导出符号签名&lt;/li&gt;&lt;li&gt;Level 3：轻量符号提取，仅保留导出函数名等基础可见性，不参与高置信漏洞判断&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;流程可以画成：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202607012118586.png&quot; alt=&quot;image-20260701211803541&quot;&gt;&lt;/p&gt;
&lt;p&gt;举一个 Go SSRF 风险例子：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-go&quot;&gt;func Fetch(c *gin.Context) {
    target := c.Query(&amp;quot;url&amp;quot;)
    resp, err := http.Get(target)
    ...
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;CodeOrion 希望追出的不是“发现 http.Get”，而是：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;GET /fetch?url=...
  -&amp;gt; gin handler Fetch
  -&amp;gt; c.Query(&amp;quot;url&amp;quot;)
  -&amp;gt; http.Get(target)
  -&amp;gt; dependency_method: net/http.Get
  -&amp;gt; Client.Get
  -&amp;gt; DefaultClient.Do&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;再比如 Go 项目调用第三方 SDK：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-go&quot;&gt;client := storage.NewClient(...)
client.Download(ctx, userControlledKey)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;CodeOrion 可以把 &lt;code&gt;go.mod&lt;/code&gt; 中的 SDK 模块解析出来，定位 &lt;code&gt;$GOMODCACHE&lt;/code&gt; 中的源码，尝试把项目调用点连接到 SDK 的 exported method，再让 Agent 判断是否存在路径穿越、对象存储越权、SSRF、任意文件读取或凭据泄露风险。&lt;/p&gt;
&lt;p&gt;Go 的优势是模块和源码路径相对规范，劣势是接口动态分派、泛型、构建标签、平台文件选择、replace 本地模块都会影响静态精度。所以 Go 侧同样采用“结构事实 + 证据链 + 必要时源码兜底”的策略。&lt;/p&gt;
&lt;h1 id=&quot;h1--codeorion-agent-&quot;&gt;&lt;a name=&quot;八、CodeOrion-Agent：把静态图谱变成审计闭环&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;八、CodeOrion-Agent：把静态图谱变成审计闭环&lt;/h1&gt;&lt;p&gt;如果 CodeOrion 是图谱底座，那么 codeorion-agent 就是审计运行时。&lt;/p&gt;
&lt;h2 id=&quot;h2-1-agent-&quot;&gt;&lt;a name=&quot;1、通用编码 Agent 做审计的问题&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;1、通用编码 Agent 做审计的问题&lt;/h2&gt;&lt;p&gt;我在做这个项目前，也测试过直接使用 Claude Code、Cursor 这类通用编码 Agent 做代码审计。效果并不是完全不好。它们读代码、总结调用关系、发现一些明显危险写法时，确实经常能给出不错的结果。&lt;/p&gt;
&lt;p&gt;但问题也很明显：在不做额外配置、不提供专门审计流程、不约束证据格式的情况下，通用编码 Agent 很容易跑几轮之后就停在一个“看起来像漏洞”的点上，然后直接给出结论。它不一定会继续追问：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;这个入口是否真的外部可达？&lt;/li&gt;&lt;li&gt;参数是否真的来自用户输入？&lt;/li&gt;&lt;li&gt;中间有没有鉴权、校验、过滤或类型约束？&lt;/li&gt;&lt;li&gt;这个调用只是调用链可达，还是数据流也可达？&lt;/li&gt;&lt;li&gt;依赖组件的版本、配置、运行条件是否满足？&lt;/li&gt;&lt;li&gt;有没有相邻接口、相似分支、反向调用点需要一起检查？&lt;/li&gt;&lt;li&gt;这个漏洞能否构造 PoC，或者至少能否形成可复核证据？&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;这不是某一个工具的问题，而是通用编码 Agent 的默认目标不是“完成一次严格安全审计”。它更擅长在代码里完成编辑、解释、修复、重构；而白盒审计需要的是持续怀疑、反复回看、证据约束和验证闭环。&lt;/p&gt;
&lt;p&gt;我希望 codeorion-agent 解决的正是这个问题：不让 Agent 只凭一次直觉下结论，而是把它放进一个更像安全审计员的工作流里。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202607012118296.png&quot; alt=&quot;image-20260701211814248&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;h2-2-spring-cloud-&quot;&gt;&lt;a name=&quot;2、Spring Cloud 跨服务调用追踪：一次探索和尝试&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;2、Spring Cloud 跨服务调用追踪：一次探索和尝试&lt;/h2&gt;&lt;p&gt;前面很多例子默认是单体应用：HTTP 入口、Controller、Service、DAO、组件调用都在同一个代码边界里。真实项目里，尤其是 Spring Cloud 微服务项目，一个外部请求经常会被网关、过滤器、Feign 客户端、WebClient、RestTemplate 和后端服务拆成多段。&lt;/p&gt;
&lt;p&gt;这会带来一个很实际的问题：单个服务内的调用链看起来不危险，但跨服务串起来之后，风险才可能完整出现。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202607012118386.png&quot; alt=&quot;image-20260701211823338&quot;&gt;&lt;/p&gt;
&lt;p&gt;我在做 Spring Cloud 相关测试时，关注的不是“能不能扫到某个 Controller”，而是能不能先把一部分跨服务事实整理进代码图，让后续审计有路径可追：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;跨服务模式&lt;/th&gt;
&lt;th&gt;我尝试抽取的事实&lt;/th&gt;
&lt;th&gt;写入图后的意义&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Spring Cloud Gateway&lt;/td&gt;
&lt;td&gt;&lt;code&gt;spring.cloud.gateway.routes&lt;/code&gt; 中的 &lt;code&gt;Path&lt;/code&gt; 和 &lt;code&gt;lb://serviceId&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;知道外部路径会被路由到哪个后端服务&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&lt;a href=&quot;https://github.com/FeignClient&quot; title=&quot;&amp;#64;FeignClient&quot; class=&quot;at-link&quot;&gt;@FeignClient&lt;/a&gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Feign 接口的 &lt;code&gt;value&lt;/code&gt; / &lt;code&gt;name&lt;/code&gt;、HTTP 方法和路径&lt;/td&gt;
&lt;td&gt;知道服务间代理调用的目标服务和目标接口&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;WebClient&lt;/code&gt; / &lt;code&gt;RestTemplate&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;代码里的 HTTP URL、服务名、路径模板&lt;/td&gt;
&lt;td&gt;知道过滤器、业务代码或 SDK 封装里发起了跨服务 HTTP 调用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;调用追踪&lt;/td&gt;
&lt;td&gt;&lt;code&gt;feign_client_call&lt;/code&gt;、&lt;code&gt;http_client_call&lt;/code&gt;、&lt;code&gt;gateway_routes_to&lt;/code&gt; 等边&lt;/td&gt;
&lt;td&gt;Agent 可以尝试沿着图边从网关追到后端服务&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;以一个典型 Spring Cloud 项目为例，跨服务链路可能长这样：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;GET /api/admin/users
  -&amp;gt; Gateway route: /api/admin/** -&amp;gt; lb://ace-admin
  -&amp;gt; ace-admin: AdminController.listUsers
  -&amp;gt; UserService
  -&amp;gt; UserMapper
  -&amp;gt; DB&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;也可能是过滤器或认证逻辑里的服务间调用：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Gateway Filter
  -&amp;gt; WebClient.get(&amp;quot;http://ace-admin/api/user/{username}/check_permission&amp;quot;)
  -&amp;gt; ace-admin: permission check endpoint
  -&amp;gt; 权限查询 / token 校验 / 用户状态判断&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这类链路对安全审计很重要。很多权限绕过、认证缺陷、SSRF、日志注入、内部接口暴露，并不只存在于某一个服务的 Controller 里，而是藏在“网关如何转发”“过滤器如何调用认证服务”“业务服务如何调用内部服务”这些跨服务边界上。&lt;/p&gt;
&lt;p&gt;CodeOrion 对 Spring Cloud 的探索仍然保持同一个原则：不直接判定漏洞，而是尝试把跨服务拓扑变成 Agent 可查询的结构事实。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202607012118629.png&quot; alt=&quot;image-20260701211831589&quot;&gt;&lt;/p&gt;
&lt;p&gt;这里也要讲清楚边界：这部分能力还处在探索和尝试阶段，首先解决的是“能不能把服务拓扑和调用候选路径纳入代码图”的问题，不等于已经完整解决微服务调用链追踪，更不等于自动证明漏洞成立。真正的漏洞判断仍然要继续确认请求参数、身份上下文、网关过滤器、服务间鉴权、配置、数据流和验证结果。&lt;/p&gt;
&lt;p&gt;但这条路线说明，Spring Cloud 这类微服务架构并不是天然的白盒盲区。只要能把 Gateway 路由、Feign 接口、WebClient / RestTemplate 调用逐步整理成结构事实，Agent 就有机会从单服务审计扩展到跨服务候选路径审计：先找到可能的后端入口，再继续追业务代码、依赖组件和证据验证。&lt;/p&gt;
&lt;p&gt;回到 codeorion-agent 本身，它不是“扫描后吐一堆告警”，而是把一次审计拆成一条可追踪的工作流：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202607012118234.png&quot; alt=&quot;image-20260701211842181&quot;&gt;&lt;/p&gt;
&lt;p&gt;这张图对应的是 codeorion-agent 的整体审计闭环。下面几个设计，分别解决“怎么审”“证据怎么落地”“怎么验证”“怎么避免过早收敛”这几个问题。&lt;/p&gt;
&lt;h2 id=&quot;h2-3-&quot;&gt;&lt;a name=&quot;3、审计方法论&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;3、审计方法论&lt;/h2&gt;&lt;p&gt;审计不是只有规则，还需要方法论。&lt;/p&gt;
&lt;p&gt;codeorion-agent 的 &lt;code&gt;skills/&lt;/code&gt; 目录按语言和漏洞类型组织审计方法，例如 Java SQL 注入、SSRF、IDOR、反序列化，Python 命令注入、路径穿越等。&lt;/p&gt;
&lt;p&gt;Agent 可以先加载对应的审计方法论，再按方法论选择 MCP 工具。它不是盲目扫全仓，而是按漏洞类型组织探索路径：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;入口点枚举
  -&amp;gt; sink（危险操作）搜索
  -&amp;gt; 调用链追踪
  -&amp;gt; 数据流确认
  -&amp;gt; sanitizer（过滤逻辑）检查
  -&amp;gt; 依赖反向追溯
  -&amp;gt; evidence（证据）登记
  -&amp;gt; finding（风险结论）输出&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这让扫描从“规则命中”变成“审计流程”。&lt;/p&gt;
&lt;h2 id=&quot;h2-4-&quot;&gt;&lt;a name=&quot;4、证据契约&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;4、证据契约&lt;/h2&gt;&lt;p&gt;我不希望 Agent 只是在报告里写“根据分析，这里存在漏洞”。&lt;/p&gt;
&lt;p&gt;在 codeorion-agent 里，finding（风险结论）必须先有 evidence（证据）。Agent 需要调用 &lt;code&gt;register_evidence&lt;/code&gt; 生成 &lt;code&gt;ev-*&lt;/code&gt;，然后在 &lt;code&gt;emit_finding&lt;/code&gt; 中引用这些证据。&lt;code&gt;emit_finding&lt;/code&gt; 会校验证据是否真实存在。&lt;/p&gt;
&lt;p&gt;也就是说，报告里的结论必须挂在具体工具结果上：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MCP 返回的 HTTP 入口&lt;/li&gt;&lt;li&gt;调用链追踪结果&lt;/li&gt;&lt;li&gt;数据流追踪结果&lt;/li&gt;&lt;li&gt;文件路径和行号&lt;/li&gt;&lt;li&gt;sandbox（沙箱）验证结果&lt;/li&gt;&lt;li&gt;原始 HTTP 请求&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;这个机制的目的很简单：减少 LLM 幻觉，让每个 finding 都能回溯到 evidence。&lt;/p&gt;
&lt;h2 id=&quot;h2-5-poc-&quot;&gt;&lt;a name=&quot;5、PoC 和验证&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;5、PoC 和验证&lt;/h2&gt;&lt;p&gt;传统 SAST 的输出经常停在“疑似”。但在真实安全审计里，我更希望尽量走到“可复现”。&lt;/p&gt;
&lt;p&gt;codeorion-agent 的 finding schema（风险结论结构）要求提供原始 HTTP 请求，并可以解析成 VerificationPoc。开启验证后，可以通过验证子 Agent、&lt;code&gt;sandbox_http&lt;/code&gt;、&lt;code&gt;sandbox_exec&lt;/code&gt; 进行 PoC 验证。&lt;/p&gt;
&lt;p&gt;这一步并不保证所有漏洞都能自动验证，但它把审计从“静态判断”推进到了“验证优先”。&lt;/p&gt;
&lt;h2 id=&quot;h2-6-&quot;&gt;&lt;a name=&quot;6、覆盖检查&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;6、覆盖检查&lt;/h2&gt;&lt;p&gt;Agent 很容易偷懒。比如找到一个明显 sink 后就结束，或者只看 Controller，不看依赖和配置。&lt;/p&gt;
&lt;p&gt;所以 codeorion-agent 里有覆盖检查。它要求报告前必须覆盖入口追踪、横向检查、依赖反向追溯等内容，避免审计过程过早收敛。&lt;/p&gt;
&lt;p&gt;这对真实审计很重要。因为漏洞不一定藏在最显眼的地方，很多关键风险来自鉴权遗漏、配置错误、二次注入、组件组合和业务状态机。&lt;/p&gt;
&lt;h1 id=&quot;h1--poc&quot;&gt;&lt;a name=&quot;九、真实靶场验证：从审计到自动化 PoC&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;九、真实靶场验证：从审计到自动化 PoC&lt;/h1&gt;&lt;p&gt;除了设计上的闭环，我还在 &lt;code&gt;java-sec-code&lt;/code&gt; 靶场上跑过多轮真实验证。这个靶场里保留了完整的 run 产物，包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;events.jsonl&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;tool_trace.jsonl&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;findings.jsonl&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;evidence/ev-*.json&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;evidence/ver-*.json&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;subagents/agent-*.jsonl&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;report/report.md&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;report/report.json&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;这些产物能说明一件事：codeorion-agent 不是只输出静态结论，而是会把“审计过程”和“验证过程”都落盘。&lt;/p&gt;
&lt;h2 id=&quot;h2-1-sql-&quot;&gt;&lt;a name=&quot;1、一次 SQL 注入审计的完整产物&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;1、一次 SQL 注入审计的完整产物&lt;/h2&gt;&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202607012148091.png&quot; alt=&quot;image-20260701214807992&quot;&gt;&lt;/p&gt;
&lt;p&gt;在 &lt;code&gt;java-sec-code&lt;/code&gt; 的一次 SQL 注入审计 run 中，最终报告发现了 5 个 SQL 注入问题：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;序号&lt;/th&gt;
&lt;th&gt;端点&lt;/th&gt;
&lt;th&gt;类型&lt;/th&gt;
&lt;th&gt;验证状态&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/sqli/jdbc/vuln&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;JDBC Statement 拼接 SQL&lt;/td&gt;
&lt;td&gt;confirmed_by_pattern&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/sqli/jdbc/ps/vuln&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;PreparedStatement 误用，拼接后再 prepareStatement&lt;/td&gt;
&lt;td&gt;confirmed_by_pattern&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/sqli/mybatis/vuln01&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;MyBatis 注解 &lt;code&gt;${username}&lt;/code&gt; 直接替换&lt;/td&gt;
&lt;td&gt;confirmed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/sqli/mybatis/vuln02&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;MyBatis XML LIKE &lt;code&gt;${_parameter}&lt;/code&gt; 直接替换&lt;/td&gt;
&lt;td&gt;confirmed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/sqli/mybatis/orderby/vuln03&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;MyBatis XML ORDER BY &lt;code&gt;${order}&lt;/code&gt; 直接替换&lt;/td&gt;
&lt;td&gt;confirmed&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;这里最有意思的不是“发现了 5 个漏洞”，而是每条风险结论都带着审计证据和验证证据。&lt;/p&gt;
&lt;p&gt;以 &lt;code&gt;/sqli/jdbc/ps/vuln&lt;/code&gt; 为例，它看起来用了 &lt;code&gt;PreparedStatement&lt;/code&gt;，但漏洞点在于 SQL 字符串已经提前拼接了用户输入：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;String sql = &amp;quot;select * from users where username = &amp;#39;&amp;quot; + username + &amp;quot;&amp;#39;&amp;quot;;
PreparedStatement st = con.prepareStatement(sql);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这类问题很容易骗过只做关键字判断的工具：它看到 &lt;code&gt;PreparedStatement&lt;/code&gt; 可能会误以为是安全写法。但 Agent 会继续检查 SQL 模板生成位置，发现用户输入在 &lt;code&gt;prepareStatement()&lt;/code&gt; 之前已经进入 SQL 字符串。&lt;/p&gt;
&lt;p&gt;审计链路可以抽象成：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202607012119097.png&quot; alt=&quot;image-20260701211913037&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;h2-2-agent-csrf-cookie&quot;&gt;&lt;a name=&quot;2、验证子 Agent 会自动处理登录、CSRF 和 Cookie&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;2、验证子 Agent 会自动处理登录、CSRF 和 Cookie&lt;/h2&gt;&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202607012148507.png&quot; alt=&quot;image-20260701214829465&quot;&gt;&lt;/p&gt;
&lt;p&gt;真实靶场并不是裸接口。很多端点访问前会跳转登录页，需要先拿 CSRF token，再登录，再带 Cookie 访问漏洞接口。&lt;/p&gt;
&lt;p&gt;在 run 的 subagent 记录里，verify 子 Agent 做了这样的事情：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;访问 &lt;code&gt;/login&lt;/code&gt; 获取登录页&lt;/li&gt;&lt;li&gt;从页面中提取 &lt;code&gt;_csrf&lt;/code&gt;&lt;/li&gt;&lt;li&gt;使用测试账号提交登录表单&lt;/li&gt;&lt;li&gt;保存 Cookie&lt;/li&gt;&lt;li&gt;携带 Cookie 请求漏洞接口&lt;/li&gt;&lt;li&gt;构造注入 payload&lt;/li&gt;&lt;li&gt;把响应摘要和 PoC 写入 &lt;code&gt;ver-*.json&lt;/code&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;可以抽象成：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202607012119132.png&quot; alt=&quot;image-20260701211925080&quot;&gt;&lt;/p&gt;
&lt;p&gt;这一步非常贴近真实审计。很多扫描器能识别代码里的危险操作，但很少会继续自动完成登录、维护 Cookie、处理 CSRF，然后在靶场里发 PoC。&lt;/p&gt;
&lt;p&gt;不过这类验证能力也有明确边界。它优先适用于靶场、测试环境和授权环境。真实业务系统中，SSO、MFA、验证码、权限分层、业务状态、异步任务、MQ、外部回连、对象存储、内网访问和 destructive payload 都可能让自动验证失败，或者需要人工提供上下文和安全边界。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;场景&lt;/th&gt;
&lt;th&gt;对 Agent 验证的影响&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;SSO / MFA / 验证码&lt;/td&gt;
&lt;td&gt;很难完全自动登录，需要人工提供会话或测试账号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;权限分层&lt;/td&gt;
&lt;td&gt;普通账号可达不代表高权限接口可验证&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;状态型漏洞&lt;/td&gt;
&lt;td&gt;需要构造订单、审批、库存、任务等业务状态&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;异步任务 / MQ&lt;/td&gt;
&lt;td&gt;HTTP 返回不一定能直接观察最终影响&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;生产环境&lt;/td&gt;
&lt;td&gt;不能随意发送破坏性 payload&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;外部依赖&lt;/td&gt;
&lt;td&gt;DNS、对象存储、回连、内网访问可能被网络策略限制&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;h2-3-&quot;&gt;&lt;a name=&quot;3、动态验证不只是“请求成功”，而是要解释结果&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;3、动态验证不只是“请求成功”，而是要解释结果&lt;/h2&gt;&lt;p&gt;在这个靶场里，不同漏洞的验证结果也不一样。&lt;/p&gt;
&lt;p&gt;MyBatis &lt;code&gt;${}&lt;/code&gt; 注入比较容易验证，因为错误回显里直接暴露了最终 SQL。例如 &lt;code&gt;/sqli/mybatis/vuln01&lt;/code&gt; 的注入 payload 进入后，响应中能看到类似：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;SQL: select * from users where username = &amp;#39;joychou&amp;#39; or &amp;#39;1&amp;#39;=&amp;#39;1&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这说明 &lt;code&gt;${username}&lt;/code&gt; 不是参数化绑定，而是字面量替换，payload 已经进入 SQL 语句。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/sqli/mybatis/orderby/vuln03&lt;/code&gt; 也能通过 ORDER BY 注入验证：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;SQL: select * from users order by id desc-- asc&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里 &lt;code&gt;--&lt;/code&gt; 注释截断了后面拼接的 &lt;code&gt;asc&lt;/code&gt;，说明 &lt;code&gt;sort&lt;/code&gt; 参数直接进入了 ORDER BY 子句。&lt;/p&gt;
&lt;p&gt;但 JDBC &lt;code&gt;PreparedStatement&lt;/code&gt; 误用那条比较有意思：靶场数据库环境没有返回有效数据，接口多次请求都是 HTTP 200 且响应体为空。这个时候 Agent 没有强行写“动态利用成功”，而是把状态记录成 &lt;code&gt;confirmed_by_pattern&lt;/code&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;请求成功返回 200。源码确认 username 参数直接拼接到 SQL 中，然后传给 prepareStatement，参数化完全失效。沙箱环境 MySQL 可能未启动或无数据，导致结果集为空，但代码漏洞模式清晰可见。&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这点很重要。自动化验证不应该为了“看起来成功”而夸大结果。能动态确认的写 &lt;code&gt;confirmed&lt;/code&gt;；环境限制导致无法完整回显，但源码和路径证据确凿的，写 &lt;code&gt;confirmed_by_pattern&lt;/code&gt;；证据不足的，应该写 &lt;code&gt;needs_review&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id=&quot;h2-4-codeorion-&quot;&gt;&lt;a name=&quot;4、CodeOrion 的结果不是一段文字&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;4、CodeOrion 的结果不是一段文字&lt;/h2&gt;&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202607012148143.png&quot; alt=&quot;image-20260701214855086&quot;&gt;&lt;/p&gt;
&lt;p&gt;一次审计最终会留下多层产物：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202607012119480.png&quot; alt=&quot;image-20260701211934431&quot;&gt;&lt;/p&gt;
&lt;p&gt;这和传统扫描器的一次性告警列表不一样。CodeOrion + codeorion-agent 输出的是一组可以复核的审计资产：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;我为什么认为这个入口可疑&lt;/li&gt;&lt;li&gt;我调用了哪些 MCP 工具&lt;/li&gt;&lt;li&gt;我读了哪些源码和图谱事实&lt;/li&gt;&lt;li&gt;我登记了哪些证据&lt;/li&gt;&lt;li&gt;我构造了什么 PoC&lt;/li&gt;&lt;li&gt;沙箱返回了什么&lt;/li&gt;&lt;li&gt;最终结论为什么是 &lt;code&gt;confirmed&lt;/code&gt;、&lt;code&gt;confirmed_by_pattern&lt;/code&gt; 或 &lt;code&gt;needs_review&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;这也是我希望它最终开源后能被持续改进的地方：每一次审计不是一个黑盒结论，而是一条可复盘、可调试、可改进的链路。&lt;/p&gt;
&lt;h1 id=&quot;h1--sast-&quot;&gt;&lt;a name=&quot;十、和传统 SAST 的区别&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;十、和传统 SAST 的区别&lt;/h1&gt;&lt;p&gt;我不会说 CodeOrion 要替代 CodeQL、Semgrep、Joern 或成熟 SAST。传统 SAST 的规则、数据流、污点分析仍然非常重要。CodeOrion 更像是把这些结构事实变成 Agent 可以消费、追问和验证的审计底座。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;传统 SAST 痛点&lt;/th&gt;
&lt;th&gt;CodeOrion + codeorion-agent 的处理方式&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;依赖硬编码规则，规则维护成本高&lt;/td&gt;
&lt;td&gt;CodeOrion 输出结构事实，Agent 按 Skill 和上下文动态组合查询&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;命中 source / sink 后误报多&lt;/td&gt;
&lt;td&gt;Agent 继续区分调用链可达、数据流可达、sanitizer、鉴权、配置和利用条件&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;很难深入第三方组件内部&lt;/td&gt;
&lt;td&gt;&lt;code&gt;trace_dependency_calls&lt;/code&gt; 建模项目代码到依赖方法、依赖内部方法的路径&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;对业务逻辑漏洞覆盖弱&lt;/td&gt;
&lt;td&gt;Agent 可以结合代码图和上下文推理 IDOR、越权、认证绕过等逻辑问题&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;报告缺少可复核证据&lt;/td&gt;
&lt;td&gt;&lt;code&gt;register_evidence&lt;/code&gt; 和 &lt;code&gt;emit_finding&lt;/code&gt; 强制 evidence_refs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;大仓库直接读源码成本高&lt;/td&gt;
&lt;td&gt;先用 MCP 查询结构化图谱，再按需读源码补证&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;finding 难复现&lt;/td&gt;
&lt;td&gt;支持 raw request、verify 子 Agent、sandbox PoC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;一次性扫描不可持续&lt;/td&gt;
&lt;td&gt;保留 transcript、tool_trace、checkpoint、findings、report，支持 resume/finalize&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;这个方向和行业趋势是一致的。Semgrep Multimodal 已经开始把 AI 用于复杂业务逻辑漏洞、自动研判、噪声过滤和修复建议。我的思路更进一步：不是先让规则扫描器吐告警，再让 AI 解释告警；而是从一开始就让 Agent 围绕代码图探索、取证和验证。&lt;/p&gt;
&lt;h1 id=&quot;h1--&quot;&gt;&lt;a name=&quot;十一、一个更接近真实审计的例子&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;十一、一个更接近真实审计的例子&lt;/h1&gt;&lt;p&gt;传统扫描器可能给出这样的结果：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;发现危险函数 eval
发现用户输入 request.body
疑似 RCE&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;但我更希望 CodeOrion + codeorion-agent 输出的是一条证据链：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;POST /api/render
  -&amp;gt; RenderController.render
  -&amp;gt; TemplateService.compile
  -&amp;gt; ThirdPartyTemplateEngine.evaluate
  -&amp;gt; dependency_method: evaluateExpression
  -&amp;gt; 危险操作: expression execution

证据：
  ev-1: 入口追踪
  ev-2: dependency call trace
  ev-3: sanitizer 检查
  ev-4: raw request / PoC&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;前者是“像漏洞”，后者是“为什么这条链成立”。&lt;/p&gt;
&lt;p&gt;这就是我认为 Agentic 代码审计（Agent 辅助代码审计）最重要的变化：从规则命中走向证据链推理。&lt;/p&gt;
&lt;h1 id=&quot;h1--&quot;&gt;&lt;a name=&quot;十二、当前边界&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;十二、当前边界&lt;/h1&gt;&lt;p&gt;开源项目必须讲清楚当前边界。&lt;/p&gt;
&lt;p&gt;CodeOrion 当前已经具备稳定的 Tree-sitter CST 图、统一 IR、SQLite 存储、框架端点提取、依赖节点和跨边界追踪能力。符号表、CallGraph、DFG、CFG 等模块已经具备模型和查询入口，但完整语义图落库、跨语言精确数据流、复杂别名分析、框架深度建模仍然是后续增强方向。&lt;/p&gt;
&lt;p&gt;也就是说，CodeOrion 当前最强的落地点不是“完整 CPG 实现”，也不是“完整替代传统 SAST 规则引擎”，而是把多语言源码解析结果、框架入口、依赖边界和查询工具统一成 Agent 可反复检索、扩展和取证的代码图底座。&lt;/p&gt;
&lt;p&gt;后续我会继续强化：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;更完整的语义边落库&lt;/li&gt;&lt;li&gt;更精确的跨文件符号解析&lt;/li&gt;&lt;li&gt;更强的框架和依赖注入建模&lt;/li&gt;&lt;li&gt;更完整的输入来源、危险操作、过滤逻辑候选生成&lt;/li&gt;&lt;li&gt;更好的组件内部调用链展开&lt;/li&gt;&lt;li&gt;更低成本的增量扫描&lt;/li&gt;&lt;li&gt;更适合安全审计的 Agent 证据视图&lt;/li&gt;&lt;/ul&gt;
&lt;h1 id=&quot;h1--&quot;&gt;&lt;a name=&quot;十三、结语&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;十三、结语&lt;/h1&gt;&lt;p&gt;我对 CodeOrion 的定位很清楚：它不是传统 SAST 的简单替代品，也不是声称 LLM 可以直接完成白盒审计，而是一个面向 Agent 的代码图审计底座。&lt;/p&gt;
&lt;p&gt;CodeOrion 负责把代码结构化，codeorion-agent 负责把结构事实变成审计行动。前者提供可查询的图，后者提供方法论、推理、证据、验证和报告。&lt;/p&gt;
&lt;p&gt;组合起来之后，白盒审计不再只是“规则扫描”，而是变成一条可以追问、可以复核、可以验证的证据链。&lt;/p&gt;
&lt;p&gt;CodeOrion 目前只是我个人的开源实验项目，并不是成熟的商业 SAST 产品。它的目标不是替代 CodeQL、Semgrep、Joern 这类成熟工具，而是探索一种更适合 AI Agent 使用的代码审计底座：先把代码结构化成可查询的事实，再让 Agent 围绕入口、调用链、依赖路径、证据和验证结果完成审计推理。&lt;/p&gt;
&lt;p&gt;这个项目的大部分工程实现都有 AI 辅助参与，我主要负责整体思路、审计方法、功能设计和结果验证。也正因为如此，CodeOrion 还有很多不完整、不精确、不稳定的地方，但它代表的是一个我想持续验证的方向：让代码审计从“规则命中”进一步走向“证据链推理”。&lt;/p&gt;
&lt;h1 id=&quot;h1--&quot;&gt;&lt;a name=&quot;十四、参考资料&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;十四、参考资料&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;Joern Code Property Graph: &lt;a href=&quot;https://docs.joern.io/code-property-graph/&quot;&gt;https://docs.joern.io/code-property-graph/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;CodeQL About data flow analysis: &lt;a href=&quot;https://codeql.github.com/docs/writing-codeql-queries/about-data-flow-analysis/&quot;&gt;https://codeql.github.com/docs/writing-codeql-queries/about-data-flow-analysis/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Semgrep Taint analysis overview: &lt;a href=&quot;https://docs.semgrep.dev/writing-rules/data-flow/taint-mode/overview&quot;&gt;https://docs.semgrep.dev/writing-rules/data-flow/taint-mode/overview&lt;/a&gt;&lt;/li&gt;&lt;li&gt;OWASP Top 10:2021 A06 Vulnerable and Outdated Components: &lt;a href=&quot;https://owasp.org/Top10/2021/A06_2021-Vulnerable_and_Outdated_Components/&quot;&gt;https://owasp.org/Top10/2021/A06_2021-Vulnerable_and_Outdated_Components/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;YASA: Scalable Multi-Language Taint Analysis on the Unified AST at Ant Group: &lt;a href=&quot;https://arxiv.org/abs/2601.17390&quot;&gt;https://arxiv.org/abs/2601.17390&lt;/a&gt;&lt;/li&gt;&lt;li&gt;TraceLens: Question-Driven Debugging for Taint Flow Understanding: &lt;a href=&quot;https://arxiv.org/abs/2508.07198&quot;&gt;https://arxiv.org/abs/2508.07198&lt;/a&gt;&lt;/li&gt;&lt;li&gt;QASecClaw: A Multi-Agent LLM Approach for False Positive Reduction in Static Application Security Testing: &lt;a href=&quot;https://arxiv.org/abs/2605.01885&quot;&gt;https://arxiv.org/abs/2605.01885&lt;/a&gt;&lt;/li&gt;&lt;li&gt;SastBench: A Benchmark for Testing Agentic SAST Triage: &lt;a href=&quot;https://arxiv.org/abs/2601.02941&quot;&gt;https://arxiv.org/abs/2601.02941&lt;/a&gt;&lt;/li&gt;&lt;li&gt;On the Security Blind Spots of Software Composition Analysis: &lt;a href=&quot;https://arxiv.org/abs/2306.05534&quot;&gt;https://arxiv.org/abs/2306.05534&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Hidden Dependencies and Component Variants in SBOM-Based Software Composition Analysis: &lt;a href=&quot;https://arxiv.org/abs/2604.21278&quot;&gt;https://arxiv.org/abs/2604.21278&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;
</description><pubDate>Wed, 01 Jul 2026 22:54:36 +0800</pubDate></item><item><title>Nacos RCE漏洞分析</title><link>https://uzzju.com/post/87.html</link><description>&lt;h1 id=&quot;h1-u6F0Fu6D1Eu7B80u4ECB&quot;&gt;&lt;a name=&quot;漏洞简介&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;漏洞简介&lt;/h1&gt;&lt;p&gt;Nacos 是一个开源的、易于使用的动态服务发现、配置和服务管理平台，用于构建云原生应用。它提供了一套简单易用的特性集，用于服务发现和服务健康监测，以及动态配置服务、服务元数据和流量管理。&lt;/p&gt;
&lt;h1 id=&quot;h1-u6F0Fu6D1Eu63CFu8FF0&quot;&gt;&lt;a name=&quot;漏洞描述&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;漏洞描述&lt;/h1&gt;&lt;p&gt;RCE（Remote Code Execution，远程代码执行）漏洞是指攻击者能够在远程服务器上执行任意代码的安全漏洞。此类漏洞通常会让攻击者完全控制受影响的系统，导致严重的安全问题。&lt;/p&gt;
&lt;h1 id=&quot;h1-u5F71u54CDu8303u56F4&quot;&gt;&lt;a name=&quot;影响范围&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;影响范围&lt;/h1&gt;&lt;p&gt;Alibaba-Nacos:version&amp;lt;=2.3.2受影晌。&lt;/p&gt;
&lt;h1 id=&quot;h1-u6F0Fu6D1Eu590Du73B0&quot;&gt;&lt;a name=&quot;漏洞复现&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;漏洞复现&lt;/h1&gt;&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202407191035005.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;用Github公开的exp可以复现该漏洞。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id=&quot;h1-u6F0Fu6D1Eu5206u6790&quot;&gt;&lt;a name=&quot;漏洞分析&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;漏洞分析&lt;/h1&gt;&lt;p&gt;从exp可以看出来，本次漏洞涉及2个接口&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;/nacos/v1/cs/ops/derby&lt;/li&gt;&lt;li&gt;/nacos/v1/cs/ops/data/removal&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202407191038426.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;这里是存在2个漏洞，1个是SQL注入，1个是文件上传，也就是条件竞争。&lt;br&gt;由于Nacos默认部署是没有鉴权的，在未配置的情况下，这里也可以未授权。&lt;/p&gt;
&lt;p&gt;SQL注入漏洞来源于：&lt;a href=&quot;https://github.com/alibaba/nacos/issues/10613&quot;&gt;https://github.com/alibaba/nacos/issues/10613&lt;/a&gt;&lt;br&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202407191054648.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;这里主要比较有意思的是这个文件上传的过程&lt;br&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202407191110624.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;核心在com.alibaba.nacos.core.utils.WebUtils#onFileUpload，这里在创建文件之后&lt;br&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202407191111210.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;会调用Consumer.accept，发布一个处理逻辑，表示文件处理开始。&lt;br&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202407191112871.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;随后在dataImport中，针对file对象里面的内容进行遍历，随后执行SQL。&lt;br&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202407191112535.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;核心的逻辑就在这，&lt;br&gt;前面的模型是，生产者，和消费者，那么Consumer这个消费者，执行前是同步的，但是在调用文件处理的时候，调用了一个异步处理，但是又没有等待异步处理完毕，然后就执行了finally里面的删除&lt;code&gt;DiskUtils.deleteQuietly(tmpFile);&lt;/code&gt;删除了临时文件，这就导致了会发生在处理时找不到文件的问题。&lt;br&gt;例如下面这张图这样。&lt;br&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202407191118368.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;那么只要让这里执行阻塞就可以了，通过大量的上传，让这里阻塞，就能够让异步执行的时候，有几率找到恶意的文件，然后进行SQLBatch导入。&lt;/p&gt;
&lt;p&gt;com.alibaba.nacos.core.persistence.DistributedDatabaseOperateImpl#dataImport 主要是把文件内容拿出来然后执行batchSQL&lt;br&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202407191129587.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;比如，成功的情况下，就会把SQL取出来，加入到batchSQL中&lt;br&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202407191132318.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;随后通过doDataImport导入&lt;br&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202407191133644.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202407191134041.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;所以漏洞原理可以概括为： 有这样一个功能，初衷是希望用户能够上传文件，且文件被异步的处理（我个人认为这里功能也有bug，因为就算正常用户去上传，也会执行finally导致文件删除，文件上传失败），通过条件竞争的方式，大量上传请求，导致这里阻塞，生产者创建了文件，但是还没来得及删，异步开始处理，导致把恶意的derby sql导入了数据库，导致了UDF问题。&lt;/p&gt;
&lt;h2 id=&quot;h2-u7591u95EEu89E3u7B54&quot;&gt;&lt;a name=&quot;疑问解答&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;疑问解答&lt;/h2&gt;&lt;p&gt;1、为什么可以UDF&lt;br&gt;我影响中，默认部署，想要利用MYSQL的UDF，好像不是一件简单的事情，需要有一些配置条件，在看到这个漏洞的时候可以UDF执行命令，这是让我比较疑惑的。&lt;br&gt;其实主要是因为，默认情况下，使用的是apache的derby数据库，这是一个Java写的数据库，&lt;br&gt;derby数据库是支持调用Java的方法的。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;CALL SQLJ.INSTALL_JAR(&amp;#39;file:///path/to/mypackage/MyFunctions.jar&amp;#39;, &amp;#39;APP.MyFunctionsJar&amp;#39;, 0);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;也就是poc中的这一段&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;post_sql = &amp;quot;&amp;quot;&amp;quot;CALL sqlj.install_jar(&amp;#39;{service}&amp;#39;, &amp;#39;NACOS.{id}&amp;#39;, 0)\n  
CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY(&amp;#39;derby.database.classpath&amp;#39;,&amp;#39;NACOS.{id}&amp;#39;)\n  
CREATE FUNCTION S_EXAMPLE_{id}( PARAM VARCHAR(2000)) RETURNS VARCHAR(2000) PARAMETER STYLE JAVA NO SQL LANGUAGE JAVA EXTERNAL NAME &amp;#39;test.poc.Example.exec&amp;#39;\n&amp;quot;&amp;quot;&amp;quot;.format(id=id,service=service);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2、这个漏洞是怎么来的？&lt;br&gt;利用条件竞争实现UDF的导入创建，随后利用一个以往发现的功能去执行SQL，导致了RCE。&lt;/p&gt;
&lt;h1 id=&quot;h1-u6F0Fu6D1Eu6392u67E5&quot;&gt;&lt;a name=&quot;漏洞排查&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;漏洞排查&lt;/h1&gt;&lt;p&gt;1、影响版本&lt;br&gt;Alibaba-Nacos:version&amp;lt;=2.3.2受影晌。&lt;/p&gt;
</description><pubDate>Fri, 19 Jul 2024 14:35:00 +0800</pubDate></item><item><title>云网OA8.0 updateUiSetup接口存在未授权FastJSON RCE</title><link>https://uzzju.com/post/86.html</link><description>&lt;h1 id=&quot;h1--oa8-0-updateuisetup-fastjson-rce&quot;&gt;&lt;a name=&quot;云网OA8.0 updateUiSetup接口存在未授权FastJSON RCE&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;云网OA8.0 updateUiSetup接口存在未授权FastJSON RCE&lt;/h1&gt;&lt;h1 id=&quot;h1-u57FAu672Cu4FE1u606F&quot;&gt;&lt;a name=&quot;基本信息&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;基本信息&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;Gitee地址：&lt;a href=&quot;https://gitee.com/bestfeng/oa_git_free&quot;&gt;https://gitee.com/bestfeng/oa_git_free&lt;/a&gt;&lt;/li&gt;&lt;li&gt;部署文档：&lt;a href=&quot;http://partner.yimihome.com/static/index.html#/index/idea_deploy8&quot;&gt;http://partner.yimihome.com/static/index.html#/index/idea_deploy8&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;h1 id=&quot;h1-u529Fu80FDu70B9&quot;&gt;&lt;a name=&quot;功能点&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;功能点&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;src/main/java/com/cloudweb/oa/controller/ApplicationController.java&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202406181720313.png&quot; alt=&quot;image-20240618172021275&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202406181642876.png&quot; alt=&quot;image-20240618164259851&quot;&gt;&lt;/p&gt;
&lt;p&gt;低版本FastJSON&lt;/p&gt;
&lt;p&gt;低版本FastJSON&lt;/p&gt;
&lt;p&gt;为什么会存在未授权，因为Filter的配置，这个oa，对于filter chain有点多，有基于spring security，也有原生的Dofilter，感觉偶尔的Chain会乱&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202406181726335.png&quot; alt=&quot;image-20240618172612295&quot;&gt; &lt;/p&gt;
&lt;p&gt;这里不登录也是可以访问的&lt;/p&gt;
&lt;h1 id=&quot;h1-u6F0Fu6D1Eu590Du73B0&quot;&gt;&lt;a name=&quot;漏洞复现&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;漏洞复现&lt;/h1&gt;&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;POST /oa/setup/updateUiSetup?applicationCode=1&amp;amp;uiSetup=payloadHTTP/1.1
Host: 127.0.0.1:8880
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:126.0) Gecko/20100101 Firefox/126.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Priority: u=1
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Content-Type: application/json
Content-Length: 18
cmd:whoami

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202406181643232.png&quot; alt=&quot;image-20240618164335202&quot;&gt;&lt;/p&gt;
</description><pubDate>Fri, 12 Jul 2024 10:22:47 +0800</pubDate></item><item><title>泛微E-Cology9 getFileViewUrl SSRF漏洞分析</title><link>https://uzzju.com/post/85.html</link><description>&lt;h1 id=&quot;h1-u6F0Fu6D1Eu63CFu8FF0&quot;&gt;&lt;a name=&quot;漏洞描述&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;漏洞描述&lt;/h1&gt;&lt;p&gt;泛微协同管理应用平台e-cology是一套兼具企业信息门户、知识文档管理、工作流程管理、人力资源管理、客户关系管理、项目管理、财务管理、资产管理、供应链管理、数据中心功能的企业大型协同管理平台。泛微E-Cology getFileViewUrl 接口处存在服务器请求伪造漏洞，未经身份验证的远程攻击者利用此漏洞扫描服务器所在的内网或本地端口，获取服务的banner信息，窥探网络结构，甚至对内网或本地运行的应用程序发起攻击，获取服务器内部敏感配置，造成信息泄露。&lt;/p&gt;
&lt;h1 id=&quot;h1-u5F71u54CDu6CDBu5FAE&quot;&gt;&lt;a name=&quot;影响泛微&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;影响泛微&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;上海泛微网络科技股份有限公司-泛微协同管理应用平台 E-cology9&lt;ul&gt;
&lt;li&gt;已复现版本： 2303.02&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;&lt;/ul&gt;
&lt;h1 id=&quot;h1-u6F0Fu6D1Eu590Du73B0&quot;&gt;&lt;a name=&quot;漏洞复现&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;漏洞复现&lt;/h1&gt;&lt;p&gt;poc&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{&amp;quot;file_id&amp;quot;:&amp;quot;1&amp;quot;,
&amp;quot;file_name&amp;quot;:&amp;quot;1&amp;quot;,
&amp;quot;download_url&amp;quot;:&amp;quot;xxxx poc url&amp;quot;,
&amp;quot;client_type&amp;quot;:&amp;quot;1&amp;quot;,
&amp;quot;isCopy&amp;quot;:&amp;quot;1&amp;quot;,
&amp;quot;user_id&amp;quot;:&amp;quot;1&amp;quot;}&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code class=&quot;language-http&quot;&gt;POST /api/doc/mobile/fileview/getFileViewUrl HTTP/1.1
Host: 
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:127.0) Gecko/20100101 Firefox/127.0
Accept: */*
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate, br
Referer: 
Content-Type: application/json
X-Requested-With: XMLHttpRequest
Origin:
Connection: keep-alive
Cookie: 
Priority: u=4
Content-Length: 135

{&amp;quot;file_id&amp;quot;:&amp;quot;1&amp;quot;,
&amp;quot;file_name&amp;quot;:&amp;quot;1&amp;quot;,
&amp;quot;download_url&amp;quot;:&amp;quot;xxxx&amp;quot;,
&amp;quot;client_type&amp;quot;:&amp;quot;1&amp;quot;,
&amp;quot;isCopy&amp;quot;:&amp;quot;1&amp;quot;,
&amp;quot;user_id&amp;quot;:&amp;quot;1&amp;quot;}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202407111140358.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h1 id=&quot;h1-u6F0Fu6D1Eu5206u6790&quot;&gt;&lt;a name=&quot;漏洞分析&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;漏洞分析&lt;/h1&gt;&lt;p&gt;com.api.doc.mobile.fileview.web.FileViewAction#getFileViewUrl&lt;br&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202407111140359.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;把JSON转为Map后，给到Execute&lt;br&gt;com.api.doc.mobile.fileview.cmd.FileViewCmd#execute&lt;br&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202407111140360.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;其中获取的DownloadUrl，就直接通过Map获取，给到null2String3&lt;br&gt;下面主要是判断Prop下的一些配置&lt;br&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202407111140361.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;需要满足第一个if，需要配置中的数字为1&lt;br&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202407111140362.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;我这边都没有配置，所以会走下面的else，不管这里走哪个分支，都可以到对应的Sink，造成SSRF&lt;br&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202407111140363.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;s3这个参数是我们的可控污点。&lt;br&gt;com.api.doc.mobile.fileview.cmd.FileViewCmd#getSocialFileViewUrlForYz(java.lang.String, java.lang.String, java.lang.String, int, java.util.Map&amp;lt;java.lang.String,java.lang.String&amp;gt;)&lt;br&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202407111140364.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;0，1，参数不为空的情况下，则会进入这里的流程。&lt;br&gt;com.api.doc.detail.util.ImageConvertUtil#doConvertForSocial(java.lang.String, java.lang.String, int, java.util.Map&amp;lt;java.lang.String,java.lang.String&amp;gt;)&lt;br&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202407111140365.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;我们进入com.api.doc.detail.util.ImageConvertUtil#doConvert&lt;br&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202407111140366.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;在这里获取了map中的filedownloadUrl，并调用com.api.doc.detail.util.ImageConvertUtil#downloadUrl&lt;br&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202407111140367.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;如果上述配置是1的情况下&lt;br&gt;在com.api.doc.mobile.fileview.cmd.FileViewCmd#execute进入&lt;br&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202407111140368.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202407111140369.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;调用链路可能就短一点了。&lt;/p&gt;
&lt;h1 id=&quot;h1-u4FEEu590Du65B9u6848&quot;&gt;&lt;a name=&quot;修复方案&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;修复方案&lt;/h1&gt;&lt;p&gt;1、升级泛微版本&lt;/p&gt;
</description><pubDate>Thu, 11 Jul 2024 11:40:39 +0800</pubDate></item><item><title>&amp;quot;限时福利：Splashtop 免费送一年高级远程支持服务，价值990元&amp;quot;</title><link>https://uzzju.com/post/84.html</link><description>&lt;p&gt;我在22年记得发过一篇文章：&lt;a href=&quot;https://uzzju.com/post/76.java&quot; title=&quot;ipad远程MacBookPro远程办公的终极解决方案&quot;&gt;ipad远程MacBookPro远程办公的终极解决方案&lt;/a&gt;，在文章中我大致对比了不同远程软件在Ipad远程MacBookPro时，是否能够完全支持触控板，秒控键盘之间的支持与兼容。&lt;/p&gt;
&lt;p&gt;在当时&lt;a href=&quot;https://www.splashtop.cn/&quot; title=&quot;Splashtop&quot;&gt;Splashtop&lt;/a&gt;这款远程软件，无疑是在此场景下最适配与兼容最完美的软件，现在也是24年了，陆陆续续我也用了这款软件2年了，目前来看，相较于Todesk，向日葵，M1 Mac的客户端总是闪退错误，&lt;a href=&quot;https://www.splashtop.cn/&quot; title=&quot;Splashtop&quot;&gt;Splashtop&lt;/a&gt;在Mac和Windows相互远程上，确实做到的最好的兼容性。&lt;/p&gt;
&lt;p&gt;现在&lt;a href=&quot;https://www.splashtop.cn/&quot; title=&quot;Splashtop&quot;&gt;Splashtop&lt;/a&gt;这款远程软件现在免费赠送一年&lt;a href=&quot;https://www.splashtop.cn/&quot; title=&quot;专业商业远程支持软件&quot;&gt;专业商业远程支持软件&lt;/a&gt;「Splashtop SOS」，价值990元！没有套路，没有任何前置条件，直接送！&lt;/p&gt;
&lt;p&gt;领取方式：微信搜索「splashtopcn」，关注「Splashtop服务号」，回复「免费SOS+账户」，&lt;a href=&quot;https://www.splashtop.cn/&quot; title=&quot;Splashtop&quot;&gt;Splashtop&lt;/a&gt; 就会送你一年 SOS 软件。&lt;/p&gt;
&lt;p&gt;还没注册账户的，访问官网 &lt;a href=&quot;https://my.splashtop.com/signup&quot;&gt;https://my.splashtop.com/signup&lt;/a&gt; 可以快速注册。&lt;/p&gt;
&lt;p&gt;Splashtop SOS 无需安装，即下即用，通过一个9位连接码即可快速连接远端设备。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202407082303213.gif&quot; alt=&quot;Splashtop SOS 连接方式&quot;&gt;&lt;br&gt;作为一款商业版远程支持软件，Splashtop SOS 拥有如下专业功能，你可以在使用过程中继续探索。&lt;br&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202407111623843.png&quot; alt=&quot;SOS远程支持软件功能&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;h2-splashtop-&quot;&gt;&lt;a name=&quot;Splashtop 更多商业版软件&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;Splashtop 更多商业版软件&lt;/h2&gt;&lt;p&gt;除了 SOS，针对不同应用场景，Splashtop 还有几款强大的商业版远程软件。&lt;/p&gt;
&lt;h3 id=&quot;h3-splashtop-business-access&quot;&gt;&lt;a name=&quot;Splashtop Business Access&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;Splashtop Business Access&lt;/h3&gt;&lt;p&gt;一款高性能远程桌面控制软件，适合需要长期稳定远程连接的公司或个人使用。&lt;/p&gt;
&lt;p&gt;Splashtop Business Access 属于无人值守的远程控制软件，一般用来远程操控自己的设备，适合远程办公等场合。Splashtop SOS 属于有人值守的远程支持软件，一般用于远程支持和协助他人，被控端有人值守。这是两者的区别。&lt;/p&gt;
&lt;h3 id=&quot;h3-splashtop-enterprise&quot;&gt;&lt;a name=&quot;Splashtop Enterprise&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;Splashtop Enterprise&lt;/h3&gt;&lt;p&gt;为大型企业的 IT 运维、托管服务供应商（MSP）提供远程运维能力。在提供远程桌面访问能力之外，也包含终端管理能力，例如操作系统更新管理、系统安全管理、系统日志汇总、资产管理等功能。&lt;/p&gt;
&lt;h3 id=&quot;h3-splashtop-on-prem&quot;&gt;&lt;a name=&quot;Splashtop On-Prem&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;Splashtop On-Prem&lt;/h3&gt;&lt;p&gt;Splashtop On-Prem 是 Splashtop Enterprise 的本地部署版本，可以完全自托管在企业网络内部，提供集中式数据库和网页管理控制台。通过本地化部署，企业可以将 Splashtop On-Prem 部署在企业内部或云平台上，所有用户数据都保留在企业内部。&lt;/p&gt;
&lt;p&gt;如有需要，可以访问官网「splashtop.cn」了解和免费体验上述产品。&lt;/p&gt;
&lt;h2 id=&quot;h2-splashtop-&quot;&gt;&lt;a name=&quot;Splashtop 软件特性&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;Splashtop 软件特性&lt;/h2&gt;&lt;h3 id=&quot;h3-1-&quot;&gt;&lt;a name=&quot;1、高性能 高画质&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;1、高性能 高画质&lt;/h3&gt;&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202407082303115.gif&quot; alt=&quot;Splashtop Business Access 远程桌面控制工具&quot;&gt;&lt;br&gt;Splashtop 一直以高性能赢得客户口碑，支持 4K 分辨率、60 FPS 帧率，延迟很低，可以带来媲美真机的沉浸式远程访问体验。特别适合需要高分辨率图形和流畅画面的行业，比如影视、动画和建筑设计。&lt;/p&gt;
&lt;h3 id=&quot;h3-2-&quot;&gt;&lt;a name=&quot;2、全平台支持&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;2、全平台支持&lt;/h3&gt;&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202407082303279.png&quot; alt=&quot;Splashtop 支持操作系统&quot;&gt;&lt;br&gt;Splashtop 拥有广泛的设备支持，你几乎可以使用任意智能设备进行远程连接，支持 Windows、Mac、Linux、iOS、Android 等主流平台。&lt;/p&gt;
&lt;h3 id=&quot;h3-3-&quot;&gt;&lt;a name=&quot;3、安全可靠&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;3、安全可靠&lt;/h3&gt;&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202407082303045.png&quot; alt=&quot;Splashtop 安全性&quot;&gt;&lt;br&gt;Splashtop 一直投入大量技术资源来提高软件安全性，提供了包括：双因素认证、黑屏、空闲会话超时、远程连接通知、会话审计记录等众多安全功能。软件至今已安全运行 19 年，从未爆出安全漏洞。&lt;/p&gt;
&lt;p&gt;Splashtop 始终将软件安全和用户隐私放在首位，所有的远程会话均受 TLS 和 256 位 AES 加密技术保护。软件符合 GDPR、SOC2、FERPA 等主要的安全合规性要求，能够保护所有用户信息安全并保持数据的机密性、完整性和可用性。&lt;/p&gt;
&lt;h3 id=&quot;h3-4-&quot;&gt;&lt;a name=&quot;4、功能全面&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;4、功能全面&lt;/h3&gt;&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202407082303959.gif&quot; alt=&quot;Splashtop Business Access 远程桌面控制软件&quot;&gt;&lt;br&gt;Splashtop 软件具备完善的专业功能，如文件传输、远程打印，团队管理、多显示器支持、聊天、共享屏幕、远程重启、会话录制等，全方位满足你的功能需求。还有更专业的远程触控笔、USB 设备重定向、麦克风直通、超高质量音频、4:4:4 色彩等功能，尤其适合建筑、设计、影视后期等行业。&lt;/p&gt;
&lt;h2 id=&quot;h2-splashtop-&quot;&gt;&lt;a name=&quot;Splashtop 简介&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;Splashtop 简介&lt;/h2&gt;&lt;p&gt;Splashtop Inc. 成立于 2006 年，总部位于硅谷，在杭州、台北、东京、新加坡、阿姆斯特丹等地设有分支机构。&lt;/p&gt;
&lt;p&gt;19 年来，Splashtop 产品一直安全稳定运营，以良好的产品和服务受到全球 3000 万用户、25万企业的信赖，包括 85% 的世界 500 强企业。2024 年，Splashtop 公司以 71 亿人民币的企业估值入选《2024·胡润全球独角兽榜》。&lt;br&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202407082303448.png&quot; alt=&quot;Splashtop 客户信赖&quot;&gt;&lt;/p&gt;
</description><pubDate>Mon, 08 Jul 2024 23:02:34 +0800</pubDate></item><item><title>未授权与垂直/水平越权(IDOR)检测实现方案</title><link>https://uzzju.com/post/83.html</link><description>&lt;h1 id=&quot;h1--idor-&quot;&gt;&lt;a name=&quot;未授权与垂直/水平越权(IDOR)检测实现方案&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;未授权与垂直/水平越权(IDOR)检测实现方案&lt;/h1&gt;&lt;h1 id=&quot;h1-todo&quot;&gt;&lt;a name=&quot;TODO&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;TODO&lt;/h1&gt;&lt;p&gt;1、去重通过接口进行去重&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;防止水平越权时参数不一致导致的同一个URL重复问题&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;2、黑名单配置&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;让用户选择可以配置黑名单来禁止检测指定URL&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;3、白名单配置&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;让用户选择可以配置白名单来检测指定URL&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;&lt;p&gt;检测host白名单配置，可以通过通配符的方式来匹配指定域名&lt;/p&gt;
&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;4、多任务&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果同时存在多个任务如何处理，来区分不同任务所对应的cookie以及域名&lt;/li&gt;&lt;/ul&gt;
&lt;h1 id=&quot;h1--idor-&quot;&gt;&lt;a name=&quot;越权(IDOR)&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;越权(IDOR)&lt;/h1&gt;&lt;h2 id=&quot;h2-1-&quot;&gt;&lt;a name=&quot;1、越权漏洞与逻辑漏洞的边界&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;1、越权漏洞与逻辑漏洞的边界&lt;/h2&gt;&lt;p&gt;一直以来，非安全人员甚至安全人员都难以区分越权和逻辑漏洞的差异在哪，什么可以认定为越权漏洞，什么可以认定为是逻辑漏洞，我这里举几个例子，来详细介绍，如何理解越权与逻辑漏洞。&lt;/p&gt;
&lt;h3 id=&quot;h3-1-1-strong-strong-&quot;&gt;&lt;a name=&quot;1.1、&lt;strong&gt;首先什么是越权漏洞&lt;/strong&gt;&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;1.1、&lt;strong&gt;首先什么是越权漏洞&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;目前越权分为两种类型&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;水平越权&lt;/li&gt;&lt;li&gt;垂直越权&lt;/li&gt;&lt;/ul&gt;
&lt;h3 id=&quot;h3-1-2-&quot;&gt;&lt;a name=&quot;1.2、什么是垂直越权&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;1.2、什么是垂直越权&lt;/h3&gt;&lt;p&gt;其中垂直越权可以理解为，正常的业务流程是一个管理员拥有后台管理的所有权限，在这个后台中有用户鉴权体系，可以新增其他角色/权限的账号登录后台，分配对应的权限则拥有对应接口与页面的访问权限。&lt;/p&gt;
&lt;p&gt;例如后台功能如下&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;商户管理&lt;/li&gt;&lt;li&gt;订单管理&lt;/li&gt;&lt;li&gt;用户管理&lt;/li&gt;&lt;li&gt;日志审计&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;如果此时新建一个普通用户账号，只分配1个日志审计功能&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;账号：test&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;那么从业务角度上来说当前&lt;code&gt;test&lt;/code&gt;用户就只能拥有日志审计查看的权限，但是在大量的企业研发的案例中会发现，内部对于权限梳理上并没有做的非常细致，这就导致了，可能商户管理的某个接口，可以让&lt;code&gt;test&lt;/code&gt;用户访问到，此时就造成了垂直越权。&lt;/p&gt;
&lt;h3 id=&quot;h3-1-3-&quot;&gt;&lt;a name=&quot;1.3、什么是水平越权&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;1.3、什么是水平越权&lt;/h3&gt;&lt;p&gt;水平越权的理解上也比较容易，水平从字面理解是一个平面，水平线，那么代入到权限中是A与B用户拥有同一个权限，例如一个商城，A是一个用户，B也是一个用户，A在网站上购买一个口罩，订单的ID为：1（如果订单ID是递增的方式的话），那么B在网站上也购买一个口罩，订单ID为：2，那么此时如果B想通过查询订单的接口，试试把ID：2改为ID：1，是否可以查询到A账号的订单信息呢？&lt;/p&gt;
&lt;p&gt;如果此时查询成功，则代表，存在水平越权的漏洞。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;订单增删改查&lt;/li&gt;&lt;li&gt;地址增删改查&lt;/li&gt;&lt;li&gt;发票增删改查&lt;/li&gt;&lt;li&gt;等……&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/UzJuMarkDownImage202303281507376.png&quot; alt=&quot;业务逻辑越权之水平垂直越权&quot;&gt;&lt;/p&gt;
&lt;p&gt;从这张图上可以看到，垂直越权是从下至上的漏洞方式，作为一个普通用户，我无法访问的数据，没有权限的数据，我可以通过查找JS，Fuzz参数等方式查询到该接口的数据，即可以认定为存在垂直越权漏洞。&lt;/p&gt;
&lt;p&gt;那么水平越权则是从同一个权限获取到同一个权限的其他用户信息，则称为水平越权。&lt;/p&gt;
&lt;h3 id=&quot;h3-1-4-&quot;&gt;&lt;a name=&quot;1.4、什么是逻辑漏洞&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;1.4、什么是逻辑漏洞&lt;/h3&gt;&lt;p&gt;为什么我会认为逻辑漏洞可以与越权漏洞分开理解，原因如下：&lt;/p&gt;
&lt;p&gt;首先举一个例子，来看一下什么是逻辑漏洞&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;以下取自火线众测后台漏洞案例&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&quot;h4-1-4-1-strong-strong-&quot;&gt;&lt;a name=&quot;1.4.1、&lt;strong&gt;案例一&lt;/strong&gt;&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;1.4.1、&lt;strong&gt;案例一&lt;/strong&gt;&lt;/h4&gt;&lt;p&gt;快手APP上有一个通讯录获取好友的功能，通过该功能可以获取手机通讯录中有多少个好友正在使用快手APP，可以直接查询到账号，那么我们换一个角度来想，如果使用生成器，生成很多的手机号码，放入到通讯录中，再打开快手的APP，那么是否就已经反向知道对应的快手账户的手机号码是多少了呢？&lt;/p&gt;
&lt;h4 id=&quot;h4-1-4-2-strong-strong-&quot;&gt;&lt;a name=&quot;1.4.2、&lt;strong&gt;案例二&lt;/strong&gt;&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;1.4.2、&lt;strong&gt;案例二&lt;/strong&gt;&lt;/h4&gt;&lt;p&gt;现在使用Keep购买一个健身用品，例如一个手环，需要支付200元，但是购买健身用品的同时会赠送一些赠品，例如赠送蜡烛，毛巾等，那么每一个商品都会存在SKUid，那么此时就可能会存在一个问题，我首先将手环加入到购物车，在购物车正常选择赠品，例如现在选择一个蜡烛，随后点击提交的时候，将蜡烛的SKUID替换为一个价值1000元的手表的SKUID，如果存在逻辑漏洞，是否就下单购买成功，只需要支付200元就可以获得1个手环和1个价值1000元的手表。&lt;/p&gt;
&lt;h4 id=&quot;h4-1-4-3-strong-strong-&quot;&gt;&lt;a name=&quot;1.4.3、&lt;strong&gt;案例三&lt;/strong&gt;&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;1.4.3、&lt;strong&gt;案例三&lt;/strong&gt;&lt;/h4&gt;&lt;p&gt;任意用户注册的逻辑场景，现在正常走注册的逻辑流程，输入账号，密码，手机号，但是我希望使用别人的手机号码进行注册，但是我又无法知道验证码是什么，那么此时提交错误的验证码，收到的返回肯定是验证码不正确，但是如果修改响应包呢？&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/UzJuMarkDownImage202303281525583.png&quot; alt=&quot;image-20230328152553546&quot;&gt;&lt;/p&gt;
&lt;p&gt;例如上图，将success和code都修改成0和true，那么此时可能会跳过验证码校验，让前端的UI进入到下一步&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/UzJuMarkDownImage202303281526524.png&quot; alt=&quot;image-20230328152639488&quot;&gt;&lt;/p&gt;
&lt;p&gt;那么此时设置登录的账号，昵称，设置密码，确认密码，点击下一步应该就是注册成功&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/UzJuMarkDownImage202303281527981.png&quot; alt=&quot;image-20230328152717947&quot;&gt;&lt;/p&gt;
&lt;p&gt;随后发现账号是可以正常登录成功的，那么此时考虑一个问题，这里到底是手机验证码验证的接口出现了问题，还是注册接口出现了问题？&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;正常的业务逻辑&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/UzJuMarkDownImage202303281528562.png&quot; alt=&quot;image-20230328152850532&quot;&gt;&lt;/p&gt;
&lt;p&gt;上面的这张图中间其实应该加一个校验，应该如下才是对的&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;这里其实会存在一个问题，那么也就是如果有人强制修改响应包来修改前端跳转的逻辑的话，如果没有做校验，也会存在问题，比如发送了验证码之后，我输入123456，随后修改这个请求的响应包，将返回的False修改为True，那么也能来到下面的注册逻辑&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/UzJuMarkDownImage202303281529907.png&quot; alt=&quot;image-20230328152913877&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;存在漏洞的业务逻辑&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/UzJuMarkDownImage202303281529929.png&quot; alt=&quot;image-20230328152925883&quot;&gt;&lt;/p&gt;
&lt;p&gt;其实除了上述验证码爆破，修改响应包后走下一步逻辑并且注册接口并未校验验证码这两个问题之外，还有一个比较少见的逻辑问题&lt;/p&gt;
&lt;p&gt;1、先正常走一遍业务登录注册逻辑&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1、输入正确验证码&lt;/li&gt;&lt;li&gt;2、服务端校验后返回Token/成功的参数(遇到过输入正确验证码之后返回一段Token，并在注册的时候会带上这个token)，把这里的响应包复制下来（这里称为正确的响应包）&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;2、走恶意的业务登录注册逻辑&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1、输入错误验证码&lt;ul&gt;
&lt;li&gt;2、拦截响应包（这里的响应包称为错误的响应包)&lt;ul&gt;
&lt;li&gt;3、将正确业务逻辑的响应包的token或者整个正确的响应包替换这个错误的响应包&lt;ul&gt;
&lt;li&gt;4、随后继续走业务注册逻辑，也会注册成功&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;上述的这个逻辑问题，我认为本质就把这里的token当做一个令牌了，服务端不在乎是谁申请的这个令牌，只校验了谁有这个令牌，这个令牌是否有效，如果有效就通过即可，最终就会导致问题。&lt;br&gt;那么哈罗这里的根本原因是，/merchant/register/registerAccount这个接口未对验证码进行校验，&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;因为拿软件暴力破解举一个例子，在软件启动时会提示用户是否注册，如果没有就无法使用，那么可以直接将汇编代码中的JNZ等判断修改为强制的JMP，这样如果没有其他校验，就可以正常使用软件功能&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这里的本质问题还是开发者无法防止用户去修改一些前端显示逻辑，但是可以在注册接口（也就是/merchant/register/registerAccount进行校验）这样哪怕用户强制修改前端逻辑，甚至在JS中fuzz或直接构造参数请求该接口，都会提示验证码错误，无法注册。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Tips: 这里需要注意的是，开发者不仅仅只是校验验证码是否有效，因为如果只校验验证码是否有效的话，那么我随便用一个手机号码发一个有效的验证码都可以使用，这样是不行的，应该还需要判断，该验证码是否属于该手机号码，并且是否有效（这里可能会说，例如腾讯 百度这种用户基数特别大的，是否会出现验证码重复的概念呢？大概率是会的，不过验证码使用后失效即可）&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;h2-2-&quot;&gt;&lt;a name=&quot;2、垂直/水平越权漏洞产生的主要原因与场景&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;2、垂直/水平越权漏洞产生的主要原因与场景&lt;/h2&gt;&lt;h3 id=&quot;h3-2-1-&quot;&gt;&lt;a name=&quot;2.1、垂直/水平越权漏洞产生的主要原因&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;2.1、垂直/水平越权漏洞产生的主要原因&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;比较通用的说法&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;通常情况下，一个 Web 程序功能流程是登录 - 提交请求 - 验证权限 - 数据库查询 - 返回结果。如果验证权限不足，便会导致越权。常见的程序都会认为通过登录后即可验证用户的身份，从而不会做下一步验证，最后导致越权。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1、通过隐藏 URL&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;实现控制访问有些程序的管理员的管理页面只有管理员才显示，普通用户看不到，利用 URL 实现访问控制，但 URL 泄露或被恶意攻击者猜到后，这会导致越权攻击。&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;2、直接对象引用&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;这种通过修改一下参数就可以产生水平越权，例如查看用户信息页面 URL 后加上自己的 id 便可查看，当修改为他人的 ID 号时会返回他人的信息，便产生了水平越权。&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;3、多阶段功能&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;多阶段功能是一个功能有多个阶段的实现。例如修改密码，可能第一步是验证用户身份信息，号码验证码类的。当验证成功后，跳到第二步，输入新密码，很多程序会在这一步不再验证用户身份，导致恶意攻击者抓包直接修改参数值，导致可修改任意用户密码。&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;4、静态文件&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;很多网站的下载功能，一些被下载的静态文件，例如 pdf、word、xls 等，可能只有付费用户或会员可下载，但当这些文件的 URL 地址泄露后，导致任何人可下载，如果知道 URL 命名规则，则会便利服务器的收费文档进行批量下载。&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;5、平台配置错误&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一些程序会通过控件来限制用户的访问，例如后台地址，普通用户不属于管理员组，则不能访问。但当配置平台或配置控件错误时，就会出现越权访问。&lt;/li&gt;&lt;/ul&gt;
&lt;h3 id=&quot;h3-2-2-&quot;&gt;&lt;a name=&quot;2.2、会有哪些场景？&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;2.2、会有哪些场景？&lt;/h3&gt;&lt;h4 id=&quot;h4-2-2-1-&quot;&gt;&lt;a name=&quot;2.2.1、垂直越权&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;2.2.1、垂直越权&lt;/h4&gt;&lt;p&gt;垂直越权出现的位置，更多的在管理后台，并且管理后台有用户鉴权体系，特别是在同一个管理后台中还存在，商户，用户，管理员，多种用户的角色和关系，这类型的场景出现垂直越权的可能性是最大的。&lt;/p&gt;
&lt;h4 id=&quot;h4-2-2-2-&quot;&gt;&lt;a name=&quot;2.2.2、水平越权&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;2.2.2、水平越权&lt;/h4&gt;&lt;p&gt;水平越权出现的位置相对来说比较普遍，例如一个商城，购物APP，发票网站等等，在订单，地址，发票，用户信息，收藏店家，删除订单等位置是最容易出现水平越权的地方，并且很多研发写代码比如一个订单号，是使用一个可递增遍历的数字来表示订单，例如订单ID为1,2,3,4,5以此类推，那么如果此时遍历这个订单ID，就有可能获取到其他用户的订单信息。&lt;/p&gt;
&lt;h2 id=&quot;h2-3-&quot;&gt;&lt;a name=&quot;3、越权漏洞检测实现的难点&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;3、越权漏洞检测实现的难点&lt;/h2&gt;&lt;p&gt;目前这个版本的越权和未授权检测是我重构之后的（代码工程能力不强），早些的一个版本也是使用mitmproxy来实现的HTTP/S的监听，但是发现，mitmproxy使用&lt;code&gt;addons = [CaptureInfoWriteFile()]&lt;/code&gt;的方式来实现&lt;code&gt;request&lt;/code&gt;和&lt;code&gt;response&lt;/code&gt;有一个问题是会出现阻塞的情况，特别是越权需要去解析一个HTTP/S请求，然后替换token请求的，那么此时在替换token请求这一步操作上很容易发生阻塞的情况，导致正常的功能测试页面一直无法返回。&lt;/p&gt;
&lt;p&gt;当前重构的版本，采用&lt;code&gt;asyncio&lt;/code&gt;异步的方式来实现的异步，每一次都会新增一个异步线程任务，使用后会清除当前线程任务。&lt;/p&gt;
&lt;p&gt;目前主要实现的难点有以下几项&lt;/p&gt;
&lt;p&gt;1、垂直越权&lt;/p&gt;
&lt;p&gt;垂直越权的实现相对简单很多，只需要将原始请求与修改后的请求的响应包进行差异值比较即可&lt;/p&gt;
&lt;p&gt;但是也无法避免&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果接口对于用户鉴权体系来说是公共的如何识别？&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;2、水平越权&lt;/p&gt;
&lt;p&gt;水平越权的实现相对就比较难，可以使用替换两个权限相同的token来进行差异值的比较，但是如果接口是&lt;/p&gt;
&lt;p&gt;目前主要实现&lt;/p&gt;
&lt;p&gt;1、如何解决参数识别问题  （已解决）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;RESFUL HTTP参数识别（已解决）&lt;br&gt;2、如何解决规则库，使用什么解决方法来让保证规则库的通用性和可扩展性&lt;br&gt;3、如何自动化识别不同的权限校验头  （已解决）&lt;br&gt;4、如何解决参数加密场景的问题  &lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;6、是否要采用数据持久化方案 使用sqlit or mysql or mongodb or redis&lt;br&gt;7、不同请求替换参数 Cookie后请求响应如何判断差异性，如余弦相似度判断，相似度应该控制在多少合适？是否有更好的算法解决该问题&lt;br&gt;8、自动化登录 防止cookie失效&lt;/p&gt;
&lt;h2 id=&quot;h2-4-&quot;&gt;&lt;a name=&quot;4、如何使用现有的方案来实现越权检测&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;4、如何使用现有的方案来实现越权检测&lt;/h2&gt;&lt;h3 id=&quot;h3-4-1-&quot;&gt;&lt;a name=&quot;4.1、余弦相似度判断差异性&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;4.1、余弦相似度判断差异性&lt;/h3&gt;&lt;p&gt; &lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/UzJuMarkDownImage202303281554404.png&quot; alt=&quot;image-20230328155457367&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;h2-5-&quot;&gt;&lt;a name=&quot;5、实践落地&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;5、实践落地&lt;/h2&gt;&lt;p&gt;针对所有的场景包括代码的编写，都是针对真实场景进行编写，不涉及靶场。&lt;/p&gt;
&lt;h3 id=&quot;h3-5-1-&quot;&gt;&lt;a name=&quot;5.1、拉卡拉&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;5.1、拉卡拉&lt;/h3&gt;&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/UzJuMarkDownImage202303281558095.png&quot; alt=&quot;image-20230328155826059&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;h3-5-2-&quot;&gt;&lt;a name=&quot;5.2、享道出行&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;5.2、享道出行&lt;/h3&gt;&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/UzJuMarkDownImage202303301728797.jpg&quot; alt=&quot;img_v2_c68fba15-786c-4371-9e44-dd4e73aedb1g&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/UzJuMarkDownImage202303301728515.jpg&quot; alt=&quot;img_v2_878ad6ba-d658-4fd2-9abd-3fb4d83ea69g&quot;&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/UzJuMarkDownImage202303301728425.jpg&quot; alt=&quot;img_v2_ccd5f023-6288-4f53-98c6-608cf1b6010g&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;h3-5-3-src&quot;&gt;&lt;a name=&quot;5.3、字节SRC&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;5.3、字节SRC&lt;/h3&gt;&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/UzJuMarkDownImage202304111429132.png&quot; alt=&quot;image-20230411142909990&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;h3-5-4-&quot;&gt;&lt;a name=&quot;5.4、自如&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;5.4、自如&lt;/h3&gt;&lt;p&gt;&lt;a href=&quot;https://i0x0fy4ibf.feishu.cn/wiki/wikcnz28wEH6ifNAsD7CVSO0Atd&quot;&gt;https://i0x0fy4ibf.feishu.cn/wiki/wikcnz28wEH6ifNAsD7CVSO0Atd&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&quot;h1-u672Au6388u6743u8BBFu95EE&quot;&gt;&lt;a name=&quot;未授权访问&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;未授权访问&lt;/h1&gt;&lt;h2 id=&quot;h2-1-&quot;&gt;&lt;a name=&quot;1、为什么会出现未授权&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;1、为什么会出现未授权&lt;/h2&gt;&lt;p&gt;未授权的场景可以理解为：访问一个接口，将cookie/token删除，重新请求接口如果还是存在数据返回，则存在未授权访问。&lt;/p&gt;
&lt;p&gt;但是未授权又分三个场景&lt;/p&gt;
&lt;p&gt;1、后端没有对请求的cookie/token进行校验就走了业务逻辑流程导致返回了数据&lt;/p&gt;
&lt;p&gt;2、后端判断了当前请求是否带有cookie/token，但是没有判断当前token/cookie是否有效&lt;/p&gt;
&lt;p&gt;3、后端判断了当前请求是否带有cookie/token，但是没有判断当前的token/cookie是否有权限访问这个数据&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;这里有点像越权的范畴，需要清晰了解未授权与越权漏洞的边界&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;h2-2-&quot;&gt;&lt;a name=&quot;2、未授权检测实现方案&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;2、未授权检测实现方案&lt;/h2&gt;&lt;p&gt;例如这是一个正常请求头&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-http&quot;&gt;Headers[(b&amp;#39;Host&amp;#39;, b&amp;#39;172.20.10.5:8109&amp;#39;), (b&amp;#39;User-Agent&amp;#39;, b&amp;#39;Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/111.0&amp;#39;), (b&amp;#39;Accept&amp;#39;, b&amp;#39;*/*&amp;#39;), (b&amp;#39;Accept-Language&amp;#39;, b&amp;#39;zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2&amp;#39;), (b&amp;#39;Accept-Encoding&amp;#39;, b&amp;#39;gzip, deflate&amp;#39;), (b&amp;#39;Connection&amp;#39;, b&amp;#39;keep-alive&amp;#39;), (b&amp;#39;Cookie&amp;#39;, b&amp;#39;session=eyJ1c2VyaWQiOjI3LCJ1c2Vycm9sZWlkIjo5OX0.ZCQjlw.IqMSJjOnlony_c1gtf18URKrGMU&amp;#39;)]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;此时存在cookie这个键值对，如果此时将cookie删除&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-http&quot;&gt;[(b&amp;#39;Host&amp;#39;, b&amp;#39;172.20.10.5:8109&amp;#39;), (b&amp;#39;User-Agent&amp;#39;, b&amp;#39;Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/111.0&amp;#39;), (b&amp;#39;Accept&amp;#39;, b&amp;#39;*/*&amp;#39;), (b&amp;#39;Accept-Language&amp;#39;, b&amp;#39;zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2&amp;#39;), (b&amp;#39;Accept-Encoding&amp;#39;, b&amp;#39;gzip, deflate&amp;#39;), (b&amp;#39;X-Requested-With&amp;#39;, b&amp;#39;XMLHttpRequest&amp;#39;), (b&amp;#39;Connection&amp;#39;, b&amp;#39;keep-alive&amp;#39;), (b&amp;#39;Referer&amp;#39;, b&amp;#39;http://172.20.10.5:8109/usermanager&amp;#39;)]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/UzJuMarkDownImage202303291945638.png&quot; alt=&quot;image-20230329194540540&quot;&gt;&lt;/p&gt;
&lt;p&gt;通过计算返回值的余弦相似度就可以获得想要的结果。&lt;/p&gt;
&lt;h1 id=&quot;h1-u8D8Au6743u5B9Eu73B0u65B9u6848u4E8C&quot;&gt;&lt;a name=&quot;越权实现方案二&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;越权实现方案二&lt;/h1&gt;&lt;p&gt;上述方案存在部分缺点&lt;/p&gt;
&lt;p&gt;1、需要用户配置代理&lt;/p&gt;
&lt;p&gt;2、需要用户手动配置账号token&lt;/p&gt;
&lt;p&gt;这在甲方安全建设推动中会极大的影响效率以及安全部门推进的速度。&lt;/p&gt;
&lt;p&gt;实现方案二主要解决了上述2个问题。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202308091616998&quot; alt=&quot;img&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;h2-1-golang-gopacket-&quot;&gt;&lt;a name=&quot;1、GoLang gopacket实现&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;1、GoLang gopacket实现&lt;/h2&gt;&lt;h3 id=&quot;h3-1-1-&quot;&gt;&lt;a name=&quot;1.1、实现方式一&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;1.1、实现方式一&lt;/h3&gt;&lt;h4 id=&quot;h4-1-1-http-&quot;&gt;&lt;a name=&quot;1.1、获取HTTP请求&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;1.1、获取HTTP请求&lt;/h4&gt;&lt;pre&gt;&lt;code class=&quot;language-go&quot;&gt;package main

import (
    &amp;quot;fmt&amp;quot;
    &amp;quot;github.com/google/gopacket&amp;quot;
    &amp;quot;github.com/google/gopacket/layers&amp;quot;
    &amp;quot;github.com/google/gopacket/pcap&amp;quot;
    &amp;quot;log&amp;quot;
    &amp;quot;time&amp;quot;
)

func main() {
    const (
        // 网络设备
        EthDev string = &amp;quot;eth0&amp;quot;
        // 抓取数据长度
        SnapLen int32 = 65535
        // 是否开启混合模式，混合模式就是不属于本网卡IP的流量
        Promisc bool = false
        // 展示细节的时间
        Timeout time.Duration = time.Second * 3
        // 抓取端口
        DstPort layers.TCPPort = 8088
    )
    // 对网卡流量进行实时捕获
    handler, err := pcap.OpenLive(EthDev, SnapLen, Promisc, Timeout)
    if err != nil {
        log.Fatalln(err)
    }
    defer handler.Close()
    // 获取包源
    source := gopacket.NewPacketSource(handler, handler.LinkType())
    var isApp bool
    for pk := range source.Packets() {
        // 网络四层模型
        // LinkLayer returns the first link layer in the packet
        // LinkLayer() LinkLayer
        // NetworkLayer returns the first network layer in the packet
        // NetworkLayer() NetworkLayer
        // TransportLayer returns the first transport layer in the packet
        // TransportLayer() TransportLayer
        // ApplicationLayer returns the first application layer in the packet
        // ApplicationLayer() ApplicationLayer

        isApp = false
        if layer := pk.TransportLayer(); layer != nil {
            if tcpLayer, ok := layer.(*layers.TCP); ok &amp;amp;&amp;amp; tcpLayer.DstPort == DstPort {
                fmt.Println()
                fmt.Printf(&amp;quot;TCP Payload: %s\n&amp;quot;, string(tcpLayer.Payload))
                fmt.Printf(&amp;quot;TCP ContentsLenght: %d \n&amp;quot;, len(tcpLayer.Contents))
                fmt.Println(pk.String())
                if len(tcpLayer.Payload) &amp;gt; 0 {
                    isApp = true
                }
            }
        }

        if isApp {
            if appLayer := pk.ApplicationLayer(); appLayer != nil {
                fmt.Println(&amp;quot;APP Contents:&amp;quot;, string(appLayer.LayerContents()))
                fmt.Println(&amp;quot;APP Contents Length:&amp;quot;, len(appLayer.LayerContents()))
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;基础实现Demo如上代码示例&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202308101200333.png&quot; alt=&quot;image-20230810120023250&quot;&gt;&lt;/p&gt;
&lt;p&gt;可以获取HTTP请求&lt;/p&gt;
&lt;h4 id=&quot;h4-1-2-https-&quot;&gt;&lt;a name=&quot;1.2、获取HTTPS请求&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;1.2、获取HTTPS请求&lt;/h4&gt;&lt;p&gt;暂时没找到实现HTTPS的方案&lt;/p&gt;
&lt;h3 id=&quot;h3-1-2-&quot;&gt;&lt;a name=&quot;1.2、实现方式二&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;1.2、实现方式二&lt;/h3&gt;&lt;pre&gt;&lt;code class=&quot;language-go&quot;&gt;package main

import (
    &amp;quot;fmt&amp;quot;
    &amp;quot;log&amp;quot;
    &amp;quot;os&amp;quot;
    &amp;quot;os/signal&amp;quot;
    &amp;quot;strings&amp;quot;
    &amp;quot;syscall&amp;quot;

    &amp;quot;github.com/google/gopacket&amp;quot;
    &amp;quot;github.com/google/gopacket/pcap&amp;quot;
)

func main() {
    handle, err := pcap.OpenLive(&amp;quot;any&amp;quot;, 1600, true, pcap.BlockForever)
    if err != nil {
        log.Fatal(err)
    }
    defer handle.Close()

    filter := &amp;quot;tcp&amp;quot;
    if err := handle.SetBPFFilter(filter); err != nil {
        log.Fatal(err)
    }

    packetSource := gopacket.NewPacketSource(handle, handle.LinkType())

    sigChan := make(chan os.Signal, 1)
    signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)

    fmt.Println(&amp;quot;Starting packet capture...&amp;quot;)
    for {
        select {
        case packet := &amp;lt;-packetSource.Packets():
            // 检查数据包是否是HTTP请求
            if appLayer := packet.ApplicationLayer(); appLayer != nil {
                payload := appLayer.Payload()
                if bytesContain(payload, []byte(&amp;quot;HTTP&amp;quot;)) {
                    // 解析HTTP请求的Header
                    headers := parseHTTPHeaders(payload)
                    fmt.Println(&amp;quot;=== HTTP Request Headers ===&amp;quot;)
                    for name, value := range headers {
                        fmt.Printf(&amp;quot;%s : %s\n&amp;quot;, name, value)
                    }
                    fmt.Println(&amp;quot;=============================&amp;quot;)
                }
            }
        case &amp;lt;-sigChan:
            fmt.Println(&amp;quot;Stopping packet capture...&amp;quot;)
            return
        }
    }
}

func bytesContain(source, target []byte) bool {
    for i := 0; i &amp;lt;= len(source)-len(target); i++ {
        if bytesEqual(source[i:i+len(target)], target) {
            return true
        }
    }
    return false
}

func bytesEqual(a, b []byte) bool {
    if len(a) != len(b) {
        return false
    }
    for i, v := range a {
        if v != b[i] {
            return false
        }
    }
    return true
}

func parseHTTPHeaders(payload []byte) map[string]string {
    headers := make(map[string]string)
    lines := strings.Split(string(payload), &amp;quot;\r\n&amp;quot;)
    for _, line := range lines {
        parts := strings.SplitN(line, &amp;quot;: &amp;quot;, 2)
        if len(parts) == 2 {
            headers[parts[0]] = parts[1]
        }
    }
    return headers
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;该实现放在调用pcap.OpenLive的时候传入了any表示所有的网卡流量都采集，并且在fillter只选择TCP，也就最后是HTTP的流量。&lt;/p&gt;
&lt;h2 id=&quot;h2-2-python-scapy-&quot;&gt;&lt;a name=&quot;2、Python Scapy实现&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;2、Python Scapy实现&lt;/h2&gt;&lt;h3 id=&quot;h3-2-1-&quot;&gt;&lt;a name=&quot;2.1、实现方式一&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;2.1、实现方式一&lt;/h3&gt;&lt;p&gt;该实现方式可以让用户准确配置，采集的端口和网卡&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# -*- coding: utf-8 -*-
# @Time    : 2023/8/11 10:17
# @Author  : UzJu
# @Site    : UzzJu.com
# @File    : py_snniffer.py
# @Software: PyCharm 
# @Comment : :)
# ! /usr/bin/env python3
from scapy.all import *


def http_header(packet):
    http_packet = str(packet)
    if &amp;quot;GET&amp;quot; in http_packet:
        return GET_print(packet)


def GET_print(packet1):
    ret = &amp;quot;***************************************GET PACKET****************************************************\n&amp;quot;
    ret += &amp;quot;\n&amp;quot;.join(packet1.sprintf(&amp;quot;{Raw:%Raw.load%}\n&amp;quot;).split(r&amp;quot;\r\n&amp;quot;))
    ret += &amp;quot;*****************************************************************************************************&amp;quot;
    print(ret)


def main():
    sniff(iface=&amp;quot;en0&amp;quot;, prn=http_header, filter=&amp;quot;tcp port 6234&amp;quot;)


if __name__ == &amp;#39;__main__&amp;#39;:
    main()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202308111102156.png&quot; alt=&quot;image-20230811110205083&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;h3-2-2-&quot;&gt;&lt;a name=&quot;2.2、实现方式二&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;2.2、实现方式二&lt;/h3&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;from scapy.all import *


def process_packet(packet):
    if packet.haslayer(TCP) and packet.haslayer(Raw):
        payload = packet[Raw].load.decode(&amp;#39;utf-8&amp;#39;, errors=&amp;#39;ignore&amp;#39;)
        if &amp;#39;HTTP&amp;#39; in payload:
            http_headers = payload.split(&amp;#39;\r\n\r\n&amp;#39;)[0].split(&amp;#39;\r\n&amp;#39;)[1:]
            print(&amp;quot;=== HTTP Request Headers ===&amp;quot;)
            for header in http_headers:
                print(header)


def main():
    sniff(filter=&amp;#39;tcp&amp;#39;, prn=process_packet, store=0)


if __name__ == &amp;quot;__main__&amp;quot;:
    main()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这种实现方式，只采集HTTP流量，并且输出，也就意味着会无差别的采集服务器上所有端口的HTTP流量(不包含HTTPS)。&lt;/p&gt;
&lt;p&gt;相较于实现方式一的好处是用户无需配置，安装agent即可。&lt;/p&gt;
&lt;h2 id=&quot;h2-3-&quot;&gt;&lt;a name=&quot;3、具体实现&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;3、具体实现&lt;/h2&gt;&lt;pre&gt;&lt;code class=&quot;language-go&quot;&gt;package main

import (
    &amp;quot;encoding/json&amp;quot;
    &amp;quot;fmt&amp;quot;
    &amp;quot;log&amp;quot;
    &amp;quot;os&amp;quot;
    &amp;quot;os/signal&amp;quot;
    &amp;quot;strings&amp;quot;
    &amp;quot;syscall&amp;quot;

    &amp;quot;github.com/google/gopacket&amp;quot;
    &amp;quot;github.com/google/gopacket/pcap&amp;quot;
)

type RequestHttpHeaders struct {
    Method  string
    URL     string
    Headers map[string]string
    Body    string
}

type ResponseHttpHeaders struct {
    Headers map[string]string
    Body    string
}

type HTTPRequestResponse struct {
    Request  HTTPHeaders `json:&amp;quot;request&amp;quot;`
    Response HTTPHeaders `json:&amp;quot;response&amp;quot;`
}

type HTTPHeaders struct {
    Method    string            `json:&amp;quot;method&amp;quot;`
    URL       string            `json:&amp;quot;url&amp;quot;`
    Headers   map[string]string `json:&amp;quot;headers&amp;quot;`
    Body      string            `json:&amp;quot;body&amp;quot;`
    IsRequest bool              `json:&amp;quot;-&amp;quot;`
}

func main() {
    handle, err := pcap.OpenLive(&amp;quot;any&amp;quot;, 65535, true, pcap.BlockForever)
    if err != nil {
        log.Fatal(err)
    }
    defer handle.Close()

    filter := &amp;quot;tcp&amp;quot;
    if err := handle.SetBPFFilter(filter); err != nil {
        log.Fatal(err)
    }

    packetSource := gopacket.NewPacketSource(handle, handle.LinkType())

    sigChan := make(chan os.Signal, 1)
    signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)

    var requestsResponses []HTTPRequestResponse

    fmt.Println(&amp;quot;Starting packet capture...&amp;quot;)
    for {
        select {
        case packet := &amp;lt;-packetSource.Packets():
            if appLayer := packet.ApplicationLayer(); appLayer != nil {
                payload := appLayer.Payload()
                if bytesContain(payload, []byte(&amp;quot;HTTP&amp;quot;)) {
                    headers, body := parseHTTPHeaderAndBody(payload)
                    isRequest := strings.Contains(string(payload), &amp;quot;GET&amp;quot;) || strings.Contains(string(payload), &amp;quot;POST&amp;quot;)

                    httpHeaders := HTTPHeaders{
                        Method:    getRequestMethod(payload),
                        URL:       getRequestURL(payload),
                        Headers:   headers,
                        Body:      body,
                        IsRequest: isRequest,
                    }

                    if isRequest {
                        requestsResponses = append(requestsResponses, HTTPRequestResponse{
                            Request:  httpHeaders,
                            Response: HTTPHeaders{},
                        })
                    } else {
                        lastIdx := len(requestsResponses) - 1
                        if lastIdx &amp;gt;= 0 {
                            requestsResponses[lastIdx].Response = httpHeaders
                        }
                    }
                }
            }
        case &amp;lt;-sigChan:
            fmt.Println(&amp;quot;Stopping packet capture...&amp;quot;)

            data, err := json.MarshalIndent(requestsResponses, &amp;quot;&amp;quot;, &amp;quot;  &amp;quot;)
            if err != nil {
                log.Fatal(err)
            }
            if err := os.WriteFile(&amp;quot;requests_responses.json&amp;quot;, data, 0644); err != nil {
                log.Fatal(err)
            }

            return
        }
    }
}

func bytesContain(source, target []byte) bool {
    for i := 0; i &amp;lt;= len(source)-len(target); i++ {
        if bytesEqual(source[i:i+len(target)], target) {
            return true
        }
    }
    return false
}

func bytesEqual(a, b []byte) bool {
    if len(a) != len(b) {
        return false
    }
    for i, v := range a {
        if v != b[i] {
            return false
        }
    }
    return true
}

func parseHTTPHeaderAndBody(payload []byte) (map[string]string, string) {
    headers := make(map[string]string)
    lines := strings.Split(string(payload), &amp;quot;\r\n&amp;quot;)
    var body string
    for i, line := range lines {
        if line == &amp;quot;&amp;quot; {
            body = strings.Join(lines[i+1:], &amp;quot;\r\n&amp;quot;)
            break
        }
        parts := strings.SplitN(line, &amp;quot;: &amp;quot;, 2)
        if len(parts) == 2 {
            headers[parts[0]] = parts[1]
            if parts[0] == &amp;quot;Host&amp;quot; &amp;amp;&amp;amp; strings.HasPrefix(parts[1], &amp;quot;http&amp;quot;) {
                headers[&amp;quot;Method&amp;quot;] = strings.Fields(lines[i+1])[0]
                headers[&amp;quot;URL&amp;quot;] = parts[1]
            }
        }
    }
    return headers, body
}
func getRequestMethod(payload []byte) string {
    lines := strings.Split(string(payload), &amp;quot;\r\n&amp;quot;)
    parts := strings.Fields(lines[0])
    if len(parts) &amp;gt; 0 {
        return parts[0]
    }
    return &amp;quot;&amp;quot;
}

func getRequestURL(payload []byte) string {
    lines := strings.Split(string(payload), &amp;quot;\r\n&amp;quot;)
    parts := strings.Fields(lines[0])
    if len(parts) &amp;gt; 1 {
        return parts[1]
    }
    return &amp;quot;&amp;quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上述代码主要功能，通过采集所有网卡(any)，最大65535字节大小的HTTP GET/POST请求，并给到结构体，最后输出到JSON文件中。&lt;/p&gt;
&lt;p&gt;采集的数据如下&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/test_file/requests_responses.json&quot;&gt;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/test_file/requests_responses.json&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202308141630042.png&quot; alt=&quot;image-20230814163015998&quot;&gt;&lt;/p&gt;
&lt;p&gt;从上面的流程中已经拿到了完整的HTTP请求，只需要传输到接口上，下面用flask简单实现一个接口&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;from flask import Flask, request

app = Flask(__name__)


@app.route(&amp;#39;/receive&amp;#39;, methods=[&amp;#39;POST&amp;#39;])
def receive_json():
    json_data = request.json
    print(&amp;quot;Received JSON Data:&amp;quot;)
    print(json_data)
    return &amp;#39;JSON data received&amp;#39;


if __name__ == &amp;#39;__main__&amp;#39;:
    app.run(host=&amp;#39;0.0.0.0&amp;#39;, port=8888)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;获取JSON数据即可。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202308151042038.png&quot; alt=&quot;image-20230815104237937&quot;&gt;&lt;/p&gt;
&lt;p&gt;主要思路&lt;/p&gt;
&lt;p&gt;1、采集HTTP请求&lt;/p&gt;
&lt;p&gt;2、传输至服务端进行解析&lt;/p&gt;
&lt;p&gt;3、替换鉴权字段重新请求&lt;/p&gt;
&lt;p&gt;4、判断是否存在越权漏洞。&lt;/p&gt;
&lt;h2 id=&quot;h2-4-&quot;&gt;&lt;a name=&quot;4、上述方案的缺点&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;4、上述方案的缺点&lt;/h2&gt;&lt;p&gt;1、无法采集HTTPS流量。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;https解决方案&lt;ul&gt;
&lt;li&gt;ebpf&lt;/li&gt;&lt;li&gt;代理装证书&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;2、gopacket无法采集到响应&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202308141521090.png&quot; alt=&quot;image-20230814152133018&quot;&gt;&lt;/p&gt;
&lt;p&gt;在测试中发现gopacket的嗅探采集是类似异步，不太好将request和response一一对应。&lt;/p&gt;
</description><pubDate>Fri, 13 Oct 2023 14:06:01 +0800</pubDate></item><item><title>洞态IAST检测优化：Fel表达式注入</title><link>https://uzzju.com/post/82.html</link><description>&lt;h1 id=&quot;h1--&quot;&gt;&lt;a name=&quot;一、简介&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;一、简介&lt;/h1&gt;&lt;p&gt;　Fel是开放的，引擎执行中的多个模块都可以扩展或替换。Fel的执行主要是通过函数实现,运算符(+、-等都是Fel函数），所有这些函数都是可以替换的，扩展函数也非常简单。&lt;/p&gt;
&lt;p&gt;   Fel有双引擎，同时支持解释执行和编译执行。可以根据性能要求选择执行方式。编译执行就是将表达式编译成字节码（生成java代码和编译模块都是可以扩展和替换的）&lt;/p&gt;
&lt;p&gt;　FEL可以进行算数运算以及逻辑运算，也可以调用类的静态方法、非静态方法。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;pom.xml&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.eweb4j&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;fel&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;0.8&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;老古董：&lt;a href=&quot;https://github.com/dbcxy/fast-el/tree/master&quot;&gt;https://github.com/dbcxy/fast-el/tree/master&lt;/a&gt;&lt;br&gt;Google Code：&lt;a href=&quot;https://code.google.com/archive/p/fast-el/&quot;&gt;https://code.google.com/archive/p/fast-el/&lt;/a&gt;&lt;br&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202310091502554.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h1 id=&quot;h1--&quot;&gt;&lt;a name=&quot;二、友商测试&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;二、友商测试&lt;/h1&gt;&lt;h2 id=&quot;h2-1-&quot;&gt;&lt;a name=&quot;1、默安-无法检测&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;1、默安-无法检测&lt;/h2&gt;&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202310091454812.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h1 id=&quot;h1--iast&quot;&gt;&lt;a name=&quot;三、洞态IAST&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;三、洞态IAST&lt;/h1&gt;&lt;h2 id=&quot;h2-1-&quot;&gt;&lt;a name=&quot;1、描述&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;1、描述&lt;/h2&gt;&lt;p&gt;el在源自于企业项目，设计目标是为了满足不断变化的功能需求和性能需求。&lt;br&gt;Fel是开放的，引擎执行中的多个模块都可以扩展或替换。Fel的执行主要是通过函数实现,运算符(+、-等都是Fel函数），所有这些函数都是可以替换的，扩展函数也非常简单。&lt;br&gt;Fel可以执行表达式，如果此时Fel执行的表达式外部可控，则可能导致安全风险。&lt;/p&gt;
&lt;h2 id=&quot;h2-2-&quot;&gt;&lt;a name=&quot;2、检测规则&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;2、检测规则&lt;/h2&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;com.greenpineyu.fel.parser.AntlrParser.parse(java.lang.String)
参数-P1
深度-当前类以及子类&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202310091525223.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202310091526271.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;h2-3-&quot;&gt;&lt;a name=&quot;3、修复方案&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;3、修复方案&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;官方没有提供标准的修复方案，但是在commit中找到了所谓的安全管理器的实现，文档中也提示需要在保证安全的情况下可使用&lt;br&gt;&lt;a href=&quot;https://github.com/dbcxy/fast-el/commit/ac0d5bdb95b5c5d52fe5df5a8b254e5e8ddd8a38&quot;&gt;https://github.com/dbcxy/fast-el/commit/ac0d5bdb95b5c5d52fe5df5a8b254e5e8ddd8a38&lt;/a&gt;&lt;br&gt;1、使用官方提供的安全管理器&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/dbcxy/fast-el/commit/ac0d5bdb95b5c5d52fe5df5a8b254e5e8ddd8a38&quot;&gt;https://github.com/dbcxy/fast-el/commit/ac0d5bdb95b5c5d52fe5df5a8b254e5e8ddd8a38&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://code.google.com/archive/p/fast-el/&quot;&gt;https://code.google.com/archive/p/fast-el/&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;/blockquote&gt;
</description><pubDate>Fri, 13 Oct 2023 14:01:35 +0800</pubDate></item><item><title>洞态IAST检测优化：阿里QLExpress组件表达式注入</title><link>https://uzzju.com/post/81.html</link><description>&lt;p&gt;1&lt;/p&gt;
</description><pubDate>Fri, 13 Oct 2023 14:00:55 +0800</pubDate></item><item><title>MacOS下高效记录会议纪要以及实时音频转文字解决方案</title><link>https://uzzju.com/post/80.html</link><description>&lt;h1 id=&quot;h1--&quot;&gt;&lt;a name=&quot;一、前言&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;一、前言&lt;/h1&gt;&lt;p&gt;&lt;strong&gt;本文解决了1个问题&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;1、如何同时带着耳机，并且能够音频识别电脑播放/会议声音转文字，还能够接收麦克风。&lt;/p&gt;
&lt;p&gt;首先为什么会有这样一篇文章，其实大家不管是甲方还是乙方，特别是甲方，大部分时间其实都是被各种会议占满，需求评审，安全评估，安全培训等等等，那么乙方，更多的是与客户开会，或与甲方一样，公司内部开会，那么此时少不了的是会议纪要，可能有些会议比较枯燥，根本不会有人认真去听，但作为打工人来说 :)!&lt;/p&gt;
&lt;p&gt;领导：小高啊，那个会议纪要你整理一下然后发给我/客户&lt;/p&gt;
&lt;p&gt;我目前基本一周的会议特别多，不管是内部会议，还是外部会议，这时候就会有一个痛点，会议纪要怎么处理？&lt;br&gt;如果是旁听状态下还好，可以边听边记。&lt;br&gt;那么如果是主讲人呢？针对会上的问题，会上的内容无法汇总，也无法记录。&lt;/p&gt;
&lt;p&gt;当然目前针对腾讯会议，飞书会议等会议办公软件，其实都提供这样的解决方案，会议录制可直接转换成文字，但这相对来说比较繁琐。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;内部会议还好，外部会议总开个录屏，给人感觉不是特别好:)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;那么有没有一款软件，可以让我在开会时，自动帮我记录会议内容？&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;华为MetaBook X Pro 就解决这样的问题，但是华为独占，做的也非常好，遥遥领先！&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;尊贵的水果用户能否拥有这样的体验？&lt;/p&gt;
&lt;p&gt;本文会带来作为个人用户的解决方案（本文以水果人用户角度出发）&lt;/p&gt;
&lt;h1 id=&quot;h1--&quot;&gt;&lt;a name=&quot;二、前期调研与产品体验&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;二、前期调研与产品体验&lt;/h1&gt;&lt;p&gt;产品试用体验上，目前体验了以下几款产品&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;产品名&lt;/th&gt;
&lt;th&gt;下载地址&lt;/th&gt;
&lt;th&gt;产品形态&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Noted&lt;/td&gt;
&lt;td&gt;MACOS APP Store&lt;/td&gt;
&lt;td&gt;客户端/多形态&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;语音备忘录日记本&lt;/td&gt;
&lt;td&gt;MACOS APP Store&lt;/td&gt;
&lt;td&gt;客户端&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;讯飞听见&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://huiji.iflyrec.com/&quot;&gt;在线录音转文字-录音整理-录音转写工具-讯飞听见会记 (iflyrec.com)&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;客户端/多形态&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;通义听悟（阿里）&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://tingwu.aliyun.com/&quot;&gt;通义听悟 - 你的工作学习AI助手 (aliyun.com)&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;浏览器/浏览器插件&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;先说实际体验&lt;/p&gt;
&lt;h2 id=&quot;h2-1-noted&quot;&gt;&lt;a name=&quot;1、Noted&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;1、Noted&lt;/h2&gt;&lt;p&gt;总体感觉比较轻量化，并且没有账号体系，macos原生使用Icloud进行同步&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202306270115079.png&quot; alt=&quot;image-20230627005250476&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202306270115969.png&quot; alt=&quot;image-20230627005308039&quot;&gt;&lt;/p&gt;
&lt;p&gt;付费，价格如下图&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202306270115546.png&quot; alt=&quot;image-20230627005516656&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;h3-1-1-&quot;&gt;&lt;a name=&quot;1.1、优点&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;1.1、优点&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;轻量化&lt;/li&gt;&lt;li&gt;编写&lt;/li&gt;&lt;li&gt;简单易用&lt;/li&gt;&lt;/ul&gt;
&lt;h3 id=&quot;h3-1-2-&quot;&gt;&lt;a name=&quot;1.2、缺点&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;1.2、缺点&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;语音转文字并不是特别准&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;见下图&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202306270116958.png&quot; alt=&quot;image-20230627005830726&quot;&gt;&lt;/p&gt;
&lt;p&gt;这是来自我在一场面试时记录的内容，这里是求职者在介绍学校，但可以发现，错别字非常严重，另外完整记录下来，可读性基本为0。&lt;/p&gt;
&lt;h2 id=&quot;h2-2-&quot;&gt;&lt;a name=&quot;2、通义听悟（阿里）&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;2、通义听悟（阿里）&lt;/h2&gt;&lt;p&gt;由于没有客户端，所以跳过&lt;/p&gt;
&lt;h2 id=&quot;h2-3-&quot;&gt;&lt;a name=&quot;3、讯飞听见&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;3、讯飞听见&lt;/h2&gt;&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202306270116961.png&quot; alt=&quot;image-20230627005923027&quot;&gt;&lt;/p&gt;
&lt;p&gt;科大讯飞目前是体验下来针对会议纪要最好的一个产品，毕竟做语音识别这么多年的大厂了。&lt;/p&gt;
&lt;p&gt;来看看语音识别的能力&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202306270116610.png&quot; alt=&quot;image-20230627010408520&quot;&gt;&lt;/p&gt;
&lt;p&gt;总体来说，转文字的识别率还是很高的，并且准确率也还行。&lt;/p&gt;
&lt;p&gt;实际会议使用上发现也不错&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202306270116325.png&quot; alt=&quot;image-20230627010530917&quot;&gt;&lt;/p&gt;
&lt;p&gt;缺点呢就是，加钱！&lt;/p&gt;
&lt;h2 id=&quot;h2-4-&quot;&gt;&lt;a name=&quot;4、总结&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;4、总结&lt;/h2&gt;&lt;p&gt;目前会继续体验《讯飞听见》和《Noted》这两款产品，想看看一款好的产品能做到什么程度。&lt;/p&gt;
&lt;p&gt;当然，一款好的产品，能够解决用户的痛点，帮助提升效率等，我觉得是值得付费的。&lt;/p&gt;
&lt;p&gt;今年也是大大小小购买了很多正版的产品，比如Macos下的超级右键，自动切换输入法等，虽然这些产品都有公开的破解版可供下载，但如果在允许的条件下，也可以对开发者进行支持。&lt;/p&gt;
&lt;h2 id=&quot;h2-5-&quot;&gt;&lt;a name=&quot;5、遇到的问题&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;5、遇到的问题&lt;/h2&gt;&lt;p&gt;其实在体验的过程中发现1个很严重的问题，如果不带耳机的情况下，外放进行电脑声音以及麦克风转文字的方案是可行的，但是如果使用耳机，那么常规的方案就不行了，至少我在macos的尝试下以及，阿里的听悟，科大讯飞，都没有见到能解决这个场景的，这也是本文带来的解决方案。&lt;/p&gt;
&lt;p&gt;场景举例&lt;/p&gt;
&lt;p&gt;1、现在需要使用腾讯会议开会，带着耳机&lt;/p&gt;
&lt;p&gt;需要实现的内容&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;戴耳机的情况下需要能够识别电脑腾讯会议音频输出并且转文字&lt;/li&gt;&lt;li&gt;戴耳机的情况下能够接受耳机的麦克风音频输入并且转文字&lt;/li&gt;&lt;/ul&gt;
&lt;h1 id=&quot;h1--&quot;&gt;&lt;a name=&quot;三、如何在使用耳机的情况下同时录制电脑的声音以及耳机的麦克风&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;三、如何在使用耳机的情况下同时录制电脑的声音以及耳机的麦克风&lt;/h1&gt;&lt;h2 id=&quot;h2-1-loopback&quot;&gt;&lt;a name=&quot;1、LoopBack&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;1、LoopBack&lt;/h2&gt;&lt;p&gt;这个问题的解决方案是使用LoopBack创建一个虚拟的音频设备，来解决该问题。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202306270116861.png&quot; alt=&quot;image-20230627011057975&quot;&gt;&lt;/p&gt;
&lt;p&gt;再安装完成后Macos下会多出一个虚拟的音频驱动，打开LoopBack开始配置&lt;/p&gt;
&lt;h2 id=&quot;h2-2-loopback-&quot;&gt;&lt;a name=&quot;2、LoopBack配置&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;2、LoopBack配置&lt;/h2&gt;&lt;p&gt;点击下方的&lt;code&gt;New Virtual Device&lt;/code&gt;来新建一个设备&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202306270116523.png&quot; alt=&quot;image-20230627011213155&quot;&gt;&lt;/p&gt;
&lt;p&gt;配置如下&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202306270116060.png&quot; alt=&quot;image-20230627011142056&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sources&lt;/code&gt;默认即可，再&lt;code&gt;output&lt;/code&gt;中新增一个输出，监听中新增并选择耳机，我这里是AirPods Pro，所以选择自己的耳机名字。&lt;/p&gt;
&lt;p&gt;随后在讯飞听见配置如下&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202306270116115.png&quot; alt=&quot;image-20230627011449964&quot;&gt;&lt;/p&gt;
&lt;p&gt;这样配置后的效果&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;能够同时将电脑的音频输出与耳机的麦克风同时音频转文字，解决了上述的痛点。&lt;/li&gt;&lt;/ul&gt;
&lt;h2 id=&quot;h2-3-&quot;&gt;&lt;a name=&quot;3、最终效果&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;3、最终效果&lt;/h2&gt;&lt;p&gt;录制电脑音频&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202306270116953.png&quot; alt=&quot;image-20230627011511871&quot;&gt;&lt;/p&gt;
&lt;p&gt;耳机语音输入&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/img/202306270116886.png&quot; alt=&quot;image-20230627011537526&quot;&gt;&lt;/p&gt;
</description><pubDate>Tue, 27 Jun 2023 11:19:57 +0800</pubDate></item><item><title> Windows11 LogonUI.exe 系统在应用程序中检测到基于堆栈都缓冲区溢出，溢出允许恶意用户获得此应用程序都控制。</title><link>https://uzzju.com/post/79.html</link><description>&lt;h1 id=&quot;h1-u95EEu9898&quot;&gt;&lt;a name=&quot;问题&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;问题&lt;/h1&gt;&lt;p&gt;LogonUI.exe系统错误&lt;/p&gt;
&lt;p&gt;系统在应用程序中检测到基于堆栈都缓冲区溢出，溢出允许恶意用户获得此应用程序都控制。&lt;/p&gt;
&lt;p&gt;事情线：2023年6月3日一整天直至次日凌晨2点，我都不在家，次日凌晨2点（6月4日）回到家中发现一直运行中都电脑出现这个提示。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/UzJuMarkDownImage202306041357775.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;描述：&lt;code&gt;LogonUI.exe&lt;/code&gt; 是 Windows 操作系统中的一个关键组件，它用于管理登录过程中显示的用户界面。”LogonUI” 实际上是 “Login User Interface” 的缩写，这就是它的主要职责：提供用户登录界面。&lt;/p&gt;
&lt;p&gt;当你启动 Windows 电脑时，&lt;code&gt;LogonUI.exe&lt;/code&gt; 将显示一个屏幕，让你输入用户名和密码或者选择一个用户账户进行登录。如果你的电脑设置了锁屏，那么在你退出锁屏并返回到 Windows 时，同样是 &lt;code&gt;LogonUI.exe&lt;/code&gt; 提供的用户界面让你输入密码。&lt;/p&gt;
&lt;p&gt;因此，如果 &lt;code&gt;LogonUI.exe&lt;/code&gt; 发生错误或者被破坏，用户可能无法正常登录到系统。在某些情况下，错误可能导致系统无法正常启动，或者在登录过程中出现问题。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Google尝试了很多方法都没什么用，推荐B站都文章：&lt;a href=&quot;https://www.bilibili.com/read/cv22299902&quot;&gt;https://www.bilibili.com/read/cv22299902&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&quot;h1-u89E3u51B3u529Eu6CD5&quot;&gt;&lt;a name=&quot;解决办法&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;解决办法&lt;/h1&gt;&lt;h2 id=&quot;h2-1-windows11-&quot;&gt;&lt;a name=&quot;1、进入Windows11 高级启动&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;1、进入Windows11 高级启动&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;注意：不要进PE，我自己做了一个大白菜PE，但是进PE无法操作这些东西，切没有SFC，总结就是不要进PE，没有用&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;开机后，进入Windows，弹出LogonUI.exe都报错后就长按电源，强制关机，反复3次左右，就会自动加载Windows高级启动&lt;/p&gt;
&lt;h2 id=&quot;h2-2-&quot;&gt;&lt;a name=&quot;2、修复&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;2、修复&lt;/h2&gt;&lt;p&gt;在高级模式中打开CMD终端，输入下面都命令&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;sfc /scannow &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;此时会自动修复&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/UzJuMarkDownImage202306041403494.png&quot; alt=&quot;image-20230604140355461&quot;&gt;&lt;/p&gt;
&lt;p&gt;随后重启会自动进入Windows安全模式，然后Windows的窗口桌面一直都是无响应，鼠标无法点击，不用管，直接WIN+R打开CMD。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/UzJuMarkDownImage202306041404424.png&quot; alt=&quot;image-20230604140459392&quot;&gt;&lt;/p&gt;
&lt;p&gt;然后再重启，就修复完毕了，就能自动进入系统&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://uzjumakdown-1256190082.cos.ap-guangzhou.myqcloud.com/UzJuMarkDownImage202306041406132.png&quot; alt=&quot;image-20230604140652078&quot;&gt;&lt;/p&gt;
</description><pubDate>Sun, 04 Jun 2023 14:11:11 +0800</pubDate></item></channel></rss>