Notification texts go here Contact Us Buy Now!

[Write-up] Practical Malware Analysis | Part 2 - Chapter 7 - Lab 7-1

Practical Malware Analysis

CHƯƠNG 7 - PHÂN TÍCH CÁC CHƯƠNG TRÌNH MÃ ĐỘC WINDOWS

Dowloads Lab tại đây


Xem lại tóm tắt nội dung của Chương 7 tại đây.

Table of Contents

Lab 7-1 Phân tích phần mềm độc hại được tìm thấy trong tệp Lab07_01.exe

Câu hỏi

1. Làm thế nào chương trình này đảm bảo rằng nó tiếp tục chạy (đạt được tính duy trì) khi máy tính được khởi động lại?
2. Tại sao chương trình này sử dụng mutex?
3. Chữ ký dựa trên máy chủ nào phù hợp để sử dụng để phát hiện chương trình này?
4. Chữ ký dựa trên mạng nào phù hợp để phát hiện phần mềm độc hại này?
5. Mục đích của chương trình này là gì?
6. Khi nào chương trình này sẽ thực hiện xong?

Phân tích chi tiết

1 Tổng quan

Môi trường phân tíchWindows 10 Flare VM
Mẫu phân tíchLab07_01.exe
Size24576 bytes
MD5C04FD8D9198095192E7D55345966DA2E
CompiledFri, Sep 30 2011, 19:49:12 - 32 Bit EXE

2 Công cụ sử dụng

3 Phân tích Tĩnh

3.1 - Sử dụng VirusTotal

Việc đầu tiên tải mẫu lên VirusTotal để kiểm tra.
https://www.virustotal.com/gui/file/0c98769e42b364711c478226ef199bfbba90db80175eb1b8cd565aa694c09852/detection

Kết quả quét trên VirusTotal cho thấy mẫu được nhận diện là Trojan.

3.2 - Sử dụng HxD



Kiểm tra header tệp xác nhận đây là tệp PE (Portable Executable - Tệp thực thi di động).

*Bên lề: Mặc dù VirusTotal đã cung cấp thông tin khá đầy đủ trong trường hợp này, việc xác định chữ ký tệp vẫn vô cùng cần thiết. Từ góc độ phân tích chuyên sâu, đặc biệt là khi đối mặt với các mẫu mã độc hoàn toàn mới, chưa từng xuất hiện trên VirusTotal, việc xác định chữ ký tệp đóng vai trò then chốt trong việc phân loại và hiểu rõ bản chất của mẫu. Càng nắm bắt được nhiều thông tin chi tiết về mẫu, quá trình phân tích sẽ diễn ra càng hiệu quả và chính xác.

3.3 - Sử dụng Exeinfo PE

Với Exeinfo PE ta biết được tệp không bị đóng gói (no packed) và được biên dịch bằng Microsoft Visual C++ v.5 - 6.00.

3.4 - Sử dụng Dependency Walker


Phân tích Import Address Table (IAT) bằng Dependency Walker. Chúng ta sẽ sử dụng Dependency Walker để kiểm tra chương trình này. Vì chương trình import một lượng lớn các hàm từ các DLL này, tôi đã phân loại ra các API như bảng bên dưới.

Loại APIChức năngAPI
Xử lý tiến trình
và luồng
Tạo và quản lý tiến trình, luồngCreateThread
ExitProcess
GetCurrentProcess
TerminateProcess
Đồng bộ hóaĐồng bộ hóa truy cập tài nguyên giữa các luồngCreateMutexA
OpenMutexA
WaitForSingleObject
CreateWaitableTimerA
SetWaitableTimer

Quản lý bộ nhớCấp phát, giải phóng và quản lý bộ nhớ heap và bộ nhớ ảoHeapAlloc
HeapCreate
HeapDestroy
HeapFree
HeapReAlloc
VirtualAlloc
VirtualFree
Xử lý chuỗi và mã hóaChuyển đổi giữa các bảng mã, so sánh chuỗiGetACP
GetCPInfo
GetStringTypeA
GetStringTypeW
LCMapStringA
LCMapStringW
MultiByteToWideChar
WideCharToMultiByte
Xử lý tệp và I/OĐọc, ghi và xử lý tệpGetFileType, WriteFile
Thông tin hệ thốngLấy thông tin về hệ thống, môi trường, phiên bảnFreeEnvironmentStringsA
FreeEnvironmentStringsW
GetCommandLineA
GetEnvironmentStrings
GetEnvironmentStringsW
GetModuleFileNameA
GetOEMCP
GetStartupInfoA
GetStdHandle
GetVersion
SystemTimeToFileTime
DLL và thư việnTải và lấy địa chỉ
hàm từ DLL
GetProcAddress
LoadLibraryA
Xử lý lỗi và ngoại lệXử lý ngoại lệ và lỗiRtlUnwind
UnhandledExceptionFilter
Dịch vụ WindowsTạo, mở và quản lý dịch vụ WindowsCreateServiceA
OpenSCManagerA
StartServiceCtrlDispatcherA
InternetMở kết nối internet và truy cập URLInternetOpenA
InternetOpenUrlA
KhácCác chức năng khácSetHandleCount
Sleep

Việc sử dụng các API liên quan đến dịch vụ Windows và Internet là dấu hiệu đáng ngờ.

3.5 - Sử dụng Strings

Dễ  dàng trích xuất các String của tệp với nhiều công cụ có sẵn như strings.exe trong bộ công cụ SysinternalsSuite, flare-floss của MandiantMalcode Analyst Pack của Sandsprite, ...

Chuỗi đầy đủ của mẫu như sẽ như dưới đây:
File: Lab07_01.exe
MD5:  c04fd8d9198095192e7d55345966da2e
Size: 24576

