TetCTF 2019

1/File

http://139.180.219.222:8004/

index.html

Ở index là 1 đoạn chat về chủ đề chính là MacOS hay Windows ngon hơn :))), và người nói MacOS ngon hơn là anh tsu (author của challenge này) nên mình nghĩ bài này liên quan gì đó tới MacOS

Mình scan thử web này có gì lạ k thì scan dc /logs, /icons,… nhưng cái làm mình chú ý là /.DS_Store (nếu bạn nào chưa biết về file này có thể đọc writeup cũ của mình về DS_Store https://medium.com/@anhkhoafto/35c3ctf-junior-2018-writeups-be9b74ccaa2f)

Đây là toàn bộ source của challenge, lấy flag thôi

TetCTF{DS_Store__seems_sad}

2/ IQTEST
Trước khi viết wu bài này thì mình khá buồn và cay vì bài này và do mình ngu + cùi bắp nên bài này tất cả là công của PeterJson từ gợi ý mình về Hash Length Extension tới nói cho mình hiểu Hash Length Extension nó hoạt động ra làm sao

Giao diện bài này thế này

Source Code :

Cookie:

Bài này có 13 câu hỏi mình trả lời đúng 13 câu hỏi thì sẽ có được flag, với mỗi câu hỏi sẽ có 2 cookie là Hash và Saved

Saved = b64(seed)

Hash = md5(concat(secrect,seed))

6 câu đầu thì dễ dàng pass vì là câu hỏi multiple choice hoặc là mấy câu đơn giản, tới câu thứ 7 thì là thế này

Có đoán cũng tới mai :))) nên quay trở lại source code của bài này, thì có 1 đoạn cần chú ý

Nếu level = NULL (không có 1 cookie nào hoặc cookie không có nghĩa) thì level sẽ được dựa vào đoạn code này, đây là phần code mình debug thử để pass tới level 13

https://repl.it/@Bui_Duc_AnhDuc/ShinyNeedyDesktopenvironment

Vấn đề là làm sao để tạo ra 1 cookie mà có md5 hash có thể gửi lên và chạy thẳng tới level 13, đây là vấn đề của Hash Length Extension

Các bạn có thể đọc qua 2 wu của PeterJson để hiểu thêm về HLE, hoặc có thể cmt bên dưới mình có thể giải đáp những cái trong giới hạn kiến thức mình học được qua đọc 2 wu này:

https://medium.com/@peterjson/matesctf-round-5-qualification-crypto-writeup-a5e287838e69 (ViettelStore — Crypto100)

https://medium.com/@peterjson/uit-hacking-contest-2018-crypto-writeup-8bf32267e93b (Crypto400-SuperSecureServer)

Mình dùng Hash Extender để giải quyết bài này

Sau đó mình dùng new signature để làm cookie hash

new string thì mình dùng b64(‘seed=’+hexdecode(newstring)) để làm cookie saved

3/ phplimit revenge

về các filter của bài này thì mọi người có thể dùng https://regex101.com/ để đọc hiểu (ban đầu khá là khó hiểu nhưng có 1 số trợ giúp từ ae bạn dì nên mình cũng hiểu 😤)

If 1 chặn không cho mình truyền argument (string) vào các hàm để đọc flag , nên chỉ có thể truyền boolean vào đây thôi

If 2 thì chặn 1 số hàm dùng để đọc flag

PeterJson lại gợi ý mình 1 hàm có thể show ra được path hiện tại + có thể truyền boolean argument vào là realpath()

Cụ thể là mình có thể sử dụng realpath(false) hoặc realpath(NULL)

mà NULL thì đã có assert() => với realpath(assert()) thì mình có được path hiện tại

Mình cần đọc những file ở path đó thì có scandir()

với scandir(realpath(assert())) thì mình có được toàn bộ những file ở path đó

