Trong các bài trước tôi đã trình bày với các bạn về một số kỹ thuật liên quan đến virus, mã độc

  1. Một số đặc tính và phương pháp phòng tránh mã độc
  2. Kiểm tra, theo dõi, phát hiện mã độc

Hôm nay tôi sẽ tiếp tục với bài viết về phân tích và diệt mã độc.

Phân tích mã độc như thế nào?

Việc phát hiện, phân tích mã độc đòi hỏi quá trình theo dõi liên tục và lặp đi lặp lại. Nếu thực hiện trên hệ thống thiết bị thật sẽ mất rất nhiều công sức và không thể kiểm soát một cách chặt chẽ và rất khó khăn để thực hiện một cách liền mạch. Vì trong quá trình phát hiện và phân tích, các chương trình mã độc có thể làm chết toàn bộ hệ thống, cô lập debugger và disasembler, trong trường hợp đó muốn tiếp tục phân tích cần khôi phục lại toàn bộ hệ thống. Đối với hệ thống thật, quá trình đó mất rất nhiều thời gian. Do đó, để phát hiện, phân tích và diệt mã độc, máy ảo là một môi trường rất lý tưởng, mặc dù trong một số trường hợp, các mã độc có thể phát hiện ra máy ảo và dừng chạy chương trình, tuy nhiên trường hợp này hoàn toàn có thể khắc phục được bằng một số thay đổi trong mã nhị phân của mã độc. Như vậy, cần thiết lập một cấu hình máy ảo với đầy đủ các bộ công cụ cần thiết phục vụ cho quá trình theo dõi, phát hiện, phân tích và diệt. Qua quá trình làm việc chúng tôi nhận thấy hiện nay đa phần các mẫu virus vẫn sử dụng  32 bit trên nền windows, do đó, một môi trường lý tưởng sử dụng cho trường hợp này là cài đặt một máy ảo sử dụng hệ điều hành Windows XP 32 bit, trên máy tính này, chúng ta cài đặt các bộ công cụ sau:

  • Nhóm các công cụ phục vụ mục đích theo dõi, giám sát: TCPView, AutoRun, ProcessMon, WireShark, ProcessExplorer
  • Nhóm các công cụ phục vụ phân tích: IDA Pro, OllyDBG, LordPE, Hex Editor Neo, 010 Editor, Notepad++
  • Nhóm các công cụ môi trường: trình duyệt (Chrome, Firefox), bộ công cụ microsoft word, outlook, …
  • Danh sách một số file, chương trình mồi: notepad.exe, calc.exe, cmd.exe, một số file cài đặt của notepad++, python, hex editor, …

Sau khi cài đặt đầy đủ các bộ công cụ trên, chúng ta tạo một bản snapshot cho cấu hình này để phục vụ cho các lần theo dõi, kiểm tra, phát hiện và phân tích mã độc.

Phân tích mã độc để xác định cách thức và hành vi

“Đối với các mẫu không phải virus (trojan, adware, worm, …) hoặc các mẫu không cần phân tích mà chỉ cần theo dõi hành vi tác động lên hệ thống thì chỉ cần dừng lại ở bước phân tích qua các công cụ giám sát

Đối với các mẫu virus (có hành vi lây file) hoặc các mẫu khác cần phân tích để lấy các đoạn mã cụ thể, cần thực hiện Giai đoạn phân tích để lấy các thông tin chi tiết hơn”

