Introduction
Trong thực tế, ta sẽ cần phải giới hạn lại những hành động mà malware sẽ thực hiện do hành động càng nhiều thì càng dễ bị phát hiện bởi các hệ thống giám sát.
Để triển khai điều, chúng ta sẽ sử dụng các đối tượng đồng bộ hóa của Windows chẳng hạn như mutex, semaphore và event. Các đối tượng này giúp điều phối việc truy cập vào các tài nguyên dùng chung giữa các thread hoặc process nhằm ngăn chặn xung đột hoặc race condition.
Semaphore
Là một cơ chế đồng bộ hóa sử dụng một giá trị trong bộ nhớ để kiểm soát quyền truy cập vào tài nguyên chia sẻ. Có 2 loại semaphore:
- Binary: có hai giá trị là 1 và 0, lần lượt tương ứng với trạng thái khả dụng và không khả dụng của tài nguyên.
- Counting: có giá trị
n
lớn hơn 1, đại diện cho số lượng tài nguyên khả dụng chon
tiến trình cùng truy cập.
Để kiểm soát quá trình thực thi, mỗi khi payload được chạy, ta sẽ tạo một named semaphore (semaphore có tên). Nếu đây là lần đầu tiên malware được thực thi, named semaphore sẽ được tạo và payload sẽ tiếp tục chạy. Ngược lại, nếu một tiến trình khác của malware khởi chạy, semaphore sẽ không được tạo do đã tồn tại một semaphore cùng tên. Điều này cho thấy payload đang hoạt động và việc thực thi sẽ được ngăn chặn nhằm tránh sự trùng lặp.
Để tạo ra semaphore có tên, ta sẽ dùng hàm CreateSemaphoreA
. Nếu semaphore có cùng tên đã được tạo ra, CreateSemaphoreA
sẽ trả về handle đến semaphore đó và GetLastError
sẽ trả về ERROR_ALREADY_EXISTS
.
HANDLE hSemaphore = CreateSemaphoreA(NULL, 10, 10, "ControlString");
if (hSemaphore != NULL && GetLastError() == ERROR_ALREADY_EXISTS)
// Payload is already running
else
// Payload is not running
Mutexes
Cũng là một cơ chế đồng bộ giống như semaphore. Mutex có 2 trạng thái là khóa và bị khóa.
Khi một thread cố gắng truy cập vào một tài nguyên chia sẻ, nó sẽ cần phải kiểm tra trạng thái của mutex. Nếu như mutex bị khóa, thread đó cần phải chờ cho đến khi mutex được mở khóa. Trong trường hợp mutex không bị khóa, thread cần khóa mutex rồi thực hiện những tác vụ cần thiết ở trên tài nguyên chia sẻ và mở khóa mutex khi hoàn tất.
Về sự khác biệt giữa mutex và binary semaphore
Một cách tổng quát, mutex có khái niệm sở hữu: chỉ có thread nào
lock
mutex thì mới có thểunlock
mutex. Đối với semaphore thì ngược lại: bất kỳ thread nào cũng có thểsignal
(release
hoặcup
) hoặcwait
(acquire
hoặcdown
). Do không có tính sở hữu, semaphore (kể cả counting semaphore) thường được dùng cho việc giao tiếp giữa các thread.Xem thêm: Mutex vs Semaphore - GeeksforGeeks
Để tạo ra một mutex có tên, ta có thể dùng hàm CreateMutexA
của Windows API:
HANDLE hMutex = CreateMutexA(NULL, FALSE, "ControlString");
if (hMutex != NULL && GetLastError() == ERROR_ALREADY_EXISTS)
// Payload is already running
else
// Payload is not running
Events
Tương tự, event là một cơ chế đồng bộ giúp điều phối việc thực thi giữa các thread và tiến trình. Event có 2 loại là tự động và thủ công. Event tự động xảy ra khi bị trigger bởi các điều kiện cụ thể chẳng hạn như khi bộ đếm thời gian kết thúc. Trong khi đó, event thủ công cần phải được set hoặc reset một cách tường minh.
Để tạo ra event, ta có thể dùng hàm CreateEventA
như sau:
HANDLE hEvent = CreateEventA(NULL, FALSE, FALSE, "ControlString");
if (hEvent != NULL && GetLastError() == ERROR_ALREADY_EXISTS)
// Payload is already running
else
// Payload is not running
Demo
Dưới đây là các minh họa cho việc sử dụng các cơ chế đồng bộ khác nhau để đảm bảo payload của malware chỉ được thực hiện 1 lần duy nhất mặc cho có nhiều tiến trình được chạy.
Sử dụng semaphore:
Sử dụng mutex:
Sử dụng event: