SLEEPWALKER: Backdoor Thụ Động Chỉ "Thức Giấc" Trước Đúng Một Gói Tin, Mang Ngôn Ngữ Bytecode Riêng, Ẩn Mình Trong ESET Management Agent

Tổng Quan
Ngày 24/08/2026, nhà nghiên cứu malware độc lập Dominik Reichel (cựu nhà nghiên cứu tại Palo Alto Networks Unit 42) công bố trên blog cá nhân (r136a1.dev) một phân tích cực kỳ chi tiết về SLEEPWALKER — một backdoor Windows trước đây chưa từng được ghi nhận công khai.
SLEEPWALKER là một backdoor thụ động (passive backdoor) theo đúng nghĩa đen: nó không tự động "gọi về" máy chủ điều khiển, không mang sẵn payload giai đoạn hai, và không có bất kỳ domain, địa chỉ IP hay URL nào được hardcode trong tệp. Nó nằm im hoàn toàn trong bộ nhớ cho đến khi một gói tin mạng được chế tạo đặc biệt (magic packet) chạm tới máy — chỉ khi đó nó mới giải mã và thực thi một "chương trình nhiệm vụ" do kẻ tấn công gửi tới.
Điểm khiến SLEEPWALKER đáng chú ý về mặt kỹ thuật không chỉ nằm ở cơ chế "magic packet" — vốn đã từng xuất hiện ở các backdoor Linux như BPFDoor mà nhóm Red Menshen sử dụng trong mạng viễn thông — mà ở việc chương trình nhiệm vụ đó không phải lệnh văn bản dễ đọc, mà là bytecode viết theo một ngôn ngữ lệnh do chính backdoor tự thiết kế, gồm 23 chỉ thị. Điều này có nghĩa là khôi phục được khóa mã hóa vẫn chưa đủ để hiểu lệnh — người phân tích còn phải dịch ngược (reverse-engineer) toàn bộ định dạng ngôn ngữ riêng đó, một định dạng không tồn tại ở bất kỳ nơi nào khác ngoài chính tệp này.
Mẫu được phân tích là một DLL Windows 64-bit chưa ký số, được thiết kế để side-load vào ERAAgent.exe — tệp thực thi của ESET Management Agent — và giả mạo dpapi.dll của Microsoft.
Lưu ý quan trọng về bối cảnh: Đây là phân tích dựa trên một mẫu binary duy nhất, không kèm ngữ cảnh thu thập (collection context). Reichel không thể xác định nạn nhân, ngành, quốc gia bị ảnh hưởng, hay thậm chí liệu mẫu này đã từng được triển khai trong thực tế hay chưa. Đây không phải báo cáo về một chiến dịch đang diễn ra, mà là một phân tích kỹ thuật sâu về năng lực của một công cụ được phát hiện qua việc rà soát backlog mẫu cũ. Tính đến ngày 26/08, ESET chưa phát hành khuyến cáo hay tuyên bố công khai nào về mã độc này.
Đôi Nét Về Bối Cảnh Phát Hiện Và Đánh Giá Vận Hành
Vì không có threat actor nào được xác định, phần này tổng hợp bối cảnh phát hiện và đánh giá về đặc điểm của chiến dịch (nếu có) đứng sau công cụ này — không phải một hồ sơ threat actor theo nghĩa thông thường.
| Thuộc tính | Chi tiết |
|---|---|
| Người phát hiện | Dominik Reichel — nhà nghiên cứu độc lập, cựu nhà nghiên cứu malware tại Palo Alto Networks Unit 42 |
| Bối cảnh phát hiện | Tìm thấy khi rà soát lại backlog mẫu cũ, sau khi mất quyền truy cập VirusTotal Intelligence đầu năm |
| Attribution (quy kết) | Không xác định được — Reichel không tìm thấy mã nguồn nào tương tự trong những gì ông từng phân tích trước đây |
| Đánh giá về tính chất vận hành | Cách tiếp cận nhất quán với một hoạt động có mục tiêu cụ thể, được đầu tư nguồn lực tốt, hơn là một cuộc tấn công mang tính cơ hội |
| Cơ sở của đánh giá trên | Dựa trên một binary duy nhất, không có ngữ cảnh thu thập đi kèm — đây là giới hạn quan trọng cần lưu ý |
| Nạn nhân / ngành / quốc gia | Không xác định được |
| Đã từng triển khai thực tế? | Không xác định được — không có bằng chứng nào trong mẫu cho thấy nó đã hoạt động ngoài thực tế |
| Thời gian biên dịch mẫu | 10/06/2024 09:18:27 UTC — cho thấy mẫu có thể đã tồn tại khá lâu trước khi bị phát hiện |
| Độ phủ phát hiện tại thời điểm công bố | Thấp (theo đánh giá của Reichel, không nêu cơ sở cụ thể) |
Phân Tích Kĩ Thuật
1. Đặc điểm tệp và cách ngụy trang
Mẫu là một DLL Windows 64-bit chưa ký số, dung lượng 59.904 byte:
SHA-256: d347170752a28e2b8c4b8b9f3cab2e3a6541ba11682c94498d26eb9002779d60
SHA-1: 2ec8aa9661a33bccc002150ce1ed02d90c3986ff
MD5: 2318327b29bb1c0e2d2b5f0211fc7fac
Imphash: 4e2dbfa7e3efd4cca2f3662797df9735
Để hoàn thiện lớp ngụy trang, tệp mang version resource sao chép từ ESET Management Agent thật: CompanyName "ESET", ProductName "ESET Management Agent", FileDescription "ESET Management Agent Module", OriginalFilename "dpapi.dll", phiên bản 11.2.2076.0.
Tệp export đúng tên và đúng 7 hàm mà dpapi.dll thật của Windows cung cấp: CryptProtectDataNoUI, CryptProtectMemory, CryptResetMachineCredentials, CryptUnprotectDataNoUI, CryptUnprotectMemory, CryptUpdateProtectedState, và iCryptIdentifyProtection. Mỗi hàm chỉ là một stub nhỏ nhảy qua một bảng con trỏ ban đầu trống rỗng. Lần đầu tiên bất kỳ hàm nào trong 7 hàm này được gọi, một bộ resolver dùng chung sẽ cố nạp một tệp tên dpapisvc.dll — một cái tên không hề thuộc về bất kỳ thành phần Windows thật nào (tên gần giống nhất trên hệ thống thật là dpapisrv.dll, một tệp hoàn toàn khác, chỉ export 2 hàm mở rộng LSA). Nếu việc nạp thất bại, resolver sẽ thoát toàn bộ tiến trình chủ, thay vì chỉ để lệnh gọi đó thất bại đơn lẻ — một chi tiết thiết kế đáng chú ý, có thể gây crash cho chính ESET Management Agent nếu điều kiện này xảy ra.
Lần gọi đầu tiên đó cũng âm thầm chạy lại toàn bộ chuỗi kiểm tra khởi động của backdoor — cho nó cơ hội thứ hai để "thức dậy" nếu lần đầu bị cản trở.
2. Trình tự khởi tạo và khởi động
Trước khi làm bất cứ điều gì, DLL kiểm tra tên tiến trình đã nạp nó. Nếu tiến trình đó không tên ERAAgent.exe, DLL vẫn ở trạng thái không hoạt động — nghĩa là nó sẽ không chạy trong debugger, sandbox, hay bất kỳ chương trình nào khác trừ khi chương trình đó mang đúng cái tên này. Sau khi vượt qua kiểm tra, một chuỗi bước ngắn đưa backdoor vào hoạt động: khởi động một luồng nền riêng biệt, cấp phát một vùng nhớ 128 KB dùng để lắp ráp các chương trình gửi tới theo nhiều phần, giải mã một chỉ thị duy nhất được lưu sẵn trong tệp, chuẩn bị hệ thống mạng và giao chỉ thị đã giải mã đó cho bộ thông dịch nội bộ.
Có hai đường dẫn độc lập cùng dẫn tới chuỗi khởi động này: (1) DLL được nạp vào ERAAgent.exe qua DllMain, và (2) lần gọi đầu tiên tới bất kỳ hàm nào trong 7 hàm DPAPI được forward. Không đường dẫn nào kiểm tra xem đường dẫn kia đã chạy hay chưa — đây là gốc rễ của một vấn đề "worker trùng lặp" tiềm ẩn trong thiết kế.
Chuỗi ERAAgent.exe dùng để kiểm tra, cùng với ba tên hàm mà tệp không hề liệt kê trong danh sách import thông thường (VirtualProtect để chạy shellcode, SetSecurityDescriptorDacl cho quyền pipe lỏng lẻo, và CryptGenRandom cho các khoảng nghỉ ngẫu nhiên) — đều không được lưu dưới dạng văn bản đọc được, mà được dựng lại từ một dãy con số ngay khi chạy.
3. Không tự động "gọi về" — không có máy chủ C2 cố định
Đây là đặc điểm cốt lõi định hình toàn bộ thiết kế của SLEEPWALKER. Sau khi xác nhận tiến trình chủ đúng tên, phần bootstrap nhúng sẵn không thực hiện bất kỳ kết nối ra ngoài nào. Thay vào đó, nó đưa card mạng vào chế độ promiscuous — cho phép nhìn thấy mọi gói tin đi qua, không chỉ những gói địa chỉ đến chính nó — rồi kiểm tra từng gói theo một khuôn mẫu cụ thể:
| Bước | Kiểm tra | Nếu thất bại |
|---|---|---|
| 1 | Gói tin dài ít nhất 48 byte | Bỏ qua |
| 2 | XOR hai giá trị 16-bit cuối của gói, sau đó XOR kết quả với 0xAAAA để có độ dài ứng viên |
— |
| 3 | Độ dài ứng viên nằm trong khoảng hợp lệ | Bỏ qua |
| 4 | Cặp byte tại vị trí (độ dài gói trừ độ dài ứng viên) bằng tổng, không phải XOR, của hai giá trị cuối trên | Bỏ qua |
| 5 | Khối dữ liệu mà độ dài ứng viên trỏ tới vượt qua kiểm tra CRC-32 riêng | Bỏ qua |
| 6 | Giải mã bằng AES-256-CCM và xử lý kết quả như một lệnh | — |
Toàn bộ quy trình này chạy trên nội dung thô của gói tin, trước cả khi Windows phân loại đó là gói TCP, UDP hay loại nào khác — nên trigger có thể "đi nhờ" bên trong gần như bất kỳ loại lưu lượng IP nào. Backdoor theo dõi tối đa 8 giao diện mạng cùng lúc, bỏ qua loopback. Sau một lần kích hoạt thành công, nó chờ ít nhất 3 giây trước khi chấp nhận trigger tiếp theo.
Vì backdoor không bao giờ chủ động gửi gì ra ngoài và không mở cổng lắng nghe rõ ràng nào theo mặc định, các công cụ giám sát kết nối tới hạ tầng độc hại đã biết hoặc lưu lượng ra bất thường sẽ không thấy bất cứ điều gì khả nghi. Thời điểm duy nhất nó "lộ diện" trên mạng là khi kẻ vận hành gửi gói trigger. Một máy hoàn toàn có thể đã bị xâm phạm bởi backdoor này trong khi không tạo ra bất kỳ dấu hiệu nào để công cụ giám sát mạng gắn cờ.
4. Xác thực và mã hóa lệnh
Mọi lệnh gửi tới backdoor được mã hóa bằng AES-256-CCM — vừa che giấu nội dung, vừa xác thực rằng thông điệp không bị thay đổi. Cấu trúc gồm: nonce 12 byte thay đổi mỗi lần, giá trị kiểm tra 16 byte, rồi tới dữ liệu mã hóa. Riêng gói trigger thô còn mang thêm một checksum CRC-32 độc lập để loại bỏ nhanh các gói không khớp mẫu trước khi tốn công giải mã.
Reichel đã khôi phục được khóa mã hóa và nonce cấu hình trong quá trình phân tích:
Khóa AES-256: 0x746531ff378dbb4bb51d2aa2b1d38d905350a959583186baf4c690f5f316b3ae
Nonce cấu hình: 0x3a6d357fb9bc51eacc8b8509
Toàn bộ mã hóa dựa trên một bản sao mbedTLS (thư viện mã hóa mã nguồn mở) được liên kết tĩnh sẵn trong tệp, chứ không nạp thêm gì khi chạy.
| Nội dung | Hướng | Bảo vệ |
|---|---|---|
| Chương trình nhiệm vụ qua trigger thô, TCP, UDP, named pipe, VMCI | Vào SLEEPWALKER | AES-256-CCM |
| Chương trình nhiệm vụ trong nhãn DNS | Vào SLEEPWALKER | Base32 chồng lên AES-256-CCM |
Chương trình tải từ tệp (RUN_FILE_SCRIPT) |
Cục bộ | AES-256-CCM |
Chương trình lồng trong CRON_SCHEDULE |
Nội bộ | AES-256-CCM, sau đó XOR trong bộ nhớ giữa các lần chạy |
Dữ liệu gửi qua TCP_SEND/UDP_SEND/ICMP_SEND/PIPE_SEND |
Ra khỏi SLEEPWALKER | Không tự động mã hóa — gửi nguyên trạng như operator cung cấp |
5. Định dạng Bytecode — "Ngôn Ngữ Lập Trình" Riêng Của Backdoor
Sau khi giải mã, một lệnh không phải văn bản hay một tài liệu cấu hình — mà là một chuỗi byte thô chỉ có ý nghĩa khi đọc theo đúng thứ tự quy định. Đây là lớp bảo vệ thứ hai, đặt sau lớp mã hóa: khôi phục khóa chỉ cho ra một luồng opcode ở một định dạng không tồn tại ở bất kỳ nơi nào khác ngoài chính tệp này — muốn hiểu được lệnh, người phân tích còn phải dịch ngược toàn bộ ngôn ngữ đó.
Mỗi chỉ thị bắt đầu bằng một byte xác định loại (trong 23 loại). Số liệu có kích thước cố định (như thời gian chờ) được ghi bằng số byte quy định, byte có trọng số cao nhất trước. Văn bản hoặc khối dữ liệu có độ dài tùy ý được ghi dưới dạng: một số đếm nhỏ cho biết bao nhiêu byte theo sau, rồi tới chính các byte đó.
Chỉ thị duy nhất thực sự được tìm thấy lưu sẵn trong tệp là SNIFF_MAGIC_PACKET (opcode 0x87), toàn bộ chỉ dài 5 byte, mang ý nghĩa: "theo dõi mọi giao diện mạng, không giới hạn thời gian, chờ gói trigger." Đây cũng là toàn bộ nội dung hữu ích của cấu hình nhúng sẵn trong tệp — mọi năng lực khác của backdoor chỉ tồn tại như một khả năng của ngôn ngữ, chờ được kích hoạt qua mạng sau này.
Một số chỉ thị mang cả một chương trình con bên trong làm tham số. Chỉ thị CRON_SCHEDULE (lập lịch) là ví dụ rõ nhất: chương trình con bên trong nó được mã hóa XOR tạm thời trong bộ nhớ giữa các lần chạy theo lịch, chỉ được giải mã (decrypt → chạy → mã hóa lại) đúng vào thời điểm thực thi. Đây là lớp bảo vệ XOR chỉ riêng có ở CRON_SCHEDULE, nằm bên trong lớp bọc AES-256-CCM chung của mọi chương trình nhiệm vụ.
6. Bảng Tham Chiếu Ngôn Ngữ Lệnh — 23 Chỉ Thị
| Chỉ thị | Chức năng |
|---|---|
| Điều khiển cơ bản | |
EXIT (0x06) |
Đặt cờ dừng toàn tiến trình — dừng mọi chương trình đang chạy, không chỉ chương trình chứa lệnh này |
SPAWN_THREAD_SCRIPT (0x0B) |
Khởi chạy một chương trình con song song trong luồng riêng |
| Thời gian và lập lịch | |
SLEEP_SECONDS (0x0C) |
Tạm dừng một số giây cố định |
SLEEP_RANDOM_SECONDS (0x0D) |
Tạm dừng ngẫu nhiên tới một giới hạn — tạo độ jitter |
CRON_SCHEDULE (0x0E) |
So khớp phút/giờ/ngày/thứ hiện tại với 4 bitmask lưu sẵn, chạy chương trình con khi khớp cả 4 |
REPEAT_N (0x0F) |
Chạy một chương trình con lặp lại số lần cố định |
LOOP_FOREVER (0x10) |
Chạy một chương trình con lặp vô hạn tới khi bị dừng |
| Gửi dữ liệu | |
TCP_SEND (0x29) |
Mở kết nối TCP, gửi dữ liệu, không chờ phản hồi (hỗ trợ đích VMCI) |
UDP_SEND (0x2A) |
Gửi một khối dữ liệu UDP, không chờ phản hồi (hỗ trợ đích VMCI) |
ICMP_SEND (0x2B) |
Giấu dữ liệu bên trong gói ping (ICMP echo request) |
PIPE_SEND (0x2C) |
Ghi dữ liệu vào named pipe Windows trên máy khác, có thể kèm đăng nhập bằng username/password |
| Nhận nhiệm vụ đầu vào | |
TCP_CONNECT_RECV (0x6F) |
Chủ động kết nối ra ngoài rồi chờ nhận chương trình tiếp theo (hỗ trợ đích VMCI) |
TCP_LISTEN_RECV (0x70) |
Mở cổng TCP, chờ một kết nối, nhận chương trình từ người kết nối tới |
UDP_BIND_RECV (0x73) |
Mở cổng UDP, chờ nhận một khối dữ liệu làm chương trình tiếp theo |
PIPE_CLIENT_RECV (0x7D) |
Kết nối tới named pipe trên máy khác, chờ nhận chương trình tiếp theo |
PIPE_SERVER_RECV (0x7E) |
Tạo named pipe cục bộ, chờ kết nối, nhận chương trình từ người kết nối tới |
| Lắp ráp và thực thi chương trình | |
STAGE_WRITE (0x32) |
Ghi một phần của chương trình lớn hơn vào vùng nhớ dùng chung 128 KB, tại vị trí chỉ định — cho phép lắp ráp từng phần không theo thứ tự |
STAGE_VERIFY_EXEC (0x33) |
So khớp fingerprint SHA-256 của các phần đã thu thập với giá trị kèm theo chỉ thị; chỉ chạy khi khớp chính xác |
DECOMPRESS_RUN (0x1F) |
Giải nén một chương trình đã nén (LZMA) về kích thước gốc rồi chạy |
RUN_SHELLCODE (0x65) |
Chỉ thị duy nhất trong ngôn ngữ giao byte trực tiếp cho CPU — chạy mã máy thô trong bộ nhớ, chuyển vùng nhớ từ ghi-được sang thực-thi-được ngay trước khi gọi |
RUN_FILE_SCRIPT (0x66) |
Đọc một tệp đã có sẵn trên đĩa, giải mã giống mọi kênh khác, rồi chạy |
| Phát hiện trigger | |
SNIFF_MAGIC_PACKET (0x87) |
Theo dõi một hoặc mọi giao diện mạng chờ gói trigger thô — chỉ thị thực sự có trong mẫu đã phân tích |
SNIFF_MAGIC_PACKET_DNS (0x88) |
Giống hệt trên nhưng đồng thời bật thêm trigger qua DNS — không active trong mẫu đã phân tích |
Một chi tiết đáng chú ý: không chỉ thị nào trong toàn bộ 23 chỉ thị ghi tệp xuống đĩa. Bất cứ thứ gì backdoor kỳ vọng tìm thấy sẵn trên máy (như tệp mà RUN_FILE_SCRIPT đọc) phải được đặt vào đó bởi một thành phần khác ngoài chính công cụ này — chỉ có RUN_SHELLCODE mới có thể tạo tệp mới, và phải thông qua chính đoạn mã máy được giao.
7. Kênh Kích Hoạt Thay Thế Và 6 Giao Thức Truyền Tải
Năm trong số các chỉ thị mạng (TCP_SEND, UDP_SEND, TCP_CONNECT_RECV, TCP_LISTEN_RECV, UDP_BIND_RECV) kiểm tra xem địa chỉ được cấp có bắt đầu bằng tiền tố vm: hay không — nếu có, chúng chuyển sang dùng kênh VMCI (Virtual Machine Communication Interface) của VMware thay vì địa chỉ mạng thông thường. Đây là kênh giao tiếp nội bộ giữa máy ảo và host vật lý, đi qua tầng ảo hóa chứ không qua card mạng vật lý — nghĩa là một bản ghi packet capture giữa hai máy sẽ hoàn toàn bỏ sót lưu lượng này. Nhóm UNC3886 (APT liên hệ Trung Quốc) từng dùng chính kỹ thuật socket VMCI để triển khai hai backdoor mang tên VirtualPita và VirtualPie, phục vụ di chuyển ngang và duy trì hiện diện giữa các host ESXi bị xâm phạm và máy ảo khách của chúng — khai thác kèm lỗ hổng zero-day CVE-2023-20867 (lỗi bypass xác thực trong VMware Tools, cho phép thực thi lệnh đặc quyền trên máy ảo khách mà không cần xác thực và không sinh log), theo tài liệu công bố tháng 06/2023 của Mandiant.
Còn có một kênh trigger thứ hai ẩn trong các truy vấn DNS trông bình thường — tuy không phải kênh đang active trong mẫu được phân tích (cần opcode 0x88 thay vì 0x87). Cơ chế: mỗi nhãn DNS (mỗi phần cách nhau bởi dấu chấm trong tên miền) mang một định dạng riêng — một ký tự đánh dấu ở đầu, một đoạn văn bản mã hóa Base32 ở giữa, và một ký tự đánh dấu ở cuối. Hai ký tự đánh dấu này mã hóa một checksum CRC-8 của đoạn giữa, cho phép backdoor phân biệt một nhãn hợp lệ với một nhãn DNS bình thường (như example hay com) mà không tốn nhiều chi phí tính toán để loại bỏ. Cách tiếp cận này cho phép lệnh "đi nhờ" qua các mạng chỉ cho phép lưu lượng DNS đi ra — điều mà rất nhiều mạng vẫn cho phép ngay cả khi hầu hết lưu lượng khác bị hạn chế.
Gộp lại, các chỉ thị mạng của SLEEPWALKER sử dụng 6 giao thức truyền tải nền tảng:
| Giao thức | Cơ chế | Ghi chú |
|---|---|---|
| TCP | socket/connect/listen/accept | Cả client và server |
| UDP | sendto/recvfrom | Gửi một lần và bind-chờ-nhận |
| ICMP | IcmpSendEcho |
Dữ liệu giấu trong payload gói ping |
| SMB named pipe | CreateNamedPipeW/CreateFileW |
Có thể mount share từ xa bằng credential được cấp — phục vụ di chuyển ngang |
| VMware VMCI | Address family qua \\.\VMCI |
Kênh guest-to-host hoặc guest-to-guest, không chạm card mạng vật lý |
| Raw/Promiscuous | Raw socket ở chế độ promiscuous | Cách nhận gói trigger thô đã mô tả ở trên |
8. Khả Năng Vươn Tới Của Kẻ Tấn Công (Network Reachability)
Đây là một trong những đóng góp phân tích giá trị nhất của Reichel: phân biệt rõ việc gửi lệnh đầu tiên tới một backdoor đang "ngủ" khác với tầm với của một tác vụ đang chạy ra sao.
| Kênh | Từ Internet | Qua Firewall/NAT | Trong mạng nội bộ | Máy đích |
|---|---|---|---|---|
| Trigger thô (lệnh đầu tiên) | Bị chặn | Bị chặn | Tới được | Tới được |
| Trigger DNS (đã lập trình, chưa active trong mẫu này) | Tới được | Tới được | Tới được | Tới được |
| VMCI (kênh guest/host) | Không áp dụng | Không áp dụng | Không áp dụng | Chỉ trong cùng host VMware |
| Kênh chủ động kết nối ra (sau trigger) | Tới được | Tới được | Tới được | Tới được |
| Kênh chờ kết nối vào (sau trigger) | Bị chặn | Bị chặn | Tới được | Tới được |
Việc gửi lệnh đầu tiên phụ thuộc vào việc một gói tin bình thường thực sự chạm được tới giao diện mạng mà backdoor đang theo dõi. Một firewall biên hoặc NAT gateway thông thường chặn lưu lượng thô, không mời gọi từ Internet mở — nên trong thực tế, kẻ vận hành cần đã có sẵn một vị trí trên hoặc gần mạng mục tiêu, hoặc thuộc một trong các ngoại lệ: máy có IP công khai, có luật NAT/port-forward trỏ tới, hoặc — ngoại lệ ít rõ ràng hơn — máy đó định tuyến hoặc chuyển tiếp lưu lượng cho máy khác (gateway, VPN server, host bắc cầu hai phân đoạn mạng). Vì backdoor bắt mọi thứ đi qua giao diện chứ không chỉ gói địa chỉ tới chính nó, một gói trigger nhắm tới một máy hoàn toàn khác vẫn có thể bị một gateway/VPN server "nhìn thấy" và kích hoạt.
Kênh DNS tồn tại trong binary như một giải pháp cho vấn đề tiếp cận này — nhưng không phải cơ chế đang được dùng trong mẫu đã phân tích. Một khi lệnh đầu tiên đã "hạ cánh," phần lớn những gì tác vụ có thể làm tiếp theo lại hướng ra ngoài thay vì cần ai đó tiếp cận vào trong — nên kẻ vận hành không cần giữ vị trí mạng ban đầu đó cho mọi hành động về sau.
Việc triển khai "cưỡi" trong ERAAgent.exe gợi ý mục tiêu thực tế là một endpoint hoặc server Windows 64-bit có cài ESET Management Agent — loại máy thường nằm sau firewall và NAT gateway, không lộ trực tiếp ra Internet. Đây chính xác là bối cảnh mà trigger thô một mình sẽ khó vươn tới, khiến việc mẫu phân tích dựa hoàn toàn vào trigger thô (không bật kênh DNS dự phòng) trở nên đáng chú ý — gợi ý kẻ vận hành đã có sẵn một vị trí nào đó trên hoặc cạnh mạng mục tiêu, hơn là một kẻ lạ trên Internet mở không có gì trong tay.
9. Thay Đổi Cấu Hình Host
Để cho phép truy cập named-pipe không xác thực, backdoor chủ động thay đổi hai cài đặt bảo mật của máy: bật EveryoneIncludesAnonymous (khiến quyền cấp cho "Everyone" áp dụng luôn cho token đăng nhập ẩn danh), và thêm tên pipe của nó vào NullSessionPipes (cho phép pipe đó được truy cập mà không cần username/password). Nó cũng tạo pipe với quyền cho phép cả "Everyone" và "Anonymous Logon" kết nối.
Chi tiết đáng chú ý: cơ chế dọn dẹp (cleanup) của backdoor có lỗi — nó ghi nhớ liệu chính nó có ghi thành công vào NullSessionPipes hay không, chứ không phải liệu entry đó đã tồn tại từ trước. Điều này có nghĩa quá trình "dọn dẹp" có thể xóa nhầm một entry hợp pháp đã có sẵn từ trước khi bị nhiễm.
Không có bất kỳ mã leo quyền nào trong tệp. Không nơi nào trong file cố gắng vượt qua User Account Control hay giành quyền cao hơn mức đang có. Việc sửa hai khóa registry trên đã đòi hỏi quyền local administrator có sẵn. Backdoor dựa hoàn toàn vào ngữ cảnh bảo mật của tiến trình chủ, chứ không tự mình giành lấy quyền đó. Đây là điểm mấu chốt xác định bản chất của SLEEPWALKER: nó là một implant hậu-xâm-nhập (post-compromise), không phải điểm xâm nhập ban đầu. Cách kẻ vận hành lần đầu tiếp cận được máy và ghi DLL độc hại vào thư mục được bảo vệ đó vẫn là một ẩn số hoàn toàn.
10. Một Góc Nhìn Đáng Chú Ý: Quy Trình Phân Tích Có AI Hỗ Trợ
Reichel dành hẳn một phần trong bài viết để mô tả phương pháp luận: ông thực hiện phân tích ban đầu hoàn toàn thủ công để giữ trải nghiệm thực hành, sau đó dùng nhiều mô hình AI frontier khác nhau để hỗ trợ xác minh và đào sâu phân tích chi tiết — thử nghiệm với Claude Opus 5 và GPT-5.6-Sol (dùng thêm Opus 4.8 và Sonnet 5 khi giới hạn an toàn khiến Opus 5 không thể tiếp tục). Ông loại Claude Fable khỏi thử nghiệm vì bộ lọc an toàn của mô hình này chặn cả những câu hỏi tổng quát có khả năng ứng dụng lưỡng dụng (dual-use).
Kết quả giữa các mô hình nhìn chung tương đồng, không có mô hình nào vượt trội nhất quán — ngoại trừ một điểm khác biệt đáng chú ý: khi phân tích sự khác nhau giữa SNIFF_MAGIC_PACKET và SNIFF_MAGIC_PACKET_DNS, Claude mô tả hai lệnh này là "giống hệt nhau về chức năng" trong cả 3 lần thử — một kết luận sai — trong khi GPT xác định đúng sự khác biệt quan trọng (opcode 0x88 bật thêm trigger DNS) ngay lần thử đầu tiên.
Reichel cũng ghi nhận: giới hạn sử dụng theo tuần của GPT dễ làm việc hơn giới hạn theo giờ của Claude trong các phiên reverse-engineering kéo dài; không lần thử nào với GPT bị gián đoạn bởi từ chối an toàn, trong khi ông gặp từ chối trong mọi lần chạy phân tích malware với Claude Opus hoặc Sonnet — đôi khi ngay từ đầu, đôi khi sau khi đã tiến triển đáng kể — dù ông đã được chấp nhận vào chương trình xác minh dành cho nhà nghiên cứu bảo mật của Anthropic. Ông đề xuất Anthropic nên siết chặt khâu xét duyệt đầu vào cho các chương trình này, đổi lại nới lỏng hạn chế cho những nhà nghiên cứu đã được duyệt khi thực hiện reverse-engineering hợp pháp.
Nhận định chung của ông: AI là công cụ mạnh để tăng tốc phân tích malware — những gì trước đây mất hàng giờ, hàng ngày hay hàng tuần giờ có thể hoàn thành nhanh hơn nhiều — nhưng không loại bỏ nhu cầu về chuyên môn kỹ thuật hay việc xác minh cẩn thận từng kết quả.
Những Gì Vẫn Còn Là Ẩn Số
Đây là phần thể hiện rõ nhất tính nghiêm túc về mặt epistemics của bản phân tích gốc, và cần được giữ nguyên tinh thần khi đưa vào báo cáo:
Nguồn gốc mẫu và nạn nhân: Không có ngữ cảnh thu thập nào gắn tệp này với một cuộc xâm nhập đã xác nhận — không thể xác định nạn nhân, ngành, quốc gia hay tổ chức bị ảnh hưởng. Yêu cầu chạy trong
ERAAgent.exechỉ cho biết mục tiêu khả dĩ là một endpoint/server Windows 64-bit có cài ESET Management Agent, không cho biết đó là máy trạm, server, gateway, VPN, hay máy ảo VMware. Không có bằng chứng nào cho thấy mẫu từng được triển khai thành công.Truy cập ban đầu và cách phát tán: DLL side-loading giải thích cách SLEEPWALKER thực thi và duy trì sau khi đã được đặt cạnh
ERAAgent.exe— không giải thích cách kẻ vận hành lần đầu xâm nhập môi trường, giành được quyền admin cần thiết, hay ghi DLL độc hại vào thư mục ứng dụng được bảo vệ đó. Không có dropper, installer, exploit, hay kỹ thuật truy cập ban đầu nào xuất hiện trong tệp này.Thành phần đi kèm và công cụ vận hành: Backdoor không thể tự cài đặt chính nó, và ngôn ngữ lệnh của nó không có cách chung nào để tạo ra các tệp mà nó kỳ vọng tìm thấy. Sự phụ thuộc chưa được giải quyết vào
dpapisvc.dllcó thể gợi ý một thành phần khác đặt một bản sao dpapi.dll thật đã đổi tên cạnh nó — nhưng không có tệp như vậy đi kèm mẫu này.Lệnh thực sự đã nhận: Chương trình nhiệm vụ được mã hóa duy nhất lưu trong mẫu chỉ khởi động bộ lắng nghe gói thô. Các chỉ thị còn lại mô tả năng lực, không phải hành vi đã quan sát được. Không có traffic trigger đã ghi lại, bộ nhớ từ máy bị nhiễm, hay tệp cục bộ liên quan, không có cách nào biết lệnh nào đã được gửi, payload nào đã chạy, dữ liệu gì đã bị thu thập, hay có di chuyển ngang xảy ra hay không.
Kênh thực sự đã sử dụng: Trigger DNS, VMCI, ICMP, named pipe và các giao thức khác đều đã được lập trình sẵn, nhưng sự hiện diện của chúng không chứng minh kẻ vận hành từng dùng chúng. Đặc biệt, hỗ trợ DNS không được bật trong phần bootstrap nhúng sẵn.
Hạ tầng và vị trí của kẻ vận hành: Không có server, domain, địa chỉ hay định danh operator nào hardcode. Trigger thô nghiêng về một kẻ vận hành đã có khả năng đưa gói tin lên hoặc qua mạng mục tiêu, nhưng mã nguồn không thể nói khả năng đó đến từ một máy bị xâm phạm khác, vị trí nội gián, hệ thống định tuyến, giao diện public-facing, hay đường nào khác.
Attribution, chiến dịch và mức độ lan rộng: Không có gì trong tệp xác định nhà phát triển hay kẻ vận hành. Reichel không tìm thấy mã liên quan nào hỗ trợ quy kết cho một nhóm đã biết, và một mẫu duy nhất này không thể xác định SLEEPWALKER đã được triển khai khi nào, rộng đến đâu, có biến thể khác hay không, hay có thuộc về một chiến dịch đang tiếp diễn hay không.
Bối Cảnh So Sánh: Không Phải Kỹ Thuật Chưa Từng Có Tiền Lệ
Các implant kích hoạt bằng "magic packet" đã từng xuất hiện trên Linux — điển hình là BPFDoor, được nhóm Red Menshen (liên hệ Trung Quốc) sử dụng bên trong mạng của các nhà mạng viễn thông, theo tài liệu của Rapid7. Điều khiến SLEEPWALKER khác biệt là sự kết hợp: một implant thụ động trên Windows, đánh thức bởi một gói tin duy nhất, hỗ trợ nhiều giao thức bí mật bao gồm kênh VMCI hiếm gặp, và triển khai qua side-loading vào một thành phần quản lý ESET đáng tin cậy.
Đáng chú ý, đây không phải lần đầu phần mềm của ESET bị lạm dụng cho side-loading: nhóm ToddyCat (APT liên hệ Trung Quốc, hoạt động từ ít nhất 2020, nhắm vào chính phủ và quốc phòng khu vực Châu Á - Thái Bình Dương) từng bị Kaspersky ghi nhận (04/2025) khai thác CVE-2024-11859 — một lỗ hổng DLL search-order hijacking có thật trong công cụ quét dòng lệnh của ESET (ecls), khiến nó nạp nhầm version.dll từ thư mục hiện tại thay vì thư mục hệ thống — để nạp một DLL độc hại mang tên TCESB (dựa trên công cụ mã nguồn mở EDRSandBlast, có khả năng vô hiệu hóa callback thông báo ở cấp kernel và dùng thêm kỹ thuật BYOVD qua driver Dell dễ tổn thương). Đây là hệ sinh thái phần mềm bảo mật của ESET liên tục thu hút sự quan tâm của nhiều nhóm tấn công khác nhau cho kỹ thuật side-loading, dù mỗi trường hợp khai thác một cơ chế riêng.
Điểm khác biệt quan trọng cần lưu ý: trường hợp TCESB/ToddyCat khai thác một lỗ hổng có CVE thật trong chính mã nguồn của ESET, và ESET đã phát hành bản vá vào tháng 01/2025. Ngược lại, theo phân tích của Reichel, cơ chế side-loading mà SLEEPWALKER dùng để nạp vào ERAAgent.exe dựa hoàn toàn vào hành vi thứ tự tìm kiếm DLL mặc định của Windows, chứ không khai thác một lỗ hổng cụ thể nào trong mã nguồn ESET — nên không có bản vá nào để chờ cho riêng trường hợp này. Phản ứng phù hợp khi xác nhận trùng khớp SLEEPWALKER là điều tra sự cố (incident response) và xây dựng lại máy (rebuild), không phải chờ nhà cung cấp phát hành bản vá.
Tóm Tắt Rủi Ro
| Chiều Rủi ro | Mức độ | Lý do |
|---|---|---|
| Khả năng ẩn mình trên mạng (Network Stealth) | Rất cao | Không beacon, không C2 cố định; công cụ giám sát lưu lượng ra/kết nối hạ tầng xấu không thấy gì bất thường |
| Độ tinh vi kỹ thuật | Cao | Ngôn ngữ bytecode tự thiết kế, mã hóa hai lớp, 6 giao thức truyền tải gồm cả kênh VMCI hiếm gặp |
| Mức độ xác nhận là mối đe dọa thực tế | Thấp / Chưa xác định | Một mẫu duy nhất, không nạn nhân xác nhận, không rõ đã từng triển khai hay chưa — cần đọc kết quả này với sự thận trọng phù hợp |
| Yêu cầu tiếp cận ban đầu | Cao | Cần quyền admin cục bộ sẵn có + khả năng đưa gói tin lên mạng mục tiêu; đây là implant hậu-xâm-nhập, không phải điểm vào |
| Tiềm năng di chuyển ngang | Trung bình-Cao | Named pipe với credential, cùng với việc chủ động làm yếu xác thực pipe trên host |
| Khả năng tồn tại lâu dài | Trung bình | Side-loading là cơ chế persistence duy nhất — tái nạp mỗi khi dịch vụ ESET Management Agent khởi động |
IOC & Artifacts
File Hashes
SHA-256: d347170752a28e2b8c4b8b9f3cab2e3a6541ba11682c94498d26eb9002779d60
SHA-1: 2ec8aa9661a33bccc002150ce1ed02d90c3986ff
MD5: 2318327b29bb1c0e2d2b5f0211fc7fac
Imphash: 4e2dbfa7e3efd4cca2f3662797df9735
Chỉ Dấu Trên Host
Một
dpapi.dllbất thường nằm cạnhERAAgent.exe.Một
dpapisvc.dllbất thường trong cùng thư mục (tên không thuộc về bất kỳ thành phần Windows thật nào).Khóa registry
EveryoneIncludesAnonymousđược đặt thành1.Một entry bất thường trong
NullSessionPipes.
Lưu ý quan trọng: hai giá trị registry trên chỉ có giá trị khi so sánh với baseline đã biết là sạch (known-good baseline) — bản thân chúng không phải bằng chứng chắc chắn của SLEEPWALKER.
Chi Tiết Kỹ Thuật Bổ Sung (phục vụ đối chiếu mẫu)
Khóa AES-256: 0x746531ff378dbb4bb51d2aa2b1d38d905350a959583186baf4c690f5f316b3ae
Nonce cấu hình: 0x3a6d357fb9bc51eacc8b8509
Thời gian biên dịch mẫu: 2024-06-10 09:18:27 UTC
Công Cụ Phát Hiện Do Tác Giả Công Bố
Reichel công bố kèm bài viết một luật YARA (khớp trên khóa AES-256 tĩnh, nonce cấu hình, đoạn mã kiểm tra magic-packet đặc trưng, và chuỗi dpapisvc.dll) cùng một script PowerShell chỉ-đọc (read-only) để quét trên diện rộng — kiểm tra sự hiện diện của dpapi.dll bất thường cạnh ERAAgent.exe, đối chiếu hash, và đọc hai giá trị registry nêu trên, trả về mã thoát (0 = sạch, 1 = cần rà soát thêm, 2 = trùng khớp xác nhận). Cả hai công cụ đều được tác giả xác minh trực tiếp trên mẫu đã phân tích trước khi công bố. Do luật YARA khớp một phần trên khóa AES tĩnh và mã đã biên dịch, một bản build lại với cấu hình compiler khác có thể phá vỡ khả năng khớp — cần diễn giải kết quả với sự thận trọng tương ứng.
Toàn văn luật YARA và script PowerShell không được tái tạo trong bài viết này — độc giả cần công cụ đầy đủ nên truy cập trực tiếp bài viết gốc của Reichel (xem phần Tham khảo).
MITRE ATT&CK Mapping
| Tactic | Technique ID | Technique Name | Mô tả trong SLEEPWALKER |
|---|---|---|---|
| Persistence | T1574.002 | Hijack Execution Flow: DLL Side-Loading | Cơ chế nạp và duy trì hiện diện duy nhất — side-load vào ERAAgent.exe |
| Defense Evasion | T1036.005 | Masquerading: Match Legitimate Name or Location | Giả tên dpapi.dll, sao chép version resource của ESET Management Agent |
| Defense Evasion | T1027 | Obfuscated Files or Information | Ngôn ngữ bytecode tự thiết kế + mã hóa AES-256-CCM hai lớp; chuỗi quan trọng dựng lại từ số tại runtime |
| Defense Evasion | T1140 | Deobfuscate/Decode Files or Information | Giải mã XOR tạm thời cho chương trình lồng trong CRON_SCHEDULE (decrypt–chạy–mã hóa lại) |
| Defense Evasion | T1556 | Modify Authentication Process | Bật EveryoneIncludesAnonymous, thêm pipe vào NullSessionPipes để cho phép truy cập không xác thực |
| Command and Control | T1205 | Traffic Signaling | Cơ chế "magic packet" cốt lõi — toàn bộ backdoor chỉ thức dậy khi nhận đúng một gói trigger |
| Command and Control | T1071.004 | Application Layer Protocol: DNS | Kênh trigger thứ hai qua truy vấn DNS (đã lập trình sẵn, chưa kích hoạt trong mẫu phân tích) |
| Command and Control | T1095 | Non-Application Layer Protocol | ICMP_SEND giấu dữ liệu trong gói ping; xử lý gói tin thô trước khi phân loại giao thức |
| Command and Control | T1132 | Data Encoding | Base32 cho nhãn DNS; định dạng bytecode riêng cho mọi kênh khác |
| Command and Control | — | (Không có ID chuẩn) | Kênh VMware VMCI — giao tiếp guest-host qua tầng ảo hóa, không qua card mạng vật lý |
| Lateral Movement | T1021.002 | Remote Services: SMB/Windows Admin Shares | PIPE_SEND/PIPE_CLIENT_RECV hỗ trợ xác thực bằng credential để di chuyển ngang |
| Command and Control | T1105 | Ingress Tool Transfer | STAGE_WRITE/STAGE_VERIFY_EXEC/DECOMPRESS_RUN — giao chương trình theo từng phần, xác minh SHA-256 trước khi chạy |
| Execution | T1106 | Native API | RUN_SHELLCODE gọi VirtualProtect rồi thực thi mã máy trực tiếp trong bộ nhớ |
| Defense Evasion | — | (Không có ID chuẩn) | Chỉ kiểm tra tên tiến trình chủ, không kiểm tra chữ ký/đường dẫn — vô tình né debugger/sandbox không mang đúng tên tiến trình |
Nhận Định Chuyên Gia
SLEEPWALKER đáng chú ý không chỉ vì kỹ thuật "magic packet" — kỹ thuật này đã có tiền lệ trên Linux qua các công cụ như BPFDoor — mà vì cách nó kết hợp nhiều lớp bảo vệ chồng lên nhau theo hướng ít thấy: một implant hoàn toàn thụ động, không hạ tầng C2 cố định, đóng gói lệnh trong một ngôn ngữ bytecode tự thiết kế thay vì định dạng lệnh thông thường, hỗ trợ 6 giao thức truyền tải gồm cả kênh VMCI vốn hiếm khi xuất hiện ngoài các nhóm APT có nguồn lực rất lớn (như UNC3886), và náu mình trong một thành phần quản lý bảo mật đáng tin cậy. Đây là mức độ đầu tư thiết kế thường chỉ thấy ở các công cụ dành cho hoạt động có mục tiêu cụ thể, không phải hàng hóa (commodity) rao bán rộng rãi.
Tuy nhiên, điều quan trọng nhất cần nhấn mạnh với đội ngũ phòng thủ là ranh giới giữa "năng lực kỹ thuật ấn tượng" và "mối đe dọa đã xác nhận." Đây là một mẫu binary duy nhất, không có nạn nhân, ngành, hay chiến dịch nào được xác nhận đứng sau nó. Bản thân tác giả phân tích — với sự trung thực đáng ghi nhận về mặt phương pháp luận — nhấn mạnh rằng gần như mọi khía cạnh về bối cảnh triển khai thực tế vẫn là ẩn số. Điều này không làm giảm giá trị của việc chuẩn bị phát hiện, nhưng đòi hỏi tổ chức phản ứng đúng mức: đây là tín hiệu để nâng cao năng lực săn tìm và sẵn sàng phát hiện (threat hunting readiness), không phải căn cứ để kích hoạt quy trình ứng phó sự cố khẩn cấp trên diện rộng.
Về mặt kỹ thuật thuần túy, có ba điểm phòng thủ nên rút ra: Thứ nhất, việc kết hợp mã hóa VÀ một định dạng lệnh riêng là một bước tiến so với các backdoor chỉ mã hóa lệnh dạng văn bản thông thường — khôi phục khóa không còn đủ để hiểu ý đồ của kẻ tấn công, kéo dài đáng kể thời gian phân tích pháp y. Thứ hai, thiết kế "chỉ kiểm tra tên tiến trình chủ" — dù đơn giản — lại hiệu quả bất ngờ trong việc né các công cụ sandbox và phân tích tự động không mô phỏng đúng tên tiến trình ERAAgent.exe. Thứ ba, việc backdoor chủ động làm yếu cấu hình bảo mật của chính hệ điều hành (EveryoneIncludesAnonymous, NullSessionPipes) để phục vụ mục đích riêng — kèm theo lỗi trong logic dọn dẹp có thể xóa nhầm cấu hình hợp pháp đã tồn tại từ trước — là một chi tiết dễ bị bỏ sót khi rà soát sau sự cố nếu không so sánh với baseline.
Việc side-loading tiếp tục nhắm vào hệ sinh thái ESET (sau tiền lệ TCESB/ToddyCat) là một tín hiệu đáng để các tổ chức đang triển khai ESET Management Agent lưu tâm — không phải vì bản thân ESET có lỗ hổng, mà vì cơ chế thứ tự tìm kiếm DLL của Windows là một bề mặt tấn công chung cho bất kỳ phần mềm quản lý tập trung nào có quyền cao và được cài đặt rộng rãi trong doanh nghiệp. Đây là lời nhắc rằng phần mềm bảo mật — vốn thường được đặt trong danh sách loại trừ (exclusion) khỏi giám sát khác — chính vì lý do đó lại là mục tiêu hấp dẫn cho kỹ thuật side-loading.
Khuyến Nghị
Threat Hunting và Phát Hiện
Rà soát ngay các chỉ dấu trên host tại mọi máy có cài ESET Management Agent: tìm
dpapi.dllbất thường cạnhERAAgent.exe, đối chiếu hash SHA-256/MD5 đã công bố, tìmdpapisvc.dll(tên không thuộc Windows thật).So sánh hai giá trị registry với baseline đã biết là sạch —
EveryoneIncludesAnonymousvàNullSessionPipes— vì bản thân chúng không phải bằng chứng chắc chắn nếu không có baseline để đối chiếu.Triển khai luật YARA và script PowerShell chỉ-đọc do Reichel công bố (xem Tham khảo) để quét trên diện rộng trong estate của tổ chức trước khi quyết định hướng phản ứng.
Lưu ý giới hạn của luật YARA: một phần luật khớp trên khóa AES tĩnh và mã đã biên dịch — một bản build lại với compiler khác có thể phá vỡ khả năng khớp, nên không nên coi kết quả "không khớp" là bằng chứng tuyệt đối không nhiễm.
Giám Sát Mạng
Không trông cậy vào giám sát kết nối C2 truyền thống để phát hiện SLEEPWALKER — vì nó không tự động gọi ra, các công cụ giám sát lưu lượng bất thường hoặc kết nối hạ tầng xấu sẽ không thấy gì.
Cân nhắc giám sát việc bật chế độ promiscuous mode bất thường trên các endpoint không có lý do nghiệp vụ chính đáng để làm vậy (không phải công cụ phân tích mạng hợp pháp).
Đặc biệt chú ý các máy đóng vai trò gateway, VPN server, hoặc bắc cầu hai phân đoạn mạng — đây là những vị trí có nguy cơ "vô tình" nhìn thấy và kích hoạt trigger nhắm tới máy khác.
Với môi trường ảo hóa VMware: cân nhắc rủi ro kênh VMCI không xuất hiện trong packet capture thông thường — cần công cụ giám sát riêng ở tầng hypervisor nếu nghi ngờ.