Sau giai đoạn theo dõi và phát hiện mã độc, chúng ta đã có các thông tin cơ bản liên quan tới mẫu cần phân tích: Các tài nguyên mẫu  tác động tới: các file, thư mục, key trên thanh ghi, cách thức hoạt động cơ bản (Hình thức, cách thức và trình tự lây lan, phá hoại). Nhiệm vụ của việc phân tích nhằm: Tìm ra triệt để các hành vi phá hoại, phân tích để diệt mẫu toàn diện nhất.

  • Phân tích cách thức lây file để diệt:
    • Dùng chương trình mồi: Sử dụng ProcessMon, chúng ta theo dõi được thư mục nào là thư mục đầu tiên mà mẫu cần phân tích, đưa các chương trình mồi vào và theo dõi sự thay đổi của chương trình mồi. Nếu chương trình mồi bị thay đổi, ta chuyển sang bước tiếp theo, nếu không, ta thay thế bằng các chương trình mồi khác và tiếp tục thử khi chọn được chương trình mồi hợp lý.
    • Tìm các API quan tâm: Snapshot lại máy ảo về trạng thái ban đầu khi chưa chạy mẫu cần theo dõi, đưa chương trình mồi chưa bị lây nhiễm vào thư mục tìm được ở bên trên. Mục đích: tìm ra đoạn mã thực hiện lây file nhanh nhất có thể. Tiến hành chạy mẫu cần phân tích bằng OllyDBG (sử dụng F8 để chạy từng câu lệnh). Chú ý theo dõi quá trình load các thư viện từ hệ thống. Khi các thư viện chứa các API cho việc thao tác tới file: FindFistFile, FindNextFile, CreateFile, CreateFileMapping, WriteFile, … thì dừng lại, tìm các đoạn mã có gọi các API:  FindFistFile, FindNextFile, CreateFile, OpenFile, WriteFile và đặt break point tại các đoạn mã này. Sau đó sử dụng câu lệnh F9 để di chuyển tới vị trí đặt break point. Nếu phát hiện ra file đang được thao tác chính là chương trình mồi thì đoạn mã tương ứng tìm được chính là đoạn mã bắt đầu thực hiện quá trình lây file.
    • Xác định đoạn mã kiểm tra lây nhiễm: Đoạn mã giữa hai API: FindFirstFile (Tìm file đầu tiên), CreateFile(mở file để đọc) là đoạn mã có thực hiện việc kiểm tra một số điều kiện ban đầu cho file bị lây nhiễm, cần debug và kiểm tra đoạn này để phục vụ cho quá trình diệt mẫu.
    • Xác định đoạn mã lây file: Đoạn mã giữa hai API: CreateFile, CreateFileMapping (mở file để đọc) và WriteFile (lệnh cuối cùng ghi nội dung lên file vì nhiều mã virus thực hiện ghi file nhiều lần) là đoạn mã thực hiện tính toán và sửa file. Để có thể tiến hành diệt mẫu và tiến hành chỉnh sửa file này về trạng thái như file gốc ban đầu, cần phân tích kỹ đoạn mã trên để xem cách mà mẫu thực hiện tính toán và chỉnh sửa file gốc. Vì đây là đoạn mã Asembly nên muốn nhanh chóng thực hiện việc phân tích đoạn mã này có một số thủ thuật sau:
      • Kiến thức về các lệnh, cấu trúc lệnh, cách thực hiện lệnh, gọi hàm trong Asembly
      • Thông tin về kiến trúc file PE, các thành phần, vị trí các thành phần của file PE. (Tôi sẽ viết bài về cấu trúc của PE file)
      • Theo dõi hàm CreateFileMapping, vì hàm này sẽ load file gốc lên 1 vùng nhớ mới, sau đó có thể thực hiện chỉnh sửa trên vùng nhớ này hoặc tiếp tục copy ra các vùng nhớ khác rồi chỉnh sửa.
  • Phân tích các hành vi
    • Dựa vào các hành vi cần theo dõi từ giai đoạn kiểm tra, theo dõi và phát hiện chúng ta sẽ lựa chọn các API tương ứng
      • Tương tác tới registry, có các API: RegCloseKey, RegOpenKeyEx, RegQueryInfoKey, RegQueryValueEx…
      • Tương tác tới các trình duyệt để lấy Cookie: các API tương tác tới file, đồng thời quan sát thư mục liên quan tới browser
      • Mở cổng hậu, tạo các socket kết nối: WSAStartup, WSASocket, WSAConnect, WSAAccept, WSASend, WSARecv…
    • Từ các hành vi này, ta tiến hành đặt các break point tại các API quan tâm và tìm được vị trí các đoạn mã mong muốn

Phân tích để diệt mã độc“Giai đoạn này chỉ áp dụng cho các mẫu có hành vi lây file (tức là các virus), đối với các mẫu khác không thực hiện lây file chúng ta chỉ cần giai đoạn  sau đó thực hiện xoá trực tiếp.” Quá trình phân tích chúng ta đã làm rõ được cơ chế lây file của mẫu: các loại file bị lây (để diệt toàn bộ file, tránh bỏ sót file), cách thức lây file cụ thể (chỉnh sửa trường nào trong file, ghi thêm nội dung vào vị trí nào trong file, lấy lại địa chỉ Entry Point gốc (Original Entry Point – OEP), … ). Ở giai đoạn này, chúng ta chỉ cần làm ngược lại các bước mà mẫu đã làm với từng file cụ thể: xác định lại OEP, chỉnh sửa lại các trường trong PE Header, xoá bỏ các phần dữ liệu bị mẫu ghi thêm vào file gốc. Lấy lại OEP là một bước quan trọng, có thể thực hiện theo cách như sau:

  • Tìm giá trị OEP được virus ghi lại file gốc. Cách này dễ nhưng ít gặp vì hầu hết các virus đều có thiết lập các thay đổi và tính toán lại OEP thay vì lưu nguyên OEP vào file cũ.
  • Dựa vào OEP của file bị lây để dự đoán và tìm OEP. Cách thức ở đây là ta sẽ tìm vị trí nhảy về OEP của chương trình đã bị lây. Từ đây ta sẽ tìm được vị trí tương đối của nó so với đầu file tức là khi file gốc chuẩn bị được lây được load trên bộ nhớ cùng với virus, ta sẽ biết được địa chỉ của lệnh trỏ về OEP. Tiến hành đặt breakpoint tại địa chỉ này và theo dõi sự thay đổi giá trị trên vùng địa chỉ đó, như vậy ta sẽ lần ra được vị trí tính toán và ghi địa chỉ trả về OEP

Để diệt tận gốc (toàn bộ các file bị lây nhiễm) cần có công cụ tự động dò tìm, phát hiện các file các file đã bị lây nhiễm dựa vào các đặc điểm nhận dạng được xác định ở giai đoạn phân tích.

