# Path Traversal Vulnerabilities --- # lab cyberjutsu ## level 1 ### 1.Phân tích code ``` <?php $file_name = $_GET['file_name']; $file_path = '/var/www/html/images/' . $file_name; var_dump($file_path); if (file_exists($file_path)) { header('Content-Type: image/png'); readfile($file_path); } else { // Image file not found echo " 404 Not Found"; ``` Xem đoạn code trên, ta có thể thấy được rằng biến $file_path dùng để lưu đường dẫn của ảnh mà người dùng mở. tại đây ta có thể ta cả thể var_dump để thấy được rõ hơn đường dẫn. Câu lệnh if dùng để kiểm tra xem đường dẫn trên có tồn tại hay không, hàm readfile dùng để đọc và hiển thị trực tiếp tệp tin. --- ### 2. attack ![ảnh](https://hackmd.io/_uploads/S1wZyKOnA.png) Chức năng của ứng dụng - Đây là 1 web để xem hình ảnh, bấm vào nút view thì hình ảnh tương ứng sẽ hiện ra #### Đặt giả thuyết - chẳng hạnnhư hình ảnh trên có URL là: `http://localhost:8091/loadImage.php?file_name=flag.png` Khi truy cập vào URL trên, ta đang thực hiện 1 lệnh GET request đền endpoint của file loadimage.php với giá trị param file_name là flag.png đề load hình ảnh lá cờ - Đoạn code của file loadimage.php: - ![ảnh](https://hackmd.io/_uploads/BJFLVtdnR.png) - như đã phân tích, đoạn code này tạo ra file_path bằng cách nối chuỗi 'var/www/html/image/' với biến $file_name, sau đó kiểm tra xem đường dẫn file có tồn tại không. Và đọc file với hàm readfile(). - Dòng số 2 là 1 untrusted data nhưng anh dev đã không hề có biện pháp phòng chống và khiến ứng dụng dính lỗi path traversal #### Chứng minh giả thuyết - ta có thông tin của thư mục bắt đầu: 'var/www/html.image' - Đích đền: etc/passwd - ta sử dụng 4 kí tự ../ tưng ứng với mõi lần quay lại với 1 thư mục - `'/var/www/html/images/../../../../etc/passwd` - như vậy ta sẽ trở lại thư mục gốc và bắt đầu với etc/passwd - ta sẽ vào burp xem kết quả: - ![ảnh](https://hackmd.io/_uploads/BkmNvt_3A.png) --- ## level 2 Ở bài lab thứ 2, chức năng của ứng dụng vẫn giống bài 1 ### 1. phân tích ![ảnh](https://hackmd.io/_uploads/HkFypXY3C.png) - Ở level 2, anh dev đã thêm 1 filter cho phép lọc ra kí tự `..`, nếu trong đường dẫn có chứa kí tự `..` thì sẽ trả về là die để chặn chúng ta có thể sử dụng kí tự`..` trờ về thư mục gốc. - Và ở câu điều kiện tiếp theo, đoạn code kiểm tra xem có tổn tại biến `$file` hay không, nếu có sẽ sử dụng hàm readfile để đọc. Có thể thấy biến `$file` được đọc trực tiếp nên chúng ta chỉ cần sử dụng `đường dẫn tuyệt đối` thay vì sử dụng kí tự `..` giống bài trước ### 2. attack - Đưa vào 1 đường tuyệt đối `etc/passwd` ![ảnh](https://hackmd.io/_uploads/SJbAyVK20.png) - vào burp, chúng ta có thể nhìn rõ hơn ![ảnh](https://hackmd.io/_uploads/ryvblNKhR.png) --- ## level 3 Đây là 1 trang web cho phép người dùng up file và xem file ![ảnh](https://hackmd.io/_uploads/SywaiKtn0.png) ### 1. Phân tích ![ảnh](https://hackmd.io/_uploads/ryLHCFKhR.png) - Qua đoạn code trên, ta có thể thấy đoạn code tạo thư mục dir từ dòng 5->11 - từ dòng 17->19 ta có thể nhận thấy untrusted data là biến `$_POST['album']`, như vậy ta có thể kiểm soát được biến `$album` - Trang web cho phép chúng ta uploaf file và xem file - Ta sẽ up thử 1 file php xem trang có thực thực thi file php hay không. ![ảnh](https://hackmd.io/_uploads/HJ4jrct2C.png) ->như vậy, trang cho phép chung ta up file thực thi php. Tuy nhiên, trang web lại không thực thi file php mà sẽ hiện thực dưới dạng text ![ảnh](https://hackmd.io/_uploads/r1bVi5F3C.png) Như ảnh trên, ta có thể thấy được file apache được cấu hình đường dẫn sẽ không thực thi bất kì đuôi file nào. Những đuổi file là `jpg, png` sẽ thực thi bình thường còn những `file html,txt,php sẽ chuyển về text`. --- ### Attack Dựa đoạn code trên ta đã biết cấu hình path được anh dev cấu hình đẻ lọc nhưng file có đuôi là html, text, php là: `'/var/www/html/upload/'.đường dẫn đến album` - Có thể thấy rằng path đường nối với album - Nên trong burp, ta thấy ban đầu đường dẫn sẽ trông như thế này `string(59) "/var/www/html/upload/5e55305bc2c603ec5d587565dbf462dd/test.php` - Để có thể bỏ qua lọc đường dẫn của dev, ta phải thêm ../.. để trở về thư mục có thể thực thi được file php. `"/var/www/html/upload/5e55305bc2c603ec5d587565dbf462dd/../../` và từ đây đường dẫn sẽ là `"/var/www/html/` Quay lại trang web, chúng chỉ cần truy cập lại lại ![ảnh](https://hackmd.io/_uploads/SJovtiKhC.png) như vậy là đã thực thi được file php --- ## level 4 ![ảnh](https://hackmd.io/_uploads/SJce6rjhR.png) ![ảnh](https://hackmd.io/_uploads/BJJEaSj3C.png) - Đây là 1 trang web cho phép người dùng chơi game ![ảnh](https://hackmd.io/_uploads/HyDHaHohC.png) - Trang cho phép người dùng upload avatar ### Phân tích code ![ảnh](https://hackmd.io/_uploads/ByMakUs3R.png) - Trên đoạn code trên, ta thấy được 1 untrusted data là biến $_POST["name"], nhưng khi qua 1 lớp kiểm tra biến trước khi vào - cụ thể là kiểm tra kí tự người dùng nhập vào nếu không thuộc từ a->z và 0->9 thì sẽ in ra lỗi. Nên đây chưa chắc đã là untrusted data. ![ảnh](https://hackmd.io/_uploads/BJUlF8onR.png) - Ở đây, ta có thể thấy được khi upload file lên thì đường dẫn sẽ luôn luôn là name."avatar.jpg". - Ở file game.php ![ảnh](https://hackmd.io/_uploads/B1JGJwj20.png) - mặc định nếu không thay đổi đường dẫn của game sẽ là: `http://localhost:8094/game.php?game=fatty-bird-1.html` - Ta có thể thay đổi đường dẫn này đến game khác - ta có thể dễ dàng nhận thấy untrusted data xuất hiện, ta có thể dựa vào hàm include để thực hiện biến game hoặc gọi đến bất kì file vào trong hệ thống --- ### Attack b1: Đầu tiên ta sẽ upload lên trang file bất kì ở Profile với nội dung thực thi file php, tuy nhiên anh dev đã cấu hình những đuôi file html, text, php sẽ đều chuyển về dạng text nên không thực trực tiếp thực hiện được nội dung trong file ![ảnh](https://hackmd.io/_uploads/rJTLbvi3A.png) Ta có thể nhận thấy rằng đường dẫn se là: `var/www/html/upload/duong/avatar.jpg` b2: Khai thác include biến game được nằm trong thư mục view, vì vậy chúng ta cần phải sử dụng ../ để thoát khỏi thư mục view. Sẽ có dạng như này: `var/www/html/view/game=fatty-bird-1.html` - ta sẽ chuyển thành `var/www/html/view/game=../upload/duong/avatar.jpg` - Đường dẫn sau khi thay đổi sẽ có dạng như này: `http://localhost:8094/game.php?game=../upload/duong/avatar.jpg` ![ảnh](https://hackmd.io/_uploads/ByHsmwinC.png) - Và như vậy đã thực thi được file php --- ## Level 5 Chiếm quyền điều khiển và đọc một tệp bí mật ở thư mục gốc ### Phân tích - Chức năng trang web - ![image](https://hackmd.io/_uploads/r1OkqibJyl.png) - Game 2 thì đang phát triển nên chưa chơi được - ![image](https://hackmd.io/_uploads/SykXcsZyJg.png) --- - Phân tích code - ![image](https://hackmd.io/_uploads/B1nYcjZkJx.png) - Bên tron src bao gồm: - Folder static: chứa các file ảnh và âm thanh - Folder views: chứa các file html dùng để hiển thị giao diện cho người dùng - File index.php: là file xử lý chính của ứng dụng - Phân tích src code trong file index.php ta thấy - Dòng 3 có sự cuất hiện của untrusted data là biến `$_GET['GAME']` - Mặc định khi truy cập, trang web sẽ hiển thị view từ file `fatty-bird-1.html` - Nếu gói GET gửi lên có kèm theo giá trị của tham số game, thì giá trị này sẽ được gán vào biến `$game` - Dòng 21 cho thấy biến `$game` sau đó được cộng chuỗi với 1 đường dẫn và đi vào hàm `include` - ![image](https://hackmd.io/_uploads/BycNhoZ1Je.png) - php include là 1 hàm cho phép copy hết tất cả nội dung của file khác vào file hiện tại, rồi thực thi --- ### Attack - Ta sẽ thử lợi dụng hàm include để attack - Từ hàm include, ta có thể tác động với biến $game - Liệu ta có thể lợi dụng $game để inlude bất kỳ file khác trên server. Tuy nhiên $game đã bị prefix với./views/ , ta có thể incude 1 file khác không nằm trong thư mục views được không? Liệu có thể sử dụng../ để thoát khỏi thư mục này. - Rồi thử với /etc/paswd - ![image](https://hackmd.io/_uploads/Syezkh-y1x.png) - Như vậy ta đã tân công path traversal và đọc được file bất kỳ trên hệ thống --- Tìm cách thự thi lệnh - Như đã nói ở trên, include sau khi copy nội dung file thì sẽ thực thi luôn nếu có code PHP trong đó. `include(untrusted-data) + kiểm soát nội dung file = RCE` - Ta có thể nghĩ đến việc upload 1 file php và include file này - Tuy nhiên ứng dụng không cho phép upload file lên server - Vậy có cách nào mà không cần upload file mà vẫn đưa được code php vào nội dung file rồi include đến file đó? - Để làm như vậy, chỉ có thể làm cho untrusted data rơi vào 1 file có sẵn trên server - VD 1 trong các tính năng mà có thể ghi dữ liệu của user vào nội dung file đó là tính năng log - Cụ thể với http Apache, mặc định cá request sẽ được ghi log lại ở đường dẫn /var/log/apache2/access.log #### Xem thêm - Thông thường khi cài đặt apache nguời ta sẽ cấu hình 2 file access log và error log để theo dõi các request gửi lên web server và điều tra khi có sự cố trong lúc xử lý request - Để xem cấu hình này, ta vào file 000-default.conf ![image](https://hackmd.io/_uploads/rkn-MnbJ1e.png) - Đây là cấu hình mặc định của apache. Và giá trị mặc định của ${APACHE_LOG_DIR} là /var/log/apache2/ --- - Thử truy cập đền `access.log` ta thấy ở đáy chwua các HTTP request gửi lên server. ![image](https://hackmd.io/_uploads/S1MEQ2Zyke.png) - Cú pháp của 1 dòng log trong như sau: ![image](https://hackmd.io/_uploads/SJetQnWy1e.png) - Như vậy, 1 số trương ra có thể tháy đổi trong gói tin HTTP gửi lên server à: Request String, Referer và User-Agent. - Nếu gửi lên server 1 cú request có chưa code php ở 1 trong 3 vị trí trên, sau đó include file access.log này thì sao? - Thử gửi 1 cú GET request có User-Agent là `<? phpinfo() ?>` - ![image](https://hackmd.io/_uploads/BJHJvh-kyx.png) - Như vậy, t có đã có thể thực thi code php trên server có thể thực hiện nhiều lệnh kahcs ngoài phpinfo như: system($_GET['cmd']) và truyền câu lệnh muốn thực thi vào tham số cmd ------------- # Lab portswigger ## level 1 ### Đề bài: ![ảnh](https://hackmd.io/_uploads/B14Uq3kAR.png) --- ### Phân tích: - ta thấy đây là trang web cho phép hiển thị hình ảnh ![ảnh](https://hackmd.io/_uploads/ryFYOhJAC.png) ta thấy đây là trang web cho phép hiển thị hình ảnh --- ### attack ![ảnh](https://hackmd.io/_uploads/BkKEY3JRR.png) - b1: Mở burp và bắt lấy goi tin chưa filename - b2:Thay đổi filename= ../../../etc/passwd ## Level 2 ### Đề bài - Đây là bài liên quan đến bypass đường dẫn tuyệt đối ![ảnh](https://hackmd.io/_uploads/B18Dn21AC.png) ### Attack ![ảnh](https://hackmd.io/_uploads/Bknd6nJ00.png) - Chỉ cần thay đổi filename = /etc/passwd ## Level 3 ### Đề bài ``` File path traversal, traversal sequences stripped non-recursively Nghĩa là, hệ thống chỉ kiểm tra và loại bỏ một lần các chuỗi path traversal (chẳng hạn như ../), nhưng nếu có nhiều chuỗi path traversal liên tiếp hoặc sử dụng các biến thể khác nhau, thì hệ thống có thể không phát hiện hết, dẫn đến khả năng kẻ tấn công vẫn có thể thực hiện truy cập trái phép vào các thư mục hoặc tệp nhạy cảm. ``` ### Attack - Ở bài này đã loại bỏ đường dẫn ../ nhưng nếu có nhiều chuỗi liên tiếp hay nhiều biến thể khác nhau thì sao? - Có thể sử dụng các biến thể như: ``` ....\/ ....// %2e%2e%2f ``` ![ảnh](https://hackmd.io/_uploads/BkQKYRc00.png) - Ta sử dụng `....//....//....//etc/passwd` để bypass ## Level 4 ### Đề bài ![ảnh](https://hackmd.io/_uploads/S19x0HsR0.png) ``` Ở bài này, đường truyền dẫn sẽ được loại bỏ những kí tự không hợp lệ(../) nhằm tránh việc truy cập không hợp lệ nhưng xảy trường hợp giải mã url nhiều lần không cần thiết (%252f<2 lần endoce> --> %2f<1 lần encode> --> kí tự "/") ``` ### Attack ![ảnh](https://hackmd.io/_uploads/ByAo-Is0C.png) - Như vậy theo đề bài, ta sẽ phải encode kí tự "/" - Ở lần đầu: `..%2f..%2f..%2fetc/passwd` - ![ảnh](https://hackmd.io/_uploads/B1pfG8jCC.png) - kết quả trả về `no such file` --- - Đến với làn encode thứ 2: `..%252f..%252f..%252fetc/passwd` ![ảnh](https://hackmd.io/_uploads/rJYgXIs0R.png) - Như vậy với 2 lần encode thì kết quả đã trả về như ta mong đợi ## Level 5 ### Đề bài ![ảnh](https://hackmd.io/_uploads/ryiJxviAC.png) - Ở bài yêu cầu chúng ta cần phải xác thực được điểm bắt đầu của đường dẫn ### Attack - Trên màn hình hiển thị của burp, ta có thể dễ dàng nhận thấy được điểm bắt đầu của đường dẫn là `/var/www/images` ![ảnh](https://hackmd.io/_uploads/B1cI7vj0C.png) - Như vậy, ta chỉ cần sửa lại `/var/www/images` --> `/var/www/images/../../../etc/passwd` -> ![ảnh](https://hackmd.io/_uploads/HyIiQDiCC.png) - Hoàn thành yêu cầu đề bài ## Level 6 ### Đề bài ![ảnh](https://hackmd.io/_uploads/B137EviRR.png) - Ở bài này sẽ yêu cầu xác thực phần mở rộng cùa file bằng cách bỏ qua byte rỗng - The application validates that the supplied filename ends with the expected file extension. ứng dụng sẽ kiểm tra tên tệp sẽ hợp lệ khi tên tệp có đuôi file như mong muốn( trường hợp là file jpg như ban đầu ) ### Attack - Ta sẽ chèn kí tự rỗng vào tên file và giữ nguyên phần mở rộng để thực thi đường dẫn - `../../../etc/passwd%20.jpg`: ở đây, kí tự %00 là 1 byte rỗng - ![ảnh](https://hackmd.io/_uploads/rkjjovi0R.png) - Hoàn thành yêu cầu đề bài