Chuyên mục: CTF
Nơi đưa ra các solution để giải CTF trong các trang web CTF hiện nay
SECATHON 2018 – RVZT
Khoan hay nhắc đến tên đề bài này có nghĩa gì mà xem nó chạy ra cái gì.
Chúng ta đi vào phân tích file ELF này qua IDA đã xem nó là gì. Flag được lưu trong mảng ptr
Sau khi nhập liệu vào ptr, thực hiện một chuỗi các hàm kiểm tra với Flag. Đầu tiên Flag phải có 26 ký tự.
Hàm tạm đặt tên là Validate() sẽ kiểm tra giá trị một số ký tự thỏa mã các điều kiện như: Là chữ số, là chữ cái, là chữ viết thường, ….
Ta suy ra:
Ptr[0->7] là chữ cái Ptr[8] ko phải số hoặc chữ
Ptr[9] là chữ hoa Ptr[10] là chữ số
Ptr[11] là chữ hoa Ptr[12] là chữ cái
Ptr[13] là chữ số Prt[14] là chữ số
Ptr[15] là chữ cái Ptr[16] là chữ hoa
Ptr[17] là chữ cái Ptr[18] là chữ số
Ptr[19] là chữ hoa Ptr[20] là chữ số
Ptr[21] là chữ số
Ta gọi đây là điều kiện (1)
Sau đó là hàm W7G( ) kiểm tra ptr[10], ptr[12]
Vì đây là hàm kiểm tra các phần tử nên ta dễ dàng viết brute force để tìm ra
Suy ra Prt[10] = ‘3’ ; Ptr[12] = ‘n’
Ta gọi là điều kiện (2)
Tiếp theo là hàm ZS1DDAW2B( )
Suy ra:
Ptr[10] = Ptr[13] = Ptr[14] = Ptr[21] = Ptr[24]
Ptr[12] = Ptr[22]
Ta gọi là điều kiện (3)
Hàm ABWW7U9LE( )
Ở đây sử dụng hàm NOIBSA5() để kiểm tra từng ký tự Ptr[15], Ptr[17], Ptr[18], Ptr[20], Ptr[23]
Trong đó hàm NOIBSA5( )
Tiếp tục brute force để tim ra các ký tự này:
=> Ptr[15] = d; Ptr[17] = p; Ptr[18] = 4; Ptr[20] = 1; Ptr[23] = c
Ta gọi là điều kiện (4)
Từ (1), (2), (3) và (4) ta có:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
S | E | C | A | T | H | O | N | { | 3 | n | 3 | 3 | d | p | 4 | 1 | 3 | n | c | 3 | } |
Vậy là còn 4 vị trí nữa chưa xuất hiện trong phần kiểm tra ở trên mà sẽ được kiểm tra bằng hàm CRC32( ). Thực tế mình không thể tìm thấy hàm tương tự với 3 tham số như trong bài để brute force được nên cả buổi chiều giải không ra.
Trong hàm main( ) có đoạn kiểm tra Ptr[9] và Ptr[11] nên đã giới hạn được 1 phần:
P<= Ptr[9], Ptr[11] << Z
Đây chính là lúc ta nhìn lại đề bài: Đề bài gồm 4 chữ cái viết hoa không có nghĩa gì “RVZT”. Và vấn đề bài toán còn 4 ký tự chưa biết. Thử thêm lần lượt các ký tự đề bài vào và kiểm tra.
Flag: SECATHON{R3Vn33dZp4T23nc3}
Qua đây ta rút ra bài học: cần đọc kỹ đề trước khi làm bài.
SECATHON 2018 – DecryptFile
Bài này không phải khó nhưng nó yêu cầu kinh nghiệm làm nhiều CTF.
Đề bài có 2 file: 1 file thực thi và 1 file đã bị mã hóa
Chạy file thực thi thấy sinh ra 1 file: file_dec tuy nhiên file này không chạy được
Dùng IDA để xem code của file thực thi:
Đầu tiên, Key được sinh ra bởi hàm sub_4010A0( ) có 32 ký tự (giống mã md5) và chuỗi tham số nhập vào sau đó được đưa vào hàm giải mã sub_4017D0( )
Đọc vào hàm sub_4010A0( ) thấy có các con số lớn và lạ. Google thì biết đây là mảng tạo của thuật toán MD5.
Tại hàm giải mã sub_4017D0( ), thực hiện đọc file “file” sau đó lấy ra 8800 bytes để giải mã bằng Key rồi lưu vào file “file_dec”.
Phương thức giải mã được hiểu đơn giản là lấy các ký tự đọc được từ “file” nếu khác 0 thì xor với ký tự của Key.
Vậy thì vấn đề ở đây là nhập vào gì để sinh ra Key giải mã file ra được một file có nghĩa.
Mở “file” bằng 101 Editor thấy có những vùng toàn ký tự ‘\0x00’ rất giống với cấu trúc một file PE. Chúng ta đặt giả thiết: Nếu như “file_dec” là một file PE thì sẽ có e_magic ở DOS_HEADER là “MZ” và có một đặc trưng DOS stub sẽ không đổi ở mọi file là:
Dựa vào giả thiết này, ta code thử xem sẽ giải mã ra gì:
Ta được mã “5c7ab41e37efc4e816ebfcbc70071aa2” nhưng khi decrypt bằng tool onlie thì không ra gì 😦
Và may mắn khi “file_dec” thật sự là một file PE nhưng chạy không được do lỗi config.
Mở “file_dec” bằng CFF explorer tìm đển Resource Editor để xem file cấu hình trong Configuration File thì nhìn thấy trong thư mục Bitmap có 1 ảnh bmp
Export file bitmap ra thì thấy ảnh này không đọc được ra gì cả. Mở file bằng 101Editor lên để xem. Đến đây nếu không kiên trì và thêm may mắn thì nhiều bạn sẽ bỏ cuộc và tìm hướng khác.
Dựa vào kinh nghiệm chơi CTF, ở phần kích thước của file, ta thay đổi thông tin của chiều dài và chiều rộng của ảnh thử xem có mang lại kết quả gì không. Thường thì sẽ là nhân chiều rộng với x thì sẽ chia chiều cao với x. Như vậy ảnh sẽ không bị lỗi. Thử tăng chiều rộng lên 2 lần và giảm chiều cao đi 2 lần thì thấy ảnh bắt đầu xuất hiện chữ nhưng chưa rõ ràng.
Tăng tiếp chiều rộng lên 2 lần và giảm chiều dài đi 2 lần nữa ta được flag 🙂
Easy CTF 2018
Giải qua lâu rồi mà giờ mới có thời gian đăng một số bài dễ trong các bài dễ.
1. The Oldest Trick in the Book 10 points
miagkbn{e3tk0u3_70_345gk7n_4n5586} ROT18 => easyctf{w3lc0m3_70_345yc7f_4f5586}
2. Intro: Web 10 points
Mở source code ra thấy ngay
easyctf{hidden_from_the_masses_1f1196}
3. Soupreme Encoder 20 points
>>’68657869745f6d6174655f6264383563633931313362333033356466633434′.decode(‘hex’)
>>’hexit_mate_bd85cc9113b3035dfc44′
easyctf{ hexit_mate_bd85cc9113b3035dfc44}
4. Intro: Netcat 20 points
$ nc c1.easyctf.com 12481
enter your player key: 900062576
thanks! here’s your key: easyctf{hello_there!_D6365DA0EC8cF9E6}
5. Look At Flag 30 points
6. Haystack 30 points
Ctr+F : “easyctf” => easyctf{PraTBqbjTeXszjeAQDiexoCCg}
7. hexedit 50 points
Ctr+F : “easyctf” => easyctf{cc9990fc}
8. Substitute 50 points
https://quipqiup.com/ => HERE: EASYCTF{THIS_IS_AN_EASY_FLAG_TO_GUESS}
9. xor 50 points
s = ‘\XJ@ZM_B@NJLO^UAXI\Q\QRCUJJVHRZJMD’
for i in range(0, 256):
flag = ”
for x in s:
flag += chr(ord(x)^i)
print flag
EASYCTF{YWSUVGLXAPEHEHKZLSSOQKCST}
10. Intro: Linux 10 points
$ cat .flag
easyctf{i_know_how_2_find_hidden_files!}
Write Up Ph03nixCTF 2018
Lâu rồi không làm CTF nhưng vẫn giữ phong độ như xưa, vẫn gà mờ. Challenge thì toàn món ăn mà món ngon thì khó ăn.
1. WarmUP: Củ kiệu tôm khô 50pt
Bài khởi động với đường link: warmup1.ph03nix.club
Nhấn “Click me!” sẽ hiện cửa sổ check flag.
Nếu không phải flag thì sẽ báo false ngay.
Kiểm tra mã nguồn và thấy ngay script. Có thể đoán ra ngay hàm kiểm tra flag sử dụng mã hóa Caesar.
Giờ chỉ cần giải mã theo phương pháp giải mã Ceasar đoạn “Wo03upe{u9o1hka_k03z_u0a_zAbkF_1um0yt4a10u_4zzb4y4uj3}” là xong.
Flag: Ph03nix{n9h1adt_d03s_n0t_sTudY_1nf0rm4t10n_4ssu4r4nc3}
2. Warm Up: Thịt gà luộc 50pt
Server: nc warmup2.ph03nix.club 13337
Có file ELFx64. Dùng IDA xem giả mã C:
Nhập tên sao cho thỏa mã điều kiện bằng giá trị cho trước, tên có 10 ký tự. Ban đầu thì mình tìm giá trị lưu trong s1 = “erosnec**d” nhưng không được.
Hint: “I wonder what is pwnable!!!!!”. Xem lại ngăn xếp thì s2 có thể tràn sang s1 được, và phần nhập s2 không kiểm tra độ dài.
Tối thiểu cần nhập 0x30-0x10= 0x20 = 32 ký tự giống nhau để tràn sang s1.
Flag: Ph03nix{w3lc0m3_t0_s0ftw@r3_3xpl01t}
3. Cryptograph – Bánh tét – 200pt
Nhìn mê cung có điểm đầu và điểm cuối. Đoán rằng chuỗi cần tìm nằm trên đường đi ngắn nhất. Ta có được chuỗi mã hóa: “ENDTBTXNYVULWOFKJEGBYSTFPFMJFYMNVCBPYDDFSQOKEGPKX”
Theo hint thì bản rõ bắt đầu bằng ENC mã bản mã hóa là END, nghi ngờ là mã hóa dịch vòng ở ký tự thứ 3. Vậy thì tại sao các ký tự trước không mã hóa dịch vòng ? Nhìn lên mê cung thấy N -> D có thay đổi hướng đi.
Thử theo quy luật: khóa dịch vòng k = 0, cứ đổi hướng đi thì k+=1
Ta được flag: Ph03nix{ENCRYPTISONEOFWAYSTOKEEPYOURMESSAGESAFEFROMHACKER}
4. Pwnable – Xôi gấc – 100pt
Server: nc pwn100.ph03nix.club 13337
Có file ELFx64. Mở file bằng IDA để xem giả mã C
Yêu cầu ở đây là số nhập vào bằng số mà server random tạo ra bằng hàm rand(). Nhưng trước đó có hàm tạo seed là srand(0) nên có thể đoán được nó là bao nhiêu. Bắt tay vào code thôi.
Dùng dll của C trong Ubuntu để tạo seed và các giá trị random khác theo đúng thứ tự tạo ra như server đã tạo. Để tránh việc trễ thời gian client-server nên mình đã thêm vào biến pad.
May mắn thay mạng nhanh, ít người giải bài này nên từ pad=0 là đã ra flag rồi.
Flag: Ph03nix{Th@nk_y0u_f0r_p@rt1c1p@t10n_Ph03n1xCTF_…@@@}
5. Reverse Engineering – Nem rán – 150pt
Có file PEx64. Chạy thử và thấy lỗi.
Mở file bằng IDA để xem.
Đoạn code ở 0x408180 được xor với số nhập vào (dl). Sau đó lại thực thi code đó, nhập lung tung lỗi là đúng rồi. Suy nghĩ, nếu nhập đúng sẽ hiện lên đoạn code in ra flag. Xem trong bảng string thấy có string hiện thị flag còn thiếu phần tên có địa chỉ 0x004080C0.
Nếu in ra flag thì sẽ có đoạn push địa chỉ vào stack để làm tham số cho hàm printf. Dump đoạn code đó ra rồi đem xor với số từ 0 -> 255 để tìm đoạn code nào có chứa lệnh push tham số 0x004080C0 tức là code sẽ có đoạn “\xC0\x80\x40\x00”
Nhập thử 136 🙂
Một nửa vấn đề đã xong. Nhập tên sai vẫn không giải quyết được gì. Debug đến đoạn kiển tra tên nhập vào.
Tên có chiều dài 0xE = 14 ký tự. Nhập không đúng độ dài là “There is nothing for you %s”. Nếu đúng thì sẽ đến đoạn kiểm tra.
Ở đây, tên nhập vào được xor với hardcode 0xD3 rồi so sánh với đoạn hex ‘A0 E3 A6 A1 B0 E0 8C B0 A1 E7 B0 B8 E0 A1’. Tìm ra tên thôi
Nhập vào và ra flag: Ph03nix{s0urc3_cr4ck3r_r4t_d3p_tr4i}
Không biết đẹp trai hay không nhưng code viết là 200pt mà cho có 150pt.
6. Miscellaneous – Măng hầm giò heo – 200pt
Server: nc misc200.ph03nix.club 13337
Hint: Do you known this algorithm?
Chạy thử, thì thấy yêu cầu giá trị nhập vào thay đổi và số lần nhập hữu hạn trong khi không gian khóa thì lớn hơn số lần nhập.
Nhìn thấy “High” và “Low” thì nghĩ đến thuật toán tìm kiếm trên cây nhị phân. Thử và nhận được đáp án.
Viết code cho bao nhiêu round cũng được mà đề có mỗi 2 round 🙂
Flag: Ph03nix{@lg0r1thm_5p3c1@l15t5_15_y0u!!!}