MatesCTF Round 4 - Piano - web2 - rewind - web3

Piano

Challenge: link

Đề bài cho ta một file thực thi exe, sau khi upload lên VirusTotal để scan thì mình phát hiện đây chương trình được viết bằng C#scan

Vì được viết bằng C# nên ta sẽ dùng dnSpy để decompile thử.
Chương trình sẽ có 12 phím đàn: A B C D E F G A# C# D# F# G#
Khi ta nhấn 1 phím đàn thì giá trị của label lbKey sẽ được cộng thêm tên của phím đàn tương ứngclick
Còn có 1 button khác có tên là Unlock, khi click thì sẽ kiểm tra lbKey nếu hợp lệ thì sẽ decrypt 1 đoạn cipher bằng AES, đây có thể là flag.unlock
Key hợp lệ là key có độ dài bằng 17 và phải thỏa mãn 2 hàm Verify_P1Verify_P2verify
Đây là 2 hàm thực hiện mã hóa RSA để kiểm tra key (key được chia thành 2 phần, phần 1 có độ dài là 8, phần 2 có độ dài là 9).
Ở hàm Verify_P1 do ta có thể factor modulus nên ta có thể decrypt và tìm được md5(Part1) và vì key là tổ hợp của 8 kí tự (A, B, C, D, E, F, G, #) nên ta có thể vét cạn để tìm Part1 từ md5(Part1).
Còn ở hàm Verify_P2 do ta không factor modulus được nên không thể decrypt được, nhưng vì Part2 có độ dài là 9 và key vẫn là tổ hợp của 8 kí tự trên nên ta cũng có thể vét cạn.

script.py
Flag: matesctf{f0ll0w_th3_sw4n}

web2

Source: backup.zip

Source trên được @DoubleVKay tìm được, coi qua source thì mình thấy chỗ có khả năng khai thác:vul

$COOKIE['user_login'] được decrypt bằng AES-CBC (key và iv đều có sẵn trong source) sau đó được unserialize và không có kiểm tra kết quả, đến đây mình được @pickaxe gợi ý về việc sử dụng hàm __toString() của class Loglog-1
__toString() là 1 Magic Method được gọi khi object được sử dụng như là 1 chuỗi, ta thấy là sau khi unserialize thì object được lưu vào $SESSION['user_login'], và ở trong profile.php có sử dụng biến này như là chuỗi, có nghĩa là khi ta load trang profile.php thì nếu cookie hợp lệ thì hàm __toString() của object $SESSION['user_login'] sẽ được gọiusing_tostring
Vậy ta sẽ craft payload sao cho sau khi decrypt AES và unserialize thì ta được 1 object của class AccessLog (không thể sử dụng trực tiếp class Log vì Log là 1 abstract class) vì hàm __toString() của class AccessLog này sẽ trả về nội dung của file có đường dẫn là thuộc tính filename của class này nên ta sẽ cho thuộc tính filename này thành đường đẫn tới file chứa flag (s3cr3t.php) là ta sẽ lấy được flag.
O:14:"Util\AccessLog":1:{s:8:"fileName";s:10:"s3cr3t.php";}

script.py
Flag: matesctf{Thi$_1s_Fl4g__0f_chall3nge}

rewind

Challenge: link

Đề bài cho ta 1 file .pcap, mở thử bằng Wireshark.
Phần đầu chỉ gồm các gói tin ARP, phần cuối có các gói tin gửi qua port 123, định dạng data nhìn rất giống base64, mình decode thử đoạn đầu thì thấy đây có thể là file .pngbase64

Mình export các gói tin ở port 123 ra và decode toàn bộ thì ta được flagflag

script.py
Flag: matesctf{s0_m4ny_3xf1l_pr0t0c0lz}

web3

Challenge: gallery_ctf.zip
Hint: gallery_ctf.conf, gallery_ctf_vhost.conf

Đọc qua source của bài này thì mình tìm được 1 vị trí có khả năng khai thác đượcext
Đó là trong hàm xử lý việc upload image thông qua url (fromURL($url)), extension của file được lưu trên server được lấy từ header Content-Type mà không qua filter nào :). Ta chỉ cần setup 1 server trả về header Content-Type: image/php là file ta upload sẽ có extension php.
Vì toàn bộ file upload chỉ có thể truy cập từ local, nên mình sẽ craft shell gửi flag về server của mình
gallery_ctf_vhost.confgallery_ctf_vhost
Shellshell
Đến đây mình cứ ngỡ là xong nhưng vẫn chưa lấy được flag. Từ đầu tới giờ mình chỉ quan tâm tới extension của file mà quên mất là tên file được gắn thêm hash sha1filename
Lúc đầu mình định bruteforce, nhưng không khả quan. Sau đó mình phát hiện ra sau khi server dùng curl download file về thì đường dẫn được lưu vào databasedb
Mình bắt đầu chuyển hướng sang tìm lỗi sql injection để có thể tìm tên file mình đã upload lên server.
Có 2 nơi thực hiện thao tác với database:

  • 1 là lúc thêm đường dẫn vào database (hàm insertDB($path)), nhưng không khả thi vì đã filter kí tự '
  • 2 là tham số p_type

