Thứ Sáu, 19 tháng 7, 2013

Data Encoding [1]

Khi phân tích malware, chúng ta thường gặp thuật ngữ data encoding, data encoding liên quan đến tất cả các hình thức thay đổi nội dung nhằm ẩn đi ý đồ ban đầu. Malware sử dụng các kĩ thuật encoding tạo ra một lớp mặt lạ cho các hành động nguy hiểm của nó, và chúng ta trong vai trò của malware analyst, chúng ta cần hiểu các kĩ thuật encoding này để hiểu hơn về malware.

Khi sử dụng data encoding, attackers sẽ chọn phương thức mà họ cảm thấy thích hợp với mục tiêu của họ nhất. Thình thoảng, họ chọn ciphers (thuật toán mã hóa) đơn giản mà dễ dàng để code và cung cấp đầu đủ tính bảo vệ ; những lúc khác, họ sử dụng ciphers phức tạp khiến cho việc nhận dạng và reverse-engineering trở nên khó khăn hơn.

Mục tiêu của việc phân tích Encoding Algorithms

Malware sử dụng encoding cho nhiều mục đích khác nhau. Ứng dụng phổ biến nhất dành cho việc mã hóa (encryption) các giao tiếp mạng. Malware còn sử dụng encoding để nguy trang cho việc hoạt động bên trong của nó. Ví dụ, một malware author có thể sử dụng encoding cho các mục đích sau:

  • Để ẩn các thông tin về cấu hình (configuration information), ví dụ như command-and-control domain
  • Để lưu thông tin đến một file tạm trước khi lấy cắp nó. 
  • Để lưu strings được sử dụng bởi malware và decode chúng trước khi cần xài
  • Để ngụy tạo malware như là một công cụ hợp lệ, ẩn đi strings được sử dụng bởi các hành động nguy hại. 
Mục đích của chúng ta khi phân tích encoding algorithms luôn luôn có hai thứ cần phải đạt được sau đây: Nhận dạng encoding functions và sau đó vận dụng kiến thức để decode nhưng bí mật của attacker.

Simple Ciphers

Các kĩ thuật encoding đơn giản đã tồn tại hàng nghìn năm. Trong khi bạn có thể cho rằng với khả năng tính toán tốc độ cao của các máy tính hiện đại đã khiến simple ciphers tuyệt chủng, nhưng không phải vậy. Các kĩ thuật encoding đơn giản thường được vận dụng để ngụy trang nội dung làm cho nó xuất hiện trước mắt người dùng dưới dạng không thể đọc được hay là chuyển dữ liệu vào trong một tập hợp kí tự khác. 

Simple ciphers thường bị xem thường vì tính không phức tạp của nó, dẫu vậy chúng mang lại nhiều lợi thế cho malware, bao gồm những điều sau:
  • Chúng đủ nhỏ khi được sử dụng trong các môi trường hạn chế ví dụ như exploit shellcode. 
  • Chúng kém rõ ràng hơn nhiều complex ciphers.
  • Chúng có chi phí thấp và do đó ảnh hưởng rất ít đến performace. 
Malware authors sử dụng một simple cipher không mong đợi được cipher họ dùng miễn dịch được trước sự phát hiện ; họ chỉ đơn giản là đang tìm kiếm một cách dễ dàng để ngăn basic analysis nhận dạng các hành vi của mình. 

Caesar Cipher

Một trong ciphers đầu tiên được sủ dụng đó là Caesar cipher. Ceasar cipher đã được sử dụng liên tục khi Roman Empire ẩn messages được chuyển đi qua chiến trường bởi những người giao liên. Nó là một hình thức cipher đơn giản, dễ dàng thực hiện bằng cách dịch chuyển (shifting), trong đó mỗi ký tự trong văn bản bằng một ký tự cách nó một đoạn trong bảng chữ cái để tạo thành bảng mã. 
Chi tiết về cách mã hóa cũng như giải mã xem thêm tại: http://vi.wikipedia.org/wiki/M%E1%BA%ADt_m%C3%A3_Caesar

XOR

XOR cipher là một simple cipher tương tự như Ceasar cipher. XOR có nghĩa là exclusive OR và là một phép logic có thể được sủ dụng để modify bits. 

