# Access Control ## What is access control? **Kiểm soát truy cập (Access Control)** là việc áp dụng các ràng buộc về ai hoặc cái gì được **ủy quyền (authorized)** để thực hiện các hành động hoặc truy cập tài nguyên. Trong ngữ cảnh của ứng dụng web, kiểm soát truy cập phụ thuộc vào **xác thực** và **quản lý phiên**: - **Xác thực (Authentication)** xác nhận rằng user chính là ai. - **Quản lý phiên (Session Management)** xác định những request HTTP nào đang được thực hiện bởi cùng một user. - **Kiểm soát truy cập (Access Control)** xác định xem user có được phép thực hiện hành động mà người đó đang cố gắng thực hiện hay không. ### Vertical access controls **Kiểm soát truy cập theo chiều dọc (Vertical access controls)** là cơ chế giới hạn quyền truy cập vào chức năng nhạy cảm đối với những loại user cụ thể. Với biện pháp kiểm soát truy cập theo chiều dọc, các loại user khác nhau có quyền truy cập vào các chức năng ứng dụng khác nhau. Ví dụ: Admin có thể sửa đổi hoặc xóa bất kỳ tài khoản nào của user, trong khi user thông thường không có quyền truy cập vào các hành động này. [Lab: Unprotected admin functionality](#Unprotected-admin-functionality) [Lab: Unprotected admin functionality with unpredictable URL](#Unprotected-admin-functionality-with-unpredictable-URL) [Lab: User role controlled by request parameter](#User-role-controlled-by-request-parameter) [Lab: User role can be modified in user profile](#User-role-can-be-modified-in-user-profile) [Lab: URL-based access control can be circumvented](#URL-based-access-control-can-be-circumvented) [Lab: Method-based access control can be circumvented](#Method-based-access-control-can-be-circumvented) ### Horizontal access controls **Kiểm soát truy cập theo chiều ngang (Horizontal access controls)** là cơ chế hạn chế quyền truy cập vào tài nguyên đối với những user cụ thể. Với điều khiển truy cập theo chiều ngang, những user khác nhau có quyền truy cập vào một tập hợp con các tài nguyên cùng loại. Ví dụ: một ứng dụng ngân hàng sẽ cho phép user xem các giao dịch và thực hiện thanh toán từ tài khoản của chính họ chứ không phải tài khoản của bất kỳ user nào khác. [Lab: User ID controlled by request parameter](#User-ID-controlled-by-request-parameter) [Lab: User ID controlled by request parameter, with unpredictable user IDs](#User-ID-controlled-by-request-parameter-with-unpredictable-user-IDs) [Lab: User ID controlled by request parameter with data leakage in redirect](#User-ID-controlled-by-request-parameter-with-data-leakage-in-redirect) [Lab: User ID controlled by request parameter with password disclosure](#User-ID-controlled-by-request-parameter-with-password-disclosure) ### Context-dependent access controls Kiểm soát truy cập phụ thuộc vào ngữ cảnh hạn chế quyền truy cập vào chức năng và tài nguyên dựa trên trạng thái của ứng dụng hoặc sự tương tác của người dùng với nó. Kiểm soát truy cập phụ thuộc vào ngữ cảnh ngăn người dùng thực hiện các hành động không đúng thứ tự. Ví dụ: một trang web bán lẻ có thể ngăn người dùng sửa đổi nội dung giỏ hàng của họ sau khi họ đã thanh toán. ## Insecure direct object references (IDOR) ### What are insecure direct object references (IDOR)? **Insecure direct object references (IDOR)** là một loại lỗ hổng kiểm soát truy cập phát sinh khi một ứng dụng sử dụng đầu vào do người dùng cung cấp để truy cập trực tiếp vào các đối tượng. Tuy nhiên, đây chỉ là một ví dụ trong số nhiều lỗi triển khai kiểm soát truy cập có thể dẫn đến việc kiểm soát truy cập bị phá vỡ. Các lỗ hổng IDOR thường liên quan nhất đến việc leo thang đặc quyền theo chiều ngang, nhưng chúng cũng có thể phát sinh liên quan đến việc leo thang đặc quyền theo chiều dọc. Có nhiều ví dụ về lỗ hổng kiểm soát truy cập trong đó các giá trị tham số do người dùng kiểm soát được sử dụng để truy cập trực tiếp vào tài nguyên hoặc chức năng. [Lab: Insecure direct object references](#Insecure-direct-object-references) ## Một vài vuln khác của Access control ### Access control vulnerabilities in multi-step processes Nhiều trang web triển khai các chức năng quan trọng qua nhiều bước. Điều này phổ biến khi: - Cần phải nắm bắt được nhiều đầu vào hoặc tùy chọn khác nhau. - Người dùng cần xem xét và xác nhận chi tiết trước khi thực hiện hành động. Ví dụ: chức năng quản trị để cập nhật thông tin người dùng có thể bao gồm các bước sau: 1. Load the form that contains details for a specific user. 2. Submit các thay đổi 3. Review các thay đổi and confirm. Đôi khi, một trang web sẽ triển khai các biện pháp kiểm soát truy cập nghiêm ngặt đối với một số bước này nhưng lại bỏ qua các bước khác. Hãy tưởng tượng một trang web nơi các biện pháp kiểm soát truy cập được áp dụng chính xác cho bước đầu tiên và bước thứ hai, nhưng không áp dụng được cho bước thứ ba. Trang web giả định rằng người dùng sẽ chỉ đạt đến bước 3 nếu họ đã hoàn thành các bước đầu tiên được kiểm soát đúng cách. Kẻ tấn công có thể truy cập trái phép vào chức năng bằng cách bỏ qua hai bước đầu tiên và trực tiếp gửi yêu cầu cho bước thứ ba với các tham số được yêu cầu. [Lab: Multi-step process with no access control on one step](#Multi-step-process-with-no-access-control-on-one-step) ### Referer-based access control Một số trang web kiểm soát quyền truy cập dựa trên header `Referer` được gửi trong request HTTP. Header `Referer` có thể được thêm vào request của trình duyệt để cho biết trang nào đã bắt đầu request. Ví dụ: một ứng dụng thực thi mạnh mẽ quyền kiểm soát quyền truy cập đối với trang quản trị chính tại `/admin`, nhưng đối với các trang phụ như `/admin/deleteUser` chỉ kiểm tra header `Referer`. Nếu header `Referer` chứa URL chính `/admin` thì yêu cầu sẽ được cho phép. Trong trường hợp này, header `Referer` có thể bị attacker kiểm soát hoàn toàn. Điều này có nghĩa là họ có thể giả mạo các request trực tiếp đến các trang phụ nhạy cảm bằng cách cung cấp header `Referer` được request và có được quyền truy cập trái phép. [Lab: Referer-based access control]() ### Location-based access control Một số trang web thực thi các biện pháp kiểm soát truy cập dựa trên** vị trí địa lý** của người dùng. Ví dụ: điều này có thể áp dụng cho các ứng dụng ngân hàng hoặc dịch vụ truyền thông nơi áp dụng luật pháp của tiểu bang hoặc các hạn chế kinh doanh. Các biện pháp kiểm soát truy cập này thường có thể bị phá vỡ bằng cách sử dụng **proxy web**, **VPN** hoặc **thao túng cơ chế định vị địa lý** phía máy khách. ## Detecting Access Control Attacks 1. Xuất hiện các request với method và truy cập các URL ẩn, không có trong UI(user interface) ``` POST /api/users/ DELETE /api/resource/ POST /admin/create_user ``` 2. Các request liên tục và trong thời gian ngắn - Các request liên tục nhau như user1, user2,.... - Các request đến user1, user2, ... được request trong thời gian ngắn, khoảng vài ms - Request đến từ IP khác nhau - Truy cập bị từ chối nhiều lần (403/401) ## Preventing Các lỗ hổng kiểm soát truy cập có thể được ngăn chặn bằng cách áp dụng phương pháp phòng thủ chuyên sâu và áp dụng các nguyên tắc sau: - Đừng bao giờ chỉ dựa vào tính năng che giấu(**obfuscation**) để kiểm soát quyền truy cập - Trừ khi một tài nguyên được thiết kế để có thể truy cập công khai, theo mặc định, hãy từ chối quyền truy cập. - Bất cứ khi nào có thể, hãy sử dụng một cơ chế toàn ứng dụng duy nhất (**application-wide**) để thực thi các biện pháp kiểm soát truy cập. - Ở mức độ code, bắt buộc dev phải khai báo quyền truy cập được phép cho từng tài nguyên và từ chối quyền truy cập theo mặc định. - Kiểm tra kỹ lưỡng và kiểm tra các biện pháp kiểm soát quyền truy cập để đảm bảo chúng hoạt động như thiết kế. # Practice lab ## Unprotected admin functionality ### Target Goal Lab này có admin panel không được bảo vệ cẩn thận. Giải quyết lab bằng cách xóa người dùng `Carlos`. ### Analysis and exploit Theo yêu cầu bài lab thì có một admin panel không được bảo vệ cẩn thận nên có thể nó path truy cập vào nó sẽ bị public. Một trong những bước đầu tiên trước khi brute-force là truy cập vào `robots.txt` > File robots.txt là một tập tin văn bản đơn giản có dạng đuôi mở rộng txt. Tệp này chứa một nhóm các tiêu chuẩn web quy định cách Robot Web (hoặc Robot của các công cụ tìm kiếm) thu thập dữ liệu trên web, truy cập, index nội dung và cung cấp nội dung đó cho người dùng. Ảnh dưới là ví dụ về tệp `robots.txt` đơn giản, chỉ ra rằng người dùng có tên `Mallorybot` không được phép thu thập bất kỳ trang nào của trang web và các user khác không thể thu thập nhiều hơn một trang sau mỗi 20 giây và không được phép thu thập thư mục `/secret` ![image](https://hackmd.io/_uploads/BJGECtIoJe.png) Quay lại bài lab, truy cập vào `/administrator-panel` và hoàn thành bài lab ![image](https://hackmd.io/_uploads/rJlWpt8jJl.png) ## Unprotected admin functionality with unpredictable URL ### Target Goal Lab này có admin panel không được bảo vệ cẩn thận. Nó nằm ở một vị trí không thể đoán trước, nhưng vị trí được tiết lộ ở đâu đó trong ứng dụng. Giải lab bằng cách truy cập admin panel và sử dụng nó để xóa người dùng `Carlos`. ### Analysis and exploit Bài lab này dev đã để lộ hàm js chứa path dẫn đến trang của admin khi Ctrl + U ![image](https://hackmd.io/_uploads/H1Yb-5Uo1g.png) Truy cập vào `/admin-h7bras` và xóa user là xong ## User role controlled by request parameter ### Target Goal Bài lab có admin panel ở `/admin`, giải lab bằng cách truy cập admin panel và sử dụng nó để xóa người dùng `Carlos`. Credential: `wiener:peter` ### Analysis and exploit Sau khi login Ctrl + U vào mục session ta thấy có 1 field `Admin` với value là `false` ![image](https://hackmd.io/_uploads/ByoXf9Ioye.png) Thử thay đổi value = `true` và ta có thể truy cập vào Admin-Panel sau đó xóa user là hoàn thành bài lab. ![image](https://hackmd.io/_uploads/rJ3SG9Uikl.png) > Lý do cho việc thay đổi value trên là vì nếu các ứng dụng web không kiểm tra kỹ lưỡng và đảm bảo tính toàn vẹn của các giá trị trong session sẽ tạo điều kiện cho attacker thay đổi thông tin session và thực hiện hành động trái phép. ## User role can be modified in user profile ### Target Goal Bài lab có admin panel ở `/admin`,nó chỉ cho phép login nếu `roleid` là 2 giải lab bằng cách truy cập admin panel và sử dụng nó để xóa người dùng `Carlos`. Credential: `wiener:peter` ### Analysis and exploit Theo đề bài lab ta sẽ tìm nơi có thể thay đổi `roleid` để chuyển thành 2 để có thể truy cập. Sau khi thao tác với các tính năng có ở web, ở mục `Change email` ta thấy được thứ cần tìm ![image](https://hackmd.io/_uploads/r1DKc5UjJl.png) Bằng cách thêm `roleid` vào Request, ta sẽ thử xem khi gửi gói tin có thể thay đổi được `roleid` không ![image](https://hackmd.io/_uploads/r1zj9cUske.png) Redirect và nó đã xuất hiện `Admin-Panel` Xóa user và hoàn thành bài lab ## URL-based access control can be circumvented ### Target Goal Website có admin panel không cần xác thực ở `/admin` nhưng front-end đã được cấu hình để block các truy cập bên ngoài vào path này. Tuy nhiên back-end được dựng trên framework có hỗ trợ header `X-Original-URL` Để giải lab này, truy cập được vào admin panel và xóa user `Carlos`. ### Analysis and exploit Theo đề bài lab web này được dựng trên framework rằng hỗ trợ` X-Original-URL` đây là 1 header rất nguy hiểm. > X-Original-URL dùng để ghi đè lên URL ban đầu và truy cập vào URL đã bị chặn từ backend và bypass access control ở frontend. ![image](https://hackmd.io/_uploads/SylPxsIjkl.png) Sửa theo `href` đã cho để xóa user ![image](https://hackmd.io/_uploads/HyXOesLjkx.png) Tuy nhiên lại có lỗi lý do là thiếu param username, do header kia chỉ lưu URL nên tham số sẽ phải để lên phần URL ban đầu ![image](https://hackmd.io/_uploads/H1sYej8oJx.png) Forward và hoàn thành bài lab. ## Method-based access control can be circumvented ### Target Goal Website này thực hiện các điều khiển truy cập dựa trên một phần dựa của medthod HTTP. Để giải lab này, khai thác các điều khiển truy cập thiếu sót để nâng bản thân để trở thành admin. Credentials `wiener:peter` ### Analysis and exploit Sau khi login vào tài khoản admin ta thấy có 1 tính năng nâng cấp người dùng ![image](https://hackmd.io/_uploads/B1ZudiLsJg.png) Ta chuyển về người dùng bình thường và thấy rằng người thường không có chức nâng cấp lên ![image](https://hackmd.io/_uploads/S1bK_jUoyl.png) Do đó ta thử xem có cách nào tự nâng cấp bản thân lên không -> bằng cách đổi phiên của bản thân(người dùng thường) vào trang đổi quyền của admin ![image](https://hackmd.io/_uploads/BJQqdi8iJx.png) Tuy nhiên nó báo lỗi không có đủ quyền nên ta sẽ đổi method gửi đi và phát hiện được rằng bảo vệ access control chỉ được thực hiện ở method POST. Thay thế bằng GET và hoàn thành bài lab. ![image](https://hackmd.io/_uploads/rkfjusUj1e.png) ## User ID controlled by request parameter ### Target Goal Bài lab có lỗ hỗng đặc quyền theo chiều dọc ở trang account của người dùng. Để giải bài lab, phải lấy được API key của người dùng `Carlos`. Credentials: `wiener:peter` ### Analysis and exploit Sau khi login với account `wiener` ta sẽ thấy url bao gồm`id=wiener` ![image](https://hackmd.io/_uploads/B1nqHAwi1g.png) Thử thay đổi param thành `carlos` và ta nhận được API key của người dùng này ![image](https://hackmd.io/_uploads/BJ_CHCPi1e.png) ## User ID controlled by request parameter, with unpredictable user IDs ### Target Goal Bài lab có lỗ hỗng đặc quyền theo chiều dọc ở trang account của người dùng tuy nhiên được bảo mật hơn bằng cách định danh GUIDs. Để giải bài lab, phải lấy được API key của người dùng `Carlos`. Credentials: `wiener:peter` ### Analysis and exploit Theo yêu cầu bài lab sau khi login chúng ta sẽ cố tìm xem có chức năng nào leak GUID của `carlos` không. ![image](https://github.com/user-attachments/assets/091788bb-7ef5-4aca-8f39-a15f0392bc61) Sau khi tìm ra các bài post có người đăng là `carlos` ta sẽ tìm cách xem có chỗ nào để lộ `GUID` không ![image](https://github.com/user-attachments/assets/cd637380-84ca-4a49-9aca-b3f6d9816657) Thay đổi param và lấy được API key, hoàn thành bài lab. ![image](https://github.com/user-attachments/assets/c5495e5d-6ad6-4b79-8a11-097eda112569) ## User ID controlled by request parameter with data leakage in redirect ### Target Goal Bài lab này có một lỗ hổng access control ở nơi mà thông tin nhạy cảm bị leak ở phần body của redirect response. Để giải bài lab, phải lấy được API key của người dùng `Carlos`. Credentials: `wiener:peter` ### Analysis and exploit Bài lab này tuy thay param bằng `carlos` thì bị redirect về trang login, do redirect không chặt chẽ nên mặc dù không đăng nhập được, trong response đã để lộ API key của `carlos`: ![image](https://github.com/user-attachments/assets/eb8c5eef-9c11-4198-bea5-c341574c9066) Submit API key và hoàn thành bài lab. ![image](https://github.com/user-attachments/assets/20de1c18-3bf5-4143-aa51-4b89ab97dd37) ## User ID controlled by request parameter with password disclosure ### Target Goal Bài lab này có trang tài khoản người dùng chứa mật khẩu hiện tại của người dùng hiện tại, được đặt sẵn trong masked input. Để giải bài lab, lấy được password của admin và xóa user `Carlos`. Credentials: `wiener:peter` ### Analysis and exploit Khi login ta thấy ở trang này có chức năng thay đổi mật khẩu mới, và khi nhìn vào password ẩn kia cũng có thể đoán được đó chính là mật khẩu hiện tại của acc ![image](https://github.com/user-attachments/assets/68039f55-d0f3-4ebe-9db4-16236f571c1d) Ctrl + U và đúng như dự đoán mật khẩu bị leak, lý do có thể là giá trị mật khẩu được đặt trực tiếp vào thuộc tính `value` ![image](https://github.com/user-attachments/assets/b30a0585-d3a3-4386-952f-dc4d7d5ba9d8) Tương tự ta sẽ được credential của `administrator` và hoàn thành bài lab ![image](https://github.com/user-attachments/assets/07ddda33-1276-4c54-aa6c-2511c65b403a) ## Insecure direct object references ### Target Goal Bài lab lưu trữ log chat của các user trên hệ thống và kết xất bằng cách dùng URL Để hoàn thành bài lab, tìm mật khẩu của carlos và đăng nhập vào. ### Analysis and exploit Từ target của bài lab, ta có thể xác định nó dính IDOR và xảy ra ở các file log được ghi lại trên URLs ![image](https://github.com/user-attachments/assets/dd79d501-0309-47f6-8eea-df7e42d40dd0) ![image](https://github.com/user-attachments/assets/e2fa0fb7-869e-49ec-b06b-f820c86b93f3) Có 1 điều khá lạ là cuộc chat đầu tiên khi ta download về là `2.txt` chứ không phải là `0.txt` hay `1.txt`. Do đó ta sẽ thử 2 file này xem có bị ẩn gì không ![image](https://github.com/user-attachments/assets/7191e27e-feed-4ef7-a3c7-cd5494932823) ![image](https://github.com/user-attachments/assets/5814f0b1-31b3-4033-a69d-4b679bb2a531) Login và hoàn thành bài lab ## Multi-step process with no access control on one step ### Target Goal This lab has an admin panel with a flawed multi-step process for changing a user's role. You can familiarize yourself with the admin panel by logging in using the credentials administrator:admin. Bài lab này có admin panel với quy trình nhiều bước thiếu sót để thay đổi vai trò của người dùng. Để giải bài lab này, đăng nhập với cred: `wiener:peter` dể trở thành admin. ### Analysis and exploit Tương tự với bài [Lab: Method-based access control can be circumvented](#Method-based-access-control-can-be-circumvented) chúng ta đăng nhập vào tài khoản `admin` , `admin panel` và bắt request upgrade role user `carlos`: ![image](https://github.com/user-attachments/assets/18d8e38f-7ecb-46e0-8d98-45deed555bf5) Logout và đăng nhập vào tài khoản wiener (normal). Lấy session cookie của wiener thay vào session trong `/admin-roles`, đổi username muốn upgrade thành `wiener`: ![image](https://github.com/user-attachments/assets/c0886119-ca31-48ab-a7c7-45e512d9494e) > Lý do cho việc thực hiện được như vậy là vì trong quá trình thực hiện nhiều bước xác thực, dev có thể nghĩ rằng khi đặt bước kiểm soát quyền từ bước 1 (truy cập vào trang /admin-role) thì các bước sau cần nữa, người dùng thông thường sẽ không thể có chức năng /admin-role này nên bước xác thực quyền (ở đây là cookie) sẽ bị bỏ qua. ## Referer-based access control ### Target Goal Bài lab này kiểm soát quyền truy cập ở admin panel. Để giải được bài lab này, tự nâng cấp bản thân lên admin Credential: `wiener:peter`, `administrator:admin` ### Analysis and exploit Với yêu cầu và thông tin tương tự như bài [Multi-step process with no access control on one step](#Multi-step-process-with-no-access-control-on-one-step) trước. Đăng nhập vào admin, bắt request upgrade user `carlos`: ![image](https://hackmd.io/_uploads/Bks31xdj1e.png) Request được gửi đi là `GET`. Tiếp theo thử đi tới URL `/admin-roles?username=carlos&action=upgrade` , bằng tài khoản `wiener`: ![image](https://hackmd.io/_uploads/BJ6BegOjkg.png) Referer header trong 1 request sẽ cho biết địa chỉ đã gửi đi request. Trong request của admin trước đó, có Referer là `/admin` (admin panel mà chỉ admin truy cập được), khi gửi request bằng wiener thì referer sẽ là `/my-account` -> Referer phải chứa `/admin`. ![image](https://hackmd.io/_uploads/H1RVMguoke.png) Sửa lại request của wiener trước đó, thêm Referer tới /admin và username=wiener, Send: ![image](https://hackmd.io/_uploads/S1LSzxuiyl.png)