Tham số p_type này có vẻ không hề được filter gì cả, nhưng khi mình inject thì không thành công. Nguyên nhân là do file gallery_ctf.conf này đây
gallery_ctf.confgallery_ctf_conf
Đây là file config của ModSecurity, file config này có hiệu lực với các truy vấn đến đường dẫn có chứa chuỗi gallery_ctf (ví dụ /gallery_ctf/index.php), server sẽ trả về HTTP status 403 nếu các truy vấn này có chứa đối số p_type sau khi qua các hàm trim, lowercase, urldecode khớp với regex [^0-9]. Hay nói cách khác là SecRule này chỉ chấp nhận tham số p_type có dạng số, đó là lý do mình inject không thành công.
Lúc đầu mình tìm cách bypass gallery_ctf để cho SecRule này không apply vào request của mình nhưng không thành công.
Mình chuyển sang tìm cách bypass tham số p_type. Sau 1 lúc debug ở local mình phát hiện ra php sẽ tự chuyển kí tự ' ' sang '_' trong tên của tham số mình truyền lên server (ví dụ ?p%20type=1 khi được gán vào $GET sẽ là $GET['p_type']=1), trong khi đó SecRule xem tham số ta truyền lên là p type, và vì tham số này không bị filter nên ta có thể input vô tư :)
Vì server mình setup trên /matesctf2019.php
nên path khi được chèn vào database sẽ có dạng:
uploads/matesctf2019_sha1().php
Mình sẽ inject bằng query như sau:
?p type=123 union select path from uploads where path like '%matesctf2019%'
Sau khi urlencode sẽ là:
?p%20type=123%20union%20select%20path%20from%20uploads%20where%20path%20like%20%27%25matesctf2019%25%27
Kết quả: uploads/matesctf2019_7b155f9d53d5cf3e125c62cdf1ac577746764bef.php
Vì thư mục upload chỉ cho phép truy cập nội bộ nên ta dùng tính năng upload thông qua url để truy vấn đến file này, đây là lý do lúc đầu mình tạo shell gửi flag về server của mình chứ không đơn thuần là in flag.final

Flag: matesctf{Byp4ss_m0ds3c_ee79e561950681b268c49b9e13878ec1}

Trong lúc dump database thì mình thấy được 1 điểm thú vịwtf
Có ai đó đã chèn vào table uploads nội dung của file flag.php, hiện tại thì mình không thể tìm ra cách nào để thực hiện điều này, vì path được chèn vào database không thể nào không có prefix uploads/, trừ khi họ chèn thông qua p_type, nhưng để làm gì?

Show Comments

Get the latest posts delivered right to your inbox.