Ascii Strings:
---------------------------------------------------------------------------
0000004D  !This program cannot be run in DOS mode.
000000BF  &Rich
000001C8  .text
000001EF  `.rdata
00000217  @.data
00001046  hHP@
00001064  VhHP@
000010A3  L$,j
000010B1  h<P@
000010B6  h<P@
0000111C  =0@@
0000115A  htP@
00001178  hPP@
0000130A  _9=4S@
0000132F  =0S@
00001376  YYh P@
00001393  =4S@
0000159A  t9UW
000015A8  ?=t"U
000015FA  QQS3
00001626  5$S@
0000163A  PSSW
000016BB  8"uD
000016FC  8"uF@
0000178F  8"u,
0000184E  -h@@
000018B2  @@f9
000018B9  @@f9
000018C3  =`@@
000018CA  SS@SSPVSS
000018EC  t#SSUP
000018F3  t$$VSS
0000196F  _^][YY
00001978  DSUVWh
00001B19  _^][
00001B63  SVWUj
00001B78  ]_^[
00001BCC  t.;t$$t(
00001C50  VC20XC00U
00001C5E  SVWU
00001C98  tEVU
00001CAA  t3x<
00001D0D  ]_^[
00001E82  hhC@
00001FE1  5XT@
0000210F  90tr
00002279  %HT@
000022F1  Wj@Y3
0000235C  t7SW
00002378      
0000244A  @AA;
000028A8  j?I_
00002B08  ulSj
00002C23  uY;]
00002CAC  pD#U
00002CFF  j #M
00002D28  j?^;
00003047  VWuBh
000030D7  tzVS
000030F9  GIt%
0000311D  t/Ku
00003217  uFWWj
0000323C  "WWSh
000032A4  9} u
000032AF  E WW
00003328  tMWWS
00003349  t@9}
000033EC  VSh 
0000343D  h(D@
000040DC  runtime error 
000040F0  TLOSS error
00004100  SING error
00004110  DOMAIN error
00004120  R6028
00004127  - unable to initialize heap
00004148  R6027
0000414F  - not enough space for lowio initialization
00004180  R6026
00004187  - not enough space for stdio initialization
000041B8  R6025
000041BF  - pure virtual function call
000041E0  R6024
000041E7  - not enough space for _onexit/atexit table
00004218  R6019
0000421F  - unable to open console device
00004244  R6018
0000424B  - unexpected heap error
00004268  R6017
0000426F  - unexpected multithread lock error
00004298  R6016
0000429F  - not enough space for thread data
000042C6  abnormal program termination
000042E8  R6009
000042EF  - not enough space for environment
00004314  R6008
0000431B  - not enough space for arguments
00004340  R6002
00004347  - floating point not loaded
00004368  Microsoft Visual C++ Runtime Library
00004394  Runtime Error!
000043A4  Program: 
000043B4  <program name unknown>
000043CC  GetLastActivePopup
000043E0  GetActiveWindow
000043F0  MessageBoxA
000043FC  user32.dll
00004552  Sleep
0000455A  CreateThread
0000456A  WaitForSingleObject
00004580  SetWaitableTimer
00004594  CreateWaitableTimerA
000045AC  SystemTimeToFileTime
000045C4  GetModuleFileNameA
000045DA  GetCurrentProcess
000045EE  CreateMutexA
000045FE  ExitProcess
0000460C  OpenMutexA
00004618  KERNEL32.dll
00004628  StartServiceCtrlDispatcherA
00004646  CreateServic
00004658  OpenSCManagerA
00004668  ADVAPI32.dll
00004678  InternetOpenUrlA
0000468C  InternetOpenA
0000469A  WININET.dll
000046A8  GetCommandLineA
000046BA  GetVersion
000046C8  TerminateProcess
000046DC  UnhandledExceptionFilter
000046F8  FreeEnvironmentStringsA
00004712  FreeEnvironmentStringsW
0000472C  WideCharToMultiByte
00004742  GetEnvironmentStrings
0000475A  GetEnvironmentStringsW
00004774  SetHandleCount
00004786  GetStdHandle
00004796  GetFileType
000047A4  GetStartupInfoA
000047B6  HeapDestroy
000047C4  HeapCreate
000047D2  VirtualFree
000047E0  HeapFree
000047EC  RtlUnwind
000047F8  WriteFile
00004804  HeapAlloc
00004810  GetCPInfo
0000481C  GetACP
00004826  GetOEMCP
00004832  VirtualAlloc
00004842  HeapReAlloc
00004850  GetProcAddress
00004862  LoadLibraryA
00004872  MultiByteToWideChar
00004888  LCMapStringA
00004898  LCMapStringW
000048A8  GetStringTypeA
000048BA  GetStringTypeW
00005030  MalService
0000503C  Malservice
00005048  HGL345
00005050  http://www.malwareanalysisbook.com
00005074  Internet Explorer 8.0


Unicode Strings:
---------------------------------------------------------------------------
00001098  @jjjj
000010E9  @jjj
000010F5  @jjj

Một số chuối đáng lưu ý được liệt kê ở dưới đây:
000045EE  CreateMutexA
...
0000460C  OpenMutexA
...
00004678  InternetOpenUrlA
0000468C  InternetOpenA
0005030   MalService
0000503C  Malservice
00005048  HGL345
00005050  http://www.malwareanalysisbook.com
00005074  Internet Explorer 8.0
Phân tích Strings:

  • Các chuỗi thể hiện hàm API của Windows:
    • CreateMutexA: Hàm này tạo ra một đối tượng mutex (Mutual Exclusion - Loại trừ Lẫn nhau). Mutex được sử dụng để đồng bộ hóa giữa các tiến trình hoặc luồng, đảm bảo chỉ có một tiến trình hoặc luồng được truy cập vào một tài nguyên chung tại một thời điểm. Trong ngữ cảnh mã độc, nó thường được dùng để đảm bảo chỉ có một instance (phiên bản) của mã độc chạy trên hệ thống.
    • OpenMutexA: Hàm này mở một mutex đã tồn tại. Mã độc sẽ sử dụng hàm này để kiểm tra xem một instance của nó đã chạy hay chưa. Nếu mutex đã tồn tại, nghĩa là một instance khác đã chạy, và instance hiện tại có thể tự kết thúc để tránh xung đột.
    • InternetOpenUrlA: Hàm này mở một URL (địa chỉ web). Mã độc có thể sử dụng hàm này để kết nối đến một máy chủ từ xa (C&C server) để tải thêm mã độc, nhận lệnh hoặc gửi dữ liệu đánh cắp.
    • InternetOpenA: Hàm này khởi tạo việc sử dụng các hàm Internet. Nó cần được gọi trước khi sử dụng các hàm như InternetOpenUrlA.
  • Các chuỗi dữ liệu:
    • MalService Malservice: Đây có thể là tên của một service (dịch vụ) mà mã độc cài đặt trên hệ thống. Service này được sử dụng để đảm bảo mã độc tự động chạy khi máy tính khởi động lại, giúp nó duy trì sự hiện diện trên hệ thống. Có vẻ như có hai phiên bản, có thể là do lỗi in ấn hoặc do các phiên bản khác nhau của mã độc.
    • HGL345: Đây là tên của mutex mà mã độc tạo ra (bằng CreateMutexA) hoặc kiểm tra sự tồn tại (bằng OpenMutexA). Như đã giải thích ở trên, mutex này đảm bảo chỉ có một instance của mã độc chạy.
    • http://www.malwareanalysisbook.com: Đây là một URL. Việc mã độc chứa URL này cho thấy nó có thể kết nối đến trang web này. Trong bối cảnh của cuốn sách "Practical Malware Analysis", thì đây có thể là một URL được sử dụng cho mục đích phân tích, hoặc trong thực tế, nó có thể là địa chỉ của một máy chủ C&C.
    • Internet Explorer 8.0: Đây là chuỗi User-Agent. User-Agent là một chuỗi được gửi bởi trình duyệt web đến máy chủ web, xác định loại trình duyệt và hệ điều hành mà người dùng đang sử dụng. Việc mã độc sử dụng User-Agent này khi kết nối internet có thể là một cách để ngụy trang hành vi của nó, giả vờ là một trình duyệt web thông thường.

Dựa vào bảng import và phân tích chuỗi có thể dự đoán rằng:

  • Mã độc sử dụng CreateMutexA với tên "HGL345" để tạo mutex, hoặc OpenMutexA để kiểm tra mutex này đã tồn tại hay chưa. Mục đích là để đảm bảo chỉ có một instance của mã độc chạy.
  • Mã độc cài đặt một service với tên "Malservice" (hoặc "MalService") để tự động khởi chạy cùng hệ thống.
  • Mã độc sử dụng InternetOpenAInternetOpenUrlA để kết nối đến URL http://www.malwareanalysisbook.com với User-Agent là "Internet Explorer 8.0".

4 Phân tích Động

Sử dụng SysAnalyzer với các thiết lập được khoanh đỏ trong hình bên dưới. Nhấn Start để quá trình phân tích tự động diễn ra.

4.1 - Phân tích lưu lượng mạng

Trích xuất nhật ký một số giao tiếp giữa trình duyệt web và một máy chủ web như dưới đây ở kết quả phân tích của SysAnalyzer:
-> 3.33.251.168:80                                
GET / HTTP/1.1
User-Agent: Internet Explorer 8.0
Host: www.malwareanalysisbook.com
Cache-Control: no-cache

-------------------------------------------------------
<- 3.33.251.168:80
HTTP/1.1 301 Moved Permanently
Date: Tue, 24 Dec 2024 16:02:10 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 74
Connection: keep-alive
Location: http://www.practicalmalwareanalysis.com
Server: ip-10-124-4-50.us-west-2.compute.internal
Vary: Accept-Encoding
X-Request-Id: af9062e9-0583-498c-a93b-9616d943678b

<a href="http://www.practicalmalwareanalysis.com">Moved Permanently</a>.

-------------------------------------------------------
-> 15.197.225.128:80
GET / HTTP/1.1
User-Agent: Internet Explorer 8.0
Host: www.malwareanalysisbook.com
Cache-Control: no-cache

-------------------------------------------------------
<- 15.197.225.128:80
HTTP/1.1 301 Moved Permanently
Date: Tue, 24 Dec 2024 16:02:10 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 63
Connection: keep-alive
Location: https://nostarch.com/malware
Server: ip-10-124-5-185.us-west-2.compute.internal
Vary: Accept-Encoding
X-Request-Id: 2d6e60d7-efe2-4cd8-b076-5e24c7c15cec

<a href="https://nostarch.com/malware">Moved Permanently</a>.

...

  • Dòng bắt đầu mỗi phiên:
    • GET / HTTP/1.1: Đây là yêu cầu truy cập trang web, với phương thức GET để lấy nội dung trang.
    • User-Agent: Internet Explorer 8.0: Thông tin về trình duyệt đang truy cập là Internet Explorer 8.0.
    • Host: www.malwareanalysisbook.com: Tên miền trang web mà trình duyệt đang yêu cầu.
    • Cache-Control: no-cache: Trình duyệt yêu cầu không sử dụng dữ liệu cache.
  • Dòng trả về của server:
    • HTTP/1.1 301 Moved Permanently: Máy chủ trả về mã trạng thái 301, nghĩa là trang web đã được chuyển hướng vĩnh viễn.
    • Date: Ngày và giờ trả về kết quả.
    • Content-Type: Kiểu nội dung được trả về (ở đây là text/html).
    • Content-Length: Độ dài nội dung trả về.
    • Location: Địa chỉ mới của trang web đã được chuyển hướng.
    • Server: Thông tin về server đang trả lời.
    • Vary: Có thể thay đổi nội dung trả về tùy thuộc vào yếu tố nào đó (ở đây là Accept-Encoding).
    • X-Request-Id: Mã định danh yêu cầu (có thể dùng để theo dõi xử lý trên server).
  • Nội dung trả về:
    • <a href="http://www.practicalmalwareanalysis.com">Moved Permanently</a>: Đây là một đoạn mã HTML thông báo trang web đã được chuyển hướng, nhưng với địa chỉ cũ (http://www.practicalmalwareanalysis.com).

*Bên lề: Internet Explorer 8.0 là một trình duyệt đã lỗi thời và không còn nhận được các bản cập nhật bảo mật. Việc sử dụng trình duyệt này có thể khiến bạn gặp phải các rủi ro bảo mật nghiêm trọng. Vì vậy, khuyến nghị bạn nên sử dụng các phiên bản trình duyệt hiện đại hơn để đảm bảo an toàn cho hệ thống.

Kết quả phân tích mạng

  • Trình duyệt tự động gửi yêu cầu đến địa chỉ mới.

4.2 - Phân tích quá trình sau thực thi

  • Sau khi chạy mã độc nó sẽ tạo ra một tiến trình con conhost.exe - là tiến trình Console Host, thường được sử dụng để cung cấp giao diện dòng lệnh cho các ứng dụng. Khả năng Lab07_01.exe có thể đang thực hiện các lệnh thông qua console.
  • Tạo ra nhiều mutex, đặc biệt là các mutex có tiền tố Wil (Windows Internal Library), cho thấy chúng đang cố gắng kiểm soát và đồng bộ hóa các hoạt động. Các mutex có tên ngẫu nhiên như \Sessions\1HGL345 cũng đáng chú ý.

  • Cài đặt vào Registry một registry key với tên "Malservice" để duy trì sự tồn tại của nó trên hệ thống. Địa chỉ là HKLM\SYSTEM\CurrentControlSet\Services Malservice=

Kết quả phân tích sau thực thi

  • Để ngăn chặn việc chạy nhiều phiên bản cùng lúc, mã độc tận dụng mutex với tên "HGL345". Nếu đây là lần đầu tiên mã độc được chạy, nó sẽ sử dụng hàm CreateMutexA để tạo mutex này. Nếu mutex đã tồn tại, điều đó có nghĩa là một phiên bản khác của mã độc đang chạy, và phiên bản hiện tại sẽ sử dụng hàm OpenMutexA để phát hiện điều này và thường tự kết thúc để tránh xung đột.
  • Cài đặt vào Registry một registry key với tên "Malservice" để tự động khởi chạy cùng hệ thống. Địa chỉ là HKLM\SYSTEM\CurrentControlSet\Services Malservice=.

*Bên lề: Lab07_01.exe có hành vi điển hình của một mã độc như tự chạy, tạo tiến trình con, sử dụng mutexes để đồng bộ hóa, giám sát hệ thống, tạo và sửa đổi tệp tạm thời, can thiệp vào cấu hình người dùng và cố gắng cài đặt một dịch vụ.

*Bên lề: Để xác minh khả năng tự duy trì của mã độc sau khi hệ thống khởi động lại, tôi đã tiến hành tắt (Shutdown) máy ảo Windows (VM) và sau đó bật lại. Kết quả cho thấy mã độc vẫn tự động chạy mỗi khi máy tính được khởi động.

5 Phân tích Mã (IDA Pro)

Mở Lab07_01.exe với IDA Pro (Phiên bản tôi đang dùng là bản IDA Pro 9.0).

5.1 - Phân tích hàm main:


Trước tiên gán giá trị aMalService ❶(hay chính là tên dịch vụ 'MalService') cho ServiceStartTable.lpServiceName. Sau đó gán giá trị sub_401040 ❷ cho ServicesStartTable.lpServiceProc.
Trong hàm main này nó gọi tới API ❸ StartServiceCtrlDispatcherA và một hàm ❹ sub_401040.

Kết quả phân tích hàm main

Hàm main chịu trách nhiệm chính cho việc khởi tạo và duy trì hoạt động của malware, đặc biệt là thông qua việc cài đặt và quản lý một Windows service.

5.2 - Phân tích hàm API StartServiceCtrlDispatcherA

API StartServiceCtrlDispatcherA đóng vai trò then chốt trong việc biến một ứng dụng thông thường thành một dịch vụ Windows. Chức năng chính của nó là thiết lập cầu nối liên lạc giữa luồng chính của tiến trình và Service Control Manager (SCM - Trình quản lý Điều khiển Dịch vụ). Nói cách khác, nó cho phép hệ thống quản lý và điều khiển ứng dụng như một dịch vụ nền.

Cụ thể, StartServiceCtrlDispatcherA đảm nhiệm ba nhiệm vụ chính:

1. Kết nối với SCM: Thiết lập kênh giao tiếp, cho phép tiến trình dịch vụ trao đổi thông tin với SCM.

2. Đăng ký dịch vụ: Đăng ký một hoặc nhiều dịch vụ mà tiến trình này sẽ quản lý. Việc đăng ký này bao gồm việc cung cấp tên dịch vụ và địa chỉ của hàm xử lý chính của dịch vụ.

3. Xử lý yêu cầu điều khiển: Lắng nghe và xử lý các yêu cầu điều khiển từ SCM, chẳng hạn như bắt đầu (Start), dừng (Stop), tạm dừng (Pause), tiếp tục (Continue) và tắt hệ thống (Shutdown).

*Bên lề: SCM là thành phần bạn thấy khi gõ lệnh services.msc trong hộp thoại "Run", được mở bằng tổ hợp phím Windows + R.

Kết quả phân tích hàm API StartServiceCtrlDispatcherA

API này kết nối chương trình với SCM, cho phép SCM quản lý dịch vụ.

5.3 - Phân tích sub_401040

Hàm sub_401040 chứa logic cốt lõi của dịch vụ. Nó bắt đầu bằng một cơ chế kiểm tra sự tồn tại của mutex, một kỹ thuật thường được sử dụng bởi phần mềm để ngăn chặn việc chạy nhiều phiên bản đồng thời.


Nhấn phím G trên bàn phím để chuyển sang chế độ đồ họa.

  • push offset Name ; “HGL345” / call ds:OpenMutexA: Lệnh này gọi hàm OpenMutexA với tham số là chuỗi "HGL345". OpenMutexA cố gắng mở một mutex đã tồn tại với tên đó.
  • test eax,eax: Kiểm tra giá trị trả về của OpenMutexA. Nếu giá trị này bằng 0 (NULL), có nghĩa là mutex không tồn tại.
  • jz short loc_401064: Nếu kết quả kiểm tra ở trên là đúng tức là test eax,eax có giá trị 0 (mutex không tồn tại), chương trình sẽ nhảy đến địa chỉ loc_401064..

Kết quả phân tích sub_401040

Đoạn mã này là kiểm tra xem mutex "HGL345" đã tồn tại hay chưa. Nếu mutex đã tồn tại (giá trị trả về khác NULL), chương trình sẽ gọi ExitProcess để kết thúc tiến trình, ngăn chặn việc khởi chạy thêm một phiên bản nữa. Ngược lại, nếu mutex chưa tồn tại, chương trình sẽ tiếp tục thực hiện các lệnh tại loc_401064.

5.4 - Phân tích loc_401064


Tại vị trí loc_401064, chương trình bắt đầu thực hiện các bước để tự cài đặt như một dịch vụ Windows. Cụ thể:

1. Tạo Mutex "HGL345": Lệnh gọi hàm CreateMutexA được sử dụng để tạo một mutex (đối tượng đồng bộ hóa) với tên "HGL345". Mục đích của việc này là để đảm bảo rằng chỉ có một phiên bản của chương trình này được chạy trên hệ thống tại một thời điểm. Nếu một phiên bản khác cố gắng chạy, nó sẽ kiểm tra sự tồn tại của mutex này và nếu nó đã tồn tại, phiên bản mới sẽ tự động kết thúc.

2. Mở kết nối đến SCM: Hàm OpenSCManagerA được gọi để thiết lập một kết nối đến Service Control Manager (SCM). SCM là thành phần quản lý các dịch vụ trên hệ thống Windows. Việc mở kết nối này là bắt buộc để có thể tạo và quản lý dịch vụ.

3. Lấy Handle của tiến trình hiện tại: Hàm GetCurrentProcess được sử dụng để lấy một handle (tay cầm) đại diện cho tiến trình hiện tại đang chạy (trong trường hợp này là Lab07-01.exe). Handle này sẽ được sử dụng trong bước tiếp theo.

4. Lấy đường dẫn tệp thực thi: Hàm GetModuleFileNameA được gọi với tham số hModule NULL (hoặc 0). Điều này có nghĩa là hàm sẽ trả về đường dẫn đầy đủ đến tệp thực thi của tiến trình hiện tại (Lab07_01.exe). Đường dẫn này rất quan trọng vì nó sẽ được sử dụng để đăng ký dịch vụ.

5. Tạo dịch vụ "malservice": Cuối cùng, hàm CreateServiceA được gọi để tạo một dịch vụ Windows mới với tên "malservice". Hàm này sử dụng các thông tin sau:

    • Kết nối đến SCM đã được thiết lập ở bước 2.
    • Đường dẫn đến tệp thực thi Lab07_01.exe đã được lấy ở bước 4.

Như vậy, Lab07-01.exe được đăng ký như một dịch vụ với tên "malservice".

Kết quả Phân tích loc_401064

Đoạn mã này là biến tệp thực thi Lab07-01.exe thành một dịch vụ Windows có tên "malservice".

*Bên lề: Điểm quan trọng (về mặt bảo mật): Đoạn mã này thể hiện một kỹ thuật thường được sử dụng bởi phần mềm độc hại. Việc kiểm tra và tạo mutex "HGL345" là một cơ chế chống chạy đa phiên bản. Nếu mutex đã tồn tại, điều đó có nghĩa là phần mềm độc hại đã chạy trên hệ thống, và phiên bản mới sẽ tự động kết thúc. Nếu mutex chưa tồn tại, phần mềm độc hại sẽ tạo mutex và tự cài đặt như một dịch vụ, cho phép nó tự động khởi động cùng với hệ thống mỗi khi máy tính được khởi động lại. Điều này giúp phần mềm độc hại duy trì sự tồn tại và khả năng hoạt động trên hệ thống bị nhiễm, ngay cả sau khi người dùng khởi động lại máy tính. Đây là một hành vi nguy hiểm và là một dấu hiệu rõ ràng của phần mềm độc hại.

5.5 - Phân tích SystemTimeToFileTime

*Bên lề: Hãy cùng tìm hiểu cách hàm SystemTimeToFileTime chuyển đổi giữa hai định dạng thời gian khác nhau: thời gian hệ thống (SYSTEMTIME) và thời gian tệp (FILETIME).

  • Thời gian hệ thống (SYSTEMTIME): Đây là định dạng quen thuộc với người dùng, biểu diễn thời gian bằng các đơn vị dễ hiểu như năm, tháng, ngày, giờ, phút và giây. Nó được thiết kế để hiển thị thời gian một cách trực quan.
  • Thời gian tệp (FILETIME): Định dạng này phức tạp hơn, biểu diễn thời gian bằng số lượng khoảng thời gian 100 nano giây (một phần mười tỷ giây) tính từ nửa đêm ngày 1 tháng 1 năm 1601 theo giờ UTC (Coordinated Universal Time). Định dạng này được sử dụng bởi hệ thống tệp để lưu trữ thông tin về thời gian tạo, sửa đổi và truy cập tệp. Do sử dụng đơn vị nano giây và gốc thời gian xa xôi, định dạng FILETIME khó được con người hiểu trực tiếp.

Đoạn mã trong hình trên thực hiện các bước sau để chuyển đổi thời gian:

1. Khởi tạo

  • xor edx, edx: Lệnh này gán giá trị 0 cho thanh ghi edx. Đây là một cách tối ưu để gán 0, nhanh hơn so với mov edx, 0.
  • Khởi tạo FileTime và Systemtime: Các biến lưu trữ thời gian tệp và thời gian hệ thống được khởi tạo (thường là gán giá trị 0 hoặc một giá trị mặc định). Việc này rất quan trọng để tránh sử dụng các giá trị rác.

2. Thiết lập năm

Giá trị 834h (tương đương 2100 trong hệ thập phân) được gán cho đối số .wYear của cấu trúc Systemtime. .wYear đại diện cho năm trong định dạng thời gian hệ thống. Vì các thành phần khác của Systemtime (như tháng, ngày, giờ, phút, giây) không được thiết lập rõ ràng trong đoạn mã, chúng được coi là có giá trị mặc định, thường là 1 cho tháng và ngày, và 0 cho giờ, phút, giây.

3. Gọi SystemTimeToFileTime

Hàm SystemTimeToFileTime được gọi. Hàm này nhận cấu trúc Systemtime (với năm đã được đặt là 2100) và chuyển đổi nó sang định dạng FileTime.

Kết quả Phân tích SystemTimeToFileTime

Kết quả của quá trình này là giá trị "ngày 1 tháng 1 năm 2100" được biểu diễn dưới định dạng thời gian tệp (FILETIME). Giá trị này sẽ là một số 64 bit biểu diễn số lượng khoảng 100 nano giây tính từ nửa đêm ngày 1 tháng 1 năm 1601 đến nửa đêm ngày 1 tháng 1 năm 2100.

5.6 - Phân tích hàm CreateWaitableTimerA

CreateWaitableTimerA là một hàm API của Windows được sử dụng để tạo một đối tượng hẹn giờ có thể được sử dụng để đồng bộ hóa các luồng (threads). Khi bộ hẹn giờ hết thời gian, nó sẽ được đặt ở trạng thái được báo hiệu (signaled), cho phép các luồng đang chờ (waiting) trên bộ hẹn giờ này tiếp tục thực thi.

Đoạn mã ở hình trên được cung cấp thực hiện các bước sau:

  1. lea edx, [esp+410h+FileTime]: Lệnh lea (Load Effective Address) này tính toán địa chỉ của biến FileTime (đã được tạo và gán giá trị tương ứng với ngày 1 tháng 1 năm 2100 như đã phân tích ở các câu trả lời trước) và lưu địa chỉ này vào thanh ghi EDX. esp+410h cho biết vị trí của biến FileTime trên ngăn xếp (stack).
  2. push edx: Lệnh push này đẩy giá trị trong thanh ghi EDX (chính là địa chỉ của biến FileTime) lên ngăn xếp. Đây là cách truyền tham số cho hàm SetWaitableTimer. Trong trường hợp này, FileTime được sử dụng để thiết lập thời điểm bộ hẹn giờ sẽ được kích hoạt.
  3. call ds:SetWaitableTimer: Lệnh call này gọi hàm SetWaitableTimer. Hàm này nhận các tham số, bao gồm cả con trỏ đến cấu trúc FILETIME được đẩy lên ngăn xếp trước đó. SetWaitableTimer sẽ thiết lập bộ hẹn giờ dựa trên thời gian được cung cấp trong FILETIME.

Kết quả phân tích CreateWaitableTimerA

Dùng hàm SetWaitableTimer để thiết lập một bộ hẹn giờ sẽ được kích hoạt vào ngày 1 tháng 1 năm 2100 cho thấy một số khả năng:

  • Trì hoãn thực thi: Mã độc có thể sử dụng bộ hẹn giờ này để trì hoãn việc thực thi một phần mã độc hại nào đó cho đến một thời điểm rất xa trong tương lai. Điều này có thể được sử dụng để tránh bị phát hiện trong quá trình phân tích ban đầu.
  • Kích hoạt theo thời gian: Một khả năng khác là mã độc được thiết kế để thực hiện một hành động cụ thể vào ngày 1 tháng 1 năm 2100, chẳng hạn như tấn công một mục tiêu cụ thể hoặc kích hoạt một chức năng nào đó. Tuy nhiên, việc chọn một thời điểm xa như vậy thường không phổ biến cho các mục đích tấn công thông thường.
  • Một cách để chiếm giữ tiến trình: Trong một số trường hợp, việc thiết lập một bộ hẹn giờ rất dài và sau đó chờ đợi nó có thể được sử dụng như một cách để giữ cho một tiến trình hoạt động mà không tiêu tốn nhiều tài nguyên CPU. Tuy nhiên, đây không phải là cách hiệu quả nhất.

5.7 - Phân tích hàm WaitForSingleObject

Dưới đây là phân tích chi tiết:

  1. 0FFFFFFFFh ; dwMilliseconds có nghĩa là chờ đợi vô tận: Giá trị 0xFFFFFFFF (tương đương với -1 trong biểu diễn số nguyên có dấu) được gán cho tham số dwMilliseconds của hàm WaitForSingleObject. Trong Windows API, giá trị này biểu thị thời gian chờ đợi là vô hạn (INFINITE). Điều này có nghĩa là hàm WaitForSingleObject sẽ chặn luồng hiện tại và chờ đợi mãi mãi cho đến khi đối tượng được chỉ định được báo hiệu (signaled), hoặc cho đến khi có một sự kiện khác làm gián đoạn việc chờ đợi (ví dụ: một APC - Asynchronous Procedure Call).
  2. WaitForSingleObject được sử dụng để đợi cho đến khi nhận được trạng thái tín hiệu, tức là tín hiệu hẹn giờ: Hàm WaitForSingleObject là một hàm API của Windows được sử dụng để đồng bộ hóa các luồng. Nó được sử dụng để chờ đợi một đối tượng đồng bộ hóa (ví dụ: một mutex, semaphore, event, thread, hoặc timer) chuyển sang trạng thái được báo hiệu. Trong trường hợp này, đối tượng được chờ đợi là một bộ hẹn giờ có thể chờ đợi (waitable timer). Khi bộ hẹn giờ đạt đến thời điểm đã được thiết lập (ví dụ: ngày 1 tháng 1 năm 2100), nó sẽ được báo hiệu.
  3. test eax, eax Hàm WaitForSingleObject trả về 0 khi ở trạng thái tín hiệu. Do đó, kiểm tra là để kiểm tra xem tín hiệu hiện có ở trạng thái tín hiệu hay không: Sau khi hàm WaitForSingleObject trả về, giá trị trả về của nó được lưu trữ trong thanh ghi EAX (trong kiến trúc x86). Theo tài liệu của Microsoft, WaitForSingleObject trả về 0 (tức là hằng số WAIT_OBJECT_0) khi đối tượng được chờ đợi đã được báo hiệu. Điều này có nghĩa là bộ hẹn giờ đã hết thời gian. Lệnh test eax, eax thực hiện phép toán AND bitwise giữa nội dung của EAX với chính nó. Phép toán này không thay đổi giá trị của EAX, nhưng nó sẽ thiết lập các cờ trạng thái (status flags) trong bộ xử lý, đặc biệt là cờ Zero Flag (ZF). Nếu EAX bằng 0, cờ ZF sẽ được đặt thành 1. Nếu EAX khác 0, cờ ZF sẽ được đặt thành 0. Mục đích của việc kiểm tra này là để xác định xem WaitForSingleObject đã trả về 0 (tức là bộ hẹn giờ đã được báo hiệu) hay chưa.
  4. jnz short loc_40113B: Nếu không bằng 0, chuyển sang quy trình chờ: Lệnh jnz short loc_40113B là một lệnh nhảy có điều kiện. jnz là viết tắt của "Jump if Not Zero" (nhảy nếu không phải là 0). Lệnh này kiểm tra giá trị của cờ ZF. Nếu ZF bằng 0 (tức là giá trị trong EAX khác 0), lệnh nhảy sẽ được thực hiện, và chương trình sẽ nhảy đến nhãn loc_40113B. Điều này có nghĩa là nếu WaitForSingleObject trả về một giá trị khác 0 (ví dụ: WAIT_TIMEOUT nếu có thời gian chờ, hoặc các mã lỗi khác), chương trình sẽ tiếp tục thực hiện các lệnh tại địa chỉ loc_40113B, thường là quay lại vòng lặp chờ đợi. Nếu ZF bằng 1 (tức là giá trị trong EAX bằng 0), lệnh nhảy sẽ không được thực hiện, và chương trình sẽ tiếp tục thực hiện các lệnh ngay sau lệnh jnz.

Kết quả phân tích hàm WaitForSingleObject

Đoạn mã này thiết lập một vòng lặp chờ đợi vô hạn bằng cách sử dụng hàm WaitForSingleObject. Hàm này được gọi với tham số là một bộ hẹn giờ đã được cấu hình để kích hoạt vào một thời điểm cụ thể (thường là rất xa trong tương lai) và thời gian chờ được đặt là vô hạn (0xFFFFFFFF). Chương trình sẽ tạm dừng (bị "treo") tại lệnh WaitForSingleObject cho đến khi bộ hẹn giờ được báo hiệu. Khi bộ hẹn giờ được báo hiệu, WaitForSingleObject sẽ trả về giá trị 0, lệnh test eax, eax sẽ thiết lập cờ ZF thành 1, và lệnh jnz sẽ không thực hiện việc nhảy. Kết quả là, chương trình sẽ tiếp tục thực hiện các lệnh tiếp theo sau lệnh jnz. Nói một cách ngắn gọn, đoạn mã này khiến chương trình tạm dừng thực thi cho đến khi bộ hẹn giờ được kích hoạt. Việc sử dụng thời điểm hẹn giờ xa như năm 2100 thường là dấu hiệu của việc mã độc muốn trì hoãn việc thực thi các hành động độc hại.

5.8 - Phân tích vòng lặp tạo luồng

Tạo luồng bằng CreateThread

Ngay sau khi luồng nhận được tín hiệu hẹn giờ, nó sẽ bắt đầu một quá trình tạo ra nhiều luồng con bằng hàm CreateThread. Hàm CreateThread là một hàm API của Windows, được sử dụng để tạo một luồng mới trong cùng một tiến trình.

Vòng lặp tạo luồng

Đoạn mã mov esi, 14h(=20) / dec esi / short loc_401126 mô tả một vòng lặp trong hợp ngữ (assembly). Cụ thể:

  • mov esi, 14h(=20): Lệnh này gán giá trị 20 (14 trong hệ thập lục phân) vào thanh ghi ESI. Thanh ghi ESI ở đây được sử dụng như một biến đếm vòng lặp.
  • dec esi: Lệnh này giảm giá trị trong thanh ghi ESI đi 1.
  • short loc_401126: Đây là một nhãn (label) trong mã. Lệnh jnz short loc_401126 (đã được đề cập trong các phân tích trước) sẽ nhảy trở lại nhãn này nếu giá trị trong ESI khác 0. Điều này tạo thành một vòng lặp. Vòng lặp sẽ tiếp tục cho đến khi giá trị trong ESI giảm xuống 0.

Tạo 20 luồng

Vì vòng lặp lặp lại 20 lần (từ 20 xuống 0), hàm CreateThread sẽ được gọi 20 lần. Do đó, tổng cộng 20 luồng mới sẽ được tạo ra, và mỗi luồng sẽ thực thi cùng một đoạn mã được chỉ định bởi startAddress.

Việc tạo nhiều luồng như vậy sau một thời gian chờ dài là một kỹ thuật thường thấy trong mã độc, nhằm trì hoãn việc thực thi hành vi độc hại và gây khó khăn cho việc phân tích.

 5.9 - Phân tích hàm startAddress

Phân tích chi tiết và làm rõ từng phần:

1. Mở http://www.malwareanalysisbook.com bằng User-agent Internet Explorer 8.0

Câu này nói rằng chương trình sẽ cố gắng truy cập trang web http://www.malwareanalysisbook.com bằng cách giả mạo là trình duyệt Internet Explorer 8.0. "User-agent" là một chuỗi văn bản được gửi bởi trình duyệt đến máy chủ web, cho biết thông tin về trình duyệt và hệ điều hành của người dùng. Việc giả mạo user-agent có thể được sử dụng để qua mặt một số cơ chế kiểm tra phía máy chủ.

2. Phần quan trọng là jmp short loc_40116D

Lệnh jmp short loc_40116D là một lệnh nhảy vô điều kiện trong hợp ngữ (assembly). Cụ thể:

  • jmp: Lệnh nhảy (jump).
  • short: Chỉ định rằng mục tiêu nhảy nằm trong phạm vi ngắn (short jump), tức là gần với vị trí hiện tại của lệnh.
  • loc_40116D: Đây là một nhãn (label) trong mã, đánh dấu địa chỉ mà chương trình sẽ nhảy tới.

Vì đây là lệnh nhảy vô điều kiện, chương trình sẽ luôn luôn nhảy đến địa chỉ loc_40116D mà không cần kiểm tra bất kỳ điều kiện nào. Điều này tạo thành một vòng lặp vô hạn.

3. Vòng lặp truy cập vô hạn

Việc liên tục nhảy tới loc_40116D tạo ra một vòng lặp vô hạn. Bên trong vòng lặp này, hành động truy cập trang web http://www.malwareanalysisbook.com được thực hiện. Vì vòng lặp là vô hạn, hành động truy cập sẽ được lặp đi lặp lại liên tục.

4. 20 luồng cố gắng kết nối không ngừng

Như đã phân tích trong các câu trả lời trước, đoạn mã này tạo ra 20 luồng, và mỗi luồng đều thực hiện vòng lặp truy cập vô hạn này. Do đó, có 20 luồng đồng thời cố gắng kết nối liên tục với trang web http://www.malwareanalysisbook.com.

5. Hệ thống bị tê liệt (DoS)

Việc 20 luồng liên tục gửi yêu cầu kết nối đến cùng một trang web sẽ tạo ra một lượng lớn lưu lượng truy cập. Nếu lượng truy cập này vượt quá khả năng xử lý của máy chủ web, máy chủ sẽ bị quá tải và không thể phục vụ các yêu cầu hợp pháp khác. Đây chính là bản chất của tấn công từ chối dịch vụ (DoS). Máy chủ bị "tê liệt" vì không thể đáp ứng được lượng yêu cầu quá lớn.

*Sự khác biệt giữa DoS và DDoS:

  • DoS (Denial of Service - Từ chối dịch vụ): Tấn công DoS được thực hiện từ một nguồn (một máy tính hoặc một mạng). Trong trường hợp này, 20 luồng được tạo ra trên cùng một máy tính, do đó đây là một cuộc tấn công DoS.
  • DDoS (Distributed Denial of Service - Tấn công từ chối dịch vụ phân tán): Tấn công DDoS được thực hiện từ nhiều nguồn (nhiều máy tính hoặc mạng khác nhau). Các máy tính này thường bị nhiễm phần mềm độc hại và được điều khiển từ xa bởi kẻ tấn công để đồng loạt tấn công mục tiêu.

Kết quả Phân tích hàm startAddress

Đoạn mã được phân tích thực hiện một cuộc tấn công DoS bằng cách tạo ra 20 luồng trên cùng một máy tính, mỗi luồng liên tục truy cập trang web http://www.malwareanalysisbook.com, gây quá tải cho máy chủ web và làm cho nó không thể hoạt động bình thường. Điểm khác biệt chính giữa DoS và DDoS là số lượng nguồn tấn công: DoS từ một nguồn, DDoS từ nhiều nguồn.

Trả lời các câu hỏi

1. Làm thế nào chương trình này đảm bảo rằng nó tiếp tục chạy (đạt được tính duy trì) khi máy tính được khởi động lại?

Để dịch vụ malservice tự động chạy mỗi khi máy tính khởi động, sẽ cần đặt tham số dwStartType trong hàm CreateService thành giá trị 2 (tức là SERVICE_AUTO_START).

dwStartType có thể nhận một trong các giá trị sau:

  • SERVICE_BOOT_START (0): Dịch vụ được khởi động bởi trình nạp hệ điều hành. Giá trị này thường được sử dụng cho các driver thiết bị.
  • SERVICE_SYSTEM_START (1): Dịch vụ được khởi động bởi nhân hệ điều hành.
  • SERVICE_AUTO_START (2): Dịch vụ được khởi động tự động bởi Trình quản lý dịch vụ (Service Manager) sau khi hệ thống khởi động hoàn tất. Đây là giá trị phổ biến nhất cho các dịch vụ nền.
  • SERVICE_DEMAND_START (3): Dịch vụ chỉ được khởi động khi có một ứng dụng hoặc dịch vụ khác yêu cầu.
  • SERVICE_DISABLED (4): Dịch vụ bị vô hiệu hóa và không thể khởi động.


Có thể xác nhận các cấu hình này bằng cách chạy lệnh sau khi Phân tích động: sc qc Malservice


2. Tại sao chương trình này sử dụng mutex?

Một mutex được sử dụng để đảm bảo rằng chỉ có một phiên bản duy nhất của chương trình được chạy tại một thời điểm. Nó ngăn chặn việc người dùng hoặc hệ thống khởi chạy nhiều phiên bản đồng thời của cùng một chương trình.

3. Chữ ký dựa trên máy chủ nào phù hợp để sử dụng để phát hiện chương trình này?

Mã độc đã tạo một dịch vụ Windows có tên "Malservice" để tự động khởi động cùng hệ thống và một mutex có tên "HGL345" để đảm bảo chỉ có một phiên bản duy nhất của nó được chạy.

4. Chữ ký dựa trên mạng nào phù hợp để phát hiện phần mềm độc hại này?

Trong quá trình hoạt động, mã độc giả mạo là trình duyệt Internet Explorer 8.0 bằng cách sử dụng chuỗi tác nhân người dùng tương ứng và thực hiện kết nối đến địa chỉ web http://www.malwareanalysisbook.com.

5. Mục đích của chương trình này là gì?

Mã độc được thiết kế để thực hiện một cuộc tấn công từ chối dịch vụ vào ngày 1 tháng 1 năm 2100 bằng cách tạo ra 20 luồng xử lý. Các luồng này sẽ thiết lập các kết nối mạng không ngừng với các trang web được xác định là độc hại, có khả năng gây quá tải cho hệ thống và/hoặc thực hiện các hành động độc hại khác như tải xuống payload bổ sung hoặc trích xuất dữ liệu.

6. Khi nào chương trình này sẽ thực hiện xong?

Mã độc được thiết kế để bắt đầu vào ngày 1 tháng 1 năm 2100 và thực hiện một số tác vụ, bao gồm việc lưu trữ dữ liệu. Chương trình này không dừng lại.

Kết thúc Lab07_01.exe

إرسال تعليق

Cookie Consent
We serve cookies on this site to analyze traffic, remember your preferences, and optimize your experience.
Oops!
It seems there is something wrong with your internet connection. Please connect to the internet and start browsing again.
AdBlock Detected!
We have detected that you are using adblocking plugin in your browser.
The revenue we earn by the advertisements is used to manage this website, we request you to whitelist our website in your adblocking plugin.
Site is Blocked
Sorry! This site is not available in your country.