Đây là lần thứ 2 mình tham gia PTIT CTF trong suốt 4 năm học tại trường P nhưng lần này khác với lần tham gia trước khi mình là thành viên ban tổ chức và là một trong những người ra đề cho mảng Web. Nếu tính ra cả vòng loại thì mình ra 3 bài Web7, Web6 và Web10. Lần tham gia này khá là đáng nhớ với mình khi mà cuộc thi bị dời lịch lên xuống rồi gặp khá nhiều chuyện trong lúc tổ chức ví dụ như server mình host các Web chall đột nhiên lăn ra chết cổng chỉ 30 phút trước khi bắt đầu thi rồi khi bắt đầu thi, con router lại lăn ra ăn vạ :v. 
    Về đề Web lần này cũng khá lạ khi bài của một ông anh D16 mà mình tưởng khó lại thành bài nhiều người làm được nhất, còn bài mà mình làm ra để cho thành bài dễ lại chẳng ai làm được :v
    Và theo yêu càu của một vài bạn thì sau đây mình sẽ viết lại lời giải chi tiết cho 2 bài Web6 và Web10 ở vòng chung kết vừa kết thúc vào sáng nay.
I. Web 10: Time Machine
    Đề bài nằm ở đây: http://35.198.212.205:1001/    
    Bài này mình lấy ý tưởng từ một giải ctf bên Arab mà mình đã ăn hành ngập mồm hồi tháng 7 hay tháng 8 gì đó :v. Trang web trên sẽ có 1 trang index hỏi key để lấy được flag:
    Việc đầu tiên với mỗi Web challenge sẽ luôn là thu thập mọi thông tin có thể có về đề bài. Bước 1 sẽ luôn là view source để xem trong html của trang web có thông tin nào có thể có thể sử dụng không:
    Như đã thấy, trong html có đề cập đến 1 trang backup. Đi đến trang này thì sẽ thấy 1 trang giống hệt với trang index :v. Nhiều bạn đến đây sẽ bị rối khi không biết đi tiếp thế nào. Tuy nhiên, hãy chú ý đến cái tên backup. Một trong những lỗi rất hay gặp ở các website là vô tình để lộ các file backup, debug từ đó cung cấp thông tin có thể là về vị trí folder root, các thông tin về server web, ngôn ngữ đang sử dụng thậm chí có thể là source code cho những kẻ tấn công. Đó chính là hướng đi của bài này. Để kiểm tra xem 1 trang web có để lộ file backup nào hay không, các bạn có thể dùng công cụ này: https://github.com/mazen160/bfac

    Sau một vài bước cài đặt các thư viện cần thiết (*Thành biết pip install khi thiếu thư viện chưa em*) và chạy file setup.py thì bfac đã sẵn sàng để sử dụng. Chạy lệnh bfac --url http://35.198.212.205:1001/backup.php bằng terminal/cmd để kiểm tra thôi:
    Kết quả cho thấy website này có 1 file ẩn với đuôi .swp. File .swp là file được tạo ra bởi các text editor trên linux như vim hay nano, chứa phiên bản recovery của file đang được mở. Đi đến url trên và tải file này về. Mở file bằng 1 hex editor hay text editor nào đó, các bạn sẽ thấy 1 đoạn code php:
    Đến đây chắc hẳn các bạn cũng có thể đoán được việc cần làm là vượt qua hàm preg_match cái regex kia để có thể lấy được nội dung file ko_so_tu_lop_1_den_lop_5.txt. Sau khi vượt qua bằng việc gửi string ____a`____the^'____a`____ lên thì các bạn sẽ có được flag:
    Khá tiếc là tiếc khi không có ai làm được bài này khi mình đã để đến 2 hint trực tiếp. 
    Hint đầu chỉ cần google là các bạn sẽ thấy một document về vim có đề cập đến đuôi file swp trong vài kết quả đầu. Hint còn lại chính là tên tool các bạn có thể sử dụng để giải bài này (*Thành nhớ việc cần làm khi đi bắt đầu test 1 website nào đó chưa e :D*).
