Icex0/OpenFirebase

GitHub: Icex0/OpenFirebase

一款专注于 Firebase 安全的自动化扫描工具,从 APK 中提取配置并检测 Realtime Database、Firestore、Storage 和 Remote Config 的未授权访问风险。

Stars: 45 | Forks: 2

OpenFirebase Logo
OpenFirebase
[![GitHub stars](https://img.shields.io/github/stars/Icex0/OpenFirebase?style=flat-square)](https://github.com/Icex0/OpenFirebase/stargazers) [![License](https://img.shields.io/github/license/Icex0/OpenFirebase?style=flat-square)](LICENSE) [![Python](https://img.shields.io/badge/Python-3.8+-blue?style=flat-square)](https://www.python.org) [![GitHub issues](https://img.shields.io/github/issues/Icex0/OpenFirebase?style=flat-square)](https://github.com/Icex0/OpenFirebase/issues) 自动化 Firebase 安全扫描器,从 APK 文件中提取 Firebase 配置,并对常见的 Firebase 服务(Realtime Database、Firestore、Storage、Remote Config)进行未经身份验证和/或经过身份验证的读取和/或写入扫描,支持所有已知的服务 URL 格式。检测意外嵌入的服务账号凭据,这些凭据可绕过安全规则获得管理员级别的访问权限。 支持多种输入方式,包括通过 JADX 反编译提取 APK、快速提取、单个或多个 Project ID。 [>> 更多信息请参阅我的博客:https://ice0.blog/docs/openfirebase <<](https://ice0.blog/docs/openfirebase)
## 环境要求 - Python 3.8+ - Java 11+(JADX 反编译和 apksigner 工具需要) ## 安装说明 ### 步骤 1:安装 Java JADX 反编译(默认模式)和 apksigner 需要 Java。 #### macOS ``` # 使用 Homebrew(推荐) brew install openjdk echo 'export PATH="/opt/homebrew/opt/openjdk/bin:$PATH"' >> ~/.zshrc source ~/.zshrc ``` #### Linux (Ubuntu/Debian) ``` # 使用 package manager sudo apt update sudo apt install default-jre ``` #### Windows ``` # 使用 Chocolatey(如已安装) choco install openjdk # 或从以下地址下载并安装: # https://www.oracle.com/java/technologies/downloads/ ``` **验证 Java 安装:** ``` java -version ``` ### 步骤 2:安装 OpenFirebase #### 推荐方式:使用 pipx ``` # 如果没有 pipx,请先安装 python -m pip install --user pipx python -m pipx ensurepath # 通过 cloning repository 安装 git clone https://github.com/Icex0/OpenFirebase.git cd OpenFirebase pipx install . ``` #### 默认字典和 Payload OpenFirebase 包含内置的 Firestore 集合字典和用于写入测试的示例 payload。必须在命令行参数中明确指定这些文件。您也可以随意使用自己的文件: - 使用 `--fuzz-collections openfirebase/wordlist/firestore-collections.txt` 进行集合模糊测试 - 使用 `--write-rtdb-file openfirebase/payloads/openfirebase.json` 进行 RTDB 写入测试 - 使用 `--write-storage-file openfirebase/payloads/openfirebase_storage_write_check.txt` 进行 Storage 写入测试 ## 工作原理
JADX 反编译(默认) OpenFirebase 默认使用 JADX 反编译进行源代码分析。此 *使用 JADX 反编译 APK* 阶段可能需要一段时间,具体取决于 APK 和您的系统(尤其是在资源有限的虚拟机上): - **自动安装**:如果未找到 JADX,OpenFirebase 将自动下载并安装 JADX。 - **快速替代方案**:使用 `--fast-extract` 跳过 JADX 反编译,并从所有 `/res/values-*` 目录(包括特定于语言环境的变体)中提取字符串资源 - **为什么使用 JADX?**:JADX 反编译通过搜索实际源代码、检测 Firestore 集合以及查找仅靠 strings.xml 分析会遗漏的其他 Firebase 模式来提供更深入的分析 - JADX 处理有 30 分钟的超时限制以防止挂起(在 config.py 中更改)。注意:在某些情况下,JADX 进程在 30 分钟后不会被终止,提取阶段将无法完成。请手动终止挂起的正确 JADX 进程,它将完成提取阶段(我会修复此问题!) - 文件按大小顺序处理(最小的先处理),因此最后阶段会花费更多时间
Firebase Realtime Database 扫描 当使用 `--read-rtdb` 或 `--write-rtdb` 选项时,脚本将扫描所有唯一的 Firebase Project ID 以检查数据库可访问性和安全状态。扫描器: - 测试标准 Firebase Realtime Database URL: - `https://PROJECT_ID.firebaseio.com/.json` - `https://PROJECT_ID-default-rtdb.firebaseio.com/.json` - 自动处理区域重定向(例如 europe-west1) - 支持同一项目中的多个 Realtime Database。如果没有手动更改,第二个数据库会自动拥有与项目相同的名称。 - **读取测试 (`--read-rtdb`)**:评估响应状态码: - **200**:公开数据库访问 - **403**:权限被拒绝(受保护) - **404**:未找到数据库 - **423**:数据库锁定/停用 - **写入测试 (`--write-rtdb`)**:尝试从指定文件写入 JSON 数据以测试写入权限 - **仅开放文件**:当发现公开数据库时,自动创建 `*_database_open_only.txt` 文件
Firebase Storage 扫描 当使用 `--read-storage` 或 `--write-storage` 选项时,脚本将扫描所有唯一的 Firebase Project ID 以检查存储桶的可访问性: - 测试 Firebase Storage 桶 URL: - `https://firebasestorage.googleapis.com/v0/b/PROJECT_ID.appspot.com/o` - `https://firebasestorage.googleapis.com/v0/b/PROJECT_ID.firebasestorage.app/o` - **读取测试 (`--read-storage`)**:评估响应状态码: - **200**:公开 Storage 访问。 - **400**:Storage 规则版本 1 - 不允许列出。 - **403**:权限被拒绝。 - **412**:服务账号缺少权限。 - **404**:未找到 Storage 桶。 - **写入测试 (`--write-storage`)**:尝试上传指定文件以测试写入权限 - **仅开放文件**:当发现公开 Storage 桶时,自动创建 `*_storage_open_only.txt` 文件
Firebase Firestore 扫描 当使用 `--read-firestore` 或 `--write-firestore` 选项时,脚本将扫描 Firestore(默认)数据库以检查可访问性: - **提取的集合**:使用在 JADX 反编译期间从每个 APK 源代码中找到的 Firestore 集合 - **集合模糊测试**:当 `--fuzz-collections` 与字典路径一起使用并发现公开 Firestore 数据库时,自动对常见集合名称进行模糊测试:`users`、`posts`、`messages`、`products`、`orders` 等 - 使用 Firestore REST API 端点: - `https://firestore.googleapis.com/v1/projects/PROJECT_ID/databases/(default)/documents/COLLECTION_NAME` - **读取测试 (`--read-firestore`)**:评估响应状态码: - **200**:包含数据的公开 Firestore 集合。 - **200 (empty)**:公开数据库但集合不存在。 - **403**:权限被拒绝。 - **404**:未找到数据库。 - **写入测试 (`--write-firestore`)**:尝试写入指定的字符串值以测试文档创建权限 - **仅开放文件**:当发现公开 Firestore 数据库时,自动创建 `*_firestore_open_only.txt` 文件
Firebase Remote Config 扫描 当使用 `--read-config` 选项时,脚本将使用提取的 Google API Key 和 App ID 扫描 Firebase Remote Config 的可访问性。扫描器: - 从所有 `/res/values-*` 目录中的字符串资源中提取 Google API Key 和 App ID - 使用 Firebase Remote Config API: - `https://firebaseremoteconfig.googleapis.com/v1/projects/{PROJECT_ID}/namespaces/firebase:fetch?key={API_KEY}` - 评估响应状态码: - **200**:Remote Config 可访问。 - **401/403**:权限被拒绝。可能存在其他 Google API 限制。 - **404**:未找到 Remote Config。 - **仅开放文件**:当发现可访问的配置时,自动创建 `*_config_open_only.txt` 文件
经过身份验证的扫描和 Google API 限制绕过 当使用 `--check-with-auth` 选项时,OpenFirebase 尝试向 Firebase 服务进行身份验证,以访问在未经身份验证的扫描期间返回 401/403 错误的受保护资源: - **账号创建和登录**:自动尝试使用 Identity Toolkit API 和提取的 API Key 创建 Firebase 用户账号,并获取 Access Token。 - **匿名登录**:如果使用邮箱/密码创建账号失败,自动重试匿名登录。 - **Android 限制绕过**:使用提取的 Android 包名和证书 SHA-1 哈希绕过“限于 Android 应用”的 API 限制 - **多 Key 测试**:测试多个提取的 API Key 和证书组合以找到有效的身份验证方法 - **身份验证重试**:使用获取的身份验证 Token 重试先前失败的读/写操作 - **身份验证持久化**:将成功的身份验证数据保存到 `auth_data.json`,以便将来使用 `--resume-auth-file`
服务账号身份验证 OpenFirebase 检测意外嵌入在 APK 文件中的 Firebase 服务账号凭据(`client_email` + `private_key`)。具有管理员级别角色(例如 `firebase-adminsdk`)的服务账号绕过所有 Firebase 安全规则,授予不受限制的访问权限。 #### 检测 - **JADX 反编译**:解析包含 `"type": "service_account"` 以及 `client_email` 和 `private_key` 字段的 JSON 文件。还会扫描 Java/Kotlin 源代码中的硬编码 PEM 私钥和 `@*.gserviceaccount.com` 邮箱 - **快速提取**:直接从 APK 读取 `assets/`、`res/raw/` 和根级 JSON 文件以查找服务账号 JSON 文件 #### 身份验证流程 当找到凭据(或通过 `--service-account` 和 `--private-key` 手动提供)时,OpenFirebase 使用 Google OAuth2 服务对服务 JWT 流程进行身份验证: 1. 使用服务账号的 RSA 私钥签名 JWT 2. 在 `oauth2.googleapis.com/token` 交换短期 Bearer Token 3. 将 Bearer Token 用于所有 RTDB、Firestore 和 Storage 扫描 —— 始终作为默认未经身份验证请求的补充 使用服务账号 Token 的结果标记为 `PUBLIC_SA`,以区别于常规身份验证结果(`PUBLIC_AUTH`)。 #### 服务账号可以访问什么 管理员级别的服务账号不仅绕过读/写的安全规则 —— 它还授予对完整 Firebase Admin SDK 的访问权限,包括: - **Realtime Database**:读/写任何路径,无论安全规则如何 - **Firestore**:读/写任何集合/文档,无论安全规则如何 - **Storage**:读/写任何桶中的任何文件,无论安全规则如何 - **Firebase Auth Admin API**:列出所有用户账号,读取用户数据(邮箱、电话、显示名称、提供商、MFA 状态、自定义声明),创建/删除用户,生成用于用户模拟的自定义 Auth Token,以及禁用 MFA
从先前结果恢复 当您已经运行过提取并希望完全跳过提取阶段(JADX 反编译)时,可以使用: - `--resume`:从包含 `*_firebase_items.txt` 文件的现有结果目录恢复,并直接进入扫描 - `--resume-auth-file`:使用结果目录中 `auth_data.json` 文件里先前保存的身份验证数据恢复,跳过试错式身份验证过程
直接 Project ID 扫描 当您已经提取了 Firebase Project ID 并希望跳过提取阶段,或者您拥有来自其他来源(如 Web)的 Project ID 时,可以使用: - `--project-id`:扫描以逗号分隔值提供的特定 Project ID - `--project-id-file`:从文件扫描 Project ID(每行一个 ID)
## 命令行参数 ### 输入选项 | 参数 | 简写 | 描述 | |----------|-------|-------------| | `--file` | `-f` | 使用 JADX 反编译处理单个 APK 文件 | | `--apk-dir` | `-d` | 对包含 APK 文件 (*.apk) 的目录进行 JADX 反编译 | | `--fast-extract` | `-F` | 使用快速提取(从所有 /res/values-* 目录提取 strings.xml)代替完整源代码分析。速度更快但有限制 | | `--resume` | `-r` | 从包含 *_firebase_items.txt 文件的现有结果文件夹恢复 | | `--exclude-project-id` | | 恢复时排除特定的 Project ID(多个 ID 用逗号分隔,只能与 --resume 一起使用) | | `--project-id` | `-pi` | 扫描特定的 Firebase Project ID 而无需提取(多个 ID 用逗号分隔) | | `--project-id-file` | `-pif` | 从文件扫描 Firebase Project ID(每行一个 ID)而无需提取 | | `--parse-dns-file` | `-pdf` | 从文件解析 DNS 条目并提取 Firebase Project ID(输出 ID 而不扫描) | ### 读取测试 | 参数 | 简写 | 描述 | |----------|-------|-------------| | `--read-rtdb` | `-rr` | 测试 Firebase Realtime Database 的未授权读取访问 | | `--read-storage` | `-rs` | 测试 Firebase Storage 桶的未授权读取访问 | | `--read-config` | `-rc` | 测试 Firebase Remote Config 的读取访问 | | `--read-firestore` | `-` | 测试 Firestore 数据库的未授权读取访问 | | `--collection-name` | | 与 --read-firestore 一起测试的集合名称(多个用逗号分隔,默认为 'users') | | `--read-all` | `-ra` | 测试 Firebase 数据库、Storage 桶、Remote Config 和 Firestore 的未授权访问 | | `--scan-rate` | `-l` | 扫描速率限制(每秒请求数) | | `--fuzz-collections` | | 当发现公开可访问的数据库时,用于 Firestore 集合模糊测试的字典文件路径 | ### 写入测试 | 参数 | 简写 | 描述 | |----------|-------|-------------| | `--write-storage` | `-ws` | 测试对 Firebase Storage 桶的写入访问(需要 --write-storage-file) | | `--write-storage-file` | | 测试 Storage 写入访问时要上传的文件路径(与 --write-storage 一起必需) | | `--write-firestore` | `-wf` | 测试对 Firestore 数据库的写入访问(需要 --write-firestore-value) | | `--write-firestore-value` | | 测试 Firestore 写入访问时要写入的字符串值(与 --write-firestore 一起必需) | | `--write-rtdb` | `-wr` | 测试对 Firebase Realtime Database 的写入访问(需要带有 JSON 数据的 --write-rtdb-file) | | `--write-rtdb-file` | | 测试 RTDB 写入访问时包含要写入数据的 JSON 文件路径(与 --write-rtdb 一起必需) | | `--write-all` | `-wa` | 测试对 Firebase Storage 桶、Firestore 数据库和 Realtime Database 的写入访问(需要 --write-storage-file、--write-rtdb-file 和 --write-firestore-value) | ### 处理选项 | 参数 | 简写 | 描述 | |----------|-------|-------------| | `--output-dir` | `-o` | 所有生成文件的输出目录(默认:results/) | | `--processes` | `-j` | 并发 APK 处理的进程数(默认:min(5, CPU count),最大:5) | | `--proxy` | `-x` | HTTP 请求的代理(格式:protocol://host:port,例如 http://127.0.0.1:8080) | | `--timeout` | `-t` | JADX 反编译的超时时间(分钟)(默认:30 分钟) | ### Remote Config 凭据 | 参数 | 简写 | 描述 | |----------|-------|-------------| | `--app-id` | `-i` | 使用 --project-id 或 --project-id-file 进行 Remote Config 扫描的 Google App ID | | `--api-key` | `-k` | 使用 --project-id 或 --project-id-file 进行 Remote Config 扫描的 Firebase API Key | | `--cert-sha1` | | 用于 Remote Config 扫描的 Android 应用证书 SHA-1 哈希(如果未提供则从 APK 提取) | | `--package-name` | | 用于 Remote Config 扫描的 Android 应用包名(如果未提供则从 APK 提取) | ### 身份验证 | 参数 | 简写 | 描述 | |----------|-------|-------------| | `--check-with-auth` | `-C` | 对于返回 401/403 的读取和写入检查,使用 Firebase 身份验证重试 | | `--email` | `-e` | Firebase 身份验证的电子邮件地址(与 --check-with-auth 一起必需) | | `--password` | `-p` | Firebase 身份验证的密码(与 --check-with-auth 一起必需) | | `--resume-auth-file` | | auth_data.json 文件的路径或包含保存的身份验证数据的结果目录,用于直接身份验证(跳过试错式身份验证过程) | ### 服务账号身份验证 | 参数 | 描述 | |----------|-------------| | `--service-account` | 服务账号电子邮件 (client_email),用于通过 Google OAuth2 JWT 流程进行管理员级别的身份验证(绕过安全规则) | | `--private-key` | 用于服务账号身份验证的 PEM 私钥文件路径(与 --service-account 一起必需)。也接受带有 `\n` 转义符的内联密钥字符串 | ## 示例 我建议使用 `--proxy http://127.0.0.1:8080` 和 Burp Suite 进行扫描,并启用 JWT 扩展以高亮显示包含 JWT Token 的请求。这在经过身份验证的扫描期间特别有用,因为它可以轻松识别哪些请求成功了。然后您可以轻松测试它们并将请求导出为 cURL 命令,从而方便在您的 PoC 中重现。 #### 仅提取单个文件 ``` # 仅使用 JADX 提取(默认) openfirebase -f file.apk ``` #### 使用快速提取仅提取 APK ``` # 使用 APK 目录并在 fast mode 下提取 openfirebase -d path/to/apks -F ``` #### 完整的未经身份验证读取和写入扫描 ``` # 提取,扫描所有服务,测试读写权限 openfirebase -d /path/to/apks --read-all --write-all --write-storage-file ./openfirebase/payloads/openfirebase_storage_write_check.txt --write-rtdb-file ./openfirebase/payloads/openfirebase.json --write-firestore-value "unauth_write_check_by_Icex0" --fuzz-collections ./openfirebase/wordlist/firestore-collections.txt ``` #### 完整的经过身份验证读取和写入扫描 ``` # 提取,扫描所有服务,测试经认证的读写权限 openfirebase -d /path/to/apks --read-all --write-all --write-storage-file ./openfirebase/payloads/openfirebase_storage_write_check.txt --write-rtdb-file ./openfirebase/payloads/openfirebase.json --write-firestore-value "unauth_write_check_by_Icex0" --check-with-auth --email pentester@company.com --password SecurePass123 --fuzz-collections ./openfirebase/wordlist/firestore-collections.txt ``` #### 从仅提取的结果恢复并执行所有读取扫描 ``` # 从仅提取 firebase 项处恢复 openfirebase --resume ./2025-08-31_20-30-00_results --exclude-project-id "abc-project" --read-all ``` #### 使用 Project ID 进行完整读取扫描(cert-sha1 和 package name 是可选的,但如果存在 Google API 限制则是必需的) ``` openfirebase --project-id openfirebase --read-all --check-with-auth --email pentester@company.com --password SecurePass123 --api-key AIz... --app-id 1:482910573864:android:ab12cd34ef56gh78ij90kl --cert-sha1 1126abfb2cc0656875e50099d1bb5376276ae5a5 --package-name com.openfire.base --proxy http://127.0.0.1:8080 ``` #### 使用来自 JSON 密钥文件的服务账号凭据进行扫描 ``` openfirebase --project-id my-project --service-account firebase-adminsdk-xxxxx@my-project.iam.gserviceaccount.com --private-key /path/to/serviceAccountKey.pem --read-all ``` #### 提取 APK 并自动使用任何发现的服务账号凭据 ``` # 如果在提取过程中发现 service account,它将被自动用于扫描 openfirebase -f app.apk --read-all ``` ## 免责声明 本软件按“原样”提供,不附带任何形式的明示或暗示的保证,包括但不限于适销性、特定用途适用性和非侵权性的保证。在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任负责,无论是在合同诉讼、侵权行为还是其他方面,由本软件或本软件中的使用或其他交易引起、由此产生或与之相关。 此工具不隶属于、未经认可也未经 Google LLC 授权。这是一个独立的安全研究工具,专为合法的安全测试目的而设计。使用此工具的风险由您自行承担。用户有责任确保遵守其所在司法管辖区内的所有适用法律和法规。
标签:APK分析, Firebase, Firestore, GraphQL安全矩阵, JADX, JS文件枚举, Python, Realtime Database, StruQ, URL提取, 云存储安全, 反编译, 图计算, 安全扫描器, 对称加密, 无后门, 服务账号泄露, 未授权访问, 白盒测试, 目录枚举, 移动安全, 网络扫描, 自动化审计, 谷歌云, 逆向工具, 配置错误检测