## LAB HTTP request smuggling Cấu trúc tổng quát của khai thác thông qua smuggling request: ![image](https://hackmd.io/_uploads/S1k5STmhyg.png) - Smuggling request bao gồm một phần request gốc mà bị smuggle (Smuggled request) đi cùng với request smuggle (Smuggle request). Bên cạnh đó là một phần request thông thường kế tiếp (Normal request). Cơ chế hoạt động tổng quát: ![image](https://hackmd.io/_uploads/ryfMU6X3ye.png) - Khi một request được xử lí bởi hai server độc lập và có cách chọn kết thúc request khác nhau thì có thể bị lợi dụng. - Tại đây, FEs sử dụng `Content-Length` trong khi BEs sử dụng `Transfer-Encoding`. Lợi dụng cơ chế xử lí khác nhau để khai thác. - FEs xử lí theo số kí tự, do vậy, nó không xem xét kĩ body chứa gì mà chỉ đếm xem body đủ số kí tự chưa, sau đó gửi thẳng tới BEs. - BEs xử lí theo "chunk", do vậy, tại điểm kết thúc "chunk" (0 - End of 1 chunk). Nó mặc định request này kết thúc và mặc định đoạn còn lại là của request kế tiếp. Do vậy, một request mới được sinh ra hoặc là hợp nhất với request kế tiếp. Do vậy, kẻ tấn công có thể lợi dụng lỗ hổng này để xâm phạm request liền kề kế tiếp hoặc là tạo ra một request mới hoàn toàn độc lập mà vốn dĩ chúng không thể tạo request này theo hành vi ứng dụng thông thường. ![image](https://hackmd.io/_uploads/r1_U4iCh1g.png) ![image](https://hackmd.io/_uploads/H1IPVsAnkg.png) ![image](https://hackmd.io/_uploads/rJxONjAnJx.png) >Note: >- Một số website có FEs hỗ trợ "HTTP/2", nhưng triển khai máy trước cơ sở hạ tầng BEs chỉ hỗ trợ "HTTP/1". FE phải dịch các request mà nó nhận được sang "HTTP/1". >- Cần thêm chuỗi `\r\n\r\n` theo sau kí tự `0` của một "chunk". >- Đôi khi bỏ chọn "Update Content-Length" của Burp Repeater là cần thiết. ### 1. HTTP request smuggling, basic `CL.TE`vulnerability >Lab bao gồm FEs và BEs. Tuy nhiên FEs không hỗ trợ "chunked encoding". Đồng thời chỉ nhận "GET" hoặc "POST" request. Cần Smuggle một request tới BEs, để biến nó thành "GPOTS" request. Lợi dụng việc FEs không xử lí "chunked encoding" nhưng BEs thì có. Ta gửi đi body với payload như sau: ![image](https://hackmd.io/_uploads/rJyU6f2iyg.png) - Tại FEs, nó xác định request kết thúc thông qua `Content-Length` header, do vậy, request body sẽ chứa đủ 6 kí tự: ![image](https://hackmd.io/_uploads/rJjTJXhjyl.png) - Tuy nhiên với `Transfer-Encoding` header, BEs sẽ xử lý theo từng "chunk", do vậy, request body sẽ kết thúc tại kí tự `0`: ![image](https://hackmd.io/_uploads/ryzm-QhiJx.png) - Khi này, kí tự `G` sẽ được BEs bỏ qua với request này và tự động chèn nó vào đầu request sau Tiếp tục gửi lại request này, có thể thấy thông báo lỗi khi xuất hiện "GPOST" request. ![image](https://hackmd.io/_uploads/HkwLCMns1e.png) ___ ### 2. HTTP request smuggling, basic `TE.CL` vulnerability >Lab bao gồm FEs và BEs. Tuy nhiên BEs không hỗ trợ "chunked encoding". Đồng thời chỉ nhận "GET" hoặc "POST" request. Cần Smuggle một request tới BEs, để biến nó thành "GPOTS" request. Lợi dụng việc BEs không xử lí "chunked encoding" nhưng FEs thì có. Ta gửi đi body với payload như sau: ![image](https://hackmd.io/_uploads/S1YbFN3sJx.png) - Tại FEs, nó xác định req kết thúc thông qua `Transfer-Encoding`, do vậy, nó sẽ lấy toàn bộ đoạn body bên trong "chunk" để gửi tới BEs: ![image](https://hackmd.io/_uploads/ByP5t43j1e.png) - Tuy nhiên với `Content-Length: 4`, BEs sẽ chỉ lấy 4 kí tự trong phần body, và mặc định chuyển toàn bộ phần còn lại của request body sang request kế tiếp: ![image](https://hackmd.io/_uploads/r1a3543sJx.png) - Khi này, phần bị BEs đẩy sang một request mới lại trở thành một request đầy đủ. Tiếp tục gửi lại request này, có thể thấy thông báo lỗi khi xuất hiện "GPOST" request. ![image](https://hackmd.io/_uploads/rknGYEnskx.png) Bổ sung: Xem xét kĩ phần request body bị BEs đẩy sang request kế tiếp: ![image](https://hackmd.io/_uploads/BJKvJrnikl.png) - Tại đây, phần `Content-Length` phải mang giá trị lớn hơn số kí tự của phần request body (`0\r\n\r\n` khi này có số kí tự là 5). ___ ### 3. HTTP request smuggling, obfuscating the TE header >Lab bao gồm FEs và BEs. Cả 2 server đều hỗ trợ "chunked encoding". Tuy nhiên, cách chúng xử lí request header trùng lặp là không giống nhau. Đồng thời chỉ nhận "GET" hoặc "POST" request. Cần Smuggle một request tới BEs, để biến nó thành "GPOTS" request. Tạo ra header `Transfer-Encoding: chunked` trùng lặp. Khi gửi đi request này, ứng dụng vẫn trả về HTTP status code "200". ![image](https://hackmd.io/_uploads/B1Kug06ikx.png) - Mặc dù xuất hiện header trùng lặp, ứng dụng không trả về lỗi. Có thể ứng dụng đã không xử lí trường hợp này, hoặc cách FEs và BEs nhận header này không giống nhau. Khi làm xáo trộn giá trị của header đầu tiên. Ứng dụng trả về HTTP status code "500": ![image](https://hackmd.io/_uploads/BJUEMC6iyg.png) - Thông báo lỗi `Proxy error` cho thấy FEs – hoạt động như một "reverse proxy" – gặp sự cố khi xử lý hoặc chuyển tiếp request tới BE. Khi làm xáo trộn giá trị của header cuối cùng. Ứng dụng trả về HTTP status code "200". Tuy nhiên khi gửi thêm một request nữa thì lại xuất hiện HTTP status code "403": ![image](https://hackmd.io/_uploads/rkGX706s1g.png) ![image](https://hackmd.io/_uploads/Sy_9QR6jJx.png) - Có thể thấy request đầu vẫn được FEs và BEs xử lí bình thường, nhưng với request kế tiếp thì xuất hiện hiện tượng request smuggling. Qua hai hành vi được trả về như trên của ứng dụng, có thể phỏng đoán được cách ứng dụng xử lí với header trùng lặp: - FEs xử lí thông qua `Transfer-Encoding` header đầu tiên, nếu giá trị của header này không phù hợp thì nó sẽ gây lỗi. - BEs xử lí thông qua `Transfer-Encoding` header cuối cùng, nếu giá trị của header này không phù hợp thì nó sẽ tự động xử lí bằng `Content-Length` header. Vì `Content-Length` header không được đưa vào trong request trên, nên giá trị của nó mặc định là `0`, khiến phần `1\r\nA\r\n0\r\n\r\n` bị chuyển sang request kế tiếp dẫn đến request smuggling. Khi này đã xác định được là bắt buộc phải dùng `Transfer-Encoding` header với FEs và lợi dụng xử lí lỏng lẻo để dùng `Content-Length` header với BEs. Lỗ hổng trở về dạng `TE.CL`. Payload khai thác cũng tương tự. ![image](https://hackmd.io/_uploads/BJskTATo1x.png) ___ ### 4. HTTP request smuggling, confirming a `CL.TE` vulnerability via differential responses >Lab bao gồm FEs và BEs. Tuy nhiên FEs không hỗ trợ "chunked encoding". Cần Smuggle một request tới BEs, để kích hoạt "404 Not Found" response. Vì đây là lỗ hổng `CL.TE`, nên sử dụng payload có ý nghĩa tương tự: ![image](https://hackmd.io/_uploads/ByPq8nAokg.png) - FEs sẽ xử lí và gửi đi toàn bộ "38" kí tự trong phần request body. - BEs sẽ chỉ nhận những đoạn trong 1 "chunk" và coi phần con lại như một phần của request kế tiếp. - Khi này request kế tiếp bị smuggling sẽ có dạng: ![image](https://hackmd.io/_uploads/ry-OmT0jkg.png) Gửi lại request này một lần nữa, xuất hiện trang "404 Not Found" response: ![image](https://hackmd.io/_uploads/S1-UR20oyx.png) ___ ### 5. HTTP request smuggling, confirming a `TE.CL` vulnerability via differential responses >Lab bao gồm FEs và BEs. Tuy nhiên BEs không hỗ trợ "chunked encoding". Cần Smuggle một request tới BEs, để kích hoạt "404 Not Found" response. Vì đây là lỗ hổng `TE.CL`, nên sử dụng payload có ý nghĩa tương tự: ![image](https://hackmd.io/_uploads/SJHgMpRsyg.png) - FEs sẽ xử lí và gửi đi 1 "chunk" hoàn chỉnh các dữ liệu trong request body. - Tuy nhiên, BEs xử lí thông qua `Content-Length` header nên chỉ nhận "4" kí tự đầu, do vậy phần còn lại được đẩy vào request kế tiếp. - Khi này, request kế tiếp bị smuggling sẽ có dạng: ![image](https://hackmd.io/_uploads/Hy42QpAjJg.png) Gửi lại request này một lần nữa, xuất hiện trang "404 Not Found" response: ![image](https://hackmd.io/_uploads/BkOTQ6Ci1l.png) ___ ### 6. Exploiting HTTP request smuggling to bypass front-end security controls, `CL.TE` vulnerability >Lab bao gồm FEs và BEs. Tuy nhiên FEs không hỗ trợ "chunked encoding". Ngoài ra FEs chặn truy cập tới `/admin`. Cần Smuggle một request tới BEs, để truy cập `/admin` và xoá user "carlos". Vì là lỗ hổng `CL.TE`, sử dụng payload tương ứng để truy cập tới `/admin`: ![image](https://hackmd.io/_uploads/S1N5x00jkl.png) Tuy nhiên `/admin` chỉ cho phép local user truy cập. ![image](https://hackmd.io/_uploads/HkkPbR0skg.png) Thử sử dụng một số kĩ thuật spoogfing header để đánh lừa thông qua IP. ![image](https://hackmd.io/_uploads/BkNFbCCo1x.png) - Tuy nhiên đều không hiệu quả. Sử dụng `Host` header thì thấy xuất hiện thông báo lỗi. ![image](https://hackmd.io/_uploads/HJKJ-CCoyl.png) - Trong request mà bị smuggling thì nó đã chứa `Host` header, do vậy ứng dụng đã xử lí và báo lỗi với trường hợp này. Tạo thêm phần body cho smuggling request, thành công truy cập vào `/admin`: ![image](https://hackmd.io/_uploads/ryq8g0Aoye.png) - Khi này, phần header của request bị smuggling đã được đẩy vào body của request smuggling, nên chỉ còn một `Host` header. Xoá user được chỉ định. ![image](https://hackmd.io/_uploads/r17peCAikg.png) ___ ### 7. Exploiting HTTP request smuggling to bypass front-end security controls, `TE.CL` vulnerability >Lab bao gồm FEs và BEs. Tuy nhiên BEs không hỗ trợ "chunked encoding". Ngoài ra FEs chặn truy cập tới `/admin`. Cần Smuggle một request tới BEs, để truy cập `/admin` và xoá user "carlos". Vì là lỗ hổng `TE.CL`, sử dụng payload tương ứng để truy cập tới `/admin`: ![image](https://hackmd.io/_uploads/SJaIV0Rs1x.png) Bypass cơ chế kiểm soát truy cập của `/admin` với non-local user: ![image](https://hackmd.io/_uploads/HJu0NCRoke.png) Xoá user được chỉ định: ![image](https://hackmd.io/_uploads/BJgHH0Aiyl.png) ___ ### 8. Exploiting HTTP request smuggling to reveal front-end request rewriting >Lab bao gồm FEs và BEs. Tuy nhiên FEs không hỗ trợ "chunked encoding". `/admin` chỉ có thể tuỷ cập từ IP `127.0.0.1`. Ngoài ra, FEs thêm một HTTP header vào req, cái tương tự với `X-Forwarded-For`. Cần Smuggle một request tới BEs, để truy xuất header được thêm bởi BEs, truy cập `admin` và xoá user "carlos". Qua thử nghiệm với 2 payload thì xác định được đây là lỗ hổng `CL.TE`: ![image](https://hackmd.io/_uploads/BJiD37yhyg.png) ![image](https://hackmd.io/_uploads/H1eshQy2Je.png) - Với FEs sử dụng `Content-Length` header, nên nó sẽ chỉ chuyển tiếp một phần của request, bỏ qua `X`. BEs sử dụng `Transfer-Encoding` header, xử lý "chunk" tiên, sau đó chờ "chunk" theo đến. Điều này sẽ gây ra sự chậm trễ có thể quan sát được. Được biết là tại FEs sẽ thêm một số header bổ sung trước khi gửi tới BEs. Cần phải tìm cách trích xuất được các header này, và gửi kèm nó trong request được smuggle thì BEs mởi chấp nhận. Lợi dụng việc chuỗi dữ liệu được sử dụng trong chức năng "Search" sẽ được phản xạ trong response: ![image](https://hackmd.io/_uploads/BypnZVy21x.png) Dựng payload khai thác `CL.TE` đồng thời khiến request bị smuggle phải nằm trong request body của smuggling request: ![image](https://hackmd.io/_uploads/Hyj31Vy2kl.png) ![image](https://hackmd.io/_uploads/HyHax4J3Jl.png) - Khi này, request bị smuggle nếu được xử lí như một request body bình thường, nó sẽ được phản xạ vào response. - Cần phải chọn giá trị phù hợp `Content-Length` trong request bị smuggle. Vì nếu quá nhỏ thì không đọc đủ dữ liệu hoặc quá lớn thì bị time out. Lần lượt thử với từng giá trị cho `Content-Length` để tìm giá trị phù hợp: ![image](https://hackmd.io/_uploads/BkftmEy3Jg.png) - Với "720" thì đủ dài để thấy toàn bộ header, thấy xuất hiện của header được thêm vào là `X-zThlYm-Ip: 1.53.37.255`. Truy cập vào `/admin` thì thấy giới hạn truy cập chỉ cho local user: ![image](https://hackmd.io/_uploads/HkMMPN12Jx.png) Cần phải truy cập `/admin` thông qua IP `127.0.0.1`: ![image](https://hackmd.io/_uploads/Hy_5D4knkx.png) - Nhận thấy, `X-zThlYm-Ip` có lẽ là header chứa IP của FEs để BEs xác nhận hoặc đích nới FEs đưa request tới. Nên thử đặt `127.0.0.1` vào đó. - Thành công truy cập `/admin` Xoá user được chỉ định: ![image](https://hackmd.io/_uploads/BkKpPE13yl.png) ___ ### 9. Exploiting HTTP request smuggling to capture other users' requests >Lab bao gồm FEs và BEs. Tuy nhiên FEs không hỗ trợ "chunked encoding". Cần Smuggle một request tới BEs, để truy xuất request được lưu trên ứng dụng của user kế tiếp và chiếm được cookies. Sử dụng payload thông thường cho dạng `CL.TE` thấy xuất hiện lỗ hổng như dự tính: ![image](https://hackmd.io/_uploads/HkPMUAXhJx.png) Xây dựng payload để lợi dụng lỗ hổng từ chức năng đăng bài thông qua POST request: ![image](https://hackmd.io/_uploads/H1lDT0Xnye.png) - Phần `POST /post/comment` được gắn vào request ban đầu tạo thành Smuggling request. - Đồng thời, phần body của Smuggle request chưa tham số `comment`. Request này được xử lí như một request mới độc lập và nó biến request kế tiếp nó thành giá trị cho tham số `comment`. Thực hiện gửi Smuggling request hai lần để kiểm tra: ![image](https://hackmd.io/_uploads/By7QACm3yg.png) - Có thể thấy, một phần của Smuggling request được đưa ra như phần "Comment". Khi đã xác nhận lỗ hổng, ta chỉ cần gửi Smuggling request một lần: ![image](https://hackmd.io/_uploads/ByuA00Qhyg.png) - Khi này, request kế tiếp của nạn nhân, trở thành giá trị cho tham số `comment` trong Smuggling request và được đưa ra màn hình. - Ta lấy được request mà nạn nhân gửi, đi kèm `Cookies` header. Thay thế giá trị các cookies của ta thành cookies của nạn nhân ![image](https://hackmd.io/_uploads/H1VzyJN3yx.png) Thành công giả danh truy cập victim account: ![image](https://hackmd.io/_uploads/Sy15nRmhyl.png) ___ ### 10.Exploiting HTTP request smuggling to deliver reflected XSS >Lab bao gồm FEs và BEs. Tuy nhiên FEs không hỗ trợ "chunked encoding". Ứng dụng cũng có lỗ hổng rXSS thông qua `User-Agent` header. Cần Smuggle một request tới BEs, khiến response của user kế tiếp xuất hiện `alert(1)`. Kiểm tra source code tại `/post?postId=6`, thấy xuất hiện trường `userAgent` trong form: ![image](https://hackmd.io/_uploads/rJvb0yE2ye.png) ![image](https://hackmd.io/_uploads/ryO8C1Ehyg.png) - Có thể thấy, khi load trang này, ứng dụng reflect giá trị của `User-Agent` header. Thử với XSS payload để xem liệu có lỗ hổng rXSS với trường hợp này không: ![image](https://hackmd.io/_uploads/ryHn0JVn1e.png) Xác nhận được trang này tồn tại lỗ hổng rXSS khi cố gắng đưa giá trị của `User-Agent` header vào response. Kiểm tra lỗ hổng HRE, với payload tương ứng với dạng `CL.TE`, thấy kết quả như dự tính: ![image](https://hackmd.io/_uploads/rJEbkeE2kg.png) Đưa rXSS payload vào smuggle request và tạo smuggling request, rồi gửi đi: ![image](https://hackmd.io/_uploads/r1zQ1g4nye.png) - Khi này, smuggle request sẽ được gửi tới user kế tiếp truy cập trang này, và khiến họ bị tấn công rXSS. --- ### 11. Exploiting HTTP request smuggling to perform web cache poisoning >Lab bao gồm FEs và BEs. Tuy nhiên FEs không hỗ trợ "chunked encoding". FEs được cấu hình để cache response nhất định. Cần smuggle một request để khiến cache bị poison, mà redirect đến exploit server, gọi ra alert(document.cookie). Sử dụng payload thông thường cho dạng `CL.TE` thấy xuất hiện lỗ hổng như dự tính: ![image](https://hackmd.io/_uploads/B1Hg77rhke.png) Thấy trong HTTP history xuất hiện request tới `/tracking.js`: ![image](https://hackmd.io/_uploads/B1sCGUrnJx.png) - Ứng dụng đã cache lại trang này thông qua các header `Cache-Control`, `X-Cache`. ![image](https://hackmd.io/_uploads/ry3ONQH3Jl.png) Trong mỗi "Post" đều có chức năng "Next post": ![image](https://hackmd.io/_uploads/r1eS1wHhJe.png) - Nó redirect user sang trang mới thông qua `Location` header. - Có thể thấy, trong `Location` header, nó có host trùng hoàn toàn với `Host` header của request. Thử thay đổi giá trị của `Host` header trong request: ![image](https://hackmd.io/_uploads/ry1aJDH2yl.png) - Với `HTTP/2` thì nó trả về `421`. Sử dụng `HTTP/1.1` thì xuất hiện `403`. Có thể thấy, từ đây ta có thể redirect ra ngoài nhưng không thể trực tiếp sử dụng do bị cấm. Thử kết hợp HSR để đánh lừa ứng dụng thực hiện smuggle request chứa redirect: ![image](https://hackmd.io/_uploads/Hk2fnoP2Jl.png) - Sau khi gửi 2 lần request, thấy xuất hiện `302`, cho thấy được ứng dụng đã thực hiện một redirect tới domain ta sửa trong `Host` header. - Có thể FEs xử lí cấm các redirect ra bên ngoài. Tuy nhiên, khi ta thực hiện smuggling, FEs bị đánh lừa, và sau đó, BEs thực hiện smuggle request như thường và redirect tới trang khác. Lợi dụng điều này, ta có thể khiến ứng dụng redirect tới domain độc hại, sau đó đánh lừa ứng dụng cache lại trang này. Dựng exploit server chứa script độc hại: ![image](https://hackmd.io/_uploads/SkjHcnP2ke.png) Thông qua HSR để lừa ứng dụng gửi request để redirect tới domain nguy hiểm: ![image](https://hackmd.io/_uploads/rkFm8nv31g.png) ![image](https://hackmd.io/_uploads/r12tInPnJe.png) - Thành công tạo redirect tới domain nguy hiểm. Lợi dụng điều ấy, tạo smuggling request để khiến ứng dụng redirect tới domain độc hại: ![image](https://hackmd.io/_uploads/Byj5F3P3Jx.png) - Tại đây, ta chỉ cần gửi request một lần. Khi này ứng dụng sẽ thực thi request đầu tiên hay là smuggled request. Sau đó, smuggle request sẽ được BEs xử lí như một request độc lập và trả về response tương ứng với request này. Đồng thời, ứng dụng cũng tự động cache sau đó, và vô tình cache lại response này. Khi này truy cập vào `/resources/js/tracking.js` sẽ thấy response độc hại được cache: ![image](https://hackmd.io/_uploads/HkY0qnwnJl.png) Folow redirection: ![image](https://hackmd.io/_uploads/HJ6jaMdnyl.png) ___ ### 12. Exploiting HTTP request smuggling to perform web cache deception >Lab bao gồm FEs và BEs. Tuy nhiên FEs không hỗ trợ "chunked encoding". FEs cache resource tĩnh. Cần smuggle một request để khiến API của victim bị cache, và sau đo truy xuất nó. Có thể sử dụng thông tin đăng nhập : `wiener:peter` Sử dụng payload thông thường cho dạng `CL.TE` thấy xuất hiện lỗ hổng như dự tính: ![image](https://hackmd.io/_uploads/ryxWKOrhJe.png) Thấy trong HTTP history xuất hiện request tới `/tracking.js`: ![image](https://hackmd.io/_uploads/ryH4O_Bn1x.png) - Ứng dụng đã cache lại trang này thông qua các header `Cache-Control`, `X-Cache`. ![image](https://hackmd.io/_uploads/ry3ONQH3Jl.png) Sử dụng payload để kết hợp khai thác WCD và HSR: ![image](https://hackmd.io/_uploads/HJMpAdH21e.png) - Đầu tiên lợi dụng HSR để gửi đi một smuggle request tới `/post?postId=6`, đồng thời đặt thêm `/resources/js/tracking.js` vào request đó. - Ứng dụng phản hồi request đầu tiên (smuggled request), tuy nhiên smuggle request được tự động xử lí như request độc lập. Sau đó, ứng dụng tự động request cache, và vô tình cache response nhạy cảm mà ta chủ đích xâm phạm. - Khi này, gửi đi lần đầu thì nó trả về `/` tuy nhiên khi gửi đến lần kế, server xử lí phần smuggle request và đi đến `/post?postId=6`. - Thử mở `/resources/js/tracking.js` thì thấy `/post/postId=6` đã được cache lại. Có thể thấy lỗ hổng WCD một cách rõ ràng. Dựng payload khai thác 2 lỗ hổng đã phát hiện trên: ![image](https://hackmd.io/_uploads/HkgRHKrn1e.png) - Khi này, ta gửi request lần đầu sẽ đi đến `/`, đồng thời đánh lừa BEs xử lí smuggle request như request độc lập. - Khi này nạn nhân gửi req thì sẽ bị đặt smuggle request ở trước: ![image](https://hackmd.io/_uploads/HkRzIFShkl.png) Sau đó kiểm tra endpoint cache: ![image](https://hackmd.io/_uploads/HJ4q8YB2Jx.png) - Có 5 endpoint cho phép cache , nhưng chỉ có 2 endpoint trên cache dữ liệu mong muốn. - Sau nhiều lần thử (đều do trang được cache lại là trang đăng nhập - có thể do thiếu cookie của victim) thì lấy được API key. ___ ### 13. `H2.CL` request smuggling >Lab này có lỗ hổng dẫn tới RS vì FEs downgrade HTTP/2 request. Cần RS khiến victim's browser tải và thực thi JS file. Thử nghiệm payload dành cho `H2.CL` ![image](https://hackmd.io/_uploads/SyEdgzuhJl.png) - Lần đầu gửi req nó trả về `/` và lần kế tiếp, `/post?postId=9` được trả về do nó đã bị smuggling. - Lợi dụng FEs downgrading để smuggle request thông qua `Content-Length` header. - HTTP/2 có cơ chế tính độ dài riêng (không dựa vào `Content-Length` như HTTP/1.1). Khi downgrade xuống HTTP/1.1, server không kiểm tra chặt chẽ, khiến nó giữ nguyên `Content-Length` giả mạo trong request. - Khi này server kết thúc smuggled request và xử lí smuggle request như một request mới. - Trong smuggle request, sử dụng phần body để khiến toàn bộ request bị nó gắn vào thành body để tránh lỗi. Mỗi khi load `/`, ứng dụng request thêm một số file JS như sau: ![image](https://hackmd.io/_uploads/Skz7fGunJg.png) Thử nghiệm một số thay đổi với path của các file JS này: ![image](https://hackmd.io/_uploads/BybYmGu3Jx.png) - Nhận thấy ứng dụng có một cơ chế xử lí nào đó, khi ta request tới path thiếu `/` cuối folder, thì nó sẽ redirect ta tới path đó thêm `/` ở cuối. - Đồng thời sự redirect này đưa ta đến domain giống với domain trong `Host`. - Có thể nhận thây đây có tiềm năng khai thác lỗ hổng redirect. Thành công redirect tới domain bên ngoài thông qua HSR: ![image](https://hackmd.io/_uploads/H1W_VzOhye.png) Dựng exploit server phù hợp để khai thác theo mục đích: ![image](https://hackmd.io/_uploads/S1U3Kf_31e.png) Sau rất nhiều lần thử thì mới có thể thành công: ![image](https://hackmd.io/_uploads/SkTytzOnyg.png) ___ ### 14. Response queue poisoning via `H2.TE` request smuggling >Lab này có lỗ hổng dẫn tới RS vì FEs downgrade HTTP/2 request. Sử dụng RQP để dừng res tại `/admin` và xoá user được chỉ định. Thử nghiệm với payload cho `H2.CL`: ![image](https://hackmd.io/_uploads/HkTjsD_31x.png) - Sau nhiều lần thử thì thấy không có hành vi đáng ngờ. Thử thêm `Transfer-Encoding` header: ![image](https://hackmd.io/_uploads/B1k_hPO31l.png) - Sau khi gửi request lần hai thì thấy hành vi như dự tính. Thành công RS thông qua `H2.TE`. Dựa theo lí thuyết thì ta có thể smuggle request, khiến ứng dụng trả về sai response. Từ đó chiếm session cookie của administrator. ![image](https://hackmd.io/_uploads/rkfOLS53Jl.png) Sau khi thử rất nhiều lần thì thấy được response của victim: ![image](https://hackmd.io/_uploads/r1rGvLc2ke.png) Sử dụng cookie nhận được để mạo danh đăng nhập và xoá user chỉ định: ![image](https://hackmd.io/_uploads/H1zVPL92Je.png) ___ ### 15. HTTP/2 request smuggling via CRLF injection >Lab này có lỗ hổng dẫn tới RS vì FEs downgrade HTTP/2 request và không làm sạch header đầy đủ. Sử dụng HTTP/2-exclusive RS vector chiềm quyền truy cập victim's account. Thử với payload cho `H2.CL` và `H2.TE` đều không khả thi: ![image](https://hackmd.io/_uploads/HyAyJj52kx.png) Thử sử dụng payload tương ứng như thông qua CRLF injection tại header: ![image](https://hackmd.io/_uploads/ryJUJoqhkx.png) - Có thể thấy kết quả tìm kiếm được reflect trong response. - Có thể thực hiện CRLF injection thành công với cả hai header `Content-Length` và `Transfer-Encoding`. - Với việc injection như trên thì tương tự như các trường hợp trước ta đã làm. Tuy nhiên, vì đây là HTTP/2 nên ta phải làm như này. Có thể thấy giá trị của tham số `search` được lưu lại và trả về trên response. Ta có thể lợi dụng điều này để capture request của victim dựa trên kịch bản đã có thông qua request smuggling. Kiểm tra cách ứng dụng xử lí độ dài body của request: ![image](https://hackmd.io/_uploads/HyavoAs2kx.png) - Mặc dù đã chỉnh giá trị của `Content-Length` thành `0`, nhưng ứng dụng vẫn nhận được đầy đủ giá trị của body request. - ![image](https://hackmd.io/_uploads/B19Z20jnkg.png) Thử kiểm tra với `Transfer-Encoding` header: ![image](https://hackmd.io/_uploads/Sknfkkh3kx.png) - Có thể thấy, dù gửi một request không hợp lệ với header này. Nhưng ứng dụng vẫn xử lí và trả về response như bình thường. Ứng dụng đã tự tính toàn độ dài request, đồng thời bỏ qua `Transfer-Encoding` header. Để có thể khai thác `H2.CL` hoặc `H2.TE` ta buộc phải khai thác thông qua lỗ hổng CRLF injection thay vì khai thác trực tiếp. Xác nhận thành công kết hợp `H2.TE` với CRLF injection: ![image](https://hackmd.io/_uploads/Hkt4Eynh1x.png) - Điều này xảy ra do với HTTP/2 không sử dụng "\r" hay "\n" là các kí tự CR và LF, nên khi các kí tự này, HTTP/2 không xử lí. - Tuy nhiên, do FEs downgrade từ HTTP/2 xuống HTTP/1.1 để gửi cho BEs. Khi này, "\n" và "\r" được xử lí bình thường, khiến header ta chèn vào được sử dụng. Thành công tạo ra một smuggle request: ![image](https://hackmd.io/_uploads/SyPi4k3hkx.png) Thử nghiệm với smuggle request nhằm xác thực tính khả thi: ![image](https://hackmd.io/_uploads/BJ69Uynhyx.png) - Do ứng dụng sử dụng HTTP/2 nên nó tự tính toán độ dài request. Ta không thể trực tiếp thay đổi `Content-Length` mã phải thay đổi trong smuggle request nhằm thực hiện capture dữ liệu của victim. Dựng smuggle request nhằm thực hiện capture request của victim: ![image](https://hackmd.io/_uploads/rkn0kl3hyl.png) - Đúng kịch bản là khi ta request smuggling, victim sẽ gửi request (chứa cookie), Lúc này, nó trả thành body của smuggle request và được hiển thị ra response. - Phải thử rất nhiều lần thì mới có thể thành công. ___ ### 16. HTTP/2 request splitting via CRLF injection >Lab này có lỗ hổng dẫn tới RS vì FEs downgrade HTTP/2 request và không làm sạch header đầy đủ. Sử dụng RQP để bắt lấy `/admin`, và xoá user chỉ định. Kiểm tra đơn giản thấy không thể can thiệp trực tiếp header gốc như `H2.TE` hay `H2.CL`: ![image](https://hackmd.io/_uploads/SyA9Nz231x.png) Dựng payload lợi dụng CRLF injection để request smuggling thông qua header: ![image](https://hackmd.io/_uploads/rJYMlXnnJe.png) Thay thế cookie nhận được và xoá user được chỉ định: ![image](https://hackmd.io/_uploads/rJhc8m3nJg.png) ___ ### 17. Bypassing access controls via HTTP/2 request tunnelling >Lab này có lỗ hổng dẫn tới RS vì FEs downgrade HTTP/2 request và không làm sạch header đầy đủ. Truy cập `/admin`, và xoá user chỉ định. FEs không tái sử dụng lại kết nối tới BE. Cần phải sử dụng HRT. Ngoài ra cần phải lưu ý một số header cần thiết. Thử cách để khai thác CRLF injection vào phần header: ![image](https://hackmd.io/_uploads/Byl_5G6h1x.png) ![image](https://hackmd.io/_uploads/HJAa9G631x.png) Khi chèn `Content-Length` header ở dưới cùng thì xuất hiện lỗi: ![image](https://hackmd.io/_uploads/BJK-2Mp31l.png) - Có thể thấy, sau khi xử lí FEs đã thêm `Content-Length` header vào trước, dẫn đến trùng lặp. - Chỉ cần đẩy phần header được injection này lên trên cùng trong các header. Dựng payload nhằm xác định trường header được FEs thêm vào: ![image](https://hackmd.io/_uploads/r1OW27phJg.png) - Khi này, với việc đẩy header được injection lên trên, thì ta biến phần còn lại của request header thành body. - Từ đó lấy được ra 3 trường header mà FEs thêm vào. - Thay đổi giá trị các trường để mạo danh 'administrator'. Kết hợp HRT và CSRFi để mở được `/admin`: ![image](https://hackmd.io/_uploads/ByBz7Nankl.png) - ![image](https://hackmd.io/_uploads/ryvCUu62kl.png) - Khi này, ta lợi dụng response của "HEAD" request để chứa response của "GET" request được tunnel. - Tuy nhiên, do độ dài mà `Content-Length` header của "HEAD" response trả về lớn hơn số kĩ tự mà "GET" response trả về nên lỗi. Thay đổi để endpoint có `Content-Length` phù hợp hơn: ![image](https://hackmd.io/_uploads/BJEXjuT2yl.png) Thành công truy cập vào `/admin`: ![image](https://hackmd.io/_uploads/rkAYsdahke.png) Xoá user được chỉ định: ![image](https://hackmd.io/_uploads/HyMjsOanyx.png) ___ ### 18. Web cache poisoning via HTTP/2 request tunnelling >Lab này có lỗ hổng dẫn tới RS vì FEs downgrade HTTP/2 request và không làm sạch header đầy đủ. Đầu độc cache và khiến victim's browser thực thi `alert(1)`. FEs không tái sử dụng lại kết nối tới BE. Cần phải sử dụng HRT. Ngoài ra cần phải lưu ý một số header cần thiết. d ___ ### 19. CL.0 request smuggling >Lab này chứa lỗ hổng `CL.0` RS. BEs bỏ qua `Content-Length` header trong request tới một số endpoint. Xác định endpoint và truy cập `/admin`. Với lỗ hổng `CL.0` RS, cách FEs và BEs xử lí kết thúc request không đồng bộ, dẫn đến request có thể bị xử lí sai. Thường thì tại một số endpoint, BEs có thể xử lí và bỏ qua phần body của request, dẫn tới nó bị trở thành request kế tiếp nếu nó hợp lệ. Từ đó bypass được AC của FEs. Thông qua cách khai thác `CL.0` RS vul để tìm endpoint phù hợp: ![image](https://hackmd.io/_uploads/SJXLrjC31x.png) - Gửi 2 request liên tiếp trên cùng một kết nối bằng "Send group". Đồng thời đặt `Connection: keep-alive` cho request đầu để đảm bảo giữ kết nối cho request kế tiếp. - Tại đây, ta thử gửi `POST` request tới `/`, kèm theo phần body là một request hợp lệ. FEs sẽ nhận đủ request này, và xác định phần body chứa số kí tự tương đương với giá trị của `Content-Length`. - Nếu với endpoint này, BEs không nhận body của request (BEs chấp nhận `Content-Length` là 0), thì request nhận được sẽ bị chia ra:![image](https://hackmd.io/_uploads/B1Qo5oA3yx.png) - Khi request đầu tiên được BEs xử lí thì nó trả về trong response tương ứng. Request bị tách ra sau đó được xử lí và trả về response nhưng không được gửi vì request tương ứng của nó là smuggling request. - Lúc này, với việc ta gửi tiếp một follow-up request, response của smuggling request sẽ được xem là response của follow-up request, và trả về. - Tuy nhiên, tại đây, response trả về lại là response của follow-up. Do đó với endpoint này, BEs vẫn xử lí body như thông thường. ![image](https://hackmd.io/_uploads/BJjHhoA3ke.png) Thử kiểm tra và gửi request tới endpoint tĩnh khả nghi: ![image](https://hackmd.io/_uploads/BJBqajC3Jl.png) ![image](https://hackmd.io/_uploads/SkjrCo0nkg.png) - Có thể thấy, BEs đã cắt bỏ body của smuggled request, dẫn tới nó (`a=1`) trở thành request độc lập. Và response của request đó đã báo lỗi "Method". - Khi này, gửi smuggle request tới `/404` thì xác nhận được là BEs đã xử lí request này. Smuggle thành công request để truy cập vào `/admin` và bỏ qua FE Access Control: ![image](https://hackmd.io/_uploads/HyB0AjA3yl.png) Xoá user được chỉ định: ![image](https://hackmd.io/_uploads/By-iJhAnkg.png) ___ ### 20. Client-side desync >Lab dễ bị tấn công client-side desync do server bỏ qua `Content-Length` ở một số endpoint. Khai thác client-side desync để làm trình duyệt nạn nhân rò rỉ session cookie qua chuỗi yêu cầu cross-domain. Xác định vector desync và gadget lưu dữ liệu, kết hợp chúng để đánh cắp cookie, rồi dùng cookie đó truy cập tài khoản nạn nhân. Tìm kiếm trong ứng dụng web thấy xuất hiện gadget khả thi tại endpoint `/`: ![image](https://hackmd.io/_uploads/HJ1WpR_Lxe.png) - Tại đây, nó sẽ thực hiện redirect tới `/en`. - Khi gửi bằng POST request, đồng thời gửi với `Content-Length` header vượt quá độ lớn của body thì ứng dụng có hành vi như thông thường. Trong khi thực hiện tương tự với `/en` thì thông báo lỗi: ![image](https://hackmd.io/_uploads/BkRmCRu8eg.png) Nhận thấy tiềm năng khai thác lỗ hổng HRS dạng CL.0 cụ thể ở đây là CL desync và nó xảy ra khi khi ứng dụng cố gắng tái sử dụng kết nối. Tiếp tục thử payload: ![image](https://hackmd.io/_uploads/S12d0C_Iel.png) - Khi gửi lần 1, res trả về là của req gốc, đến lần thứ 2 thì thấy res là của smuggled req. - Có thể thấy, ứng dụng tái sử dụng kết nối, dẫn đến smuggled req được xử lí theo đúng quy trình của HRS. Payload này tương tự, nhưng biến dòng đầu của req kế thành header và khiến req đó trở thành một phần của smuggled req: ![image](https://hackmd.io/_uploads/SyKW_1FUxl.png) Sau khi xác định được gadget, tiến hành thử nghiệm trên browser: ``` fetch('https://0af5008b04c941d1805b1788007300db.h1-web-security-academy.net/', { method: 'POST', body: 'GET /404pls HTTP/1.1\r\nX-Foo: x', // malicious prefix mode: 'cors', // ensures the connection ID is visible on the Network tab credentials: 'include' // poisons the "with-cookies" connection pool }).catch(() => { fetch('https://0af5008b04c941d1805b1788007300db.h1-web-security-academy.net', { mode: 'no-cors', credentials: 'include' }) }) ``` - Với payload này, khi chạy trên tab Console của browser. Nó sẽ `fetch` tới URL được chỉ định. Và sẽ cung cấp rõ một số thông số của request đó. Đáng lẽ log trong Console và thông tin trong Network sẽ phải trả về như sau: ![image](https://hackmd.io/_uploads/By_zK1KLlx.png) ![image](https://hackmd.io/_uploads/HJJNtyt8eg.png) Tuy nhiên, có thể do lỗi trình duyệt nên nó đã không tự động reuse connection, dẫn đến không smuggle được request tới `/404`: ![image](https://hackmd.io/_uploads/rkhOOkKIgl.png) Mặc dù vậy với payload và cách thử nghiệm trên vẫn hoàn toàn đúng. Có thể vấn đề nằm ở browser nên khi gửi tới victim vẫn hoạt động bình thường. Maliciuos requets: ![image](https://hackmd.io/_uploads/rkQ9K1KUxl.png) Basic request (Victim view): ![image](https://hackmd.io/_uploads/SJMot1tUxg.png) Reveal data: ![image](https://hackmd.io/_uploads/Bkg3K1FLex.png) ``` <script> fetch('https://0a60000703fc70a5802821ad00340048.h1-web-security-academy.net', { method: 'POST', body: 'POST /en/post/comment HTTP/1.1\r\nHost: 0a60000703fc70a5802821ad00340048.h1-web-security-academy.net\r\nCookie: session=KFXoXHYr4ZgonH1mys6ZZAk6jpyUfeY3; _lab_analytics=aGPTAehZ9tQdIwJbtADdpsiIhjWtU5DDyADCYdqDsd5k9PRrvuQYNXARQoscGl8BlCjXXTf59xrB6u3eTLQUiP72fZWP7lb9vcvBuBpjBcg7qkPsJEcRYWoagiljKOQJV3ORBYqFy4gUS8sCDNlO2n5q9pNXZ0OsX0QtPlEDn4R5nr3JJuh9JkxF2GWAZHVPEeCohRicXLhsAQBmSOLpEgqj5lkXTkXIkB6fGkR4v9iVC094fu66Xd18Fou4zmjJ\r\nContent-Length: 1020\r\nContent-Type: x-www-form-urlencoded\r\nConnection: keep-alive\r\n\r\ncsrf=XTItF2ikhGbDVNNzwqukN39BO5LhjPkz&postId=2&name=wienerhacked&email=wiener@web-security-academy.net&website=https://portswigger.net&comment=', mode: 'cors', credentials: 'include', }).catch(() => { fetch('https://0a60000703fc70a5802821ad00340048.h1-web-security-academy.net/my-account', { mode: 'no-cors', credentials: 'include' }) }) </script> ``` Lấy được cookie của victim: ![image](https://hackmd.io/_uploads/Hyi3YJFIxg.png) Thành công truy cập trang cá nhân bằng cookie của victim: ![image](https://hackmd.io/_uploads/BJrpKJFLgl.png) ___ ### 21. Server-side pause-based request smuggling >Lab dính lỗi pause-based server-side request smuggling (CL.0). Tìm vector desync, smuggle request truy cập /admin, rồi xóa user carlos