# BUSINESS LOGIC VULNERABILITIES WIRTE UP --- ###### tags: `PortSwigger` `Writeup` ## 1. Lab: Excessive trust in client-side controls ![](https://i.imgur.com/1GDoHpN.png) - Lab này sẽ không kiểm tra đầu vào của người dùng 1 cách kỹ lưỡng và đầy đủ, tạo điều kiện cho ta có thể khai thác, từ đó mua những vật phẩm với giá thành ko như dự định. - Để solve được lab, hãy mua 1 chiếc "Lightweight l33t leather jacket". - Ta được cấp tài khoản và mật khẩu của bản thân: wiener:peter - Đầu tiên, em chọn mục mua hàng và chọn "Lightweight l33t leather jacket", sau đó thêm vào giỏ hàng rồi ấn Place Order. Dòng lỗi xuất hiện ra là em không thể mua được vì không đủ tiền - Em nhận thấy có 1 tab là POST /cart -> đây chính là thao tác thêm vào giỏ hàng, nên em đã thử đổi giá tiền của chiếc áo khoác này, từ 1337,00$ thành 1,00$ ![](https://i.imgur.com/SnHaTTS.png) - Thật bất ngờ là nó đã hoạt động!!!, em ngay lập tức gửi respond vào web browser để thực hiện việc mua hàng: ![](https://i.imgur.com/Sj8K9Gw.png) - Em đã mua 2 chiếc với giá 2 đô, và đồng thời solve được lab ## 2. Lab: High-level logic vulnerability ![](https://i.imgur.com/uU4r6pW.png) - Vẫn như lab trước, nhiệm vụ của chúng ta là mua chiếc "Lightweight l33t leather jacket" với tài khoản và mật khẩu được cấp: wiener:peter - Đầu tiên, đặc điểm của lab này rõ ràng đã khác với lab trước khi họ không còn gửi kèm cả giá tiền trong phương thức post, nên việc chỉnh giá tiền không còn thực hiện được nữa - Tuy nhiên, họ lại cho phép ta mua ÂM số lượng hàng hóa, điều này nghĩa là gì, nghĩa là em có thể mua ÂM một số lượng hàng hóa nhất định để cân bằng lại với 1337$ kia, và cụ thể là em đã chọn mặt hàng "Dancing In The Dark" với giá 7$. Theo tính toán thì em cần 190 mặt hàng với id=4 này để cân bằng với chiếc áo khoác ![](https://i.imgur.com/DyoOZ2d.png) - Em ngay lập tức đưa tab POST /cart vào tab Repeater để sửa đổi request, với việc đưa id=4 và quantity=-190, em đã đặt -190 mặt hàng "Dancing In The Dark" ![](https://i.imgur.com/ety7Mny.png) - Sau đó, việc thanh toán đã quá dễ dàng: `1337 - 190*7 = 7`, em chỉ việc phải trả 7$ cho một chiếc áo khoác, và như vậy, em đã solve được lab trên: ![](https://i.imgur.com/LXSkJTy.png) ## 3. Lab: Low-level logic flaw ![](https://i.imgur.com/HYqZvJI.png) - Nhiệm vụ của chúng ta vẫn giống như các lab trước, là mua chiếc áo "Lightweight l33t leather jacket", lab này vẫn không kiểm tra đầu vào của user một cách đầy đủ - Nhưng đặc biệt ở lab này, là khi em nhập vào ÂM số lượng hàng hóa, nếu số lượng hàng hóa < hoặc = 0, nó sẽ xóa mặt hàng đó khỏi giỏ hàng - Nhưng có một điều rất đáng ngờ ở đây, là khi em thử nhập quantity lớn (1000; 100; ...) nó lại ghi là giá trị không thỏa mãn, số 99 là số to nhất thỏa mã số lượng mua ![](https://i.imgur.com/hAira9O.png) ![](https://i.imgur.com/3nwIzCM.png) - Chả có cớ gì mà nó lại giới hạn số lượng mua hàng, ngoại trừ khi nó giới hạn **Số tiền có thể mua**, em đang nghi ngờ là em có thể làm **tràn số tiền em phải trả**, từ đó bypass được số tiền: - Để làm tràn số thì em không thể send mãi ở tab Repeater, nên em đã lựa chọn chuyển sang Intruder ![](https://i.imgur.com/3gBqRlF.png) - Em chọn null payloads vì em không gửi 1 biến số gì cả, đồng thời để 1000 request, đồng nghĩa với việc em mua xấp xỉ hơn 90000 cái áo ![](https://i.imgur.com/opyoDHG.png) ![](https://i.imgur.com/jPkLKbJ.png) - Quả đúng như dự đoán, chắc chắn người code trang web đã để giới hạn INT hoặc tương tự cho đơn vị total này, vì `số lượng áo * 1337$` đã vượt quá giới hạn INT, từ đó nó trả về cho em giá trị âm ![](https://i.imgur.com/FnAEA2t.png) - Em đã sử dụng 1 sản phẩm khác để cân bằng số tiền âm: ![](https://i.imgur.com/LmObtwR.png) - Tiếp tục gửi 1000 payloads với 99 sản phẩm này để xem giá tiền sẽ như thế nào ![](https://i.imgur.com/8efGB93.png) ![](https://i.imgur.com/UkFHUne.png) - Gửi xong thì tiền của em đã về số dương, giờ em chỉ cần giảm mặt hàng "Pest Control Umbrella" để phù hợp với ví tiền là xong ![](https://i.imgur.com/At4TXBU.png) - Sau một hồi cân bằng thì em đã mua được với giá $3.87, quá lời ![](https://i.imgur.com/md5I3Wp.png) - Đặt hàng, em đã solve được lab trên: ![](https://i.imgur.com/iZz0vRP.png) ## 4. Lab: Inconsistent security controls ![](https://i.imgur.com/QmX1WUw.png) - Lab này có chứa một logic khiến cho 1 người dùng tùy ý có thể truy cập được những tính năng của admin mà đáng lẽ ra nó chỉ có ở nhân viên công ti - Để solve lab thì ta cần truy cập vào admin panel và xóa Carlos. - Lúc mới vào em đã thử xem liệu ta có thể forward đến được trang /admin hay /admin_panel không, thì khi em chạy đến /admin, nó đã hiện là: ![](https://i.imgur.com/CBa8JIv.png) - Nghĩa là nhiệm vụ của em là biến tài khoản của mình thành tài khoản của nhân viêc công ty DontWannaCry - Thế nên là đầu tiên em sẽ đăng kí với tên mình như sau: ![](https://i.imgur.com/tO2Qy0C.png) - Sau đó check ở trong email của bản thân: ![](https://i.imgur.com/19ad9s7.png) - Sau đó em đăng nhập thành công với tên tài khoản và mật khẩu là `bruh`, em tiến vào my account và rất ngạc nhiên vì trang web cho em có thể đổi email: ![](https://i.imgur.com/AiJYCP8.png) - Ta còn nhớ lúc khi mình mới vào chứ, họ bảo nếu làm việc cho DontWannaCry thì hãy đăng ký với domain email @dontwannacry.com nên em đã thay đổi với email như vậy ![](https://i.imgur.com/v2k10Vn.png) - Quá tuyệt vời, em đã bypass thành công và em có thêm tab Admin panel, vào tab và xóa đi carlos, em đã solve được lab: ![](https://i.imgur.com/na1ai34.png) ## 5. Lab: Weak isolation on dual-use endpoint ![](https://i.imgur.com/IuNTebY.png) - Lab này có chứa lỗ hổng mà mình có thể lấy được quyền của admin dựa vào đầu vào của người dùng, để solve lab, truy cập vào tài khoản của administrator và xóa Carlos. - Em được cấp tài khoản của bản thân là: wiener:peter - Đầu tiên, em đã đăng nhập vào tài khoản của mình và chọn phần My account, ở đây ta có tính năng đổi mật khẩu, đổi email, và đặc biệt hơn là có thể thay đổi username, thứ mà đáng lẽ ra không nên cho thay đổi ![](https://i.imgur.com/frCaIYY.png) - Em đã thử để username là: **administrator**, nhập mật khẩu hiện tại là mật khẩu của tài khoản wiener, đồng thời đặt mật khẩu mới là 1, nhưng nó đã thông báo về là mật khẩu hiện tại không đúng ![](https://i.imgur.com/NEK4CfM.png) - Có thể là trang web đã check xem tài khoản và mật khẩu trong DB nên mới như vậy, em chợt nghĩ đến nếu em bỏ current-password đi thì nó có được không, và không ngờ rằng nó đã thực sự hoạt động: ![](https://i.imgur.com/TgyZaaH.png) - Chỉ với việc bỏ current-password, em đã thành công tạo được tài khoản **administrator** với mật khẩu là **1**, đăng nhập và xóa tài khoản **Carlos**, em đã solve được lab: ![](https://i.imgur.com/heb5zRr.png) ## 6. Lab: Insufficient workflow validation ![](https://i.imgur.com/TbeDJfw.png) - Lab này chứa một lỗ hổng trong quá trình mua hàng, để solve lab, ta cần phải mua chiếc "Lightweight l33t leather jacket" - Em được cấp tài khoản của bản thân: wiener:peter - Khởi đầu bài lab, em đã mua hàng như bình thường, và hiện tại em đang ở tab **GET /cart**: ![](https://i.imgur.com/6QlhyRs.png) - Thay vì chạy qua các bước check, em đã forward thẳng trang web đến **GET /cart/order-confirmation** , là tab mà hoàn thành ở các lab mua hàng trước đó khi thanh toán xong sẽ trỏ đến, và thật bất ngờ là nó đã bypass được thành công lab này - Như vậy, em đã solve được lab ![](https://i.imgur.com/ScKC2et.png) ## 7. Lab: Authentication bypass via flawed state machine ![](https://i.imgur.com/9PQzJaI.png) - Lab này có chứa lỗ hổng trong quá trình đăng nhập, để solve lab, ta cần qua được phần kiểm duyệt của lab, vào admin panel và xóa tài khoản Carlos - Em được cấp tài khoản của bản thân là: wiener:peter - Đầu tiên em đã thử forward đến tab /admin, thì em có thông báo: ![](https://i.imgur.com/MOKHDv8.png) - Sau đó em thử đăng nhập bình thường, và nó cho em chọn 1 trong 2 vai trò: người dùng hoặc tác giả - Dù chọn 1 trong 2 thì nó vẫn không khác nhau là mấy, em đã thử sử dụng Burp Repeater để sửa role = administrator nhưng nó đã không hoạt động, vì để sửa role thì em phải đăng nhập, và đăng nhập thì token CSRF của em sẽ hết hạn, nên việc chỉnh sửa Request ở tab /role-selector là không khả thi ![](https://i.imgur.com/VjeLPzw.png) - Em đã nghĩ đến việc, nếu như em là admin, thì liệu có phải là khi đăng nhập vào em sẽ không cần phải chọn role nữa không? Nếu em không chọn role sau khi đăng nhập thì em có trở thành admin không? - Em đã sử dụng Intercept để thực hiện việc này, mục tiêu của em là sẽ drop khi trang web định forward sang /role-selector mà chạy sang tab home - Thì ở đây, thay vì em cho forward tiếp, em sẽ drop trang này, đồng thời đưa trang web kia về tab home, nghĩa là em sẽ đăng nhập tài khoản thành công mà không cần phải chọn role, từ đó trang web sẽ tự nhận em là admin ![](https://i.imgur.com/5fOONLr.png) - Đúng như em dự đoán, trang web đã cho em quyền admin và admin panel đã xuất hiện ![](https://i.imgur.com/tLWJ4k3.png) - Vào admin panel thì đã có danh sách tài khoản ![](https://i.imgur.com/i1XXvIj.png) - Xóa tài khoản Carlos, em đã solve được lab: ![](https://i.imgur.com/Cfqt79j.png) ## 8. Lab: Flawed enforcement of business rules ![](https://i.imgur.com/ufjOk2X.png) - Trang web này có chứa một lỗ hổng trong quá trình mua hàng, để solve được lab, em cần mua chiếc "Lightweight l33t leather jacket" với tài khoản được cấp: wiener:peter - Khi em lướt xuống cuối, em đã thấy việc đăng ký để nhận đc voucher, nên em đã đăng ký và trang web cho em voucher SIGNUP30, cùng với voucher NEWCUST5 ![](https://i.imgur.com/A0gGz10.png) - Em đã áp dụng nó cho đơn hàng của mình, và nhận ra chỉ với 2 voucher là chưa đủ - Nếu em nhập thêm tiếp SIGNUP30 thì nó báo về là coupon đã được sử dụng, nhưng nếu em nhập NEWCUST5 thì sao? ![](https://i.imgur.com/yrWnk28.png) - Thật bất ngờ, nó lại sử dụng tiếp voucher đó ![](https://i.imgur.com/sCPN7Tk.png) - Tận dụng lỗ hổng này, em sử dụng xen kẽ 2 loại voucher này đến khi giá tiền trong khả năng chi trả (cụ thể là 0$ vì em là người tham lam) ![](https://i.imgur.com/VPa4fST.png) - Đặt hàng và em đã solve thành công được lab trên: ![](https://i.imgur.com/aRSFYFs.png) ## 9. Lab: Infinite money logic flaw ![](https://i.imgur.com/oQCEYrf.png) - Trang web này có chứa một lỗ hổng trong quá trình mua hàng, để solve được lab, em cần mua chiếc "Lightweight l33t leather jacket" với tài khoản được cấp: wiener:peter ![](https://i.imgur.com/Vr59pyO.png) - Có một điều khá là hay là mua giftcard với mã giảm giá, thì ta mất `7$`, và khi ta redeem lại thẻ này thì họ lại trả lại `10$` -> lời `3$` rồi =)) ![image](https://hackmd.io/_uploads/BJxkl8kV6.png) ![image](https://hackmd.io/_uploads/SyO-l8k4T.png) - Vấn đề là mỗi lần làm được 3$ này thì em cần mua gift card, thêm voucher, nhập giftcard để redeem thì mới được `3$`, em sẽ tìm cách nào đó để tự động hóa quá trình này - Sử dụng macro để tạo thành 1 chain tự động hóa việc redeem giftcard: ![image](https://hackmd.io/_uploads/BkKSUoxVp.png) + Post /cart để đặt hàng 1 gift-card + GET /cart để lấy token csrf + POST /cart/coupon để sử dụng coupon SIGNUP30 với csrf token vừa lấy + POST /cart/checkout sử gửi lại csrf, nếu đúng trả về status 303 + GET /cart/order-confirmation?order-confirmed=true để xác nhận mua hàng -> trả về giá trị gift-card + POST /gift-card để redeem gift-card vừa lấy - Cài đặt macro cho các req như sau: + Tại GET /cart lấy giá trị của `csrf` trong form response: ![image](https://hackmd.io/_uploads/H1W8Thx46.png) + Tại POST /cart/coupon lấy giá trị `csrf` từ request trước, coupon set cứng là SIGNUP30 ![image](https://hackmd.io/_uploads/Skdcp3eVT.png) + Tiếp tục lấy giá trị `csrf` của request trước đó tại POST /cart/checkout + Tại GET /cart/order-confirmation?order-confirmed=true lấy giá trị của `gift-card` trong response ![image](https://hackmd.io/_uploads/Sy7xChg4T.png) + Tại POST /gift-card lấy giá trị `csrf` từ request 4 (POST /cart/checkout) và giá trị `gift-card` từ request trước đó ![image](https://hackmd.io/_uploads/ry3X0hxN6.png) - Chain thành công!!, có thể lựa chọn test macro để xem nó có hoạt động đúng ý mình không. - Sau khi test macro thành công, em sẽ đưa nó vào rule để áp dụng với URL của lab: + Thêm macro vừa tạo vào actions: ![image](https://hackmd.io/_uploads/BJzOwsl4T.png) + Scope là với mọi URL cho chắc cú: ![image](https://hackmd.io/_uploads/SJTFwsxVT.png) - Giờ mình chỉ cần đưa vào Intruder cho chạy 500 lần null payloads và rung đùi ngồi đợi tiền thôi(Lưu ý chỉ chạy 1 request mỗi lần gửi vì nó phải chạy cả 1 chain nên gửi nhiều request 1 lúc không ăn đâu): - Kết quả sau một hồi chờ đợi: ![image](https://hackmd.io/_uploads/B1c46sxEp.png) - Giờ thì ta đã có thừa tiền để mua áo rồi ![image](https://hackmd.io/_uploads/H1NDTseE6.png) - Solved :heavy_check_mark: :heavy_check_mark: ![image](https://hackmd.io/_uploads/Byzi6oxNa.png) ## 10. Lab: Inconsistent handling of exceptional input ![image](https://hackmd.io/_uploads/ByXIcr14a.png) - Lab này không xử lý một cách đầy đủ, khiên cho việc có thể khai thác vào tính năng đăng kí để được quyền admin, solve lab bằng cách xóa user `carlos` ở trang admin panel - Mở trang đăng kí lên đập vào mắt là thông báo nếu là nhân viên của Dontwannacry thì có thể thêm đuôi `@dontwannacry.com` vào email để nhận dạng, sure kèo là ta sẽ có thể có quyền truy cập đến admin panel bằng tài khoản của nhân viên Dontwannacry như các bài trước - Flow đăng ký đến tài khoản sẽ như sau: + Đăng kí với username, email, password và csrf token và session ![image](https://hackmd.io/_uploads/r1LduSJNT.png) + Truy cập đến đường dẫn server trả về chữa token registration ![image](https://hackmd.io/_uploads/By15_H1Ea.png) + Woala, có tài khoản: ![image](https://hackmd.io/_uploads/ByALur14a.png) - Có một lưu ý nữa là ta vẫn có thể nối chuỗi email của mình vào sau `@dontwannacry.com` để gửi về email client vì email của ta accept các sub domains: ![image](https://hackmd.io/_uploads/Sk3osBk4T.png) - Tuy nhiên nối như thế cũng không thể cứu được ta trong tình huống này ![image](https://hackmd.io/_uploads/S1Gy3ByN6.png) - Đề bài là exceptional input? ngoại lệ đối với input nghĩa là như thế nào, em cũng không hiểu, nên em sẽ thử làm với một email siêu dài, nếu không có gì bất thường thì sẽ chuyển sang nhét vài thằng chữ Trung Của vào xem sao, bắt đầu bằng việc viết ra 300 chữ a (xin lỗi vì đã lười nên em dùng python) ![image](https://hackmd.io/_uploads/HJmiOHJVT.png) ![image](https://hackmd.io/_uploads/BkU3uBkVp.png) - Email vẫn trả về như thường ![image](https://hackmd.io/_uploads/B19auBkNT.png) - Ô, nhưng khi đăng nhập vào tài khoản test2 này thì đoạn email đã bị cắt :thinking_face:, kiểm tra length của đoạn này thì chỉ còn 255 kí tự, vậy là giới hạn input cho email là 255, tuyệt vời ![image](https://hackmd.io/_uploads/rJvxtrJNa.png) - Hoàn toàn có thể tiến hành khai thác bằng khác chèn thêm sao cho sau khi lên server nó chỉ còn đoạn gmai; `@dontwannacry.com`, còn đoạn nối đến email của mình thì sẽ nhồi thêm ở ngoài ![image](https://hackmd.io/_uploads/ryVGKSJ4a.png) - Thay thế các ký tự cuối bằng `@dontwannacry` sao cho vẫn vừa khít 255 kí tự ![image](https://hackmd.io/_uploads/BJ9vYHJET.png) - Nối thêm email của mình vào ![image](https://hackmd.io/_uploads/rkr5KryNa.png) - Gửi request chứa email vừa tạo ![image](https://hackmd.io/_uploads/Hk6ecryEa.png) ![image](https://hackmd.io/_uploads/r1Mf5SyV6.png) - End game, sau khi login server truncate còn đúng 255 ký tự chứa mail của nhân viên dontwannacry, admin panel hiện ra ngay trước mặt ![image](https://hackmd.io/_uploads/HyxQ5HJEa.png) - Solved :heavy_check_mark: :heavy_check_mark: :heavy_check_mark: ![image](https://hackmd.io/_uploads/ByJEqBy4a.png) ## 11. Lab: Authentication bypass via encryption oracle ![image](https://hackmd.io/_uploads/SJS3RRPLT.png) - Lab này chứa lỗi logic để lộ cách mà website encrypt data, để solve lab mình cần vào được admin và xóa tài khoản carlos - Sau khi mình mày mò ở trang login thì thấy có một cookie là `stay-logged-in` là `unFHAJjibASOwIkAN%2fp2krjGsXjjpWbqtSI0IK0D9Ic%3d`, mình đem nó paste đi muôn nơi ở trang bình luận thì nhận được thông báo này: ![image](https://hackmd.io/_uploads/HJkdyJ_Up.png) - Nó đưa thông báo vào một cookie notification, nên mình thử xóa đi và thêm a vào thì phát hiện ra trong thuật toán có base64 ![image](https://hackmd.io/_uploads/Hk5t8Cw8T.png) - Mình thử đi base64 chữ admin và nhét vào thì nhận thông báo tiếp phải đủ block 16 chữ thì mới có thể encode, coi bộ có vẻ không ngon ![image](https://hackmd.io/_uploads/rk36IRD8a.png) - Sau đó mình đưa giá trị cookie stay-logged-in vào thì thấy nó decode ra giá trị:` wiener:1702515826472` -> username và timestamp ![image](https://hackmd.io/_uploads/Hk0bxkOLa.png) - Vậy là chức năng này sẽ có thể decode đoạn cipher text cho mình, còn nếu như bình luận với email sai thì nó sẽ encode đoạn thông báo `Invalid email address: Email` ra cho mình, hmmm - Vậy thì thử để email là `administrator:1702515826472` xem sao ![image](https://hackmd.io/_uploads/SyFU2RvLa.png) - Mình nghĩ đoạn đầu nó là chữ invalid kia nên không lấy, và chuyển sang lấy phần còn lại thì ăn tiếp thông báo đoạn block không phải bội của 16: ![image](https://hackmd.io/_uploads/S1_82APIa.png) - Nghĩ lại cũng đúng, chỗ `Invalid email address: ` mới có 23 byte, phải có nó thì đoạn cipher mới đủ chia hết cho 16, vậy thì mình sẽ thêm 9 ký tự -> xóa 32 ký tự đi thì sẽ decode được - Email bây giờ sẽ là: `123456789administrator:1702515826472` ![image](https://hackmd.io/_uploads/rJPfpCvLa.png) - Nhét vào decoder, xóa 32 byte đầu (nếu không thì bỏ luông 32 ký tự cũng được), rồi encode lại base64 ![image](https://hackmd.io/_uploads/Hy8gR0DL6.png) - Đưa vào notification mình thấy đã decode ra thành công `administrator:1702515826472` ![image](https://hackmd.io/_uploads/BJmwAAvUp.png) - Trỏ đến homepage với cookie đấy là mình đã thấy admin panel rùi ![image](https://hackmd.io/_uploads/r1wKAAwI6.png) - Solved :heavy_check_mark: :heavy_check_mark: :heavy_check_mark: ![image](https://hackmd.io/_uploads/rykoRRPLT.png)