scandir sẽ trả về array, mình chỉ biết mỗi hàm print_r() để in ra array nhưng bị filter mất :((

Ok vậy thôi mình làm thủ công

sau 1 hồi mò thì tới được path này

[http://139.180.219.222/?code=echo(next(next(scandir(realpath(assert()))));](http://139.180.219.222/?code=echo(next(next(scandir(realpath(assert()))));)

Là file index, nên thôi mình quyết định coi file cuối cùng tên gì luôn

http://139.180.219.222/?code=echo(end(scandir(realpath(assert()))));

dùng readfile() để đọc file này

view-source:http://139.180.219.222/?code=readfile(end(scandir(realpath(assert()))));

4/ phplimit revenge v2

Phải nói là PHP khá là ảo diệu khi mình làm đc bài này :3 mình ko hiểu tác giả chặn strlen rồi rand làm gì nhưng sau 1 thời gian đọc các hàm trên w3schools thì thấy có 4 hàm là dirname, basename, realpath, pathinfo thì đều bị blacklisted theo như web này nói

search đi search lại cũng thấy web nào nói là dùng glob() kèm vs pattern

đắn đo mãi thì thử vs php online thì mình thấy là glob() trả về array theo pattern *, mỗi phần tử là các file trong thư mục 😆

'*' thì nó là string, làm sao để tạo *? booom, 1 idea khá là xịn cũng lầy vc, là tính ra số 42 r chr() để thành *

bắt đầu đi từ exp(assert()) , lý do mình gọi assert() vì nó là mặc định là TRUE == 1, thực hiện các phép tính toán (làm đại) thì may thật ra dc số 42 😖

mình cũng ko hiểu tại sao local tính ra số khác server tính số khác

dc 42 r thì biến nó thành * và glob :3

như trên glob trả về array, nhưng trước tiên coi thử có bn file hay folder con trong folder này (/var/www/html/)

hên vl :))) là có 3 file (ko biết có folder hay ko). Tiện vl, mình dùng các hàm này để di chuyển con trỏ tới các element trong array. Hên là vì tác giả để chỉ có 3 file, chứ 4 files mà flag nằm ở vị trí thứ 3 mình cũng chả biết trỏ kiểu gì =))

đoán bừa flag nằm cuối nên mình dùng end(…)

Coi thử có cái gì trong này

:)))) classic trick từ a tsu, ok mọi chuyện từ giờ còn khó hơn

okay, mình cần bây giờ là .. để có thể view các file trong parrent folder

ok, got it, ko dùng glob()nữa mà mình sẽ dùng scandir('.')thay cho glob() vì như hình bên trên glob('*') ko return về . hoặc ..

Hay quá có rồi :))) bây giờ là công đoạn làm cách nào tính cho ra được số 46 (decimal của .)

Bằng các biện pháp nghiệp vụ kết hợp vs kĩ năng toán học mà mình có với 1 ít tâm linh nào đó đã cho mình sức mạnh tính ra dc 64 =))) thử xem sao

có . rồi thì scandir hiện tại là (.) lấy next() là (..), rồi scandir(..), lấy end là có real flag

Mà flag của mình đâu rồi

Suy nghĩ 1 chút thì mình nó chỉ show content của parent dir thôi chứ mình chưa ở parent dir

dùng chdir() thì chắc được vì mình đã có .. rồi nên nhưng làm sao đọc flag?

thế lực siêu nhiên nào đó lại giúp mình khi chdir() return về boolean và nó là true == 1 . Thì sao nhỉ :3 nghĩa là mình đang có mặt ở .. và chỉ cần dùng phép toán mà thần linh đã ban cho tính từ exp(assert()) == chdir(‘..’)

http://45.76.181.81/?code=readfile(end(scandir(chr(strrev(floor(rad2deg(tan(sin(round(chdir(next(scandir(chr(strrev(floor(rad2deg(tan(sin(round(exp(assert())))))))))))))))))))));

Written on January 8, 2019