PratikKaran23/aem-hunter

GitHub: PratikKaran23/aem-hunter

一款针对 Adobe Experience Manager 的单文件未授权安全审计扫描器,覆盖 Dispatcher 绕过、暴露控制台、CVE 检测等数十类漏洞,通过功能验证有效降低误报率。

Stars: 0 | Forks: 1

# AEM Hunter — 未授权 AEM 安全扫描器 单文件 Adobe Experience Manager (AEM) 审计扫描器。只需指定一个 URL, 它就会深入运行所有已知的 AEM 漏洞检测 —— 无需身份验证,无需 cookie,也没有角色概念。输出结果为控制台 + HTML + JSON 报告。 ## 安装说明 ``` git clone https://github.com/PratikKaran23/aem-hunter.git cd aem-hunter pip install -r requirements.txt ``` 单一依赖:`requests`。`httpx[http2]` 是可选的(用于仅支持 HTTP/2 的 目标 —— 见下文)。 ## 使用方法 ``` python3 aem_hunter.py # prompts for URL python3 aem_hunter.py https://aem.example.com python3 aem_hunter.py -u https://aem.example.com python3 aem_hunter.py -u TARGET --proxy http://127.0.0.1:8080 python3 aem_hunter.py -u TARGET --aggressive # bigger dispatcher fuzz python3 aem_hunter.py -u TARGET --http2 # HTTP/2-only targets python3 aem_hunter.py -u TARGET --exploit # end-to-end JSP-RCE PoC ``` 每次运行都会将 `report--unauthenticated-.{json,html}` 写入 当前目录(使用 `-o` 可覆盖此设置)。 ### 仅支持 HTTP/2 的目标 许多企业级 AEM 部署位于 **仅支持 HTTP/2** 的 CDN/WAF/LB 之后。Python `requests` 仅支持 HTTP/1.1,因此直接扫描会因 `UnknownProtocol('HTTP/2')` 而终止,导致所有请求失败。有两个选项: - **通过 Burp/mitmproxy** (`--proxy ...`) —— 代理会将 HTTP/2 降级为 HTTP/1.1,因此默认后端可以直接工作。 - **原生 HTTP/2** —— 无需代理: pip install 'httpx[http2]' python3 aem_hunter.py -u https://aem.example.com --http2 该工具会在预检时检测到 HTTP/2 错误,并提示您该使用哪种修复方法。 ### 所有标志参数 | 标志 | 用途 | | -------------------------- | ------------------------------------------------------------------------ | | `target` / `-u` | 目标 URL(位置参数或 `-u`;如果不存在则提示输入) | | `--proxy` | 通过代理路由(例如 Burp) | | `--http2` | 原生 HTTP/2 后端(需要 `httpx[http2]`) | | `-o, --output-dir` | 报告输出位置(默认:当前目录) | | `--aggressive` | 扩展的 dispatcher-bypass / Sling-selector payload 集(请求数约增加 10 倍) | | `--exploit` | 端到端 JSP RCE PoC + 反序列化探测(部署并移除金丝雀文件) | | `--collaborator DOMAIN` | 通过 Burp Collaborator 实现的带外 SSRF | | `--ssrf-callback HOST:PORT`| 自建 OOB SSRF 监听器(需要测试人员可访问的 IP) | | `-v, --verbose` | 详细的请求日志记录 | TLS 验证始终关闭(渗透测试默认设置)。 ## 测试内容 以下每一项检测均在 **未授权** 状态下运行: | 类别 | 覆盖范围 | | ---------------------- | ------------------------------------------------------------------------------------------------- | | 指纹识别 | 实例类型(Author 与 Publish)、版本提示、Sling / Day / CQ headers | | 默认凭据 | `admin`、`author`、`anonymous`、`replication-receiver`、Geometrixx 演示用户、`vgnadmin`、`audit`、`grios` 等 | | 暴露的控制台 | Felix `/system/console/*`(bundles、components、services、configMgr、scr、JMX、threads、memoryusage、profiler、logs、healthcheck、events、slingauth、jcrresolver、depfinder、status-*)、CRX DE、CRX Package Manager、CRX Explorer、Groovy Console、WebDAV、miscadmin、BulkEditor、Granite operations 控制台(maintenance、healthreports、replicationqueue、systemoverview、diagnosistools) | | QueryBuilder | `/bin/querybuilder.json` 暴露、feed.xml、selector bypass、**`p.hits=selective&p.properties=rep:password` 哈希转储**、跨类型 rep:User 枚举 | | Dispatcher bypass | `.css`/`.js`/`.png`/`.html` selector 技巧、`;` 分号滥用、`..;/` Jetty 规范化、`%2f`/`%00`/`%0a` 特性、双斜杠、URL 编码技巧、traversal+suffix 组合(通过 `--aggressive` 获取完整集合) | | Sling 信息转储 | 在 `/`、`/content`、`/etc`、`/apps`、`/libs`、`/var`、`/home`、`/tmp`、`/conf` 以及许多子路径上的 `.json`、`.1.json`、`.tidy.json`、`.infinity.json`、`.harray.4.json`、`.children.json`、`.feed.xml` | | JCR 枚举 | `users.1.json`、`groups.1.json`、`currentuser.json`、infinity 转储、authorizables servlet | | 云服务泄露 | `/etc/cloudservices.infinity.json` — AWS / Salesforce / 第三方凭据泄露 | | Crypto key 泄露 | `/etc/key.infinity.json` 主密钥(允许您离线解密 `{...}` 加密的机密) | | 匿名用户创建 | `:operation=createUser` POST 到 `/libs/granite/security/post/authorizables` | | SSRF(URL 确认) | linkchecker、SalesforceSecretServlet (CVE-2018-5006)、ReportingServicesServlet (CVE-2018-12809)、DAM cloud proxy、OpenSocial proxy、SiteCatalyst、AutoProvisioning、Google OAuth fetcher | | SSRF(带外) | 通过 Burp Collaborator (`--collaborator`) 或自建监听器 (`--ssrf-callback`) 的相同集合 | | **2025 CVEs** | CVE-2025-54253 (OGNL RCE Forms JEE)、CVE-2025-54254 (XXE)、CVE-2025-49533 (反序列化) | | **2024 CVEs** | CVE-2024-43712、CVE-2024-43711、CVE-2024-32813、CVE-2024-32812、CVE-2024-32811、CVE-2024-26031、CVE-2024-26030、CVE-2024-20767 (Forms 文件读取)、CVE-2024-20736 | | **2023 CVEs** | CVE-2023-22368、CVE-2023-22366、CVE-2023-22365 | | **2022 CVEs** | CVE-2022-30679、CVE-2022-30680、CVE-2022-23710 (SOAP XXE) | | **2021 CVEs** | CVE-2021-44519 (Forms 上传 XXE 基线)、CVE-2021-43762 (路径遍历) | | **2019 CVEs** | CVE-2019-8088、CVE-2019-8087、CVE-2019-8086 (Forms XSS) | | **2018 CVEs** | CVE-2018-5006、CVE-2018-12809、CVE-2018-19298、CVE-2018-19297 | | **2017 / 2016 CVEs** | CVE-2017-3104 (SSTI)、CVE-2016-7882 (WCMDebugFilter 反射型 XSS)、CVE-2016-1027 | | Sling POST 滥用 | 在 `/content/usergenerated`、`/var/dam` 创建任意节点、匿名用户创建 | | 复制 | `/etc/replication.infinity.json` 中的传输凭据 — 直接的横向移动原语 | | 源码泄露 | 在基于 JSP 的路径上的 `.source` / `.servlet` selector 技巧 | | 额外的 servlet 暴露 | GQLServlet、LoginStatusServlet(+ 默认凭据检查)、AuditLogServlet、CRXDE logs、Disk Usage、BackgroundServlet、MergeMetadata、dumplibs、nodetypes、ContentFinder suggestions | | 反射型 XSS | ChildrenList selector、CRXDE setPreferences、WCMDebugFilter、WCMSuggestionsServlet、CQ UI widgets、designs/default `0.gif`、标记为 CVE 的 XSS sinks、**暴露的 SWF 反射型 XSS** | | 开放重定向 | `resource=`、`redirect=`、`return=`、`next=`、登录 `resource=`、WCM 页面重定向(HTTP 30x + HTML/JS sinks) | | GraphQL | Endpoint 枚举 + introspection (`{__schema{types{...}}}`) | | WebDAV 方法 | `OPTIONS` 发现可写方法(PUT/DELETE/MKCOL/MOVE)、PROPFIND XXE | | ACS AEM Tools | AEM Fiddle JSP-eval RCE、ACS Tools 是否存在 | | 反序列化 | ExternalJobServlet Java 不受信任的反序列化探测 (`--exploit`) | | Nuclei 路径集 | 从 projectdiscovery/nuclei-templates AEM 集移植的约 45 项检测 + Cappricio aem-xss | servlet/XSS/SSRF 的大部分覆盖范围移植自 [0ang3el/aem-hacker](https://github.com/0ang3el/aem-hacker),并使用此工具的 身份验证绕过和报告功能重新实现。 ### 带外 SSRF — Burp Collaborator (`--collaborator`) AEM 连接器 servlet 中的盲 SSRF 通过带外方式进行确认。 推荐的方法是 **Burp Collaborator**: ``` python3 aem_hunter.py -u TARGET --proxy http://127.0.0.1:8080 --collaborator abc123.oastify.com ``` 它为每个 servlet(Salesforce / Reporting / SiteCatalyst / AutoProvisioning / Opensocial / linkchecker)触发一个子域。在 Collaborator 选项卡中如果出现对 `salesforcesecret.abc123.oastify.com` 的 DNS/HTTP 命中, 即可确认是通过 SalesforceSecretServlet (CVE-2018-5006) 等实现的 SSRF 等。(该工具无法替您轮询 Collaborator,因此它会报告已触发的探测以及用于归因的子域到 servlet 的 映射关系。) 或者,如果您有一个测试人员可访问的 IP(VPS/隧道,而不是通过 Burp), 请使用自建的自动确认监听器: ``` python3 aem_hunter.py -u TARGET --ssrf-callback 1.2.3.4:8000 ``` ### `--exploit` — 端到端 RCE PoC 默认情况下,提权模块会安全地确认原语(创建然后 立即删除一次性的测试制品)。使用 `--exploit`,它还会尝试 端到端的 JSP RCE PoC(通过 Sling POST servlet / package install / `sling:resourceType` 链部署并移除一个金丝雀 JSP)。该金丝雀仅会打印 `System.getProperty("user.name")` — 证明执行了 Java 代码而无需运行 OS 命令。仅在您被授权进行积极利用的系统上使用 `--exploit`。 ## 准确性 — 杜绝“shell 已加载 = 严重”的误报 AEM author 实例会将诸如 CRXDE、 Package Manager 和 Felix console 等控制台的 **HTML/JSP shell** 提供给*任何人*(HTTP 200),而实际的 功能仍处于登录状态。简单的扫描器会将该 200 标记为 CRITICAL — 这是一个误报。本工具不会这样做: - **登录/身份验证墙的响应会被抑制。** 一个实际上是登录 页面的 200 响应(`j_security_check`、`granite.shell.login`、`QUICKSTART`、登录表单、 身份验证重定向、401/403)永远不会被报告为可访问。 - **控制台是通过功能验证的,而不是通过其 shell。** CRITICAL 仅在 特权操作实际成功时才会触发 —— `bundles.json` 返回 实时的 OSGi 清单,package service 返回真实的 package 列表, 或者受保护的 JCR 节点返回真实的 `jcr:primaryType` JSON。如果仅渲染了 shell,您只会得到一条 **INFO** 提示,而不是 critical。 - **数据 Endpoint 必须返回真实的 JCR/JSON**,而不是空的 `{}` 或 HTML 页面,并且只有在响应体实际包含 类似机密的内容时,严重程度才会被提升。 因此,在一个被锁定的 author 实例上,您将主要看到 INFO —— 这是 最真实客观的结果。 ## 报告 每次运行都会生成: - 带有严重性标签的实时控制台输出 - `report--unauthenticated-.json` — 机器可读的发现 - `report--unauthenticated-.html` — 带有证据的样式化报告、 请求/响应片段、参考和 CVE 章 HTML 使用内联 CSS,因此它可以在没有 互联网访问的物理隔离机器上完美渲染。报告被 git-ignored 忽略,因此检测结果永远不会被提交。 ## 参考 基于以下公开研究构建: - 0ang3el/aem-hacker - Assetnote / hopgoblin - HackTricks AEM section - Mikhail Egorov, "Hacking AEM" (adaptTo 2018) - Adobe APSB advisories, CISA KEV (CVE-2025-54253) - Various HackerOne disclosures (#1247163, #436555, #698991, …) - projectdiscovery/nuclei-templates (http/misconfiguration/aem set) - Cappricio-Securities/aem-xss ## 许可证 MIT。请负责任地使用。
标签:AEM, CISA项目, Python, 无后门, 运行时操纵, 逆向工具