Tiếp nối phần 1, sau đây là writeup challenge 8 -> 11 của chúng mình
08_backdoor
Đề bài cho 1 file thực thi .NET có tên FlareOn.Backdoor.exe
Phân tích từ hàm main(), ta thấy hàm flared_38 decompile bị lỗi “An exception occurred when decompiling this method”.
Tiến hành kiểm tra một số hàm khác, ta thấy chương trình đã bị làm rối, nhiều hàm tình trạng tương tự function flared_38.
Kỹ thuật làm rối như sau:
- Byte code của mỗi hàm đều bị thay đổi bằng junk code
- Mỗi lần gọi vào hàm bị làm rối, chương trình sẽ bị exception và được xử lý ở nhánh catch{}
- Luồng thực thi nhánh catch{} sẽ patch lại byte code cho chính hàm gây nên exception lúc runtime, sau đó chương trình thực thi hàm vừa được patch
Hàm flare_71() là hàm patch byte code và thực thi hàm sau khi patch
Hàm flare_71() nhận 2 tham số quan trọng là Dictionary<uint v1, int v2> m, byte[] b
- Mỗi một dictionary m được gán trị trong hàm flare_74() lúc runtime đại diện cho một hàm bị làm rối:
- Giá trị uint v1: vị trí của token cần được patch
- Giá trí int v2: giá trị token sẽ được patch vào vị trí unit
- byte[] b chính là byte code đúng của hàm bị làm rối, b cũng được gán trị tương tự m
Để patch những hàm bị làm rối, ta có thể viết python script
Sau khi chạy script, ta patch được 6 hàm
- FLARE12.flared_46(): rc4 encrypt/decrypt
- FLARE15.flared_66(): tính hash của hàm dựa vào một số thông tin của hàm như MaxStackSize, ReturnType…
- FLARE15.flared_67(): patch byte code cho những function bị làm rối
- FLARE15.flared_68(): tính token
- FLARE15.flared_69(): Tìm kiếm tên section theo hash được tính bởi flared_66() và trả về byte code chứa trong section nếu tìm thấy
- FLARE15.flared_70():
- Lấy token của hàm gây ra exception
- Tính hash cho hàm đó
- Tìm kiếm lấy byte code đúng của hàm
- Giải mã byte code bằng RC4, key hardcode {18, 120, 171, 223}
- Patch lại byte code cho hàm
Dựa trên những hàm đã biết, ta viết C# code để patch những hàm còn lại.
Sau khi patch lần 2, toàn bộ hàm đều đã được compile.
Chương trình được thiết kế như 1 backdoor đúng với tên của nó vậy. Ở hàm FLARE14.flared_56(), ta thấy một thread được tạo để xử một số case command
Tiếp theo, ta cần xác định cách backdoor kết nối tới C&C và command được xử lý như thế nào
Ở đây, kỹ thuật dns tunneling được sử dụng để giao tiếp với C&C. Mỗi gói tin dns phản hồi sẽ được hàmFLARE05.flared_33(byte[] r) kiểm tra
- Điều kiện: byte đầu tiên của IP được phản hồi lớn hơn hoặc bằng 128
- 3 byte còn lại: số lượng bytes sẽ nhận từ những IP được phản hồi trong các gói tin tiếp theo
Nếu gói tin thỏa mãn điều kiện trong hàm FLARE05.flared_33(), hàm FLARE05.flared_32() lưu từng giá trị byte IP của những gói tin phản hồi tiếp theo vào FLARE14.ListData
Quay trở lại function FLARE14.flared_56(), ta thấy byte đầu tiên của ListData là taskType. Nếu taskType bằng FLARE06.TT.C = 0x2B thì luồng thực thi sẽ vào nhánh xử lý command, và cmd chính là phần dữ liệu còn lại của ListData được chuyển đổi sang string
Mỗi lần thực thi command, backdoor làm 3 nhiệm vụ sau:
- Nối chuỗi tham số command base64 vào “powershell -exec bypass -enc”
- Thêm dữ liệu vào IncrementalHash FLARE14.h
- Gọi function flare_56 -> flared_55 để xóa dữ liệu đầu tiên trong Collection FLARE15.c nếu cmd ^ 248 bằng nó
Mỗi khi Collection c có sự kiện xóa dữ liệu, function flare_53 sẽ được gọi. Function FLARE14.flare_55() được thực thi khi Collection c bị remove hết dữ liệu.
Function flare_55 gọi đến flared_54 thực hiện:
- Tìm kiếm section name là string bắt đầu của FLARE14.sh (đã được đảo ngược) và trả về dữ liệu section tìm thấy vào byte[] d
- Tính hash sha256 của FLARE14.h lưu vào byte[] hashAndReset
- Giải mã byte[] d bằng thuật toán rc4
- Ghi dữ liệu sau khi giải mã vào file trong thư mục tmp và thực thi nó
Ta có thể đoán được khả năng flag sẽ được giấu ở đây. Bây giờ ta cần fake dữ liệu phản hồi trong gói tin dns, để backdoor thực hiện từng case command và thứ tự command phải bằng giá trị đầu tiên của Collection FLARE14.c^248. Vì mỗi lần kiểm tra hay thực thi 1 case command, dữ liệu phản hồi chỉ cần tối đa 4 bytes (1 IP) nên ta chỉ cần gửi fake 2 gói kề nhau để thực thi 1 command
- Gói 1: IP phản hồi thỏa mãn byte đầu tiên >= 128, 3 bytes còn lại là số lượng bytes của tasktype(1 byte) + cmd(1 hoặc 2 bytes)
- Gói 2: IP phản hồi thỏa mãn byte đầu tiên = 0x2B = 43, 1 hoặc 2 bytes tiếp theo là cmd
Python script là lựa chọn tốt để làm việc này
Thực thi dns server và fake IP phản hồi
Sau khi fake dns server và thực thi file Backdoor.exe, backdoor mở tệp .gif chứa flagFlag: W3_4re_Kn0wn_f0r_b31ng_Dyn4m1c@flare-on.com
09_encryptor
Đề bài cho
- 1 file thực thi flare.exe
- 1 bị đã bị mã hóa SuspiciousFile.txt.Encrypted
Dựa vào file đề cho, ta nghĩ đến 1 trường hợp ransomware. Sử dụng yara rule, ta phát hiện loại mã hóa được sử dụng là Chacha256
Phân tích từ hàm main, ta thấy flare.exe đọc file có đuôi mở rộng “.EncrytMe”, sau đó mã hóa file đó và ghi vào file có định dạng “.Encrypted”
Hàm Init_Data() random 2 giá trị số nguyên tố 64 bytes p,q, ta liên tưởng đến thuật toán mã hóa RSA và dễ dàng nhận ra các hàm tính n, phi_n, d để dùng cho việc mã hóa key của thuật toán Chacha
Xref các địa chỉ n và d, ta thấy 2 giá trị này được dử dụng trong hàm Encrypt
Đúng như dự đoán, hàm Encrypt random 2 giá trị key 32 bytes và iv 12 bytes dùng cho thuật toán Chacha để mã hóa file input, sau đó chúng được mã hóa bằng thuật toán RSA. Tuy nhiên, ở đây tác giả dùng để d để mã hóa thay vì e, sau đó các giá trị n, cipher_key được ghi vào cuối file .Encryted
Như vậy, ta cần giải mã tìm key, iv của thuật toán Chacha và giải mã file SuspiciousFile.txt.Encrypted. Ta có thể viết python script để có được flag
Flag: R$A_$16n1n6_15_0pp0$17e_0f_3ncryp710n@flare-on.com
10_Nur_getraumt
Sử dụng Mini Vmac để giả lập môi trường MAC, ta cần bỏ ký tự unicode trong tên file để Mini vMac có thể đọc Disk Image
Sau khi đọc ổ đĩa chứa
- 1 file thực thi Nur getraumt
- 1 icon Desktop Folder
- Công cụ Super ResEdit
Chạy thử file thực thi, chương trình cho phép ta nhập 1 chuỗi ký tự và hiển thị Flag Value khi ta ấn try
Phân tích module main, ta thấy chương trình load resource FLAG với cấu trúc
- 1 byte đầu: kích thước của flag
- Data tiếp theo: flag đã mã hóa
- 2 bytes cuối: crc16 của flag
Hàm DecodeFlag thực hiện xor từng byte flag với từng byte password ta nhập vào
Ta biết 1 phần flag là “@flare-on.com”, tiến hành xor với flag đã mã hóa ta tìm được 1 phần key ” du etwas Zei”
Một phần key tìm được là tiếng Đức, ta tìm thông tin trên internet và thấy nó là 1 phần của lời bài hát “Hast Du Etwas Zeit Für Mich”
Thử lấy câu “Hast Du Etwas Zeit Für Mich” làm key giải mã, ta thu được string “Dann_singe_ich_ein_L”
Để ý thì “Dann_singe_ich_ein_L” chính là câu thứ 2 của bài hát và kích thước của câu hát đúng bằng kích thước flag 0x2d, submit và ta có thể làm bài 11.
Flag: Dann_singe_ich_ein_Lied_fur_dich@flare-on.com
11_the_challenge_that_shall_not_be_named
Đề bài cho 1 file thực thi 11.exe
11.exe được compile từ .py -> .exe, vì vậy ta có thể sử dụng pyinstxtractor kết hợp với uncompile6.exe để decompile .exe -> .py.
Sau khi decompile, ta được 1 file 11.py được bảo vệ bởi pyarmor.
Pyarmor được sử để làm rối python scripts, nó thực thi python objects lúc runtime. Thử dump memory và tìm kiếm 1 số string liên quan đến flag như “@flare-on.com”, ta có được flag.
Flag: Pyth0n_Prot3ction_tuRn3d_Up_t0_11@flare-on.com
By,
RE Team