Một XOR cipher sử dụng một static byte value và modify mỗi byte của plaintext thông qua việc thực hiện phép tính logic XOR với giá trị đó. Cho ví dụ, Figure 14-1 shows cách message ATTACK AT NOON có thể được encoded sử dụng XOR với byte 0x3C. Mỗi kí tự được biểu diễn bởi một cell, với ASCII character (hay là control code), và hex value của kí tự nằm ở phía dưới cùng. 

Như bạn có thể thấy trong ví dụ này, XOR cipher thường trả kết quả theo bytes mà không bị giới hạn bởi các kí tự có thể in ra được (những ô được tô xậm trong hình vẽ). C trong ATTACK được chuyển sang dạng hex là 0x7F, mã hex này ám chỉ delete character. Cũng tương tự như vậy, space character được dịch thành 0x1C là mã cho file separator. 

XOR cipher dễ sử dụng bởi vì nó đơn giản - chỉ yêu cầu một lệnh máy và reversible.

Một reversible cipher sử dụng cùng một function để encode và decode. Để decode những thứ encoded với XOR cipher, bạn có thể lặp lại XOR function với key giống như trong quá trình encoding. 

Quá trình implementation XOR encoding như chúng ta đang thảo luận - nơi mà key là giống nhau trong mọi encoded byte - còn được gọi với cái tên single-byte XOR encoding.

Brute-Forcing XOR Encoding

Nào hãy tưởng tượng chúng ta đang điều tra một sự cố liên quan đến malware. Chúng ta biết được rằng vài giây trước khi malware starts, 2 files được tạo trong thư mục cache của browser. Một trong các file đó là SWF file, đó là file chúng ta nghi vấn nó được sử dụng exploit browser's Flash plug-in. Một file khác có tên là a.gif , nhưng nó không có GIF header, những gì bắt đầu với các kí tự GIF87a hoặc GIF89a. Thay vào đó, file a.gif bắt đầu với các bytes như trong Example 14-1

Ok. Chúng ta nghi ngờ file này là một XOR-encoded executable, nhưng làm thế nào chúng ta có thể tìm ra ? Một chiến lược khi làm việc với single-byte encoding đó là brute force. 

Bởi vì chỉ có 256 giá trị có thể cho mỗi kí tự trong file, thật dễ dàng và nhanh gọn để cho máy tính thử tất cả 255 single-byte keys có thể được XORED với file header, và so sanh output bạn mong đợi cho excutable file. XOR encoding sử dụng từng key trong 255 keys có thể được thực hiện bởi một script, và Table 14-1 shows output của những script như vậy 

Brute-Forcing Many Files

Brute-forcing có thể được sử dụng một cách chủ động. Ví dụ, nếu bạn muốn search nhiều files để kiểm tra cho XOR-encoded PE files, bạn có thể tạo 255 signatures cho tất cả các sự kết hợp XOR, tập trung vào các phần tử của file mà bạn nghĩ có thể biểu diễn được. 

Cho ví dụ, chúng ta muốn search cho single-byte XOR encodings của string This program. Nó là phổ biến đối với PE file header để chứa một string như là This program must be run under Win32, hay là This program cannot be run in DOS. Qua việc sinh ra tất cả các hoán vị của string ban đầu với mỗi giá trị XOR có thể, chúng ta có thể đưa ra một tập các signatures để search, như bạn có thể thấy trong Table 14-2


NULL-Preserving Single-Byte XOR Encoding

Nào hãy nhìn lại encoded file trong Example 14-1. Chú ý vào sự xuất hiện một cách "náo loạn" của XOR key 0x12, chỉ nhìn qua chúng ta cũng có thể nhận ra điều này. Hầu hết các bytes trong phần mở đầu của header là 0x12! Nó demo một điểm yếu của single-byte encoding: Nó thiếu đi một cách hiệu quả để ẩn đi khởi user nếu user thực hiện scanning thủ công encoded content với hex editor. Nếu encoded content có một số lượng lớn NULL bytes, single-byte "key" trở nên càng rõ ràng. 

Malware authors đã phát triển một cách thông minh hơn để giảm thiểu vấn đề này bằng việc sử dụng NULL-preserving single-byte XOR scheme. Không giống như XOR encoding scheme thông thường, NULL-preversing single-byte XOR scheme có 2 ngoại lệ:
  • Nếu plaintext character là NULL hoặc là key chính nó, khi đó byte được bỏ qua.
  • Nếu plaintext character không là NULL cũng chẳng phải key, khi đó nó được encoded qua XOR với key. 
