Mỗi loại mã độc được viết để thực hiện các hành vi và trên các nền tảng khác nhau. Hacker luôn có các kỹ thuật khác nhau để làm khó, mất thời gian hơn trong quá trình phân tích và phản ứng của bên phân tích. Đối với mã độc Android được viết bằng Java, hacker thường có một số cách cụ thể để làm được việc này bao gồm:
• Nạp các file Dex bổ sung trong quá trình thực thi.
• Thêm code rác gây rối cho người phân tích.
• Làm rối tên các lớp, phương thức, tên biến, các chuỗi.
• Kết hợp làm rối tên các phương thức với việc gọi phương thức qua java reflection.
• …
Trong bài viết này mình xin chia sẻ một vài cách mình biết để giải mã các chuỗi đã bị mã hóa gây khó khăn trong quá trình dịch ngược đọc hiểu hành vi của mã độc.
Trước hết hãy thử xem qua một vài đoạn mã đã được mã hóa trông sẽ như thế nào?Nó sẽ trông như thế này:

Hoặc kiểu như này:

Để giải mã mớ bòng bong này mình có thể thực hiện theo hai cách mà mình biết.


Cách 1:

  1. Dùng APKTool bung file dex ra thành các mã file .smali
  2. Viết 1 đoạn python tìm kiếm các chuỗi cần giải mã, thường là các const-string. Ví dụ như:
    00000354  const-string  v8, "ZmJraA=="
  3. Viết hàm giải mã và lưu vào chỗ nào đó để tiện cho việc xem lại.

Cách này khá chuối nhưng khá hiệu quả và dễ thực hiện.

Cách 2:
Sử dụng công cụ Jeb Decomplier kết hợp viết Script để tự động. Để làm được việc này trước hết cần chuẩn bị môi trường để chạy script.

Tải Jython bản stand-alone và đặt vào thư mục script của Jeb tại đây:

http://www.jython.org/downloads.html


Để kiểm tra mọi thứ đã ổn, ta thử chạy một vài script sẵn có để xem chạy được chưa.
Thử chạy với JEB2UIDemo.py và xem kết quả ở Logger.
Focused view: None
Views and fragments:

  • Bytecode/Hierarchy
  • Hierarchy
  • Bytecode/Description
  • Description
  • Hex Dump
  • Disassembly
  • Strings
  • m/Source
  • Description
  • Source
  • Certificate/Certificate
  • Description
  • Hex Dump
  • Certificate

Focusing the second Unit view (if any)

Chạy được như vậy là bước đầu ta đã làm đúng.

Việc tiếp theo là viết script phục vụ mục đích giải mã chỗ String hồi nãy. Việc viết Script cho Jeb cũng khá khoai vì nó không phổ biến để bạn có thể tìm được trợ giúp từ các trang hỏi đáp cho dev mà bạn thường tìm trên google, tự mò doc của jeb và một số scripts có sẵn để xem như thế nào.
Đầu tiên hãy quan sát lại nơi xuất hiện của các chuỗi sau khi bị mã hóa.


m.f = a.a("LWhjeGNiY3FncS14bHJnY2hxXWhiMg==");

Trong Jeb API, mỗi một dòng lệnh trong phần body của một method là một Istatement, Istatement là một Interface được triển khai thành các lớp cụ thể bao gồm: ICompound, IJavaAssignment, IJavaBlock, IJavaBreak, IJavaCall, IJavaContinue, IJavaDefinition, IJavaDoWhile, IJavaFor, IJavaGoto, IJavaIf, IJavaLabel, IJavaMonitor, IJavaNew, IJavaNewArray, IJavaReturn, IJavaSwitch, IJavaThrow, IJavaTry, IJavaWhile.
Trong đó thường gặp là các IjavaAssignment một câu lệnh gán với 2 nhánh trái và phải, hai nhánh này có thể là các field, các IjavaCall. IjavaCall là các câu lệnh gọi (invoke trong mã smali) với đầy đủ thông tin như IJavaMethod, IjavaParam ...
m.f = a.a("LWhjeGNiY3FncS14bHJnY2hxXWhiMg==");
Vậy đối với trường hợp của lệnh này, việc ta cần làm là tách lấy param trong vế phải của câu lệnh chính là chuỗi bị mã hóa. Giải mã chuỗi này và gán lại cho vế phải.

a.a("d3JwcQ==")

Đối với các câu lệnh gọi với tham số là kết quả trả về của hàm a.a ta cần tách lấy tham số, giải mã và gán lại cho tham số này giá trị sau khi đã giải mã.
Bạn đọc có thể tham khảo đoạn mã sau:

https://github.com/tantinhte/JebScriptDeObfuscateString

Trong bài viết sau, mình sẽ phân tích một mẫu cụ thể sử dụng jeb và script để giảm thời gian trong một số thao tác, hỗ trợ việc phân tích mã độc.

Thông tin mẫu sử dụng trong bài viết:

file: android.apk
MD5:d1fc502d1d5ef850666261e123f066a7
SHA-1: 04fbeebd67ade3d38ed72f244723e2a715fc71c0
SHA-256: 69ebddfb651c3d57411c40fe08f8045a98e6f00e9c665f95fab31c08647a1027