Lưu ý

  • Đối với các loại mẫu lây file hệ thống đòi hỏi có các kỹ thuật phân tích và xử lý riêng.
  • Đối với các mẫu đa hình và siêu đa hình, tức là mã nhận diện tự động thay đổi sau mỗi lần lây nhiễm, quá trình phát hiện sẽ phức tạp hơn vì không thể sử dụng các mẫu nhận diện cố định. Để có thể phát hiện các loại mẫu này, cần sử dụng một cơ chế mới: Máy trạng thái. Nguyên nhân, với các mẫu đa hình, siêu đa hình, giai đoạn đầu tiên khi chạy nó cần có đoạn code giải mã để giải mã đoạn code mã hoá thân virus sau đó mới trả về điều khiển cho chương trình. Toàn bộ các mã sau đoạn giải mã được gọi là trạng thái ổn định của virus, đoạn code giải mã chính là đoạn đa hình. Để phát hiện được virus đa hình, siêu đa hình cần thực thi và kiểm tra các mẫu trong máy trạng thái, nếu sau một thời gian hoặc một số lượng câu lệnh nhất định mà đạt tới được trạng thái ổn định thì tức là mẫu đó chính là một mẫu đa hình, siêu đa hình.
  • Quá trình diệt sẽ phải dựa vào trình tự phân tích mẫu bằng tay.

Ngoài ra, để tránh quá trình bị phân tích, dịch ngược, virus còn trang bị thêm cho nó một số kỹ thuật để che giấu bản thân: kỹ thuật pack và anti debug, anti máy ảo. Cần nắm được các kỹ thuật này để có thể vượt qua trong quá trình phân tích lấy hành vi và phân tích để diệt:

  • Kỹ thuật mã hóa (Pack): Pack là kỹ thuật mã hóa để làm giảm kích thước file, che giấu mã thật của virus. Với việc sử dụng pack, virus sẽ phải mã hóa và lưu toàn bộ header và nội dung file lại, đồng thời cung cấp hàm giải mã để giải mã thông tin lên bộ nhớ và khôi phục trạng thái các thanh ghi cũng như OEP. Điểm mấu chốt của sử dụng pack đó là khi bắt đầu chương trình, virus sẽ phải thực hiện unpack, lúc này trạng thái các thanh ghi sẽ được bảo vệ bằng cách đẩy toàn bộ vào stack (PUSHAD). Quá trình giải mã thành công, trạng thái các thanh ghi sẽ được khôi phục trở lại (POPAD), sau đó sẽ có lệnh chuyển điều khiển về OEP. Như vậy Unpack chính là việc tìm được chương trình ở trạng thái giải mã thành công.
  • Kỹ thuật Anti: Anti anti debugger & VM: một số virus sử dụng các kỹ thuật anti debugger & VM  để tránh bị phân tích, dịch ngược. Nguyên tắc thực hiện là virus sẽ sử dụng một số API được cung cấp để phát hiện ra virus đang được chạy dưới các debugger hoặc môi trường máy ảo. Có rất nhiều tình huống có thể xảy ra trong trường hợp này nhưng nhìn chung chương trình sẽ không thể chạy trên máy ảo hoặc không thể chạy thông qua debugger. Để vượt qua ta có nhiều phương pháp khác nhau. Trước tiên cần kiểm tra thông tin về PE header xem có sự khác biệt lớn gì hay không. Sau đó cần tìm ra đoạn mã antidebugger, anti VM và tiến hành chỉnh sửa để có thể vượt qua được đoạn mã anti đó. Hầu hết các phương pháp anti đều cố gắng tạo ra các Exception nếu không có debugger để EIP trỏ tới cấu trúc SEH được sắp xếp trước nhằm khôi phục quyền điều khiển, nếu có debugger thì Exception sẽ không xảy ra và debugger bị phát hiện. Một số phương pháp sử dụng để phát hiện có debugger:
    • Sử dụng hàm IsDebuggerPresent.
    • Kiểm tra cờ NtGlocalFlag.
    • Đặt cờ kiểm tra Hardware breakpoint.
    • Tìm lớp Windows của OllyDBG.
    • Sử dụng Int3.
    • Phát hiện memory breakpoint sử dụng PAGE_GAURD.
    • Kiểm tra thông qua NtQueryInformationProcess.
    • Phát hiện thông qua các plugin của IDA: OllyInvisible, HideDebugger.
    • Phát hiện bằng cách tìm kiếm xâu OLLY.
    • Anti Process Dump.
    • Tính toán chênh lệnh thời gian khi thực thi 1 lệnh để xác định được quá trình debug.
    • Dựa vào LDR Module: nếu debug ở mức user mode, bộ nhớ được cấp phát sẽ kết thúc bằng: 0xFEEEFEEE.
    • Thay đổi cờ EFLAGS sẽ có khả năng tạo ra Exception, thông qua đó có thể detect được debugger.
Trong bài tiếp theo tôi sẽ tiến hành phân tích một mẫu Virus cụ thể theo đúng trình tự như đã trình bày ở các bước trong bài viết này

Tài liệu tham khảo

Chia sẻ bài viết này