Như Table 14-3, code cho modified XOR không phức tạp hơn là mấy so với XOR ban đầu 


Trong Table 14-3, C code dành cho XOR function ban đầu nằm phía bên trái, và NULL-preserving XOR function nằm phía bên tay phải. Vì vậy nếu key là 0x12, khi đó bất cứ 0x00 hoặc 0x12 sẽ không được chuyển đổi, nhưng bất cứ byte nào khác 2 byte này sẽ được chuyển đổi thông qua việc XOR với 0x12. Khi một PE file được encoded theo kiểu này, key với những gì nó encoded sẽ không dễ để ta thể có một cái nhìn trực quan về nó. 

Nào hãy cùng nhau so sánh Example 14-1 (với 0x12 key) với Example 14-3. Example 14-3 biểu diễn cùng encoded PE file,  cũng là encoded với 0x12, nhưng lúc này NULL-preversing encoding, việc làm này gây ra khó khăn trong việc nhận diện XOR encoding và không có bằng chứng nào về sự hiện diện của key ở đây cả. 

 
Kĩ thuật  NULL-preversing XOR còn đặc biệt phổ biến trong shellcode, nơi điều quan trọng là có thể thực hiện encoding với một lượng rất nhỏ code. 

Nhận dạng XOR Loops trong IDA Pro

Nào bây giờ hãy tưởng tượng bạn tìm thấy shellcode bên trong SWF file. Bạn đang disassembling shellcode trong IDA Pro, và bạn muốn tìm XOR loop mà nghi ngờ rằng nó tồn tại để decode file a.gif liên kết với nó. 

Trong disassembly, XOR loops có thể bị nhận dạng bởi một số lượng nhỏ loops với một lệnh XOR nằm giữa của một loop. Cách dễ dàng nhất để tìm ra một XOR loop trong IDA Pro là search tất cả instances của XOR instruction, làm như sau:

1. Đảm bảo rằng bạn đang nhìn vào code (window title nên chứa "IDA View").
2. Chọn Search -> Text
3. Trong Text Search dialog, enter xor, chọn Find all occurences checkbox, và sau đó click OK. Bạn nhìn thấy một cửa sổ giống như trong Figure 14-2

                                                Figure 14-2

Việc search một XOR instruction không có nghĩa là XOR instruction được sử dụng cho encoding. XOR instruction có thể được sử dụng với nhiều mục đích khác nhau. Một trong số đó là sử dụng XOR để clear các nội dung của một thanh ghi. XOR instructions có thể được tìm thấy dưới 3 hình thức :
  • XOR một thanh ghi với chính thanh ghi đó.
  • XOR của một thanh ghi (hoặc memory reference) với một constant
  • XOR giữa một thanh ghi (hoặc memory reference) với một thanh ghi khác (hoặc memory reference)
Nó xuất hiện phổ biến trong dạng đầu tiên, bởi vì XOR của một thanh ghi với chính nó là một cách hiệu quả để làm cho giá trị thanh ghi trở về 0. May mắn thay, việc clearing một thanh ghi không có liên quan gì đến data encoding, vì vậy chúng ta có thể lờ nó đi. Như bạn có thể nhìn thấy trong Figure 14-2, hầu hết các instructions được liệt kê là lệnh XOR của một thanh ghi với chính nó (ví dụ như xor edx, edx).

Một XOR encoding loop có thể được sử dụng hoặc trong hai forms sau: một XOR của một thanh ghi  với một constant hoặc là một XOR của một thanh ghi với một thanh ghi khác. Nếu bạn gặp may, XOR sẽ xuất hiện cùng với một thanh ghi và một constant, bởi vì điều đó công nhận rằng bạn có thể đang chứng kiến encoding, và bạn sẽ biết được key. Lệnh xor edx, 12h trong Figure 14-2 là một ví dụ của dạng thứ hai của XOR. 

Một trong các dấu hiệu của encoding là một small loop chứa XOR function. Hãy nhìn vào lệnh chúng ta nhận diện được trong Figure 14-2. Như ta thấy trong IDA Pro flowchart trong Figure 14-3 chỉ ra, lện XOR với 0x12 xuất hiện như là một phần của một small loop. Bạn có thể nhìn thấy một block tại loc_4012F4 tăng một biến đếm, và block tại loc_401301 kiểm tra xem biến đếm này có vượt quá một độ dài cho trước không. 



1 nhận xét: