Giới thiệu
AJAX và các dịch vụ Web mang tích tương tác cao đã tạo nên xương sống cho các ứng dụng thế hệ Web2.0. Tuy nhiên sự chuyển biến của công nghệ này đã mang ra các thách thức mới cho các chuyên gia bảo mật.
Bài báo này xem xét một vài phương pháp, các công cụ và các bí quyết để phân tích các ứng dụng Web 2.0 (gồm có AJAX) và khám phá các lỗ hổng bảo mật bằng việc sử dụng Firefox và các phần khác đi kèm của nó. Các đối tượng chính của bài báo này là về:
- Kiến trúc ứng dụng Web 2.0 và các vấn đề bảo mật liên quan tới nó.
- Việc phát hiện các thách thức như việc tìm ra các lời gọi ẩn, các vấn đề crawling và khám phá mặt logic của AJAX.
- Phát hiện các lời gọi XHR với công cụ Firebug.
- Mô phỏng trình duyệt một cách tự động với Chickenfoot.
- Việc gỡ rối các ứng dụng từ quan điểm bảo mật bằng việc sử dụng bộ gỡ rối Firebug.
- Phương pháp để phát hiện lỗ hổng.
Tổng quan ứng dụng Web 2.0
Thuật ngữ mới “Web 2.0” được đưa ra cho thế hệ tiếp theo của các ứng dụng Web cùng với việc đưa vào các tiến bộ của kỹ thuật. Dịch vụ Web XML-driven chạy trên SOAP, XML-RPC và REST đang được cung cấp cho các thành phần ở phía trình chủ. Các ứng dụng mới này có một sức mạnh vượt trội về giao diện người dùng bằng cách sử dụng AJAX và các thành phần ứng dụng Internet phong phú.
Sự thay đổi công nghệ này là dựa trên một kiến trúc tổng thể của các ứng dụng Web và sự truyền thông giữa máy chủ và máy khách. Tuy vậy đi kèm với là các vấn đề liên quan đến bảo mật và các thách thức mới về bảo mật.
Các sâu máy tính mới như Yamanner, Samy và Spaceflash đang khai thác các AJAX framework (trình khách) bằng việc cung cấp các cách mới trong tấn công và lấy cắp thông tin mật.
Hình 1: kiến trúc Web 2.0 |
Trên hình 1, quá trình bên phía trình duyệt ở bên trái có thể được phân chia thành các lớp dưới đây:
- Lớp trình diễn - HTML/CSS cung cấp diện mạo bề ngoài cho các ứng dụng trong cửa sổ trình duyệt.
- Logic & Process – JavaScript chạy trong các ứng dụng hợp lý về trình duyệt để thực thi công việc và logic truyền thông. Các thành phần của AJAX cư trú bên trong lớp này.
- Transport - XMLHttpRequest (XHR) – đối tượng này cho khả năng truyền thông không đồng bộ và XML thay đổi giữa các HTTP(S) trên máy chủ và khách.
Các thành phần của trình chủ phía bên phải của hình 1 là một nhóm các thành phần phía sau firewall bao gồm các dịch vụ web được triển khai theo các mã nguồn ứng dụng web truyền thống. Mã nguồn AJAX đang chạy trên trình duyệt có thể gọi trực tiếp đến các dịch vụ web dựa trên XML và thay đổi thông tin mà không phải refresh lại toàn bộ trang. Sự truyền thông toàn vẹn này được ẩn dưới người dùng, hay nói theo cách khác người dùng sẽ không cảm thấy bất kỳ một sự trỏ trực tiếp (redirect) nào. Sử dụng redirect và refresh là một phần tích hợp của thế hệ web đầu tiên. Trong thế hệ web 2.0 này chúng được giảm nhẹ bằng việc sử dụng Ajax.
Đánh giá các thách thức của web 2.0
Trong khung làm việc không đồng bộ, ứng dụng không có nhiều “Refreshes” và “Redirects”. Kết quả là, nhiều mã nguồn bên phía trình chủ (server-side) có thể được thực thi bởi một kẻ tấn công đã ẩn. Dưới đây là ba thách thức quan trọng cho người làm công tác bảo mật về công nghệ mới này:
1. Việc phát hiện ra các lời gọi ẩn: Nó là rất cần thiết để một ai đó phân biệt các lời gọi ẩn được tạo bởi trang được tải xuống trên trình duyệt. Bởi vì công nghệ này sử dụng JavaScript trên HTTP(S) để tạo ra các lời triệu gọi đến máy chủ backend.
2. Các thách thức Crawling: Các ứng dụng kiểm tra truyền thống cũng gặp thất bại trên hai mặt chính: một là để tái tạo trình duyệt và hai là để nhận ra mã nguồn trình chủ trong toàn bộ quá trình. Nếu mã nguồn bị truy cập bằng một đối tượng XHR thông qua JavaScript thì nó có vẻ như là việc crawling ứng dụng mà không chọn lọc chúng.
3. Khám phá logic: Các ứng dụng web ngày nay được tải với JavaScript và nó rất khó khăn để cô lập phần logic cho các sự kiện riêng biệt. Mỗi trang HTML có thể tải ba hay bốn mã nguồn JavaScript từ server. Mỗi file trong đó lại có thể có nhiều chức nằng, nhưng sự kiện đang sử dụng có thể chỉ là một phần nhỏ của tất cả các file này.
Chúng ta cần phải nghiên cứu một cách tỉ mỉ và phân biệt phương pháp và các công cụ để bắt kịp cuộc chạy đua trong việc đánh giá ứng dụng web. Với mục đích của bài báo này, chúng tôi sẽ sử dụng Firefox làm trình duyệt và thử tác dụng của một vài plug-in của nó để xem tác dụng với các thách thức trên.
Khám khá các lời gọi ẩn
Các ứng dụng web 2.0 có thể tải một trang đơn từ server nhưng có thể phải gọi vài đối tượng XHR khi tạo thành trang cuối cùng. Việc gọi này có thể kéo nội dung hay JavaScript từ máy chủ một cách không đồng bộ. Trong kịch bản như vậy, thách thức ở đây là việc chỉ ra tất cả các cuộc gọi XHR và mã nguồn được kéo xuống từ máy chủ. Thông tin này có thể giúp để nhận ra tất cả các mã nguồn có thể và các lỗ hổng liên quan. Lấy một ví dụ đơn giản.
Mục đích của chúng tôi là có thể có tin tức về công việc kinh doanh bằng việc tìm một tin tức đơn giản được định vị trên địa chỉ http://example.com/news.aspx
Trang này trong trình duyệt sẽ giống như mô tả trong hình 2 dưới đây.
Hình 2: một trang ví dụ đơn giản |
Với ứng dụng web 2.0, các lời triệu gọi Ajax được đưa đến server bằng việc sử dụng đối tượng XHR. Chúng ta có thể chỉ ra các cuộc gọi này bằng việc sử dụng một công cụ được biết đến đó là Firebug. Firebug là một plug-in nhúng vào trình duyệt Firefox và có khả năng nhận ra các triệu gọi XHR.
Trước khi duyệt qua một trang với plugin, phải chọn option để ngăn chặn các cuộc gọi XHR được chọn như hình 3.
Hình 3: Thiết lập Firebug để ngăn chặn các triệu gọi XMLHttpRequest |
Với Firebug option để ngăn chặn các cuộc gọi XMLHttpRequest có thể, chúng tôi duyệt các trang giống nhau để tìm ra tất cả các triệu gọi đối tượng XHR được tạo bởi trang riêng biệt này đến server. Sự thay đổi này được thể hiện trên hình 4.
Hình 4 |
Chúng ta có thể nhìn thấy vài request được tạo bởi trình duyệt sử dụng XHR. Nó đã tải dojo AJAX framework từ máy chủ trong khi đồng thời tạo ra các triệu gọi mã nguồn trên server để đem về nội dung bài báo mới.
http://example.com/ getnews.aspx?date=09262006
Nếu chúng ta nhìn vào code, chúng ta sẽ thấy hàm trong JavaScript.
function getNews() { var http; http = new XMLHttpRequest(); http.open("GET", " getnews.aspx?date=09262006", true); http.onreadystatechange = function() { if (http.readyState == 4) { var response = http.responseText; document.getElementById('result').innerHTML = response; } } http.send(null); } |
Mã trước tạo thành một cuộc gọi không đồng bộ đến backend web server và hỏi mã nguồn của trang getnews.aspx?date=09262006. nội dung của trang được thay tại vị trí id trong trang HTML. Rõ ràng rằng ở đây, cuộc gọi Ajax sử dụng đối tượng XHR.
Bằng việc phân tích ứng dụng trong định dạng này, chúng tôi có thể chỉ ra các lỗ hổng bên trong cũng như các yêu cầu POST. Cho ví dụ, sủ dụng lại trường hợp ở trên, tham số “date” là lỗ hổng cho một tấn công vào SQL.
Các thách thức kéo theo và mô phỏng trình duyệt
Một công cụ do thám quan trọng khi thực hiện đánh giá ứng dụng web là một con dệp web (crawler). Con dệp này có thể bò trườn vào các trang và chọn ra tất cả các link (HREF). Nhưng cái gì sẽ xảy ra nếu các HREF chỉ vào một hàm JavaScript tạo các triệu gọi Ajax bằng việc sử dụng đối tượng XHR. Khi đó dệp web này có thể mất tất cả các thông tin.
Trong nhiều trường hợp nó trở thành rất khó để mô phỏng môi trường này. Cho ví dụ, đây là một tập các link đơn giản:
go1 go2 go3 |
Link “go1” khi click sẽ thực hiện hàm getMe(). Mã cho hàm getMe() được viết ở dưới. Chú ý rằng hàm này có thể được bổ sung trong một file tách biệt hoàn toàn.
function getMe() { var http; http = new XMLHttpRequest(); http.open("GET", "hi.html", true); http.onreadystatechange = function() { if (http.readyState == 4) { var response = http.responseText; document.getElementById('result').innerHTML = response; } } http.send(null); } |
Code có trước tạo thành một triệu gọi Ajax đơn giản đến nguồn hi.html trên server. Có thể mô phỏng click này một cách tự động không? Câu trả lời ở đây là có thể. Đây là một phương pháp sử dụng Firefox plug-in Chickenfoot, phương pháp này có thể cung cấp các JavaScript-based API và sự mở rộng giao diện có thể lập trình được cho trình duyệt.
Bằng việc sử dụng Chickenfoot plugin, bạn có thể viết JavaScript đơn giản với trình duyệt. với phương pháp này, nhiệm vụ đơn giản như việc đi qua các trang web là có thể hoàn toàn tự động. Cho ví dụ, kịch bản đơn giản dưới đây sẽ “click” tất cả các “neo” với các sự kiện onClick. Sự thuận lợi của plug-in này trên các con dệp web truyền thống là hoàn toàn khác nhau: mỗi sự kiện onClick tạo nên các triệu gọi backend XHR-based mà các dệp có thể làm mất bởi vì chúng cố gắng phân tích cú pháp JavaScript và chọn các link khả thi nhưng không thể thay thế các sự kiện onClick thực.
l=find('link') for(i=0;ia = document.links[i]; test = a.onclick; if(!(test== null)){ var e = document.createEvent('MouseEvents'); e.initMouseEvent('click',true,true,document.defaultView,1,0,0,0, 0,false,false,false,false,0,null); a.dispatchEvent(e); } } |
Bạn có thể tải kịch bản này trong phần Chickenfoot và chạy nó như hình 5.
Hình 5 |
Phương pháp này, giúp một người có thẻ tạo JavaScript và truy cập vào các ứng dụng nền Ajax từ bên trong trình duyệt Firefox. Có một vài hàm gọi API có thể được sử dụng trong chickenfoot plugin. Lệnh “fetch” để xây dựng tiện ích crawling là rất hữu ích.
Tìm theo logic và phân tích các ứng dụng
Để phân tích các ứng dụng Ajax phía trình khách, chúng ta cần phải đi qua lần lượt một cách cẩn thận để chỉ ra quá trình logic. Một cách chỉ ra toàn bộ sự logic này là lần từ từ qua mỗi dòng code. Thường thì mỗi một sự kiện gọi sẽ xử lý một vài chức năng trong các file cụ thể. Do vậy, chúng ta cần phải sử dụng một kỹ thuật để tìm qua code có liên quan được thực thi trong trình duyệt.
Có vài chương trình gỡ rối cho JavaScript có thể được sử dụng để thực hiện đối tượng trên. Firebug chỉ là một trong vài chương trình này. Tuy nhiên chúng ta nên sử dụng Firebug lại lần nữa trong ví dụ này.
Hãy lấy một ví dụ đơn giản cho quá trình logic. Trang login.html chấp nhận một username và một password từ người dùng (hình 6). Sử dụng đặc tính “inspect” của Firebug để chỉ ra thuộc tính của form.
Hình 6 |
Sau khi kiểm tra (inspect) thuộc tính form, nó chứng tỏ rằng đã có một lời gọi hàm được đưa đến hàm “auth”. Bây giờ chúng ta có thể chạy đặc tích gỡ rối của Firebug như mô phỏng trên hình 7 và cách ly logic bên trong với các sự kiện riêng lẻ.
Hình7. Gỡ rối với Firebug. |
Tất cả sự lệ thuộc JavaScript trong trang riêng lẻ này có đều có thể xem được. Các lời gọi đều đến ajaxlib.js và validation.JavaScript. Hai kịch bản này phải có vài hàm. Nó có thể được suy diễn rằng quá trình login đã sử dụng vài hàm đó. Chúng ta có thể sử dụng một dụng “breakpoint” để đi qua toàn bộ ứng dụng. Khi một breakpoint được thiết lập, chúng ta có thể nhập vào thông tin, click nút “Submit” và điều khiển quá trình thực thi. Trong ví dụ của chúng tôi, chúng tôi đã thiết lập một breakpoint trong hàm “auth” như hình 8.
Hình 8: Thiết lập một breakpoint và quá trình thực thi điều khiển |
Bây giờ chúng ta hãy bước vào quá trình giỡ rối bằng việc click nút “step in” được khoanh vùng trên hình 8. JavaScript sẽ chuyển đến hàm khác, userval, cư trú trong file validation.js như trong hình 9.
Hình 9. Chuyển đến trang validation.js |
Phần chữ trên hình thể hiện mẫu hàm thông thường được sử dụng để xác nhận tính hợp lệ của trường người dùng. Khi có sự hợp lệ chương trình sẽ thực hiện chuyển đến hàm khác là callGetMethod như trong hình 10.
Hình 10 |
Cuối cùng (hình 11), tại vị trí cuối cùng của chương trình, chúng ta có thể quan sát thấy lời gọi các dịch vụ web backend bằng đối tượng XHR.
Hình 11 |
Ở đây, chúng ta đã chỉ ra được vị trí mã nguồn cho các dịch vụ web backend.
http://example.com/2/auth/ws/login.asmx/getSecurityToken?username=amish&password=amish
Mã nguồn trước cho thấy các dịch vụ web đang chạy dưới môi trường .NET. Toàn bộ quá trình phân tích này ch thấy một điều thú vị rằng chúng ta đã tìm được thói quen hợp lệ người dùng có thể bị đi qua một cách dễ dàng.
Tiếp tục đánh giá hơn nữa, chúng ta có thể truy cập dịch vụ web và các endpoint của nó bằng việc sử dụng một file WSDL và làm trực tiếp đến dịch vụ. chúng ta có thể chạy các tấn công khác với SQL hay XPATH với các công cụ như wsChess.
Trong trường hợp này, ứng dụng có thể hổng trong XPATH. Phương pháp cho sự kiểm tra các dịch vụ web là khác nhau và không được đề cập đến trong bài viết này. Mặc dù vậy, kỹ thuật như trên cũng có thể giúp chúng ta nhận ra sự tấn công phía trình khách như là các tấn công thủ công XSS, DOM, đi qua điều khiển bảo mật trình khách, thi hành code Ajax nguy hiểm.
Kết luận
Kiến trúc hướng dịch vụ (SOA), Ajax, các ứng dụng Internet phong phú (RIA) và các dịch vụ Web là các thành phần cho các ứng dụng web thế hệ tiếp theo. Giữ nhịp độ với kỹ thuật này và chống lại các thách thức bảo mật ứng dụng thế hệ tiếp theo chúng ta cần phải thiết kế và phát triển các công cụ và các phương pháp khác. Một trong những phương pháp truy cập ứng dụng là việc sử dụng hiệu quả một trình duyệt.
Trong bài báo này, chúng tôi đã giới thiệu ba kỹ thuật để truy cập các ứng dụng web 2.0. Bằng việc sử dụng các phương pháp này, nó hoàn toàn có thể phân biệt và cô lập các lỗ hổng liên quan đến Ajax. Kịch bản tự động duyệt có thể giúp chúng ta trong việc định hình web và khám phá để tìm ra các lỗ hổng trên mã nguồn của trình chủ.
Các ứng dụng thế hệ tiếp theo sử dụng JavaScript một cách rộng rãi. Các công cụ gỡ rối là con dao của chúng ta giúp chúng ta có thể chống lại các thách thức này. Các kỹ thuật sử dụng trong bài báo này là điểm khởi đầu tốt đẹp cho các đánh giá web 2.0 sử dụng Firefox.