II. Web6:Music Blog 1
    Đề bài nằm tại: http://35.187.245.113:1001/
    Bài này thì mình có ý tưởng từ một bài về secure session trong php mình vô tình đọc được nhưng không nhớ link :v. Bài này có khó hơn bài trên 1 chút.
    Việc đầu tiên cũng giống bài trên thôi, F12 để xem source html của website. Ở đây các bạn sẽ thấy 1 đoạn base64. Khi decode ra sẽ có được username-password để login:
    Login thành công, các bạn có thể thấy website chỉ có chức năng chính là View flag và View Lyrics. Tất nhiên, khi bấm vào View flag, các bạn sẽ bị 403 vì không có quyền :D. Quay lại trang index, khi F12 lên các bạn sẽ thấy cũng có 1 file backup có tên flag.php.bak. Tải file này về thì các bạn có thể xem được cách thức server kiểm tra quyền để cho các bạn flag:
    Như các bạn có thể thấy, server sẽ lấy user info của account hiện tại đang login và kiểm tra session của account có đúng là admin hay không. Sau đó là 1 đoạn code check 1 biến đã được hash từ trường Hmac trong cookie session_token với 1 biến được nối từ trường User cũng trong cookie session_token với 1 số random. Nếu bạn nào tinh ý thì hoàn thấy đoạn code kiểm tra này có thể bypass được khi việc so sánh chỉ sử dụng toán tử ==. Toán tử này trong php có 1 "tính năng" là chỉ kiểm tra giá trị chứ không kiểm tra kiểu dữ liệu của 2 biến được so sánh. Tìm một vài bài viết về "tính năng" trên google thì các bạn sẽ biến đến 1 cụm từ là "Magic hash" (Chi tiết các bạn có thể đọc tại đây https://www.whitehatsec.com/blog/magic-hashes/). Từ đó, việc bypass đoạn code kiểm tra này rất dễ. Chỉ cần decode base64 cookie ra, sửa trường User thành 0e và sửa trường Hmac thành 1 giá trị Magic hash SHA-1 là 10932435112
    Tuy nhiên, vấn đề lại nằm ở dòng if($_SESSION['permission']==="admin"). Cho bạn nào chưa biết cookie phpsessid chỉ là 1 id đại diện cho file session chứa thông tin session hiện tại và biến $_SESSION chính là một mảng có giá trị là các thông tin có trong session file đó. Vấn đề là làm sao để có thể chỉnh sửa được biến này? Lúc này, quay lại kiểm tra nốt chức năng View lyrics, chỉ bằng công cụ BurpSuite và 1 payload vô cùng thông dụng, các bạn có thể thấy chức năng này có lỗi Path Traversal:
     Bình thường, php sẽ tự động tạo 1 file session tại vị trí /var/lib/php/sessions/sess_*phpsessid* khi có sessionid được sinh ra và nó sẽ tự động phân quyền để cho file session này chỉ có thể được user root có quyền đọc và chỉnh sửa. Tuy nhiên, đôi khi người code web vì một mục đích nào đó có thể đã sửa lại quyền của file session này cho phép bất cứ user nào cũng có thể đọc hay sửa file. Đây là 1 việc rất nguy hiểm vì thông qua file session này, người dùng có thể chèn các đoạn code dẫn đến việc chiếm quyền điều khiển server. Đây chính là lỗi PHP Session file poison (các bạn có thể đọc thêm ở đây http://ha.xxor.se/2011/09/local-session-poisoning-in-php-part-1.html). 
    Lợi dụng lỗi Path Traversal, các bạn có thể đọc được file session của session hiện tại:
    Như các bạn thấy, param name trong post request cũng được ghi vào session file, đến đây thì các bạn hoàn toán có thể inject code php vào file session thông qua param này. Rồi server sẽ xử lý include session file khi các bạn gửi request => đoạn code inject sẽ được thực hiện:
    Với request trên, mình đã có thể ghi đè được biến $_SESSION['permission'] thành admin. Việc bypass đoạn code kiểm tra để lấy flag thì mình đã nói bên trên hoặc các bạn có thể làm theo cách nhanh hơn: chạy trực tiếp lệnh terminal thông qua hàm system trong php:
    Bằng lệnh ls -lR mình đã có thể list hết các file và folder có trong folder root web ra (*Đạt nhớ về học lại lệnh Linux nhé em :D*). Khi thấy có 1 controller là viewflag thì các bạn chỉ cần cat file đó ra là có được flag:
    Bài này cũng khá tiếc khi mình cũng hint 2 lần nhưng chỉ có 1 bạn làm được. Với hint 1 các bạn có thể google để hiểu rõ về quyền của file session và hint 2 chính là câu lệnh trực tiếp gây ra lỗi
P/S: 
    - Khi gửi request thông qua repeater của burpsuite thì các bạn nên gửi 2 lần để server trả về kết quả đúng :v Mình cũng méo hiểu sao bị lỗi này nữa :v
    - Burpsuite là 1 công cụ rất mạnh trong web ctf nói riêng và pentest web nói chung. Các bạn có thể học dùng tool này để dễ dàng hơn trong quá trình chơi ctf.
    - Thông qua bài này, mình cũng hy vọng có những bạn có cùng gu âm nhạc với mình :D
Và đó là writeup cho 2 bài web mà mình ra đề trong vòng chung kết PTIT CTF 2020. Nếu có gì sai sót, mình rất mong có được sự góp ý, sửa chữa của các bạn. Mình sẽ tiếp tục bật server cho đến hết tuần sau. Cảm ơn mọi người đã đọc bài viết dài + khô này của mình xD. Hy vọng năm sau tiếp tục được gặp lại các bạn trong PTIT CTF 2021.