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
Phân tích chi tiết
1 Tổng quan
2 Công cụ sử dụng
- VirusTotal (https://www.virustotal.com): Kiểm tra nhanh bằng nhiều engine antivirus.
- HxD (https://mh-nexus.de/hxd): xem chữ ký của tệp.
- ExeInfo (https://github.com/ExeinfoASL/ASL): để phát hiện xem tệp có bị đóng gói không.
- Stings (https://learn.microsoft.com/en-us/sysinternals/downloads/strings): quét các tệp và trích xuất các chuỗi ký tự ASCII và Unicode có thể in được.
- IDA Pro (https://hex-rays.com/ida-pro): Trình dịch ngược để phân tích mã assembly.
- SysAnalyzer (https://sandsprite.com/iDef/SysAnalyzer/): dùng để phân tích và theo dõi hành vi của mã độc trên hệ thống.
- Dependency Walker (https://www.dependencywalker.com/): hiển thị danh sách các DLL.
3 Phân tích Tĩnh
3.1 - Sử dụng VirusTotal
https://www.virustotal.com/gui/file/0c98769e42b364711c478226ef199bfbba90db80175eb1b8cd565aa694c09852/detection
3.3 - Sử dụng Exeinfo PE
3.4 - Sử dụng Dependency Walker
3.5 - Sử dụng Strings
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
000045EE CreateMutexA ... 0000460C OpenMutexA ... 00004678 InternetOpenUrlA 0000468C InternetOpenA 0005030 MalService 0000503C Malservice 00005048 HGL345 00005050 http://www.malwareanalysisbook.com 00005074 Internet Explorer 8.0
- 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 và 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 InternetOpenA và InternetOpenUrlA để 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
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 Internet Explorer 8.0 cố gắng truy cập www.malwareanalysisbook.com.
- Máy chủ đã phản hồi bằng mã trạng thái 301, chuyển hướng trình duyệt đến địa chỉ mới www.practicalmalwareanalysis.com.
- Trình duyệt tự động gửi yêu cầu đến địa chỉ mới.
- Máy chủ của www.practicalmalwareanalysis.com lại thông báo trang web đã chuyển hướng vĩnh viễn sang https://nostarch.com/malware.
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=
- Để 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=.
- Trình duyệt Internet Explorer 8.0 cố gắng truy cập www.malwareanalysisbook.com. Nhưng máy chủ đã phản hồi bằng mã trạng thái 301, chuyển hướng trình duyệt đến địa chỉ. mới www.practicalmalwareanalysis.com. Sau đó Trình duyệt tiếp tục tự động gửi yêu cầu đến địa chỉ mới đến khi nhận được phản hồi. Máy chủ của www.practicalmalwareanalysis.com phản hồi lại trang web đã chuyển hướng vĩnh viễn sang https://nostarch.com/malware.
5 Phân tích Mã (IDA Pro)
5.1 - Phân tích hàm main:
Kết quả phân tích hàm main
5.2 - Phân tích hàm API StartServiceCtrlDispatcherA
Kết quả phân tích hàm API StartServiceCtrlDispatcherA
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.
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 là 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:
- 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).
- 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.
- 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:
- 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).
- 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.
- 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.
- 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
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.
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.
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.
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.
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.