KCSC Recruitment 2024
Solutions for some challenges in KCSC Recruitment 2024
KCSC Recruitment 2024
rev/riel warmup
- 4 solves / 460 pts / by 13r_ə_Rɪst
- Given files: chall.exe
- Description: w-weo cum to REV, các bạn có thể tải ida tại đây
Solution
Load file đề bài cho vào IDA64, chuyển qua tab code assembly, ta có thể thấy được các phần của flag. Ghép chúng lại và ta được flag KCSC{have_u_known_IDA_after_this_real_warmup}
rev/Elif
- 8 solves / 280 pts / by noobmannn
- Given files: FlagChecker1.py
- Description: Có phải thứ này là code Al không vậy???
Solution
Đọc qua file được cho, ta thấy có rất nhiều phương trình có dạng như này
|
|
Để giải được dạng bài này, ta chỉ cần sử dụng Z3 và thu được flag là KCSC{700_much_1f-3l53_f0r_fl46ch3ck3r!!!7ry_z3<3}
|
|
rev/Go
- 4 solves / 460 pts / by noobmannn
- Given files: FlagChecker2
- Description: Thứ này khó nhìn quá :((( Bạn có thể giúp tôi xử lý nó được không???
Solution
Đây là một file binary được viết bằng Go. Sau một hồi phân tích kết hợp debug, mình đoán đây là đoạn code check độ dài input. Từ đây, có thể suy đoán được độ dài input là 51.
|
|
Đoạn mã check flag nằm ở dưới đây
|
|
Đoạn kiểm tra trên có thể được mô tả như sau:
|
|
Thực hiện debug, mình có viết 1 script nhỏ để lấy toàn bộ giá trị của mảng check
trong IDA Python
|
|
Sau khi đã có đầy đủ dữ liệu, ta dễ dàng viết lại thuật toán giải mã và thu được flag KCSC{7h15_15_345y60l4n6_ch4ll3n63_7ea2da17_<3<3!!!}
|
|
rev/Time travel
Solution
Load file vào IDA64, ta thấy đoạn code của chương trình chính rất ngắn gọn.
Chương trình khởi tạo seed để gọi hàm rand()
, mở file enc.txt
và ghi dữ liệu bị encrypt vào file.
Ý tưởng để giải bài này rất đơn giản. Vì format flag là KCSC{
vậy nên ta sẽ có được 5 giá trị random đầu tiên. Tiếp đến, ta sẽ bruteforce seed để tìm ra seed chính xác của tác giả.
|
|
Công việc còn lại là là xor ngược lại để lấy flag. Kết quả thu được là KCSC{0xffffff_is_1970-07-14,I_created_this_challenge_at_"the_end"_of_time}
|
|
rev/Từng Quen
- 1 solve / 500 pts / by 1conmeo
- Given files:
- Description: Benjamin bị kẻ xấu loMbeoS mã hóa mất 1 file quan trọng, hãy giúp anh ấy khôi phục lại file này. Benj fan WREN EVANS
Solution
Load file đề bài cho vào IDA64, dưới đây là phần chính của chương trình.
Ta thấy chương trình tạo 16 số random, đổi 4 số random cuối bằng giá trị có sẵn. Ở phần mã hóa, ta có thể tóm gọn lại như sau
|
|
Do flag format là KCSC{
ta sẽ xor ngược lại để tính được 5 giá trị random đầu tiên. Sau đó sẽ bruteforce tất cả các seed để tìm ra seed chính xác của tác giả.
Đây là đoạn code để mình lấy 5 giá trị random đầu tiên
|
|
Sau khi có các giá trị random, mình sẽ đi bruteforce seed. Lưu ý là đề bài cho chúng ta file exe
nên ta phải compile source code này trên Windows
|
|
Khi đã tìm thấy seed, ta thực hiện xor ngược lại để tìm ra flag. Kết quả thu được là KCSC{nhin em anh boi roi anh thua roi tim em lam loi anh chua tung dam noi anh yeu mot ai the nay!!}
|
|
rev/Shelter
- 0 solve / 500 pts / by noobmannn
- Given files: FlagChecker3.exe
- Description: There is some Crypto in this :3
Hint 1: https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptencrypt
Hint 2: Hint 1 → cách mã hoá, phân tích - tìm những thứ cần thiết và hãy để tool làm việc mà nó phải làm
Solution
Load file đề bài cho vào IDA64. Sau khi phân tích chức năng các hàm, mình đã rename lại và có kết quả như sau
|
|
Phân tích hàm paddingInput()
, nhiệm vụ của hàm này chỉ là padding 0
vào input
sao cho độ dài input
chia hết cho 16 và không lớn hơn 80 byte.
|
|
Hàm sha256_key
sử dụng các hàm encrypt của WinAPI để tạo hash SHA256 của link https://www.youtube.com/watch?v=fzQ6gRAEoy0
Hàm md5_iv()
có chức năng tương tự như hàm sha256_key
. Thay vì tạo hash SHA256 thì sẽ tạo hash MD5 cho link https://www.youtube.com/watch?v=fzQ6gRAEoy0
Quan sát hàm encryptData
, ta thấy hàm sử dụng thuật toán AES để mã hóa dữ liệu.
Các bước thực hiện mã hóa của hàm này diễn ra như sau:
- Gọi hàm
CryptAcquireContextW
để set context mã hóa là AES. - Gọi hàm
CryptImportKey
để lấy keysha256Hash
. Nó được cất trongpdData
ở phía dưới
- Gọi hàm
CryptSetKeyParam
để set IV và chế độ mã hóa AES CBC. - Gọi hàm
CryptEncrypt
để mã hóa dữ liệu.
Sau khi mã hóa dữ liệu, hàm checkFlag
được gọi để so sánh encrypted input với mảng ans
đã có sẵn
|
|
Sau khi hiểu rõ toàn bộ luồng hoạt động của chương trình, mình đã viết lại toàn bộ các hàm để tạo ra sha256_hash
và md5_iv
. Sau đó gọi hàm CryptDecrypt
của WinAPI để giải mã.
Flag thu được là KCSC{md5_4nd_5h4256_4nd_435_w17h_w1n4p1_YXV0aG9ybm9vYm1hbm5uZnJvbWtjc2M=}
|
|
Ngoài việc sử dụng WinAPI để decrypt, chúng ta có thể sử dụng python để giải mã như sau
|
|
rev/s1mple flag checker but no SEE
- 2 solves / 496 pts / by 13r_ə_Rɪst
- Given files: Flag_Checker.java
- Description: no SEE or no C, you see :))
Solution
Đề bài cho chúng ta một file flag checker được viết bởi ngôn ngữ Java
|
|
Đây là câu lệnh để kiểm tra flag bằng nhiều hàm check
lồng nhau:
|
|
Ta thấy tên hàm không khác nhau nhưng các đối số được truyền vào khác nhau. Đây là cách viết nạp chồng hàm trong lập trình hướng đối tượng. Để dễ phân biệt, mình sẽ rename các hàm lại tránh việc nhầm lẫn.
Hàm check1
Chỉ đơn giản là đi kiểm tra input có bắt đầu bằng cụm từ KCSC{
và kết thúc bằng }
hay không.
|
|
Hàm check2
|
|
Ý tưởng của hàm trên là đi kiểm tra giá trị tại các index trong mảng pos[]
có phải là chữ số không. Sau đó convert thành số nguyên, lưu vào mảng num[]
rồi đi kiểm tra các điều kiện biểu thức. Mình sẽ dùng Z3 để đi tìm các giá trị của mảng num[]
như sau
|
|
Mình có comment lại 1 điều kiện do BitVec không tính mũ được nhưng kết quả tìm ra vẫn thỏa mãn tất cả các điều kiện.
Sau bước check này, ta thu được flag có dạng KCSC{*****0****5***0********4*1*************4****5******}
Hàm check3
|
|
Giá trị của các index trong mảng pos[]
là _
. Ta được flag có dạng KCSC{*****0****5*_*0*_**_***4_1*_**_**_*****4***_5***_**}
Hàm check5
|
|
Hàm này chúng ta tiếp tục sử dụng Z3 để giải.
|
|
Sau khi tìm được giá trị của mảng tmp[]
, mình tiếp tục lắp ráp nó vào flag theo đúng vị trí trong mảng f1nal[]
.
|
|
Flag chúng ta thu được là KCSC{*****0****5*_O0P_of_Jav4_1s_ez_to_aP***4**_*5**_**?}
Hàm check4
|
|
Hàm này duyệt một substring sau KCSC{
và trước }
trong input với 2 con trỏ left
và right
. Mỗi con trỏ này sẽ liên tục tăng lên và giảm đi, cuối cùng nó sẽ dừng tại vị trí mà ở đó là một ký tự. Tiếp theo, nó sẽ check input[left] = let[cnt + 1]
và input[right] = let[cnt]
không và cnt += 2
. Lấy ví dụ như flag là KCSC{*****0****5*_O0P_of_Jav4_1s_ez_to_aP***4**_*5**_**?}
thì *
đầu tiên bên trái phải là let[1] = 'P'
và *
đầu tiên bên phải phải là let[0] = 't'
.
Tới đây, chúng ta hoàn toàn có thể làm bằng tay để hoàn thiện flag. Mình có viết một script nhỏ để làm công việc này. Kết quả chạy sẽ bị lỗi out of range
nhưng mình không biết tại sao lại bị như vậy. Vì vậy, mỗi lần chạy mình sẽ in ra luôn mảng flag
và kết quả cuối cùng thu được là chính xác.
|
|
Convert mảng kia thành string và thu được flag là KCSC{PoLym0rphi5m_O0P_of_Jav4_1s_ez_to_aPPro4ch_i5nt_it?}
|
|
List Challenges
rev/Lies
- 0 solve / 500 pts / by noobmannn
- Given files: FlagChecker4.exe
- Description: Don’t miss anything
rev/ransom
- 0 solve / 500 pts
- Given files: Public.zip
- Description: Mr.Benj rất thích nghe mumble rap. Một ngày anh ta trong bài hát yêu thích của anh ta có 1 đoạn nghe rất lạ. Hãy giúp anh ta tìm nó.
rev/Just not a s1mple flag checker
- 0 solve /500 pts / by 13r_ə_Rɪst
- Given files: chall.exe
- Description: Cảnh này thật quen thuộc, ta đã từng thấy nó ở đâu rồi…