2019/04/26

MatesCTF S3R4 - Web 1,2,3

1, 2, 3 em có thấy thiếu nhịp nào không :?



Web1:
URL http://35.225.65.132:80/matesctf-01/
Sau khi dùng dirsearch để scan các file và thư mục thì có kết quả là

Để ý đến mail 1 chút thì sẽ thấy thư mục này có thể xem được có file gì bên trong
Nhận thấy website này cũng ít entrypoint, thử guessing và scan vào input thì không thấy gì đáng ngờ. Vậy thì có gì đáng ngờ ở cái mail này?

  • Sử dụng phpmailer : tiền sử dính bug lead to RCE
  • Xem file version để biết phiên bản đang sử dụng là 5.2.16, nhìn date thì cũng thấy cách đây khá lâu rồi
Vậy là tìm hiểu thử các exploit liên quan đến phpmailer xem sao. Có anh này viết khá chi tiết: https://github.com/opsxcq/exploit-CVE-2016-10033 và https://exploitbox.io/paper/Pwning-PHP-Mail-Function-For-Fun-And-RCE.html . Chắc mình không phân tích lại nữa.
Có 2 hướng khai thác, với điều kiện là có 1 thư mục "writable"
  • Tạo file shell
  • Đọc 1 file
Hướng đọc tạo shell thì có payload cần -oQ để tìm 1 thư mục queue file tạm, nhưng đề có vẻ đã filter việc dùng -oQ, cụ thể hơn là str_pos('-o') của lower email address. Trong lúc debug thì mình phát hiện là họ không dùng strict compare (===) mà dùng (==), điều này dẫn đến nếu input bắt đầu bằng -o thì bypass được nhưng khiến câu lệnh sendmail lỗi. Thử bỏ -oQ thì không tạo được file.
Hướng đọc file, về sau khi 1 bạn trong team nói với mình về việc đọc file cấu hình, điều này mình đã bỏ qua vì đinh ninh thiếu -oQ thì không được. Nhưng không ngờ là được thật.
Vậy thì payload chỉ đơn giản là :
"Fred\" -Ccontact.php -X../img/hihi.txt Bloggs"@example.com
"Fred\" -C../index.php -X../img/hihi.txt Bloggs"@example.com
"Fred\" -C../login.php -X../img/hihi.txt Bloggs"@example.com



Web2:
Sáng dậy thấy một bạn kêu có đội chưa gì đã 4k điểm. Mình thì mới ngủ dậy, ngày thì học cả ngày thì định buông, nhưng mà vì bài này có source nên cũng cố làm rồi đi học :?

Scan dir ra file backup, tưởng là source, hóa ra là source thật :D
Sau khi audit một hồi thì phát hiện là Controller dùng unserialize để kiểm tra user hợp lệ từ cookie. Sau đó gán vào $_SESSION

Mà Class OpenCiper thì có sẵn key các thứ. Việc tiếp theo là tìm 1 gadget. Dựa theo các file được require/include thì trong Utils/Log abstract class này cung cấp magic function __toString có thể được gọi bằng các hàm có ép kiểu sang string.
Và đâu đó trong code cũng có chỗ như vậy trong /views/profile.php

Thời gian địa điểm rõ ràng, à quên, còn việc vượt qua str_replace null byte, tại vì fileName là 1 biến protected nên khi serialize tên biến sẽ được thêm prefix là \0*\0 , nên có thể dùng cách thay đổi serialize string từ s thành S như mình từng trình bài tại Web100 (https://movrment.blogspot.com/2019/04/acebear-ctf-2019-web-category.html)

PoC



Web3:
Bài này đến gần cuối giờ BTC mới chịu đưa hint. Mà với một đứa chơi CTF cũng có thời gian lâu như mình thì độ nhạy cảm để guessing là gần như không còn. Gần như chỉ biết làm mấy bài có source
Bạn biết muốn disable mình thì làm gì rồi đấy :)
Ok, trở lại vấn đề. Có một tiếng để yêu lại từ đầu bài này trước khi hết giờ. Mã nguồn gồm 2 file.

index.php
Dễ thấy có sql injection, nhưng mà không dễ thế đâu sói :( Vẫn còn ModSec
Dù từng cài đặt ModSec vài lần nhưng mình vẫn thấy hiệu quả của ModSec là 1 cái gì đó khá xa vời. Và mục đích của challenge này chắc có lẽ cũng để dạy mọi người, cũng như mình về việc đọc, hiểu, và viết một cái ModSec vừa nhanh, vừa chuẩn.

Vậy thì cái SecRule nhằm mục đích chặn không cho bạn truyền tham số p_type ngoài số từ 0-9 nên là dù có inject kiểu gì thì cũng sẽ bị chặn thôi
Cái bên trên là gì thì mình cũng không biết :?

Giả sử như là SQL injection được thì làm gì tiếp? Trong file config.php
Có 2 chức năng được cài đặt để upload file lên server

  • "fromURL": upload file từ 1 URL
  • "fromUpload" : khá ổn rồi



Nếu tính dựa trên những gì có thể controll được thì "fromURL" có thể controll được cả "ext" của file, như vậy là có thể tạo 1 file .php bằng cách gửi header "Content-type: image/php"
Tuy nhiên filename là một thứ không kiểm soát được hoàn toàn mà là kết quả của sự random và 1 tham số thời gian. Tuy nhiên thì nó có lưu vào trong DB, nên việc SQLinjection có thể cần thiết.

Thời gian không còn nhiều nên mình chợt nghĩ đến bruteforce, được gì và mất gì? Timestamp có thể extract được từ response của server. Còn gần 100k hash cho rand() thì không nhiều. Chỉ có vấn đề là cần request thực sự nhanh do lúc này gần hết giờ rồi. Quả thật là việc race to win không hiệu quả lắm. Mình cũng nghĩ đến việc tăng hiệu quả brute bằng cách làm các file có cùng timestamp nhưng trong bài này thì do filename được tạo trước khi có http request nên sẽ không được.

Đáng tiếc là sau khi hết thời gian một lúc, mình mới chợt để ý đến 1 trick của PHP.

https://stackoverflow.com/questions/68651/get-php-to-stop-replacing-characters-in-get-or-post-arrays#answer-68742

Về cơ bản, $_GET của ?p_type hay ?p.type đều như nhau. ModSec bypassed. SQL injection solved -> lúc này chỉ cần query ra filename vừa insert vào db. Sau đó dùng chính "fromURL" để execute code php (từ remote file với mime image/php) (do uploads đã bị restrict chỉ còn local). disable_functions chỉ gây thêm chút khó khăn.

Và flag?


Web4??? Xin lỗi tác giả nhưng mình bận mấy bài kia quá nên không làm kịp :(

Enjoy :D


No comments:

Post a Comment