1. Thu thập thông tin

Target nhận được là một file exe: exe

Kiểm tra thông tin sơ bộ:

  • Định dạng file là: PE32
  • Được code bằng Visual C: Microsoft Visual C/C++(2013)[-]
  • Tìm kiếm thông tin về string, thấy có một số string thú vị sau:

  • Tìm kiếm thông tin liên quan tới Crypto: thấy có các thông tin liên quan tới Base64; Rijndael
  • Mở file bằng một trình Hex Editor bất kỳ, tìm kiếm và thấy có dấu hiệu của một PE file khác. Khả năng exe khi chạy sẽ drop ra PE file này. Thông tin về PE file được tìm thấy nằm tại offset như trong hình dưới:

  • Quan sát thông tin sơ bộ PE file trên, nhận thấy đây là một file dạng dll, có tên là: dll. File dll này có thể được code bằng .NET và code của nó có gọi gì đó liên quan tới PowerShell:

  • Chạy thử file exe, nhận được giao diện của Escape Room:

  • Tìm hiểu thông qua help thì biết được đây là một mini game, người chơi phải đi theo ý đồ của tác giả, sau đó tiến hành các hành động như nhặt đồ, mặc đồ, bỏ đồ đã nhặt, nói chuyện với ai đó …

2. Extract embedded flareon.dll

Sử dụng công cụ của bên thứ ba để kiểm tra lại, có được thông tin về file PE file được nhúng là một DLL và kích thước của file này:

Thực hiện trích xuất toàn bộ file DLL từ file zsud.exe và lưu lại với tên là flareon.dll:

Kiểm tra file flareon.dll, biết được file này được code bằng .NET (đúng như thông tin đã phán đoán ở trên): .NET(v4.0.30319)[-]. Sử dụng công cụ dnSpy để decompile, có được toàn bộ class four cùng với 2 method là SmthDecrypt2 như sau:

Nghiên cứu toàn bộ code trên:

  • Smth(string arg): method này nhận tham số truyền vào là một chuỗi có dạng Base64String, chuỗi này được chuyển đổi và lưu vào một mảng byte[] là cipherText. Sau đó sẽ gọi method Decrypt2 để tiến hành giải mã cipherText thu được.
  • Decrypt2(byte[] cipherText, string key): thực hiện giải mã toàn bộ cipherText với key giải mã là “soooooo_sorry_zis_is_not_ze_flag”.
  • Kết quả sau khi giải mã sẽ là một PowerShell script được lưu vào biến script. Sau đó, thực hiện script này thông qua Invoke().

Như vậy, để có được PowerShell script, phải tìm được chuỗi Base64 đầu vào để giải mã là gì.

3. Tìm chuỗi Base64 và lấy PowerShell script

Kết hợp với quá trình phân tích tĩnh bằng IDA và debug thông qua OllyDbg, tìm được nơi khởi tạo ra chuỗi Base64 có độ dài 0x0000E12D (57645) tại sub_4023D0().

Lấy toàn bộ nội dung của chuỗi Base64 này, sau đó viết lại một chương trình nhỏ thực hiện thao tác như code của file flareon.dll để giải mã toàn bộ chuỗi Base64. Kết quả thu được chính là PowerShell script cần tìm. PowerShell này chứa toàn bộ mã nguồn của mini game Escape Room:

Chạy thử ps script, giao diện của game xuất hiện tương tự như lúc thực thi file zsud.exe:

4. Tìm hiểu code của PowerShell

Sau một vài ngày đọc code và debug PowerShell script, tìm được một số thông tin rất quan trọng như sau:

  • File này có sử dụng tới các hàm srand()rand() nằm trong lib dll:

  • Khi vào chơi game, sẽ đứng tại vị trí $map.StartingRoom = $vestibule. Thông tin tại vị trí này là “You are in the vestibule. Try looking around.”.
  • Từ vị trí $vestibule, nếu đi ‘s’ thì chắc chắn sẽ bị ‘locked out’. Vì đây chính là đường một chiều:

  • Từ ví trí $vestibule chỉ có một bước đi duy nhất (‘n’) là tới được $lobby:

  • Tại $lobby sẽ thấy có “reception desk”. Quan sát bàn của lễ tân sẽ thấy có “a sign-in sheet and laptop on top and a few drawers on the sides”. Đọc code của script thì thấy tại drawers sẽ có một cái “key”.

  • key” được định nghĩa là một chuỗi như sau:

  • Khi nhặt “key” tại drawer, sẽ gọi tới hàm Invoke-TransferThing([PSObject][ref]$container_old,[PSObject][ref]$container_new, $thing). Đoạn code này sẽ kiểm tra nếu như đã nhặt được key thì sẽ gọi hàm srand(42) dùng để khởi tạo một số ngẫu nhiên theo số seed là 42. Hàm srand() thường sẽ được gọi trước khi gọi hàm rand().

  • Sau khi lấy được key thì mỗi bước đi tiếp theo trong mê cung đều gọi tới hàm Invoke-MoveDirection($char, $room, $direction, $trailing). Tại hàm này sẽ gọi hàm rand() % 6 để sinh số ngẫu nhiên nằm trong khoảng từ 0 – 5. Hàm này như sau:

  • Biến $dir_short lúc này sẽ chứa thông tin về hướng di chuyển của người chơi, ${N} lúc này sẽ chứa số ngẫu nhiên được tạo bởi hàm rand()%6. Lệnh $directions_enum[$dir_short] -eq ($n) sẽ kiểm tra xem giá trị của bước dịch chuyển mà người dùng nhập vào có trùng khớp với số ngẫu nhiên được tạo ra bởi hàm rand() không? Nếu trùng thì sẽ thực hiện gọi tới hàm Invoke-XformKey([String]$keytext, [String]$desc) để biến đổi nội dung của “key” đã nhặt được ban đầu.
  • Code thực hiện biến đổi key tại hàm Invoke-XformKey([String]$keytext, [String]$desc) như sau:

  • Kiểm tra thông tin về $directions_enum , thu được một thông tin rất giá trị như sau:

  • Dựa vào thông tin trên, có thể thấy ứng với một bước di chuyển trong mê cung, thì sẽ sử dụng $directions_enum để mapping kí tự nhập vào tương ứng với số mấy. Ví dụ: nếu nhập vào là “w” thì sẽ tương ứng với số “3”, nhập “e” tương ứng với số “2” …
  • Như vậy, từ đây nhận thấy có một điều hơi vô lý, nếu như sử dụng hàm rand()%6 để sinh số ngẫu nhiên trong khoảng từ 0 – 5 thì việc nhập kí tự để di chuyển trong mê cung sẽ rất khó cho kết quả so sánh bằng như đã đề cập ở lệnh if bên trên. May mắn lắm thì mới trùng thôi J, và tôi cũng có được vài lần vô tình nhập trùng với số do rand tạo ra, lolz.
  • Do khi run file exe thì mới bung PowerShell để chạy game, và khi PowerShell gọi tới srand(42)rand()%6 thì khả năng các hàm này có thể đã bị can thiệp bởi file binary rồi.

Câu hỏi đặt ra, làm thế nào để biết vị trí mà binary can thiệp tới các hàm srand()rand()?

5. Sử dung FLOSS để deobfuscate strings

Trong quá trình nghiên cứu binary, tôi không tìm thấy thông tin về thư viện msvcrt.dll cũng như các hàm như srand()rand(). Khả năng thông tin về chúng đã bị encrypted/obfuscated trong binary.

Lúc này, chợt nhớ FLARE team có một công cụ là FLOSS (FireEye Labs Obfuscated String Solver) chuyên dùng để deobfuscate strings. Chạy thử công cụ này với file zsud.exe, có được kết quả như sau:

Theo kết quả có được thì FLOSS đã decoded được các string liên quan tới msvcrt.dll và srand. Sử dụng tùy chọn –i của FLOSS tạo ra một IDAPython script để chú thích string đã được giải mã vào file IDB của IDA.

Kết quả sau khi chạy script trong IDA:

6. Xác định bảng index các bước đi trong mê cung

Theo thông tin mà FLOSS cung cấp, sẽ tới được đoạn code giải mã các chuỗi msvcrt.dll và srand:

Tổng kết lại, sub_406530() thực hiện nhiệm vụ sau:

  • Gọi hàm decode_string để giải mã ra các chuỗi dll và srand.
  • Lấy handle của dll thông qua API LoadLibraryA.
  • Lấy địa chỉ của các hàm rand và srand trong thư viện dll thông qua API GetProcAddress.
  • Thực hiện hook hai hàm rand và srand.

Sau khi thực hiện toàn bộ code trên, hàm rand() gốc bị thay đổi, nhảy tới jmp

Lệnh cũ của hàm rand() được lưu lại tại địa chỉ:

Hàm srand() gốc cũng bị thay đổi, nhảy tới jmp   zsud.004010B9 <– srand_mod()

Lệnh cũ của hàm srand() được lưu lại tại địa chỉ:

Nhớ lại phần phân tích code của PowerShell, sau khi game thực thi hoàn toàn, người chơi nhặt được key thì sẽ gọi srand(42). Lúc này, hàm srand đã bị hooked để nhảy tới địa chỉ 0x004010B9. Từ 0x004010B9 sẽ tới sub_407140:

Code tại sub_407140 sẽ thực hiện việc gán dword_45BD28 giá trị bằng 1. Như đã mô tả, khi nhận được key, thì bất kỳ bước đi tiếp theo trong mê cung đều sẽ gọi tới hàm rand() % 6 để tạo số ngẫu nhiên trong khoảng 0 – 5 và so sánh với giá trị số được mapping tương ứng với bước dịch chuyển. Nếu bằng nhau thì sẽ gọi hàm Invoke-XformKey để biến đổi key. Hàm rand lúc này đã bị hooked để nhảy tới địa chỉ 0x00401019. Từ địa chỉ 0x00401019 sẽ tới sub_4070F0:

Code tại sub_4070F0 sẽ thực hiện việc lấy giá trị tại index_table tại địa chỉ 0x459CB8. Bảng này chứa các index như sau:

Dựa vào bảng trên, có thể thấy sau khi nhặt được key thì các bước di chuyển tiếp theo trong mê cung phải tuân theo bảng này. Kết hợp bảng này và bảng mapping có được ở trên, sẽ suy ra được các bước đi tương ứng.

Sau khi đi tới được phòng của Kevin thực hiện các thao tác sau để lấy key:

Với chuỗi hexa mà Kevin cung cấp, ta có được flag để submit là: mudd1ng_by_y0ur53lph@flare-on.com

“You are in the maze. The maze you are in…

In the maze, you saw the maze …

See some thing, you get some thing

Go around, North, South, East, West, Up, Down..

 

Long long long … Nightmare..so long

Shell shell shell … the Ghost in the shell

Wear some thing, You drop some thing…

Say to Kevin, Kevin: “Hello mate!! Long time no see .. you look tired, lolz!!”

Here is something, you become the king!!!…..”

No Comments
Post a Comment