BAN CƠ YẾU CHÍNH PHỦ HỌC VIỆN KỸ THUẬT MẬT MÃ NGUYỄN THỊ LAN HƯƠNG NGHIÊN CỨU MỘT SỐ KỸ THUẬT TIÊM TIẾN TRÌNH VÀ ỨNG DỤNG TRONG VIỆC PHÁT TRIỂN CÔNG CỤ RÀ SOÁT CHƯƠNG TRÌNH ĐỘC HẠI ĐỀ ÁN THẠC SỸ
HÀ NỘI – 2025
BAN CƠ YẾU CHÍNH PHỦ
HỌC VIỆN KỸ THUẬT MẬT MÃ
NGUYỄN THỊ LAN HƯƠNG
NGHIÊN CỨU MỘT SỐ KỸ THUẬT TIÊM TIẾN TRÌNH VÀ ỨNG DỤNG TRONG VIỆC PHÁT TRIỂN CÔNG CỤ RÀ SOÁT CHƯƠNG TRÌNH ĐỘC HẠI
Chuyên ngành: An toàn thông tin
Mã số: 8480202
Khóa: CHAT10
ĐỀ ÁN THẠC SĨ
NGƯỜI HƯỚNG DẪN KHOA HỌC:
TS. Lại Minh Tuấn – Học viện KTMM
HÀ NỘI – 2025
i
LỜI CAM ĐOAN
Tôi xin cam đoan bản đồ án này do tôi tự nghiên cứu dưới sự hướng dẫn của
thầy giáo TS. Lại Minh Tuấn. Để hoàn thành đồ án này, tôi chỉ sử dụng những tài
liệu đã ghi trong mục tài liệu tham khảo, ngoài ra không sử dụng bất cứ tài liệu
nào khác mà không được ghi. Nếu sai, tôi xin chịu mọi hình thức kỷ luật theo quy
định của học viện.
Hà Nội, ngày tháng năm 2025
Học viên thực hiện
Nguyễn Thị Lan Hương
ii
LỜI CẢM ƠN
Lời đầu tiên, em xin gửi lời biết ơn sâu sắc tới thầy TS. Lại Minh Tuấn đã
tận tình chỉ bảo, hướng dẫn em trong không chỉ quá trình thực hiện đề án này, nhờ
sự giúp đỡ và những chia sẻ của thầy cô, em đã có những định hướng riêng cho
tương lai của mình.
Em xin chân thành cảm ơn các thầy, cô trong Khoa an toàn thông tin nói
riêng và toàn thể các cán bộ của Học viện Kỹ thuật mật mã nói chung đã tạo điều
kiện để em có thể học tập và phát triển bản thân trong một môi trường rất tốt. Cảm
ơn các thầy cô đã cung cấp cho em không chỉ kiến thức mà còn là kỹ năng sống,
đó là những hành trang hữu ích cho em trên chặng đường dài phía trước của cuộc
đời.
Em cũng xin gửi lời cảm ơn đến những người anh, người bạn, người đồng
nghiệp trong Trung tâm Phân tích và Chia sẻ nguy cơ an ninh mạng, công ty
TNHH MTV An ninh mạng Viettel đã cung cấp cho em những kiến thức về lập
trình, hệ điều hành, về dịch ngược, rà soát mã độc và tạo điều kiện cho em hoàn
thiện bài nghiên cứu chuyên đề này.
Em xin chân thành cảm ơn!
iii
MỤC LỤC
LỜI CAM ĐOAN .......................................................................................... i
LỜI CẢM ƠN ............................................................................................... ii
MỤC LỤC .................................................................................................... iii
DANH MỤC VIẾT TẮT ............................................................................. vi
DANH MỤC CÁC HÌNH VẼ ................................................................... viii
DANH MỤC CÁC BẢNG BIỂU ................................................................ xi
CƠ SỞ LÝ THUYẾT ........................................................... 4
MỞ ĐẦU ....................................................................................................... 1
Cấu trúc bộ nhớ của tiến trình trên hệ điều hành Windows .............. 4
Khái niệm về luồng và tiến trình................................................. 4
Không gian bộ nhớ của một tiến trình ........................................ 6
Các loại bộ nhớ trong tiến trình .................................................. 8
Quản lý bộ nhớ của tiến trình.................................................... 12
Một số Windows API liên quan đến tiến trình ................................ 15
Windows API ............................................................................ 15
Cách Windows tạo tiến trình mới ............................................. 16
Các hàm API cấp phát bộ nhớ của tiến trình ............................ 21
Tổng quan về kỹ thuật tiêm tiến trình .............................................. 21
Giới thiệu chung về kỹ thuật tiêm tiến trình ............................. 21
Tác động của kỹ thuật tiêm tiến trình trong phần mềm độc hại 24
Một số công cụ và giải pháp phòng chống hiện nay ................. 26
Kết luận chương 1 ............................................................................ 28
NGHIÊN CỨU MỘT SỐ KỸ THUẬT TIÊM TIẾN TRÌNH
iv
VÀ DẤU HIỆU PHÁT HIỆN ............................................................................. 30
Phân loại các kỹ thuật tiêm tiến trình cơ bản ................................... 30
Tiêm thư viện động (DLL-based injection) .............................. 30
Thay thế tiến trình ..................................................................... 34
Tiêm dựa trên thao tác file thực thi (Executable Tampering) .. 39
Các kỹ thuật tiêm khác .............................................................. 44
So sánh các loại kỹ thuật tiêm tiến trình ................................... 50
Dấu hiệu đáng ngờ trên bộ nhớ để phát hiện có tiêm tiến trình....... 50
Bộ nhớ Private Memory có quyền thực thi (+X) ...................... 51
Thay đổi quyền bộ nhớ bất thường ........................................... 51
Sửa đổi bất thường trong Image Memory ................................. 52
Vùng Mapped Memory chứa quyền thực thi ............................ 53
Vùng nhớ thực thi không liên kết với module .......................... 53
Sự khác biệt giữa bộ nhớ và file trên đĩa .................................. 54
Lạm dụng section object để tiêm mã ........................................ 54
PHÁT TRIỂN CÔNG CỤ RÀ SOÁT BỘ NHỚ ĐỂ PHÁT
Kết luận chương 2 ............................................................................ 55
HIỆN VÙNG NHỚ ĐỘC HẠI TRONG BÀI TOÁN PHÁT HIỆN MÃ ĐỘC . 56
Xây dựng công cụ ............................................................................ 56
Lựa chọn nền tảng và thư viện kỹ thuật .................................... 56
Sơ đồ hoạt động ........................................................................ 57
Thực nghiệm và đánh giá kết quả .................................................... 64
Môi trường thử nghiệm ............................................................. 64
Kịch bản thử nghiệm ................................................................. 65
v
Phân tích và đánh giá kết quả ................................................... 66
Kết luận ..................................................................................... 91
Kết luận chương 3 ............................................................................ 92
KẾT LUẬN ................................................................................................. 94
TÀI LIỆU THAM KHẢO ........................................................................... 95
vi
DANH MỤC VIẾT TẮT
Từ viết tắt Ý nghĩa Mô tả
API Application Giao diện lập trình ứng dụng, cung cấp các
Programming hàm giúp tiến trình thao tác với bộ nhớ,
Interface luồng, DLL...
DLL Dynamic- Thư viện liên kết động, có thể được nạp vào
Link Library tiến trình để thực thi mã.
PE Portable Định dạng tệp thực thi trên Windows, bao
Executable gồm .exe, .dll, .sys.
NTDLL Windows Thư viện chứa các hàm hệ thống cấp thấp
Native API như NtAllocateVirtualMemory,
Library NtWriteVirtualMemory giúp thao tác bộ
nhớ tiến trình.
PID Process Mã định danh duy nhất của một tiến trình
Identifier trên Windows.
TID Thread Mã định danh của một luồng trong tiến trình.
Identifier
RWX Read-Write- Quyền truy cập bộ nhớ cho phép đọc, ghi và
Execute thực thi mã - thường bị lợi dụng để chạy mã
độc.
MEM_COMMIT Memory Cờ trong Windows API dùng để cấp phát bộ
Commit nhớ cho tiến trình.
HANDLE Object Tham chiếu đến đối tượng hệ thống như tiến
trình, luồng, hoặc bộ nhớ được cấp phát. Handle
IAT Bảng địa chỉ nhập của tiến trình, chứa danh Import
Address sách các API được sử dụng.
Table
vii
Từ viết tắt Ý nghĩa Mô tả
ETW Event Cơ chế theo dõi sự kiện trong Windows.
Tracing for
Windows
EDR Endpoint Giải pháp bảo mật giúp phát hiện các hoạt
Detection động đáng ngờ trên thiết bị đầu cuối.
and Response
AV Antivirus Phần mềm bảo mật được thiết kế để ngăn
chặn, phát hiện và loại bỏ virus và các loại
phần mềm độc hại khác như sâu, trojan,
phần mềm gián điệp khỏi máy tính, mạng và
các thiết bị khác.
viii
DANH MỤC CÁC HÌNH VẼ
Hình 1.1. Cấu trúc của tiến trình trong hệ điều hành .................................... 4
Hình 1.2. Mối quan hệ giữa tiến trình và các luồng ..................................... 6
Hình 1.3. Ví dụ các loại bộ nhớ trong một tiến trình vmware-tray.exe ...... 10
Hình 1.4. Phân giải địa chỉ .......................................................................... 14
Hình 1.5. Các hàm được sử dụng để tạo một tiến trình mới ....................... 17
Hình 1.6. Không gian địa chỉ ảo của một tiến trình mới được tạo ............. 19
Hình 1.7. Sơ đồ các API được sử dụng để cấp phát bộ nhớ tiến trình........ 21
Hình 1.8. Top 10 kỹ thuật được mã độc sử dụng nhiều nhất được thống kê
bởi Picus Security, CrowdStrike, Recorded Future và Red Canary năm 2020 .. 23
Hình 1.9. Các nhóm APT và dòng mã độc sử dụng tiêm tiến trình (nguồn:
Mitre ATT&CK) ................................................................................................. 24
Hình 2.1. Các bước thực hiện kỹ thuật DLL Injection sử dụng cách 2. ..... 31
Hình 2.2. Ví dụ về kỹ thuật DLL Injection sử dụng cách 2 ........................ 32
Hình 2.3. Luồng thực thi reflect DLL injection .......................................... 34
Hình 2.4. Luồng thực thi của kỹ thuật Process Hollowing ......................... 35
Hình 2.5. Tiến trình được tạo với trạng thái CREATE_SUSPENDED. .... 36
Hình 2.6. Mã độc Ransom.Cryak thực hiện kỹ thuật Process Hollowing. . 37
Hình 2.7. Một ví dụ về Process Hollowing. ................................................ 38
Hình 2.8. Kỹ thuật Module Stomping ......................................................... 39
Hình 2.9. Luồng thực thi của Process Doppelganging ............................... 40
Hình 2.10. Luồng thực thi của Process Herpaderping (theo jxy-s) ............ 42
Hình 2.11. Luồng thực thi của Process Ghosting ....................................... 43
Hình 2.12. Ví dụ minh họa APC injection .................................................. 45
Hình 2.13. So sánh các loại kỹ thuật tiêm tiến trình ................................... 50
Hình 3.1. Sơ đồ hoạt động của công cụ khi kiểm tra vùng nhớ là PE file .. 61
Hình 3.2. Sơ đồ hoạt động của công cụ khi kiểm tra vùng nhớ là Mapped file
............................................................................................................................. 62
Hình 3.3. Sơ đồ hoạt động của công cụ khi kiểm tra vùng nhớ Unkown
private .................................................................................................................. 64
ix
Hình 3.4. Tệp thực thi payload ................................................................... 66
Hình 3.5. Thực hiện kỹ thuật Process Hollowing ....................................... 67
Hình 3.6. Kết quả rà soát kỹ thuật Process Hollowing bằng công cụ ......... 67
Hình 3.7. Luồng tồn tại trong vùng nhớ Private ......................................... 68
Hình 3.8. PE file tại địa chỉ 0x1C0000 ....................................................... 69
Hình 3.9. Thực thi file được trích xuất tại địa chỉ 0x00000000001C0000. 70
Hình 3.10. Thực hiện kỹ thuật Process Ghosting ....................................... 71
Hình 3.11. Kết quả rà soát kỹ thuật Process Ghosting bằng công cụ ......... 72
Hình 3.12. PE file dưới địa chỉ 0x00007FF64CB60000 ............................ 73
Hình 3.13. Công cụ thực hiện trích xuất vùng nhớ nghi ngờ ra file ........... 74
Hình 3.14. Thực thi file được trích xuất ra tại địa chỉ 0x00007FF64CB60000
của tiến trình ........................................................................................................ 74
Hình 3.15. Tệp DLL hiển thị Message Box ................................................ 75
Hình 3.16. Thực hiện kỹ thuật reflect DLL injection ................................. 76
Hình 3.17. Kết quả rà soát kỹ thuật Reflective DLL Injection ................... 76
Hình 3.18. Các vùng nhớ khác hiển thị trên công cụ .................................. 77
Hình 3.19. PE file tại địa chỉ 0x00000000009E0000 ................................. 78
Hình 3.20. Trích xuất vùng nhớ 0x00000000009E0000 bằng công cụ ...... 78
Hình 3.21. Dịch ngược file được trích xuất để xác minh ........................... 79
Hình 3.22. Mẫu mã độc APT32 .................................................................. 80
Hình 3.23. Chức năng của mã độc trong libusb-1.0.dll .............................. 81
Hình 3.24. Các chế độ hoạt động của mã độc ............................................. 82
Hình 3.25. Chức năng tạo mutex và giải mã AES của mã độc ................... 84
Hình 3.26. Giải nén LZMA ......................................................................... 85
Hình 3.27. Kỹ thuật Process hollowing trong mẫu mã độc APT32 ........... 86
Hình 3.28. Giải nén shellcode cuối bằng LZMA ........................................ 86
Hình 3.29. Giải nén shellcode bằng LZMA trên Cyberchef ....................... 87
Hình 3.30. Kết quả rà soát mẫu mã độc APT32 bằng công cụ ................... 88
Hình 3.31. Trích xuất vùng nhớ nghi ngờ chứa shellcode lưu vào trong thư
mục memdmp-11-6-2025~23.47.46 .................................................................... 90
x
Hình 3.32. File được trích xuất ra bằng công cụ chính là shellcode mã độc
............................................................................................................................. 91
xi
DANH MỤC CÁC BẢNG BIỂU
Bảng 1.1. Các loại bộ nhớ trong tiến trình .................................................. 10
Bảng 3.1. Bảng chế độ hoạt động của mã độc ............................................ 82
MỞ ĐẦU
Trong thời đại số hóa hiện nay, các mối đe dọa an ninh mạng ngày càng trở
nên nghiêm trọng và tinh vi hơn. Các loại mã độc không ngừng phát triển với độ
phức tạp ngày càng cao, từ cách thức lây nhiễm, phương pháp ẩn mình đến cách
thức thực hiện các hành vi nguy hiểm, gây ra những thiệt hại nặng nề về tài chính,
uy tín và thông tin cho các tổ chức. Trước tình hình đó, việc chủ động phát hiện
các cuộc tấn công mạng - hay còn gọi là "threat hunting" - đang trở thành một yêu
cầu cấp thiết đối với mọi hệ thống bảo mật.
Một trong những kỹ thuật thường được sử dụng bởi mã độc hiện nay là tiêm
tiến trình (process injection). Đây là kỹ thuật cho phép mã độc chèn và thực thi
trong không gian tiến trình của các ứng dụng hợp pháp nhằm ẩn mình, qua mặt
các hệ thống phòng thủ và duy trì sự tồn tại lâu dài trong hệ thống mục tiêu. Các
kỹ thuật tiêm tiến trình như DLL Injection, Process Hollowing, Reflective DLL
Injection, APC Injection, và Thread Hijacking đang được khai thác ngày càng phổ
biến trong nhiều loại mã độc, từ spyware, ransomware đến các chiến dịch tấn công
có chủ đích tinh vi (APT - Advanced Persistent Threat). Kỹ thuật này là một trong
những phương thức được rất nhiều nhóm tấn công ưa chuộng nhằm né tránh sự
phát hiện của các sản phẩm bảo mật.
Để có thể chủ động săn tìm được các nguy cơ tiềm ẩn trên hệ thống, các
chuyên gia an ninh mạng cần phải liên tục trau dồi kiến thức chuyên môn về các
kỹ thuật mà kẻ tấn công sử dụng, cũng như cập nhật các phương pháp phát hiện
mới nhất. Tuy nhiên, các công cụ rà soát mã độc hiện nay đa số vẫn tập trung vào
kỹ thuật phát hiện dựa trên chữ ký (signature-based) hoặc hành vi đơn lẻ. Những
phương pháp này chưa đủ khả năng để nhận diện và phân tích sâu các hành vi
tiêm tiến trình phức tạp. Điều này tạo ra một lỗ hổng đáng kể trong khả năng
phòng chống và điều tra số khi đối mặt với các kỹ thuật ẩn mình tinh vi. Nhiều
cuộc tấn công có chủ đích (targeted attacks) đã thành công trong việc vượt qua hệ
thống phòng thủ nhờ sử dụng kỹ thuật tiêm tiến trình để tránh bị phát hiện trong
quá trình thực thi mã độc.
2
Thực tế cho thấy, hầu hết các hệ thống phòng thủ hiện tại trên thế giới chủ
yếu phát hiện các cuộc tấn công dựa theo dấu hiệu. Với cách thức phát hiện này,
các hệ thống phòng thủ chỉ có thể nhận diện được những cuộc tấn công đã biết
trước đó, và việc vượt qua những hệ thống như vậy tương đối dễ dàng đối với kẻ
tấn công có kinh nghiệm. Ví dụ điển hình là việc làm rối mã nhị phân
(obfuscation) của một tệp tin mã độc sẽ khiến các hệ thống phòng thủ truyền thống
gặp khó khăn trong việc phát hiện. Ngoài ra, các hệ thống phòng thủ dựa trên dấu
hiệu còn bị giới hạn khả năng phát hiện trong khoảng thời gian cập nhật cơ sở dữ
liệu về dấu hiệu đã biết. Điều này dẫn đến tình trạng các dấu hiệu của cuộc tấn
công đã được công bố nhưng hệ thống phòng thủ hiện tại lại không phát hiện được
kịp thời, tạo ra khoảng trống bảo mật nguy hiểm.
Do đó, việc nghiên cứu, tổng hợp và đánh giá các kỹ thuật tiêm tiến trình
phổ biến, đồng thời ứng dụng những hiểu biết này vào việc phát triển công cụ hỗ
trợ rà soát, phát hiện chương trình độc hại là hết sức cần thiết và mang tính thực
tiễn cao. Xuất phát từ những thách thức trên, đề tài "NGHIÊN CỨU MỘT SỐ
KỸ THUẬT TIÊM TIẾN TRÌNH VÀ ỨNG DỤNG TRONG VIỆC PHÁT
TRIỂN CÔNG CỤ RÀ SOÁT CHƯƠNG TRÌNH ĐỘC HẠI" được lựa chọn,
với mục tiêu:
Tìm hiểu, phân tích chi tiết các kỹ thuật process injection phổ biến và
dấu hiệu bất thường trong bộ nhớ.
Xây dựng công cụ có khả năng rà soát, phát hiện vùng nhớ nghi vấn
chứa mã độc.
Thử nghiệm công cụ trong các kịch bản tấn công mô phỏng và đánh
giá hiệu quả.
Nghiên cứu này không chỉ nhằm tìm hiểu sâu về các kỹ thuật tiêm tiến trình
phổ biến, phân tích cơ chế hoạt động của chúng, mà còn hướng đến việc đề xuất
và phát triển các giải pháp hiệu quả để phát hiện và ngăn chặn các mối đe dọa
này. Đề tài không chỉ góp phần tăng cường năng lực phòng thủ nội tại của các hệ
thống thông tin, mà còn phục vụ cho công tác điều tra số và ứng phó sự cố hiệu
3
quả hơn, góp phần nâng cao năng lực bảo mật cho các hệ thống thông tin trong
bối cảnh các cuộc tấn công mạng ngày càng phức tạp.
Các nhiệm vụ chính đã thực hiện bao gồm: nghiên cứu cơ sở lý thuyết về
tiến trình và bộ nhớ Windows; tìm hiểu, nghiên cứu, so sánh các kỹ thuật tiêm
tiến trình; xây dựng và triển khai công cụ phát hiện dựa trên phân tích bộ nhớ;
tiến hành mô phỏng thực nghiệm nhiều kịch bản tiêm tiến trình khác nhau; và cuối
cùng, ứng dụng công cụ để rà soát mẫu mã độc thực tế.
Đề án gồm ba chương chính:
Chương 1: Trình bày cơ sở lý thuyết về tiến trình, bộ nhớ trong Windows,
khái quát về kỹ thuật process injection và một số giải pháp phòng chống hiện nay.
Chương 2: Nghiên cứu chuyên sâu một số kỹ thuật process injection, phân
tích dấu hiệu bất thường trong bộ nhớ giúp phát hiện tấn công.
Chương 3: Mô tả quá trình xây dựng công cụ rà soát bộ nhớ, tiến hành thử
nghiệm với nhiều kịch bản process injection, phân tích và đánh giá kết quả, đồng
thời áp dụng công cụ vào phân tích một số mẫu mã độc APT.
Kết quả nghiên cứu cho thấy công cụ đã phát hiện hiệu quả các dấu hiệu
process injection, từ vùng nhớ RWX bất thường, mã bị sửa đổi, đến các module
không có chữ ký số, đồng thời hỗ trợ trích xuất bộ nhớ nghi ngờ để phục vụ công
tác phân tích mã độc. Đây là đóng góp mang tính thực tiễn cao, góp phần tăng
cường khả năng phòng thủ và điều tra số trước các mối đe dọa ngày càng phức
tạp.
4
CƠ SỞ LÝ THUYẾT
Cấu trúc bộ nhớ của tiến trình trên hệ điều hành Windows
Khái niệm về luồng và tiến trình
Tiến trình
Tiến trình là đơn vị cơ bản trong quản lý tài nguyên của hệ điều hành
Windows. Mỗi tiến trình đại diện cho một chương trình đang được thực thi trong
hệ thống, bao gồm nhiều thành phần quan trọng, trong đó cốt lõi nhất là không
gian địa chỉ bộ nhớ ảo riêng biệt (Virtual Address Space). Không gian địa chỉ này
được hệ điều hành cấp phát độc lập cho từng tiến trình nhằm đảm bảo các chương
trình hoạt động tách biệt, ngăn chặn sự can thiệp trái phép vào vùng nhớ của các
tiến trình khác, từ đó đảm bảo tính ổn định và bảo mật của toàn hệ thống.
Bên trong không gian địa chỉ của một tiến trình chứa các đoạn mã (code
segments) và dữ liệu (data segments) cần thiết cho việc thực thi chương trình. Tuy
nhiên, để chương trình thực sự được thực thi, tiến trình đó phải có ít nhất một
luồng (thread) hoạt động. Luồng chính là thực thể thực thi các chỉ thị của chương
trình trong không gian địa chỉ được cấp phát cho tiến trình.
Hình 1.1. Cấu trúc của tiến trình trong hệ điều hành
Đặc điểm của tiến trình:
Trạng thái (State): Trong suốt vòng đời của mình, một tiến trình có thể
chuyển đổi qua nhiều trạng thái khác nhau như New (đang được khởi tạo),
Ready (sẵn sàng chờ CPU), Running (đang thực thi), Waiting (chờ đợi sự
kiện I/O), và Terminated (đã hoàn thành).
5
Định danh tiến trình (PID - Process ID): Mỗi tiến trình được gán một số
định danh duy nhất (PID) để hệ điều hành có thể quản lý và phân biệt các
tiến trình trong hệ thống.
Khối điều khiển tiến trình (Process Control Block - PCB): Đây là cấu trúc
dữ liệu quan trọng chứa toàn bộ thông tin cần thiết để hệ điều hành quản
lý tiến trình. PCB bao gồm các thông tin như trạng thái tiến trình, con trỏ
chương trình (program counter), nội dung các thanh ghi CPU, thông tin
lập lịch CPU, thông tin quản lý bộ nhớ, thông tin về các file đang mở, và
trạng thái I/O.
Không gian bộ nhớ độc lập: Mỗi tiến trình sở hữu không gian địa chỉ bộ
nhớ riêng biệt, bao gồm các vùng như code segment (mã chương trình),
data segment (dữ liệu toàn cục và tĩnh), heap (vùng cấp phát động), và
stack (ngăn xếp cho các biến cục bộ).
Luồng
Luồng là đơn vị thực thi cơ bản bên trong một tiến trình, được hệ điều hành
Windows lập lịch để thực thi. Nếu không có luồng, tiến trình sẽ không thể thực
hiện bất kỳ thao tác nào. Luồng còn được gọi là "lightweight process" (tiến trình
nhẹ) do nó chia sẻ tài nguyên với các luồng khác trong cùng tiến trình, giúp giảm
thiểu chi phí chuyển đổi ngữ cảnh. Đặc điểm của luồng bao gồm:
Đa luồng trong tiến trình: Mỗi tiến trình có ít nhất một luồng chính (main
thread), nhưng có thể tạo thêm nhiều luồng con để thực hiện các tác vụ
đồng thời, giúp cải thiện hiệu năng của ứng dụng.
Thành phần riêng của luồng: Mỗi luồng sở hữu các thành phần riêng biệt
bao gồm con trỏ lệnh để theo dõi lệnh tiếp theo cần thực thi, ngăn xếp
riêng để lưu trữ biến cục bộ và thông tin gọi hàm, và tập thanh ghi CPU
(register set) để lưu trạng thái thực thi.
Chia sẻ tài nguyên: Các luồng trong cùng một tiến trình chia sẻ chung
không gian địa chỉ bộ nhớ, bao gồm code segment, data segment, và heap,
nhưng mỗi luồng có ngăn xếp riêng. Điều này cho phép các luồng trao
6
đổi thông tin dễ dàng thông qua các biến chia sẻ, nhưng cũng đòi hỏi cơ
chế đồng bộ hóa để đảm bảo tính nhất quán của dữ liệu.
Khối điều khiển luồng (Thread Control Block - TCB): Tương tự như PCB
đối với tiến trình, mỗi luồng được quản lý thông qua TCB chứa thông tin
về trạng thái luồng, con trỏ ngăn xếp, độ ưu tiên, và các thông tin cần thiết
khác cho việc lập lịch và thực thi.
Hiệu suất cao hơn: Việc tạo, chuyển đổi ngữ cảnh, và hủy bỏ luồng nhanh
hơn đáng kể so với tiến trình do luồng chia sẻ tài nguyên và không yêu
cầu cấp phát không gian địa chỉ mới.
Mối quan hệ giữa tiến trình và luồng:
Tiến trình đóng vai trò là container (vùng chứa) cung cấp môi trường và
tài nguyên cần thiết, trong khi luồng là đơn vị thực thi thực sự. Một tiến
trình có thể chứa nhiều luồng thực thi đồng thời, tất cả đều sử dụng chung
tài nguyên của tiến trình nhưng có ngăn xếp và con trỏ lệnh riêng. Mối
quan hệ này cho phép các ứng dụng đa nhiệm thực hiện nhiều công việc
song song, tối ưu hóa việc sử dụng CPU và cải thiện khả năng đáp ứng
của hệ thống.
Hình 1.2. Mối quan hệ giữa tiến trình và các luồng
Không gian bộ nhớ của một tiến trình
Mỗi tiến trình trong hệ điều hành Windows được cấp phát một không gian
địa chỉ bộ nhớ ảo riêng biệt, được gọi là Virtual Address Space (VAS). Không gian
7
này cho phép tiến trình hoạt động độc lập, tránh xung đột và truy cập trái phép
đến vùng nhớ của tiến trình khác, góp phần đảm bảo tính ổn định và an toàn của
hệ thống. Không gian địa chỉ ảo của một tiến trình thường được chia thành các
vùng chính sau:
Phân đoạn mã (Text Segment)
Phân đoạn mã chứa mã máy (machine code) của chương trình. Đây là phần
mã mà CPU sẽ thực thi trong quá trình chạy, bao gồm tất cả các lệnh và logic của
chương trình.
Phân đoạn này thường được gán quyền chỉ đọc và thực thi (Read-Execute).
Điều này đảm bảo rằng mã chương trình không thể bị sửa đổi bởi chính chương
trình trong suốt quá trình thực thi, giúp bảo vệ tính toàn vẹn và ngăn chặn các lỗi
tiềm ẩn hoặc các cuộc tấn công bảo mật.
Phân đoạn dữ liệu (Data Segment)
Phân đoạn dữ liệu chứa dữ liệu toàn cục và biến tĩnh của chương trình. Phân
đoạn dữ liệu bao gồm:
Data Segment (.data): Chứa các biến toàn cục đã được khởi tạo. Những biến
này có giá trị ban đầu được lập trình viên gán trước khi chương trình chạy, cho
phép chúng được sử dụng ngay lập tức tại thời điểm thực thi.
BSS Segment (.bss): Chứa các biến toàn cục chưa được khởi tạo. BSS chiếm
không gian bộ nhớ nhưng không lưu trữ dữ liệu bên trong; thay vào đó, tất cả
các biến trong BSS sẽ được tự động khởi tạo bằng không khi chương trình bắt
đầu.
Phân đoạn này thường được gán quyền bộ nhớ PAGE_READWRITE.
Vùng nhớ động (Heap)
Heap là khu vực bộ nhớ dùng cho việc cấp phát động (dynamic allocation)
trong thời gian chạy. Chương trình có thể yêu cầu cấp phát hoặc giải phóng bộ
nhớ thông qua các hàm như malloc, free trong C/C++ hoặc HeapAlloc, HeapFree
trong Windows API. Mỗi tiến trình có một Heap mặc định nhưng có thể tạo nhiều
8
Heap nếu cần thiết. Phân đoạn này thường được gán quyền bộ nhớ
PAGE_READWRITE.
Ngăn xếp (Stack)
Mỗi luồng trong tiến trình có một ngăn xếp riêng. Ngăn xếp chứa dữ liệu tạm
thời, bao gồm các biến cục bộ, tham số hàm, và địa chỉ trả về khi gọi hàm. Ngăn
xếp sử dụng cấu trúc LIFO (Last In, First Out), điều này có nghĩa là mục được
thêm vào cuối sẽ được lấy ra đầu tiên. Stack tự động quản lý bộ nhớ cho các biến
cục bộ, nhờ đó nó tự động giải phóng bộ nhớ khi biến ra khỏi phạm vi (scope).
Điều này giúp ngăn ngừa các lỗi liên quan đến rò rỉ bộ nhớ. Phân đoạn này thường
được gán quyền bộ nhớ PAGE_READWRITE.
Mỗi phân đoạn trong không gian bộ nhớ của một tiến trình đều thực hiện
những chức năng riêng biệt, giúp quản lý hiệu quả tài nguyên bộ nhớ và đảm bảo
rằng chương trình thực thi một cách ổn định và an toàn. Sự phân chia này không
chỉ hỗ trợ trong việc tối ưu hóa hiệu suất mà còn nâng cao khả năng quản lý và
bảo mật cho các tiến trình trong hệ điều hành.
Các loại bộ nhớ trong tiến trình
Bộ nhớ của một tiến trình điển hình trên Windows có thể được phân loại
thành ba loại khác nhau dựa trên mục đích sử dụng và cơ chế quản lý. Các loại bộ
nhớ này tương ứng trực tiếp với trường Type trong cấu
trúc MEMORY_BASIC_INFORMATION, được trả về bởi API VirtualQueryEx
khi phân tích không gian địa chỉ tiến trình.
Private Memory
Private Memory là bộ nhớ được dành riêng cho một tiến trình cụ thể và không
được chia sẻ với các tiến trình khác trong hệ thống. Tất cả bộ nhớ được cấp phát
thông qua Native API NTDLL.DLL!NtAllocateVirtualMemory hoặc Windows
API VirtualAlloc thuộc loại này. Private Memory bao gồm các vùng quan trọng
như heap (vùng cấp phát động), stack (ngăn xếp luồng), và các vùng dữ liệu riêng
được tiến trình yêu cầu cấp phát trong quá trình thực thi.
9
Theo thiết kế chuẩn, Private Memory chủ yếu được sử dụng cho mục đích
lưu trữ dữ liệu và không nên chứa mã thực thi. Các vùng stack và heap thường có
quyền đọc-ghi (+RW) mà không có quyền thực thi. Trong cấu trúc
MEMORY_BASIC_INFORMATION, Private Memory được xác định bởi giá trị
Type là MEM_PRIVATE.
Mapped Memory
Mapped Memory là bộ nhớ được phân bổ dưới dạng section object, cho phép
ánh xạ file hoặc chia sẻ bộ nhớ giữa các tiến trình. Bộ nhớ vật lý của section này
có thể được chia sẻ bởi nhiều tiến trình khác nhau, giúp tối ưu hóa việc sử dụng
tài nguyên hệ thống. Mapped Memory được tạo ra thông qua các API như
CreateFileMapping và MapViewOfFile (Windows API) hoặc NtCreateSection và
NtMapViewOfSection (Native API).
Các vùng Mapped Memory phần lớn có quyền "read-only" (+R) hoặc "read-
write" (+RW), được sử dụng cho mục đích chia sẻ dữ liệu giữa các tiến trình hoặc
ánh xạ file vào bộ nhớ để truy cập hiệu quả. Trong cấu trúc
MEMORY_BASIC_INFORMATION, Mapped Memory được xác định bởi giá
trị Type là MEM_MAPPED.
Image Memory
Image Memory là bộ nhớ được sử dụng để lưu trữ các module thực thi như
EXE (executable files) và DLL (Dynamic Link Libraries). Khi một file PE được
tải vào tiến trình, nội dung của nó được ánh xạ vào không gian địa chỉ dưới dạng
Image Memory. Bộ nhớ vật lý của Image Memory có thể được chia sẻ giữa nhiều
tiến trình, đặc biệt đối với các DLL hệ thống thường được sử dụng chung như
kernel32.dll, ntdll.dll, user32.dll. Điều này giúp tiết kiệm bộ nhớ vật lý vì DLL
chỉ được tải vào bộ nhớ một lần và được chia sẻ bởi tất cả các tiến trình sử dụng
nó.
Image Memory chứa các code sections (thường có quyền +RX) và data
sections (thường có quyền +R hoặc +RW) được định nghĩa trong cấu trúc PE của
module. Trong cấu trúc MEMORY_BASIC_INFORMATION, Image Memory
được xác định bởi giá trị Type là MEM_IMAGE.
10
Hình 1.3. Ví dụ các loại bộ nhớ trong một tiến trình vmware-tray.exe
Bảng 1.1. Các loại bộ nhớ trong tiến trình
Loại bộ Đặc điểm Sử dụng Lưu ý bảo mật
nhớ
Private - Chỉ thuộc về một tiến - Dùng cho dữ - Nếu có quyền
Memory trình, không chia sẻ với liệu tạm thời thực thi (+X) trong
tiến trình khác. hoặc cấp phát vùng này, có thể là
- Cấp phát qua động của tiến dấu hiệu của
NTDLL.DLL!NtAllocate trình. shellcode hoặc mã
VirtualMemory. - Dùng cho biến độc.
- Gồm: cục bộ và tham - Một số mã độc sử
dụng Process
11
Đặc điểm Sử dụng Lưu ý bảo mật Loại bộ
nhớ
+ Heap: Bộ nhớ cấp phát số hàm trong Hollowing hoặc
động. stack. Heap Spraying để
+ Stack: Lưu biến cục bộ, tiêm mã độc vào
tham số hàm, địa chỉ trả vùng Private
về. Memory.
- Thường được giải phóng
khi tiến trình kết thúc.
Mapped - Ánh xạ từ section object, - Dùng cho - Tiến trình độc hại
Memory có thể chia sẻ giữa nhiều Shared Memory, có thể tiêm mã vào
tiến trình. File Mapping. vùng Mapped
- Thường chỉ có quyền - Dùng để chia sẻ Memory bằng cách
read-only, nhưng có thể dữ liệu giữa các ánh xạ tệp thực thi
cấp quyền ghi trong một số tiến trình hoặc giả mạo.
trường hợp đặc biệt. ánh xạ file vào - Nếu một tiến trình
- Có thể ánh xạ trực tiếp từ bộ nhớ để truy có quyền ghi vào
file trên ổ đĩa vào bộ nhớ. xuất nhanh hơn. vùng Mapped
- Một số ứng Memory của tiến
dụng sử dụng để trình khác, có thể
tạo Memory- gây rủi ro bảo mật.
Mapped Files
nhằm cải thiện
hiệu suất
đọc/ghi.
Image - Chứa các tệp thực thi như - Dùng để chứa - Quyền thực thi
Memory EXE, DLL. mã thực thi của (+X) thường chỉ
- Bộ nhớ vật lý của Image tiến trình (EXE, xuất hiện trong
Memory có thể được chia DLL). vùng Image
12
Đặc điểm Sử dụng Lưu ý bảo mật Loại bộ
nhớ
sẻ giữa nhiều tiến trình để - Dùng để nạp Memory.
tối ưu hóa hiệu suất. thư viện chia sẻ - Nếu mã độc chỉnh
- Khi một tệp thực thi được sửa nội dung bộ
tải, hệ thống ánh xạ nội nhớ này (VD: DLL
dung tệp vào bộ nhớ. Injection, Process
Hollowing), có thể
làm thay đổi hành
vi của tiến trình
hợp pháp.
Quản lý bộ nhớ của tiến trình
Quản lý bộ nhớ là một trong những chức năng nền tảng của hệ điều
hành, quyết định đến hiệu suất và tính ổn định của toàn hệ thống. Trên nền tảng
Windows, nhiệm vụ này được thực hiện bởi Bộ quản lý bộ nhớ ảo (Virtual
Memory Manager - VMM), thành phần chịu trách nhiệm tổ chức và phân bổ
không gian bộ nhớ ảo cho các tiến trình.
Bộ quản lý bộ nhớ ảo
Bộ quản lý bộ nhớ ảo là thành phần hoạt động ở chế độ kernel (kernel-mode)
của hệ điều hành Windows, đảm nhận vai trò quản lý toàn bộ không gian địa chỉ
ảo cho các tiến trình trong hệ thống. Bộ nhớ ảo (Virtual Memory) cho phép hệ
thống sử dụng một phần dung lượng ổ đĩa cứng để mô phỏng RAM vật lý
thông qua cơ chế Paging File, từ đó mở rộng khả năng xử lý vượt qua giới hạn
của bộ nhớ vật lý. Các chức năng của bộ quản lý bộ nhớ ảo:
1. Cách ly không gian địa chỉ: Mỗi tiến trình được cấp phát một không gian
địa chỉ ảo độc lập, bắt đầu từ địa chỉ 0x00000000. Cơ chế này ngăn chặn
các tiến trình thực hiện các thao tác đọc hoặc ghi trái phép vào không gian
bộ nhớ của tiến trình khác, đảm bảo tính toàn vẹn và bảo mật của hệ
thống.
13
2. Ánh xạ địa chỉ ảo sang địa chỉ vật lý: VMM sử dụng cấu trúc Page Table
để thực hiện việc ánh xạ địa chỉ ảo sang địa chỉ vật lý trong RAM. Khi
CPU thực hiện truy cập một địa chỉ ảo, hệ điều hành tra cứu Page Table
để xác định vị trí thực tế của dữ liệu - có thể nằm trong RAM hoặc trên
Paging File của ổ đĩa cứng.
3. Cấp phát bộ nhớ động: VMM cho phép các tiến trình yêu cầu cấp phát bộ
nhớ bổ sung trong quá trình thực thi thông qua các API như VirtualAlloc
hoặc HeapAlloc. Hệ thống tự động gán các khung trang (page frames) từ
RAM hoặc sử dụng Paging File trên ổ đĩa khi bộ nhớ vật lý đầy.
4. Tối ưu hóa tài nguyên hệ thống: VMM cho phép hệ thống thực thi các
ứng dụng với tổng dung lượng bộ nhớ yêu cầu vượt quá RAM vật lý hiện
có, giúp ngăn ngừa lỗi thiếu bộ nhớ (Out of Memory) và duy trì sự ổn
định trong hoạt động.
Cơ chế phân trang
Phân trang là quá trình trong đó các vùng bộ nhớ tạm thời không được sử
dụng được chuyển xuống ổ đĩa cứng, giải phóng RAM cho các tác vụ đang hoạt
động. Hệ điều hành chia cả RAM vật lý và bộ nhớ ảo thành các khối có kích thước
cố định gọi là trang (page), thường có kích thước 4KB trên hệ điều hành Windows.
Nguyên lý hoạt động của cơ chế phân trang:
- Hoán đổi trang (Page Swapping): Khi RAM đạt đến ngưỡng đầy, hệ điều
hành tự động chuyển các trang dữ liệu ít được sử dụng từ RAM xuống Paging File
trên ổ đĩa. Hệ thống duy trì thông tin về thời điểm mỗi trang được truy cập lần
cuối (thông qua các cờ được bộ xử lý quản lý) để xác định trang nào có thể được
loại bỏ khỏi RAM.
- Xử lý ngoại lệ trang (Page Fault Handling): Khi tiến trình cố gắng truy cập
một trang đã bị chuyển xuống đĩa, bộ xử lý phát sinh ngoại lệ Page Fault do mục
tương ứng trong Page Table được đánh dấu không hợp lệ. Hệ điều hành sẽ tạm
dừng tiến trình, đọc dữ liệu từ Paging File trở lại RAM, cập nhật Page Table, sau
đó cho phép tiến trình tiếp tục thực thi.
14
- Phân trang theo yêu cầu (Demand Paging): Cơ chế này cho phép hệ thống
chỉ tải các trang bộ nhớ vào RAM khi chúng thực sự được yêu cầu, thay vì tải
toàn bộ chương trình trong quá trình khởi động. Phương pháp này giúp tối ưu hóa
việc sử dụng RAM và giảm thời gian khởi động ứng dụng.
Phân giải địa chỉ
Khi một tiến trình thực hiện truy cập bộ nhớ, địa chỉ ảo mà tiến trình sử dụng
phải được dịch sang địa chỉ vật lý tương ứng. Quá trình phân giải này đóng vai
trò quan trọng do địa chỉ trong không gian ảo của tiến trình không trùng khớp với
địa chỉ vật lý trong RAM. Ví dụ minh họa, nếu tiến trình notepad.exe thực hiện
truy cập bộ nhớ tại địa chỉ ảo 0x0041EF10 và địa chỉ vật lý tương ứng là
0x01EE2F10, khi lệnh assembly "mov eax, [0x0041EF10]" được thực thi, giá trị
thực tế được chuyển vào thanh ghi EAX là giá trị tại ô nhớ vật lý 0x01EE2F10.
VMM sử dụng Page Table để thực hiện phép dịch này một cách tự động và trong
suốt đối với tiến trình.
Hình 1.4. Phân giải địa chỉ
Cơ chế bảo vệ và kiểm soát truy cập bộ nhớ
Hệ điều hành quản lý và bảo vệ bộ nhớ tiến trình thông qua Page Table kết
hợp với các cờ bảo vệ (Protection Flags). Mỗi vùng bộ nhớ được gán các quyền
truy cập cụ thể, ngăn chặn các hành vi truy cập trái phép và tăng cường tính bảo
mật. Mỗi vùng nhớ được gán quyền truy cập cụ thể:
o Bộ nhớ chỉ được đọc, không thể ghi hoặc thực thi.
PAGE_READONLY:
o Sử dụng cho các dữ liệu không thay đổi (như các hằng số hoặc tài
15
nguyên chỉ đọc).
o Bộ nhớ cho phép cả đọc và ghi.
o Thường dùng cho các vùng dữ liệu thay đổi liên tục như stack hoặc
PAGE_READWRITE:
heap.
o Bộ nhớ chỉ được thực thi, không thể đọc hoặc ghi.
o Sử dụng cho mã lệnh (“machine code”) trong các phân đoạn mã
PAGE_EXECUTE:
như .text.
o Bộ nhớ cho phép đọc, ghi, và thực thi.
o Quyền này thường bị hạn chế do nguy cơ bị khai thác bởi mã độc
PAGE_EXECUTE_READWRITE:
(vd: injection mã độc).
Khi tiến trình cố gắng thực hiện truy cập vào vùng nhớ không hợp lệ hoặc vi
phạm quyền đã được thiết lập, CPU phát sinh ngoại lệ Access Violation, và hệ
điều hành sẽ chấm dứt tiến trình hoặc kích hoạt trình xử lý ngoại lệ. Các API như
VirtualProtect cho phép thay đổi quyền truy cập bộ nhớ trong thời gian chạy
(runtime), cho phép các chương trình điều chỉnh cơ chế bảo vệ bộ nhớ theo nhu
cầu.
Hệ điều hành sử dụng các cơ chế này kết hợp với các công nghệ bảo mật
hiện đại như DEP (Data Execution Prevention) và ASLR (Address Space Layout
Randomization) để giám sát tính toàn vẹn của mã và dữ liệu, bảo vệ hệ thống khỏi
các lỗ hổng bảo mật như buffer overflow, stack overflow, hoặc code injection.
Một số Windows API liên quan đến tiến trình
Windows API
Windows API (Application Programming Interface) là tập hợp các giao diện
lập trình được Microsoft cung cấp để tương tác và điều khiển hệ điều hành
Windows. API này cho phép lập trình viên thực hiện các thao tác hệ thống như
16
tạo tệp (CreateFileA), phân bổ bộ nhớ từ xa (VirtualAllocEx), và nhiều chức năng
khác có thể tìm thấy trực tuyến tại trang của Microsoft.
Microsoft đặc biệt khuyến khích việc sử dụng các cuộc gọi được ghi lại vì
nó giúp người lập trình windows có cảm giác mượt mà hơn; tuy nhiên, một số
lệnh gọi WinAPI được cấu thành từ các lệnh gọi phức tạp hơn, đôi khi không được
ghi lại như những API khác. Các cuộc gọi cấp thấp hơn này thường cung cấp khả
năng kiểm soát hệ điều hành tốt hơn so với các đối tác cấp cao hơn của chúng.
Một nhóm các chức năng cấp thấp hơn này được gọi là Native API. Đây là nhóm
các hàm cấp thấp hơn, cung cấp khả năng kiểm soát sâu hơn đối với hệ điều hành.
Native API được sử dụng trong quá trình khởi động hệ thống (trước khi Windows
API khả dụng) và khi lập trình trình điều khiển. Các hàm trong Native API bắt
đầu với tiền tố "Nt" (cho lệnh gọi từ user mode) hoặc "Zw" (cho lệnh gọi từ kernel
mode). Ví dụ: NtTerminateProcess có thể thay thế TerminateProcess để chấm dứt
tiến trình, mặc dù hàm cấp cao hơn thường thực hiện thêm các bước đảm bảo thực
thi "sạch".
Các tác giả phần mềm độc hại thường sử dụng Native API để vượt qua phân
tích hành vi của AV/EDR, nhằm hoàn thành mục tiêu tương tự nhưng với các API
ít được giám sát hơn.
Cách Windows tạo tiến trình mới
Hệ điều hành Windows cung cấp nhiều phương thức để khởi tạo tiến trình,
từ Shell API cấp cao chỉ yêu cầu tên tệp tin đến Native API cấp thấp đòi hỏi phân
tích cú pháp thủ công tệp nhị phân và tạo luồng khởi tạo. Mặc dù có sự đa dạng
về các API khởi tạo tiến trình, tất cả các phương thức này cuối cùng đều tập trung
vào hai system call cốt lõi.
17
Hình 1.5. Các hàm được sử dụng để tạo một tiến trình mới
Tất cả các hàm API được ghi lại đầy đủ trong tài liệu Microsoft cuối cùng
đều dẫn đến hai hàm chính là CreateProcess hoặc CreateProcessAsUser. Một số
API cấp cao gọi các hàm này một cách trực tiếp, trong khi các API khác yêu cầu
cơ chế COM/RPC (Component Object Model/Remote Procedure Call) để chuyển
tiếp yêu cầu đến các thành phần hệ điều hành chuyên dụng như dịch vụ AppInfo,
WMI (Windows Management Instrumentation), Secondary Logon, hoặc
Windows Explorer).
Hàm CreateProcess là hàm API cấp cao được sử dụng rộng rãi nhất để tạo
tiến trình mới trên Windows. CreateProcess nhận các tham số đầu vào bao gồm
tên file thực thi, dòng lệnh, thuộc tính bảo mật, cờ tạo tiến trình, biến môi trường,
và cấu trúc STARTUPINFO. Hàm này tạo ra một tiến trình mới cùng với luồng
chính (primary thread) của nó.
Mặc dù CreateProcess là một hàm khá phức tạp với nhiều tham số, phần lớn
logic cốt lõi được thực hiện bên trong system call NtCreateUserProcess ở tầng
kernel. Ngoài việc dựa vào các cấu trúc Native API và được thiết kế tối ưu hơn,
18
NtCreateUserProcess có chức năng tương tự như CreateProcess. Hàm này nhận
tên file, tham số, và mảng thuộc tính làm đầu vào, sau đó tạo ra một tiến trình sẵn
sàng thực thi với luồng khởi tạo ban đầu.
Quá trình tạo tiến trình mới trên Windows thông qua API CreateProcess
được thực hiện qua 6 bước cơ bản:
Bước 1 - Mở tệp tin thực thi: Hệ điều hành mở file thực thi (.exe) được chỉ
định và xác thực định dạng PE (Portable Executable).
Bước 2 - Tạo đối tượng tiến trình: Thực hiện lời gọi hệ thống
NtCreateProcess để tạo đối tượng tiến trình, bao gồm khởi tạo khối EPROCESS,
không gian địa chỉ ảo, khối tiến trình nhân KPROCESS, ánh xạ file image vào
không gian địa chỉ, và khởi tạo PEB (Process Environment Block).
Bước 3 - Tạo luồng khởi tạo: Tạo luồng chính (primary thread) cùng với
stack và ngữ cảnh (context) của nó. Thread Environment Block (TEB) cũng được
khởi tạo trong bước này.
Bước 4 - Thông báo hệ thống con: Thông báo cho Windows subsystem về
tiến trình mới được tạo để đăng ký và quản lý.
Bước 5 - Bắt đầu thực thi luồng: Kích hoạt luồng khởi tạo để bắt đầu thực
thi.
Bước 6 - Hoàn tất khởi tạo không gian địa chỉ: Trong ngữ cảnh của luồng và
tiến trình mới, hoàn thiện việc khởi tạo không gian địa chỉ, nạp các thư viện liên
kết động (DLL) cần thiết, và bắt đầu thực thi chương trình.
19
Hình 1.6. Không gian địa chỉ ảo của một tiến trình mới được tạo
Khi tiến trình mới được tạo, không gian địa chỉ ảo ban đầu của nó chỉ chứa
hai thành phần thực thi được ánh xạ: chương trình chính (main executable) và
ntdll.dll. Thư viện ntdll.dll là thư viện cơ sở cung cấp giao diện Native API cho
user mode và đóng vai trò quan trọng trong quá trình khởi động tiến trình. Các
phần phụ thuộc khác (kernel32.dll, shell32.dll, v.v.) được tải sau theo yêu cầu bởi
luồng đầu tiên khi module loader (được triển khai trong ntdll) bắt đầu giải quyết
các phụ thuộc của chương trình. Ngoài mã thực thi, không gian địa chỉ của mỗi
tiến trình mới chứa một số cấu trúc dữ liệu cơ bản sau:
PEB - Process Environment Block là một vùng bộ nhớ lưu trữ và tham
chiếu chéo thông tin trong toàn bộ quá trình bên trong, bao gồm process
parameters, heaps và danh sách các mô-đun đã được tải.
RTL_USER_PROCESS_PARAMETERS - một cấu trúc kiểm soát các đối
số dòng lệnh, biến môi trường, cài đặt giao diện và các tùy chọn cấu hình
20
khác. CreateProcess xây dựng hầu hết các trường của nó từ
STARTUPINFO, do đó có sự giống nhau.
TEB - Thread Environment Block: Đây là cấu trúc dữ liệu thiết yếu lưu trữ
hầu hết các thông tin cấu hình riêng cho từng luồng. Nhiều hàm API phổ
biến như GetCurrentProcessId, GetCurrentThreadId, và GetLastError truy
xuất thông tin trực tiếp từ các trường tương ứng trong TEB mà không cần
thực hiện system call, giúp tối ưu hiệu suất.
Thread Stack: Mỗi luồng có một vùng stack riêng được dành riêng để lưu
trữ phân cấp cuộc gọi hàm (call hierarchy) và các biến cục bộ. Vùng stack
này được cấp phát trong không gian địa chỉ của tiến trình và có kích thước
mặc định có thể được cấu hình.
Các tiến trình được tạo thông qua NtCreateUserProcess (và do đó
CreateProcess cùng tất cả các hàm API cấp cao hơn) luôn bao gồm ít nhất một
luồng. Luồng khởi tạo này sẽ có một TEB riêng và một vùng stack được cấp phát
tại một vị trí nào đó trong không gian địa chỉ của tiến trình. Không có tiến trình
nào có thể tồn tại mà không có ít nhất một luồng thực thi.
21
Các hàm API cấp phát bộ nhớ của tiến trình
Hình 1.7. Sơ đồ các API được sử dụng để cấp phát bộ nhớ tiến trình
Hình trên hiển thị sơ đồ các hàm API được sử dụng để cấp phát bộ nhớ tiến
trình và cách các hàm liên kết với nhau. Mô hình này mang lại tính linh hoạt cao
cho lập trình viên khi lựa chọn mức độ kiểm soát phù hợp với nhu cầu ứng dụng,
cùng với khả năng cho các hệ thống con như trình quản lý heap tồn tại ở giữa và
giúp đảm bảo rằng việc cấp phát và giải quyết khối bộ nhớ nhỏ xảy ra hiệu quả.
Các hàm gọi nhau theo cách này được kết nối với các mũi tên.
Tổng quan về kỹ thuật tiêm tiến trình
Giới thiệu chung về kỹ thuật tiêm tiến trình
Chèn mã độc vào một tiến trình thực thi hợp lệ của hệ điều hành hay còn
được gọi là process injection. Kẻ tấn công có thể chèn mã vào các tiến trình để né
tránh các biện pháp phòng thủ dựa trên tiến trình cũng như có thể nâng cao đặc
quyền. Tiêm tiến trình là một phương pháp thực thi mã tùy ý trong không gian địa
chỉ của một tiến trình đang chạy khác. Việc chạy mã trong ngữ cảnh của tiến trình
khác có thể cho phép truy cập vào bộ nhớ của tiến trình, tài nguyên hệ thống/mạng
22
và có thể cả đặc quyền cao hơn. Thực thi thông qua tiêm tiến trình cũng có thể né
tránh việc phát hiện từ các sản phẩm bảo mật vì việc thực thi được che giấu dưới
một tiến trình hợp pháp.
Tiêm tiến trình là một kỹ thuật quan trọng trong khai thác Windows, cho
phép tiêm nạp mã vào một tiến trình khác để thực thi. Kỹ thuật này thường được
sử dụng rộng rãi bởi mã độc, Red Team, và các nhóm tấn công APT để tránh bị
phát hiện.
Các kỹ thuật tiêm tiến trình được thiết kế để vượt qua các cơ chế bảo mật
của Windows như:
Phần mềm chống vi-rút (Antivirus - AV)
Phòng chống thất thoát dữ liệu (Data Loss Prevention - DLP)
Tường lửa cá nhân (Personal Firewall)
Các kỹ thuật này cho phép mã độc thực thi các hành động nhạy cảm như:
Truy cập mạng
Chạy mã độc dưới danh nghĩa tiến trình hợp pháp
Bỏ qua kiểm tra bảo mật của hệ điều hành
23
Hình 1.8. Top 10 kỹ thuật được mã độc sử dụng nhiều nhất được thống kê bởi
Picus Security, CrowdStrike, Recorded Future và Red Canary năm 2020
Kỹ thuật tiêm tiến trình luôn nằm trong top 10 các kỹ thuật phổ biến nhất
được sử dụng bởi các kẻ tấn công theo thống kê trong năm 2020 bởi Picus
Security, CrowdStrike, Recorded Future và Red Canary.
24
Hình 1.9. Các nhóm APT và dòng mã độc sử dụng tiêm tiến trình (nguồn: Mitre
ATT&CK)
Một số nhóm APT và dòng mã độc đã được ghi nhận là sử dụng kỹ thuật
Tiêm tiến trình trong các cuộc tấn công của chúng (theo khung MITRE
ATT&CK).
Tác động của kỹ thuật tiêm tiến trình trong phần mềm độc hại
Việc phát hiện phần mềm độc hại rất dễ dàng khi bạn có thể liệt kê các tiến
trình đang chạy và lọc ra những tiến trình hợp pháp nằm trong hệ điều hành hoặc
phần mềm đã cài đặt. Tuy nhiên, nếu phần mềm độc hại có thể đóng gói mã độc
của nó trong một tiến trình hợp pháp, nó sẽ ẩn trên hệ thống bị nhiễm. Việc chạy
mã tùy ý trong không gian địa chỉ của một tiến trình khác cho phép mã độc truy
cập vào tài nguyên mạng, hệ thống và bộ nhớ của tiến trình đích.
Kỹ thuật tiêm tiến trình giúp kẻ tấn công ba lợi ích chính như sau:
Việc thực thi mã dưới danh nghĩa một tiến trình hợp pháp có thể né
tránh các biện pháp kiểm soát bảo mật. Mã độc thường ngụy trang
thành tiến trình hợp pháp để tránh bị phát hiện.
Có thể trốn tránh việc điều tra số trên đĩa vì mã độc hại được thực thi
bên trong không gian bộ nhớ của tiến trình hợp pháp.
25
Nếu tiến trình đích có quyền truy cập của quản trị viên vào tài nguyên
hệ thống, việc tiêm tiến trình có thể dẫn đến leo thang đặc quyền. Ví
dụ: nếu tiến trình đích có đặc quyền truy cập Internet, mã độc có thể
vượt qua kiểm soát bảo mật để giao tiếp hợp pháp qua Internet.
Các biện pháp kiểm soát bảo mật (security controls) có thể nhanh chóng phát
hiện các tiến trình tùy chỉnh hoặc bất thường. Do đó, các kẻ tấn công thường lợi
dụng các tiến trình Windows phổ biến và hợp pháp sau đây để che giấu hoạt động
độc hại của chúng. Các tiến trình hợp pháp thường bị lạm dụng như:
Các tiến trình Windows gốc tích hợp sẵn bao gồm các tệp như
explorer.exe, cmd.exe, PowerShell.exe, svchost.exe, regsrv32.exe,
dllhost.exe, vbc.exe, services.exe, cvtres.exe, msbuild.exe,
RegAsm.exe, RegSvcs.exe, rundll32.exe, csc.exe, AppLaunch.exe và
arp.exe.
Các tiến trình của phần mềm thông thường bao gồm các trình duyệt
và ứng dụng phổ biến như iexplore.exe, ieuser.exe, opera.exe,
chrome.exe, firefox.exe, outlook.exe và msi.exe.
Kẻ tấn công sử dụng các phương pháp sau khi chọn tiến trình mục tiêu để
tiêm mã độc hại:
Một tiến trình đích cụ thể được gọi trong code.explorer.exe và
svchost.exe là những tiến trình được sử dụng phổ biến nhất.
Một danh sách các tiến trình đích được xác định trong mã. Ví dụ:
Carbon backdoor của nhóm Turla bao gồm tệp cấu hình bao gồm danh
sách các tiến trình đích để tiêm. Một danh sách điển hình bao gồm các
tiến trình Windows và trình duyệt gốc.
Trong một số tình huống tấn công, tiến trình mục tiêu không được xác
định trước đó và một tiến trình máy chủ lưu trữ phù hợp được đặt tại
thời gian chạy trong kiểu tấn công này. Ví dụ: nhóm CopyKittens đã
sử dụng các hàm API của Windows để trích xuất danh sách các tiến
trình hiện đang hoạt động và để xử lý từng tiến trình mục tiêu trong
chiến dịch của mình.
26
Có nhiều cách khác nhau để đưa mã vào một tiến trình, nhiều cách trong số
đó lạm dụng các chức năng hợp pháp. Các triển khai này tồn tại cho mọi hệ điều
hành chính nhưng thường là dành riêng cho các nền tảng cụ thể.
Các mẫu phức tạp hơn có thể thực hiện tiêm nhiều lần để phân đoạn các mô-đun
và tránh xa hơn nữa việc phát hiện, sử dụng các đường ống được đặt tên hoặc các
cơ chế giao tiếp giữa các quá trình (IPC) làm kênh liên lạc.
Một số kỹ thuật process injection cơ bản:
Process Hollowing
Process Herpaderping
Process Doppelgänging
Dynamic-link Library Injection
Asynchronous Procedure Call
Một số công cụ và giải pháp phòng chống hiện nay
Hiện tại, phần lớn các hệ thống bảo mật vẫn áp dụng phương pháp phát hiện
dựa trên chữ ký (signature-based detection). Mặc dù cách tiếp cận này mang lại
tốc độ xử lý nhanh và độ chính xác cao đối với các mẫu mã độc đã được nhận
diện trước đó, nhưng trong bối cảnh các kỹ thuật tiêm tiến trình ngày càng phức
tạp, việc chỉ dựa vào chữ ký đã không còn đủ hiệu quả.
Các kỹ thuật injection hiện đại thường được áp dụng các phương pháp làm
rối mã (obfuscation), đóng gói (packing) và tùy biến phức tạp, khiến cho việc
nhận diện theo chữ ký trở nên không đủ mạnh để bảo vệ hệ thống một cách toàn
diện.
Tổng quan các giải pháp hiện có bao gồm:
1. Sysinternals Sysmon
Chức năng chính: Sysmon là một công cụ giám sát hệ thống mạnh mẽ, có khả
năng thu thập nhật ký chi tiết về các hoạt động của tiến trình, truy cập mạng,
và các thay đổi trên hệ thống.
o Event ID 8: Phát hiện tạo luồng từ xa (CreateRemoteThread)
Ưu điểm: Cung cấp các sự kiện quan trọng như:
o Event ID 10: Giám sát truy cập bộ nhớ tiến trình (ProcessAccess)
27
Hạn chế: Hiệu quả của Sysmon phụ thuộc nhiều vào cấu hình. Với cấu hình
không tối ưu, nó có thể bỏ sót các kỹ thuật tiêm tinh vi hơn như tiêm shellcode
(shellcode injection) hoặc các phương pháp lẩn tránh khác.
2. Event Tracing for Windows (ETW)
Chức năng chính: ETW là một cơ chế ghi nhật ký hiệu suất cao ở cấp độ nhân
(kernel-level), cho phép giám sát các lệnh gọi API nhạy cảm như
VirtualAllocEx, WriteProcessMemory, và CreateRemoteThread.
Ưu điểm: Cung cấp khả năng phát hiện các hành vi bất thường dựa trên chuỗi
lệnh gọi API, ngay cả khi mã độc thay đổi chữ ký (signature).
Hạn chế: ETW tạo ra một lượng dữ liệu nhật ký (log) khổng lồ, gây khó khăn
cho việc lưu trữ và phân tích nếu không có hệ thống quản lý và tối ưu hóa hiệu
quả.
3. Endpoint Detection and Response (EDR)
Chức năng chính: EDR là các giải pháp bảo mật toàn diện, tích hợp khả năng
phân tích hành vi, học máy (machine learning), và phân tích ngữ cảnh để phát
hiện các mối đe dọa phức tạp.
Ưu điểm: Có khả năng phát hiện các kỹ thuật tiêm tiến trình mà không cần phụ
thuộc vào các mẫu (pattern) hay chữ ký có sẵn, dựa trên việc xác định các
chuỗi hành vi bất thường.
Hạn chế: Nhiều nghiên cứu đã chỉ ra rằng các giải pháp EDR có thể bị qua mặt
(bypass) bởi các kỹ thuật lẩn tránh tinh vi. Kẻ tấn công thậm chí có thể nhắm
vào chính EDR để làm sai lệch dữ liệu theo dõi (telemetry data).
4. Windows Defender Attack Surface Reduction (ASR)
Chức năng chính: ASR là một tập hợp các quy tắc được thiết kế để ngăn chặn
các hành vi thường bị mã độc lạm dụng, bao gồm cả việc chặn các lệnh gọi
API nguy hiểm.
Ưu điểm: Giúp giảm thiểu bề mặt tấn công (attack surface) một cách hiệu quả
bằng cách áp dụng các chính sách phòng ngừa cứng rắn.
28
Hạn chế: ASR chủ yếu mang tính phòng ngừa (prevention) và không phải là
một giải pháp phát hiện (detection) toàn diện. Nó có thể bị vô hiệu hóa hoặc
không đủ linh hoạt để đối phó với các kỹ thuật mới.
5. YARA và Sigma Rules
Chức năng chính: Đây là các ngôn ngữ quy tắc cho phép các nhà phân tích bảo
mật xây dựng các bộ luật tùy chỉnh để tìm kiếm các mẫu mã độc, chuỗi ký tự,
hoặc hành vi cụ thể trong tệp tin và bộ nhớ.
Ưu điểm: Rất hiệu quả trong các hoạt động săn tìm mối đe dọa (threat hunting)
chủ động, cho phép phát hiện các biến thể mã độc đã biết.
Hạn chế: Hiệu quả của chúng phụ thuộc vào các mẫu (pattern) có sẵn. Do đó,
chúng gặp khó khăn trong việc phát hiện các biến thể hoàn toàn mới hoặc các
kỹ thuật tiêm chưa từng được biết đến.
Các giải pháp hiện tại, dù mang lại nhiều lợi ích về phát hiện và phòng chống
kỹ thuật tiêm tiến trình, vẫn bộc lộ những hạn chế cơ bản. Đầu tiên, chúng dễ dàng
bị bỏ lọt các phương thức injection mới hoặc các biến thể đã được tùy biến tinh
vi, dẫn đến nguy cơ mã độc vượt qua cơ chế giám sát. Bên cạnh đó, việc sử dụng
các dấu hiệu gián tiếp khiến hệ thống có thể sinh ra nhiều cảnh báo giả (false
positives), ảnh hưởng đến hiệu quả vận hành và gây khó khăn cho quá trình phân
tích. Ngoài ra, những giải pháp này còn gặp thách thức lớn khi xử lý các dạng
malware không chứa file hoặc kỹ thuật reflective injection, do chủ yếu tập trung
nhận diện dấu hiệu mà chưa đi sâu vào phân tích trực tiếp dữ liệu bộ nhớ.
Để khắc phục những hạn chế trên, cần thiết phải nghiên cứu và phát triển
hướng tiếp cận mới dựa trên phân tích bộ nhớ (Memory Analysis), cho phép phát
hiện các kỹ thuật tiêm tiến trình một cách trực tiếp và chính xác hơn.
Kết luận chương 1
Chương này sẽ cung cấp một cái nhìn tổng quát về cấu trúc bộ nhớ của tiến
trình. Đồng thời, chương này cũng đã trình bày về khái niệm và tổng quan về tiêm
tiến trình. Kỹ thuật này vẫn liên tục thay đổi và cập nhập nhằm mục đích ẩn giấu
mã của nó tránh bị phát hiện. Trong chương 2, em sẽ nghiên cứu tìm hiểu một số
29
kỹ thuật tiêm tiến trình tiêu biểu hiện nay và đưa ra các dấu hiệu đáng ngờ trên bộ
nhớ để phát hiện có tiên tiến trình.
30
NGHIÊN CỨU MỘT SỐ KỸ THUẬT TIÊM TIẾN TRÌNH
VÀ DẤU HIỆU PHÁT HIỆN
Phân loại các kỹ thuật tiêm tiến trình cơ bản
Tiêm thư viện động (DLL-based injection)
DLL Injection
DLL Injection là quá trình chèn mã độc vào một tiến trình đang chạy. Code
được sử dụng ở đây là ở dạng thư viện liên kết động (DLL).
Có 2 cách để thực hiện kỹ thuật này:
Cách 1: Sử dụng hàm LoadLibraryA() để thực thi mã độc
LoadLibraryA() là hàm trong kernel32.dll để nạp DLL, file thực thi hoặc các
loại thư viện khác. Tham số truyền vào của hàm là tên DLL. Nghĩa là chúng ta
chỉ cần cấp phát một vùng nhớ, ghi đường dẫn đến DLL và chọn điểm bắt đầu
thực thi là địa chỉ của hàm LoadLibraryA(), tham số truyền vào là địa chỉ của
vùng nhớ chứa đường dẫn đến DLL.
Nhược điểm chính của hàm LoadLibraryA() là nó sẽ đăng ký DLL với
chương trình nên sẽ dễ bị phát hiện (mỗi chương trình đều có một bảng các DLL
sẽ nạp).
Mở một tiến trình đích (OpenProcess)
Tạo mới một đoạn bộ nhớ trong tiến trình (Virtual ALLocEx)
Ghi shellcode vào phần mới được phân bổ (WriteProcessMemory)
Tạo một luồng mới trong tiến trình từ xa để thực thi hàm LoadLibrary
Công thức cơ bản của kỹ thuật này cũng có 5 bước:
Xóa bỏ vùng nhớ vừa tạo mới để xóa dấu vết (VirtualFreeEx)
để tải DLL độc hại (CreateRemoteThread)
Cách 2: Nhảy đến DLLMain (hoặc một entry point khác):
Một phương thức thay thế cho LoadLibraryA() là nạp toàn bộ DLL vào vùng
nhớ và xác định offset tới DLL entry point. Sử dụng phương thức này sẽ tránh
được việc đăng ký DLL với chương trình (tàng hình) và thực thi DLL trong
process.
31
Kỹ thuật này cũng sử dụng được với các định dạng file PE khác, thay vì nhảy
và DLL Main thì ta có thể nhảy vào Entry Point của file EXE.
Hình 2.1. Các bước thực hiện kỹ thuật DLL Injection sử dụng cách 2.
Mở tiến trình đích (OpenProcess).
Tạo một vùng nhớ mới trong tiến trình (VirtualAllocEx).
Thực hiện Map Image của file PE lên vùng nhớ vừa khởi tạo.
Tạo mới một thread để thực thi file PE vừa được map lên
Công thức cơ bản cả kỹ thuật này có 4 bước:
(CreateRemoteThread).
32
Hình 2.2. Ví dụ về kỹ thuật DLL Injection sử dụng cách 2
Reflective DLL Injection
Reflective DLL injection là một kỹ thuật cho phép kẻ tấn công đưa DLL vào
tiến trình nạn nhân từ bộ nhớ chứ không phải đĩa. Đối với kỹ thuật DLL injection
thông thường đều sử dụng hàm LoadLibrary để tải DLL. Vì vậy nó bị giám sát rất
nhiều bởi phần mềm bảo mật. Tuy nhiên, đối với kỹ thuật Reflective DLL
33
injection, kỹ thuật này sẽ triển khai LoadLibrary một cách thủ công và hỗ trợ tải
các tệp DLL từ bộ nhớ.
Cách thức hoạt động của phương pháp tiêm phản xạ được tác giả ban đầu
của kỹ thuật này là Stephen Fewer mô tả như sau:
Quá trình thực thi được chuyển qua CreateRemoteThread() hoặc một
shellcode bootstrap nhỏ, tới hàm ReflectiveLoader của thư viện, một
hàm đã xuất được tìm thấy trong bảng xuất của thư viện.
Vì hình ảnh của thư viện hiện sẽ tồn tại ở một vị trí tùy ý trong bộ nhớ,
ReflectiveLoader trước tiên sẽ tính toán vị trí hiện tại của hình ảnh của
chính nó trong bộ nhớ để có thể phân tích cú pháp các tiêu đề của
chính nó để sử dụng sau này.
ReflectiveLoader sau đó sẽ phân tích cú pháp bảng xuất kernel32.dll
của tiến trình máy chủ để tính toán địa chỉ của ba chức năng mà trình
tải yêu cầu, cụ thể là LoadLibraryA, GetProcAddress và VirtualAlloc.
Lúc này ReflectiveLoader sẽ phân bổ một vùng bộ nhớ liên tục mà nó
sẽ tiến hành tải hình ảnh của chính nó vào đó. Vị trí không quan trọng
vì trình tải sẽ định vị lại hình ảnh một cách chính xác sau này.
Các tiêu đề và phần của thư viện được tải vào vị trí mới của chúng
trong bộ nhớ.
ReflectiveLoader sau đó sẽ xử lý bản sao mới được tải của bảng nhập
hình ảnh của nó, tải bất kỳ thư viện bổ sung nào và giải quyết các địa
chỉ chức năng đã nhập tương ứng của chúng.
ReflectiveLoader sau đó sẽ xử lý bản sao mới được tải của bảng di
chuyển hình ảnh của nó.
ReflectiveLoader sau đó sẽ gọi chức năng điểm vào của hình ảnh mới
được tải của nó, DllMain với DLL_PROCESS_ATTACH. Thư viện
hiện đã được tải thành công vào bộ nhớ.
34
Cuối cùng, ReflectiveLoader sẽ trả lại quá trình thực thi cho shellcode
bootstrap ban đầu đã gọi nó hoặc nếu nó được gọi thông qua
CreateRemoteThread, luồng sẽ kết thúc.
Hình 2.3. Luồng thực thi reflect DLL injection
Thay thế tiến trình
Process Hollowing
Process Hollowing là một kỹ thuật lẩn tránh tinh vi, cho phép thực thi mã
độc dưới danh nghĩa của một tiến trình hợp pháp. Ý tưởng cốt lõi của kỹ thuật này
là "khoét rỗng" một tiến trình hợp pháp đang tồn tại và thay thế mã nguồn của nó
bằng mã độc.
Quá trình này diễn ra theo các bước sau:
1. Khởi tạo tiến trình ở trạng thái treo: Đầu tiên, kẻ tấn công tạo ra một tiến
trình mới (tiến trình đích) từ một tệp thực thi hợp pháp trên hệ thống (ví dụ:
svchost.exe) nhưng ở trạng thái bị treo (suspended state). Ở trạng thái này,
tiến trình đã được cấp phát bộ nhớ nhưng chưa thực thi bất kỳ mã lệnh nào.
2. Gỡ bỏ mã gốc (Unmapping): Tiếp theo, phần image (là mã thực thi của
chương trình đã được nạp vào bộ nhớ RAM) của tiến trình đích sẽ bị gỡ bỏ
(unmapped) khỏi không gian bộ nhớ ảo của nó.
3. Tiêm mã độc: Kẻ tấn công sẽ cấp phát một vùng nhớ mới và ghi image của
mã độc (tiến trình nguồn) vào không gian địa chỉ vừa bị làm trống của tiến
35
trình đích. Về cơ bản, tiến trình hợp pháp lúc này không còn chứa mã lệnh
gốc của nó nữa, mà thay vào đó là mã của chương trình độc hại.
4. Điều chỉnh địa chỉ (Rebasing): Nếu địa chỉ cơ sở (Image Base) của mã độc
mới không khớp với địa chỉ cơ sở của mã gốc, kẻ tấn công sẽ thực hiện quá
trình rebasing (sắp xếp lại địa chỉ). Quá trình này điều chỉnh lại các địa chỉ
tuyệt đối trong mã độc để chúng hoạt động chính xác tại vị trí mới trong bộ
nhớ.
5. Cập nhật điểm bắt đầu (Entry Point): Thanh ghi EAX của luồng chính đang
bị treo sẽ được cập nhật để trỏ đến entry point (điểm bắt đầu thực thi) của
mã độc vừa được tiêm vào.
6. Kích hoạt thực thi: Cuối cùng, tiến trình sẽ được cho tiếp tục chạy
(resumed). Hệ điều hành sẽ bắt đầu thực thi từ entry point mới, và do đó,
mã độc sẽ được thực thi dưới vỏ bọc của một tiến trình hoàn toàn hợp pháp.
Hình 2.4. Luồng thực thi của kỹ thuật Process Hollowing
Các API Calls được sử dụng trong kỹ thuật Process Hollowing:
Kernel32.dll: CreateProcessA, ReadProcessMemory, WriteProcessMemory,
GetThreadContext, SetThreadContext, ResumeThread.
36
Ntdll.dll: NtQueryInformationProcess, NtUnmapViewOfSection,
ZwUnmapViewOfSection.
Ưu điểm của kỹ thuật này là đường dẫn của tiến trình bị rỗng vẫn sẽ chỉ ra
đường dẫn hợp pháp và bằng cách thực thi trong bối cảnh tiến trình hợp pháp,
phần mềm độc hại có thể vượt qua tường lửa và hệ thống ngăn chặn xâm nhập
máy chủ. Ví dụ: nếu tiến trình svchost.exe bị rỗng, đường dẫn vẫn sẽ trỏ đến tệp
thực thi hợp pháp (C:\Windows\system32\svchost.exe), nhưng chỉ trong bộ nhớ,
phần thực thi của svchost.exe được thay thế bằng mã độc, điều này cho phép
những kẻ tấn công vẫn không bị phát hiện từ các công cụ điều tra
DarkComet là một trong nhiều họ phần mềm độc hại sử dụng các kỹ thuật
chèn mã độc vào tiến trình treo. Một số tạo tác có thể được sử dụng để phát hiện
tiến trình rỗng. Một tặng cho hoạt động này là một tiến trình được sinh ra với cờ
CREATE_SUSPENDED, như được hiển thị trong ảnh chụp màn hình sau từ mẫu
DarkComet.
Hình 2.5. Tiến trình được tạo với trạng thái CREATE_SUSPENDED.
37
Hình 2.6. Mã độc Ransom.Cryak thực hiện kỹ thuật Process Hollowing.
38
Hình 2.7. Một ví dụ về Process Hollowing.
Module Stomping
Các bước cơ bản của kỹ thuật này:
Mở một tiến trình đích và lấy handle của tiến trình đích: OpenProcess.
Tải mô-đun đích trong tiến trình đích.
Ghi tải trọng tại địa chỉ điểm vào (entrypoint) của mô-đun đã tải:
LoadLibraryA
Tạo luồng để thực thi tải trọng.
39
Các API calls trong kỹ thuật Module Stomping bao gồm:
Kernel32.dll: OpenProcess, ReadProcessMemory,
WriteProcessMemory, VirtualAllocEx, VirtualProtectEx,
CreateRemoteThread, QueueUserAPC,
Psapi.dll: EnumProcessModules, GetModuleFileNameEx
Ntdll.dll: NtAllocateVirtualMemory
Hình 2.8. Kỹ thuật Module Stomping
Tiêm dựa trên thao tác file thực thi (Executable Tampering)
Process Doppelganging
Windows Transactional NTFS (TxF) được giới thiệu trong Vista như một
phương pháp để thực hiện các hoạt động tệp an toàn. Để đảm bảo tính toàn vẹn
dữ liệu, TxF chỉ cho phép một luồng xử lý được thực hiện ghi vào tệp tại một thời
điểm nhất định. Cho đến khi luồng xử lý ghi bị chấm dứt, tất cả các luồng xử lý
khác được cách ly khỏi trình ghi và chỉ có thể đọc phiên bản đã cam kết của tệp
tồn tại tại thời điểm xử lý được mở. Để mất mát dữ liệu, TxF thực hiện khôi phục
tự động nếu hệ thống hoặc ứng dụng bị lỗi trong khi giao dịch ghi.
Mặc dù không được dùng nữa, nhưng các API TxF vẫn được bật trên
Windows 10.
Kẻ tấn công có thể lạm dụng TxF để thực hiện một biến thể xử lý không có
tệp. Tương tự như Process Hollowing, Process doppelgänging liên quan đến việc
thay thế bộ nhớ của một tiến trình hợp pháp, cho phép thực thi mã độc che giấu
có thể trốn tránh sự phát hiện của các hệ thống phòng thủ. Tiến trình sử dụng TxF
40
của doppelgänging cũng tránh việc sử dụng các hàm API được giám sát cao như
NtUnmapViewOfSection, VirtualProtectEx và SetThreadContext.
Chèn vào mã độc vào luồng xử lý tập tin (Process Doppelgänging) được thực
Transact - Tạo giao dịch TxF bằng cách sử dụng hợp pháp sau đó ghi đè
hiện theo 4 bước:
tệp bằng mã độc. Những thay đổi này sẽ được tách biệt và chỉ hiển thị
Load - Tạo một phần chia sẻ của bộ nhớ và tải tệp thực thi độc hại.
Rollback - Hoàn tác các thay đổi đối với tệp thực thi gốc, loại bỏ hiệu
trong bối cảnh giao dịch.
Animate - Tạo một tiến trình từ phần bộ nhớ bị nhiễm độc và bắt đầu
quả mã độc khỏi hệ thống tệp.
thực hiện.
Hình 2.9. Luồng thực thi của Process Doppelganging
Hành vi này có thể sẽ không dẫn đến các đặc quyền nâng cao do tiến trình
được chèn được sinh ra từ (và do đó thừa hưởng bối cảnh bảo mật) của tiến trình
mã độc. Tuy nhiên, thực thi thông qua tiến trình doppelgänging có thể trốn tránh
sự phát hiện từ các sản phẩm bảo mật do việc thực thi được che dấu theo một tiến
trình hợp pháp.
Các API calls trong kỹ thuật Process Doppelganging bao gồm:
KtmW32.dll: CreateTransaction, RollbackTransaction
41
Kernel32.dll: CreateFileTransactedA, WriteFile,
Ntdll.dll: NtCreateSection, NtCreateProcessEx, NtCreateThreadEx
Process Herpaderping
Kỹ thuật tương đối mới này sử dụng một giải pháp thay thế đơn giản nhưng
rất hiệu quả là sửa đổi nội dung trên đĩa sau khi hình ảnh đã được ánh xạ. Vì
NtCreateProcess yêu cầu người gọi mở tệp thực thi theo cách thủ công, chúng ta
có thể sử dụng cơ hội này để yêu cầu quyền ghi vào tệp - điều trở nên bất khả thi
do các quy tắc khóa khi chúng ta tạo section. Sau khi có được handle này, chúng
ta có thể sao lưu nội dung tệp gốc và ghi đè lên nó bằng payload. Sau đó, chuẩn
bị phần hình ảnh (phần này đọc và lưu vào bộ nhớ cache của payload) và khôi
phục nội dung của tệp về trạng thái ban đầu. Mặc dù khôi phục, section object vẫn
sử dụng dữ liệu payload. Cuối cùng, đóng tệp và tiến hành tạo tiến trình cấp thấp
điển hình (sử dụng đối tượng phần đã thay đổi). Đáng chú ý, bởi vì kẻ tấn công
không bao giờ xóa tệp hoặc hoàn nguyên các giao dịch, phần không bao giờ mất
liên kết với tệp gốc. Ngay cả các AV biết về Process Doppelgänge sẽ không nhận
thấy bất kỳ điều gì đáng ngờ về tiến trình mới trừ khi họ thực hiện so sánh đầy đủ
mã trong bộ nhớ với dữ liệu trên đĩa.
Process Herpaderping được thực hiện theo các bước như sau:
Ghi mã độc vào đĩa, giữ cho handle mở. Đây là những gì sẽ thực thi
trong bộ nhớ.
Ánh xạ tệp dưới dạng image section (NtCreateSection,
SEC_IMAGE).
Tạo đối tượng tiến trình bằng cách sử dụng section handle
(NtCreateProcessEx).
Sử dụng cùng một tay cầm tệp đích, che khuất tệp trên đĩa.
Tạo chuỗi ban đầu trong tiến trình (NtCreateThreadEx).
Đóng handle. IRP_MJ_CLEANUP sẽ xảy ra tại đây. Vì nội dung của những
gì đang thực thi đã bị ẩn, nên việc kiểm tra tại thời điểm này sẽ dẫn đến kết luận
không chính xác.
42
Hình 2.10. Luồng thực thi của Process Herpaderping (theo jxy-s)
Các API Calls được sử dụng trong kỹ thuật Process Herpaderping:
Kernel32.dll: CreateFileW, WriteFile, SetFilePointer, CloseHandle .
43
Ntdll.dll: NtOpenFile, NtSetInformationFile, NtCreateSection,
NtCreateProcessParametersEx, NtCreateProcessEx,
NtCreateThreadEx.
Process Ghosting
Kỹ thuật này có thể ẩn hoàn toàn tên tệp do thông tin mà hệ thống thu thập
trong quá trình tiến trình được tạo. Ngoài ra, nhiều sản phẩm bảo mật chọn tham
gia xác minh tệp một cách đồng bộ, tức là trước khi có thể giả mạo tên của tệp.
Đó là nơi mà các quyết định về kiến trúc của NtCreateProcess phát huy tác dụng
và mang lại lợi ích cho những kẻ tấn công. Syscall này sử dụng các section objects
(hay còn gọi là ánh xạ bộ nhớ), như chúng ta đã biết từ các cuộc thảo luận ở trên,
có thể làm mất liên kết của chúng với các tệp trên đĩa, ẩn danh nó một cách hiệu
quả. Khi nó xảy ra, hệ thống không thể truy vấn tên và thiết lập danh tính của tiến
trình mới từ khi nó bắt đầu tồn tại, dẫn đến một số kết quả đặc biệt. Hiệu ứng đáng
chú ý nhất là chuỗi rỗng mà hệ thống sử dụng để hiển thị tên của tiến trình. Đáng
chú ý, người gọi vẫn cần cung cấp một số tên tệp trong trường ImagePathName
của RTL_USER_PROCESS_PARAMETERS, nhưng chuỗi này có thể trỏ đến
một tệp tùy ý được lựa chọn.
Hình 2.11. Luồng thực thi của Process Ghosting
Việc triển khai cơ bản của Process Ghosting hoạt động như sau:
Tạo một tệp tạm thời.
Đặt tệp vào trạng thái chờ xóa bằng cách sử dụng
NtSetInformationFile(FileDispositionInformation).
Viết tải trọng thực thi vào tệp. Nội dung không được duy trì vì tệp
đang chờ xóa. Trạng thái chờ xóa cũng ngăn chặn việc mở tệp từ bên
ngoài.
44
Tạo một phần hình ảnh cho tập tin.
Đóng HANDLE đang chờ xóa, xóa tệp.
Tạo một tiến trình bằng cách sử dụng phần hình ảnh.
Gán đối số tiến trình và biến môi trường.
Tạo một luồng để thực thi trong tiến trình.
Các kỹ thuật tiêm khác
Chèn mã độc vào APC
Chèn mã độc vào APC (Asynchronous Procedure Call) thường được thực
hiện bằng cách đính kèm mã độc vào hàng đợi APC của luồng xử lý. Các hàm
APC trong hàng đợi được thực thi khi luồng vào trạng thái có thể cảnh báo. Một
luồng đi vào trạng thái có thể cảnh báo nếu nó gọi các hàm SleepEx,
SignalObjectAndWait, MsgWaitForMultipleObjectsEx,
WaitForMultipleObjectsEx hoặc WaitForSingleObjectEx. Mã độcthường tìm
kiếm bất kỳ chuỗi nào ở trạng thái có thể thay đổi, sau đó gọi OpenThread và
QueueUserAPC để xếp hàng APC vào chuỗi. QueueUserAPC nhận ba đối số:
1) Handle của luồng đích;
2) Một con trỏ tới chức năng mà mã độc muốn chạy;
3) Tham số được truyền cho con trỏ hàm.
Quá trình tiêm shellcode vào tiến trình sử dụng APC queue diễn ra như sau:
Tìm tiến trình để đưa payload vào: CreateToolHelp32Snapshot,
Process32First, Process32Next.
Cấp phát bộ nhớ trong tiến trình đó:
VirtualAllocEx/NtAllocateVirtualMemory.
Ghi tải trọng vào bộ nhớ được cấp phát đó: WriteProcessMemory.
Thay đổi chế độ bảo vệ bộ nhớ từ PAGE_READ_WRITE thành
PAGE_EXECUTE_READ sử dụng VirtualProtectEx.
Tìm tất cả các luồng trong tiến trình đó: Thread32First, Thread32Next.
Đặt chức năng APC vào hàng đợi cho tất cả các luồng: OpenThread,
QueueUserAPC.
45
Chức năng APC ở đây trỏ đến shellcode của chúng ta. Tải trọng sẽ
được thực thi khi luồng chuyển sang trạng thái có thể cảnh báo.
Các API call được sử dụng trong APC Injection:
Kernel32.dll: CreateToolHelp32Snapshot, Process32First,
Process32Next, Thread32First, Thread32Next, OpenProcess,
WriteProcessMemory, VirtualProtectEx, OpenThread,
QueueUserAPC.
Ntdll.dll: NtAllocateVirtualMemory
Hình 2.12. Ví dụ minh họa APC injection
Ở hình ví dụ bên trên, mã độc trước tiên gọi OpenThread để lấy một xử lý
của một luồng khác, sau đó gọi QueueUserAPC với LoadLibraryA làm con trỏ
hàm để đưa DLL độc hại của nó vào một luồng khác.
46
Thread Name-Calling Injection
Tổng quan kỹ thuật
Thread Name-Calling Injection là một biến thể của kỹ thuật code injection,
cho phép chèn shellcode vào một tiến trình đang chạy mà không cần quyền ghi
vào vùng nhớ của tiến trình đó (PROCESS_VM_WRITE). Kỹ thuật này khai thác
cơ chế mô tả luồng (Thread Description) trong Windows để đưa mã độc vào bộ
nhớ và thực thi nó.
Cụ thể, kỹ thuật này hoạt động theo hai bước chính:
Ghi shellcode vào mô tả luồng: Windows cho phép gán một chuỗi mô
tả (description) cho mỗi luồng, chuỗi này được lưu trữ trong bộ nhớ
tiến trình sở hữu luồng. Khi chuỗi mô tả này bị thay đổi thành
shellcode, mã độc sẽ được ghi vào bộ nhớ tiến trình mà không cần
quyền PROCESS_VM_WRITE.
Thực thi shellcode: Sau khi shellcode được ghi vào bộ nhớ, các kỹ
thuật như APC injection hoặc thread hijacking sẽ được sử dụng để
kích hoạt mã độc.
Cơ chế hoạt động chi tiết
Quyền truy cập tối thiểu: Thread Name-Calling Injection chỉ yêu cầu một số
quyền truy cập tối thiểu để giảm nguy cơ bị phát hiện, bao gồm:
PROCESS_QUERY_LIMITED_INFORMATION: Đọc thông tin cơ bản từ
PEB của tiến trình.
PROCESS_VM_READ: Đọc dữ liệu từ bộ nhớ của tiến trình mục tiêu.
PROCESS_VM_OPERATION: Thực hiện các thao tác như cấp phát hoặc
thay đổi quyền truy cập bộ nhớ.
PROCESS_CREATE_THREAD (nếu sử dụng APC injection hoặc tạo luồng
mới): Tạo luồng mới trong tiến trình mục tiêu.
Quá trình thực thi:
[1] Ghi dữ liệu từ xa thông qua Thread Description
47
Kỹ thuật này lợi dụng API GetThreadDescription để ghi shellcode
vào bộ nhớ tiến trình mục tiêu. Cụ thể:
Tìm một luồng trong tiến trình mục tiêu.
Sử dụng API SetThreadDescription để gắn shellcode vào mô
tả luồng.
Gọi GetThreadDescription để xác định địa chỉ bộ nhớ nơi
shellcode được ghi vào.
[2] Sử dụng PEB để lưu trữ tạm
PEB (Process Environment Block) chứa nhiều thông tin về tiến trình và có
thể được đọc/ghi từ xa. Kỹ thuật này tận dụng trường SpareUlongs trong PEB để
lưu địa chỉ trả về của API GetThreadDescription.
ULONG_PTR remote_peb_addr(IN HANDLE hProcess) {
PROCESS_BASIC_INFORMATION pi = { 0 };
DWORD ReturnLength = 0;
auto
pNtQueryInformationProcess
=
reinterpret_cast
GetProcAddress(GetModuleHandle("ntdll.dll"),
"NtQueryInformationProcess"));
if (!pNtQueryInformationProcess) return NULL;
NTSTATUS status = pNtQueryInformationProcess(
hProcess,
ProcessBasicInformation,
&pi,
sizeof(PROCESS_BASIC_INFORMATION), &ReturnLength);
if (status != STATUS_SUCCESS) {
std::cerr << "NtQueryInformationProcess failed" <<
std::endl;
return NULL;
}
return (ULONG_PTR)pi.PebBaseAddress;
Cách lấy địa chỉ PEB từ xa:
}
48
[3] Chuyển shellcode vào vùng nhớ có thể thực thi
Sau khi shellcode được ghi vào vùng nhớ tiến trình mục tiêu, cần thay đổi
quyền truy cập bộ nhớ để cho phép thực thi mã độc.
Các API được sử dụng:
VirtualProtectEx: Thay đổi quyền truy cập vùng nhớ thành
PAGE_EXECUTE_READWRITE.
VirtualAllocEx: Nếu cần, cấp phát vùng nhớ mới với quyền RWX và
sao chép shellcode sang đó.
Code mẫu để đổi quyền bộ nhớ:
bool set_memory_executable(HANDLE hProcess, void*
remotePtr, size_t payload_len) {
DWORD oldProtect = 0;
if (!VirtualProtectEx(hProcess, remotePtr,
payload_len, PAGE_EXECUTE_READWRITE, &oldProtect)) {
std::cout << "Failed to change memory protection:
" << GetLastError() << "\n";
return false;
}
return true;
}
[4]Thực thi shellcode bằng APC
APC (Asynchronous Procedure Call) là một cơ chế cho phép thực hiện mã
Chèn shellcode vào hàng đợi APC của luồng mục tiêu.
Kích hoạt luồng để thực thi shellcode.
trên luồng hiện có. Kỹ thuật này sử dụng APC để:
Code mẫu sử dụng APC:
49
bool execute_shellcode(HANDLE hThread, void*
shellcodePtr) {
auto _RtlDispatchAPC =
GetProcAddress(GetModuleHandle("ntdll.dll"),
"RtlDispatchAPC");
if (!_RtlDispatchAPC) {
std::cerr << "Failed to get RtlDispatchAPC
address\n";
return false;
}
return queue_apc_thread(hThread, _RtlDispatchAPC,
shellcodePtr, nullptr, nullptr);
}
Ưu điểm của kỹ thuật Thread Name-Calling Injection
Kỹ thuật "Thread Name-Calling Injection" mang lại một số lợi thế đáng kể
cho kẻ tấn công, giúp lẩn tránh hiệu quả các cơ chế phòng thủ hiện có. Các ưu
điểm chính bao gồm:
Khả năng lẩn tránh cao: Kỹ thuật này không dựa vào các hàm API
tiêm mã độc truyền thống (như CreateRemoteThread hay
WriteProcessMemory). Do đó, nó có thể vượt qua các giải pháp bảo
mật dựa trên việc giám sát các mẫu hành vi đã biết, vốn thường tập
trung vào các API nguy hiểm này.
Không yêu cầu quyền ghi bộ nhớ: Một ưu điểm quan trọng là kỹ thuật
này không yêu cầu quyền PROCESS_VM_WRITE, một quyền truy
cập nhạy cảm và thường bị giám sát chặt chẽ. Việc không cần đến
quyền này giúp giảm thiểu dấu vết hoạt động và hạ thấp nguy cơ bị
các hệ thống phòng thủ phát hiện và ngăn chặn.
Lạm dụng các hàm API hợp pháp: Kỹ thuật này lợi dụng các hàm API
hệ thống hoàn toàn hợp pháp và ít bị nghi ngờ là SetThreadDescription
và GetThreadDescription. Việc sử dụng các hàm được thiết kế cho
50
mục đích gỡ lỗi và nhận dạng luồng khiến cho hành vi độc hại trở nên
khó phân biệt với các hoạt động bình thường của hệ thống, tạo ra một
"điểm mù" cho các công cụ bảo mật.
So sánh các loại kỹ thuật tiêm tiến trình
Process Injection là một nhóm kỹ thuật được sử dụng để thực thi mã độc bên
trong tiến trình hợp pháp, giúp mã độc tránh bị phát hiện, duy trì sự tồn tại và thực
thi các payload độc hại một cách ẩn danh. Từ sự tìm hiểu về cơ chế các thức hoạt
động của các loại kỹ thuật tiêm tiến trình ở trên, dưới đây là so sánh chi tiết các
kỹ thuật phổ biến, bao gồm cơ chế hoạt động, ưu điểm, nhược điểm và dấu hiệu
nhận diện.
Hình 2.13. So sánh các loại kỹ thuật tiêm tiến trình
Dấu hiệu đáng ngờ trên bộ nhớ để phát hiện có tiêm tiến trình
Nguyên tắc phân bố quyền truy cập trong hoạt động bình thường: Trong hoạt
động chuẩn của hệ thống, quyền thực thi (executable permission, ký hiệu +X) hầu
như chỉ xuất hiện trong vùng Image Memory, nơi chứa mã thực thi hợp lệ của các
module đã được tải. Các vùng Mapped Memory phần lớn có quyền "read-only"
51
hoặc "read-write" mà không có quyền thực thi. Private Memory theo thiết kế chỉ
nên chứa dữ liệu với quyền +R hoặc +RW. Khi phát hiện sự xuất hiện quyền thực
thi (+X) trong vùng Private Memory, đây là một chỉ báo bất thường cao cho thấy
có khả năng có mã độc hoặc shellcode được tiêm vào tiến trình.
Các kỹ thuật tiêm mã tiến trình thường để lại các dấu vết đặc trưng trong cấu
trúc bộ nhớ của tiến trình bị xâm nhập. Phân tích các bất thường trong bộ nhớ tiến
trình dựa trên việc so sánh với các nguyên tắc phân bố quyền chuẩn là phương
pháp hiệu quả để phát hiện hoạt động tiêm mã độc hại. Dưới đây là các chỉ báo cụ
thể và phương pháp phát hiện để nhận biết hoạt động tiêm tiến trình.
Bộ nhớ Private Memory có quyền thực thi (+X)
Private Memory thường được sử dụng cho mục đích lưu trữ dữ liệu như heap
hoặc stack của tiến trình, và theo thiết kế không nên chứa mã thực thi. Sự xuất
hiện quyền thực thi (Execute permission, ký hiệu +X) trong vùng Private Memory
là một chỉ báo bất thường cho thấy khả năng cao có hoạt động tiêm mã.
Cơ chế khai thác: Các kỹ thuật tiêm tiến trình phổ biến sử dụng Native API
NTDLL.DLL!NtAllocateVirtualMemory để cấp phát vùng bộ nhớ mới với quyền
đọc-ghi-thực thi (+RWX). Sau khi cấp phát, mã độc như shellcode hoặc tệp PE
(Portable Executable) được ghi vào vùng này và được thực thi thông qua các
phương thức như tạo luồng từ xa (remote thread creation).
Phương pháp phát hiện: Thực hiện phân tích cấu trúc
MEMORY_BASIC_INFORMATION của từng vùng nhớ trong không gian địa
chỉ tiến trình. Kiểm tra trường Type để xác định vùng Private Memory
(MEM_PRIVATE) và trường Protect để phát hiện sự xuất hiện của quyền thực
thi như PAGE_EXECUTE, PAGE_EXECUTE_READ, hoặc
PAGE_EXECUTE_READWRITE. Các vùng Private Memory với quyền thực thi
không liên kết với module hợp lệ là đáng ngờ.
Thay đổi quyền bộ nhớ bất thường
Việc thay đổi quyền truy cập bộ nhớ từ đọc-ghi (+RW) sang đọc-thực thi
(+RX) hoặc thêm quyền thực thi vào vùng bộ nhớ hiện có là kỹ thuật phổ biến
52
được sử dụng sau khi mã độc đã được ghi vào bộ nhớ. Phương pháp này giúp mã
độc sẵn sàng thực thi trong khi che giấu ý định độc hại ban đầu bằng cách tránh
cấp phát trực tiếp vùng nhớ với quyền +RWX.
API thường được sử dụng:
NTDLL.DLL!NtProtectVirtualMemory: Native API để thay đổi quyền
bảo vệ bộ nhớ
KERNEL32.DLL!VirtualProtectEx: Phiên bản Windows API được sử
dụng phổ biến hơn cho các thao tác từ xa
Phương pháp phát hiện: Giám sát các sự kiện thay đổi quyền bộ nhớ liên tiếp
trong cùng một vùng địa chỉ. Nếu phát hiện chuỗi thay đổi quyền từ +RW sang
+RX hoặc xuất hiện quyền +RWX trong bộ nhớ Private Memory, đây là chỉ báo
đáng ngờ cho thấy khả năng có mã độc được ghi và chuẩn bị thực thi. Sử dụng
các công cụ giám sát như ETW (Event Tracing for Windows) để theo dõi các lời
gọi API VirtualProtectEx và NtProtectVirtualMemory.
Sửa đổi bất thường trong Image Memory
Image Memory được sử dụng để lưu trữ các module tĩnh (executable files và
DLL) đã được tải vào không gian địa chỉ tiến trình. Theo thiết kế chuẩn, vùng này
thường chỉ có quyền đọc (+R) hoặc đọc-thực thi (+RX) cho code sections, và
quyền đọc-ghi (+RW) cho data sections. Sự thay đổi quyền bộ nhớ hoặc nội dung
trong Image Memory là dấu hiệu tiến trình có thể bị xâm phạm.
Kịch bản tấn công: Kẻ tấn công có thể thay thế một DLL hợp lệ bằng mã
độc, hoặc sửa đổi code section của module hợp lệ để chèn các đoạn mã thực hiện
hành vi độc hại như hooking, code patching, hoặc IAT (Import Address Table)
manipulation.
Phương pháp phát hiện: So sánh nội dung của Image Memory với tệp gốc
trên ổ đĩa bằng cách tính toán hash (MD5, SHA-256) hoặc so sánh từng byte. Nếu
phát hiện khác biệt trong code sections hoặc sự thay đổi bất thường về quyền truy
cập (ví dụ: code section có quyền +RW), tiến trình có khả năng cao đã bị can
thiệp.
53
Vùng Mapped Memory chứa quyền thực thi
Mapped Memory thường chứa dữ liệu được ánh xạ từ file hoặc shared section
objects và theo thiết kế chuẩn có quyền đọc (+R) hoặc đọc-ghi (+RW). Sự xuất
hiện quyền thực thi (+X) trong Mapped Memory không liên kết với module hợp
lệ là chỉ báo nghi ngờ cao.
Kịch bản tấn công: Kẻ tấn công có thể tạo một section object từ file chứa mã
độc hoặc từ bộ nhớ, sau đó ánh xạ section này vào tiến trình mục tiêu bằng
NtMapViewOfSection. Sau khi ánh xạ, quyền truy cập được thay đổi để cho phép
thực thi mã độc. Kỹ thuật này được sử dụng trong các phương pháp như Process
Doppelgänging và Process Herpaderping.
Phương pháp phát hiện: Kiểm tra cấu trúc
MEMORY_BASIC_INFORMATION để xác định các vùng có Type là
MEM_MAPPED và có quyền PAGE_EXECUTE, PAGE_EXECUTE_READ,
hoặc PAGE_EXECUTE_READWRITE. Xác minh xem vùng Mapped Memory
có liên kết với file hợp lệ trên đĩa hay không bằng cách kiểm tra trường
MappedFileName. Các vùng Mapped Memory có quyền thực thi nhưng không
liên kết với module hợp lệ hoặc liên kết với file ở vị trí đáng ngờ (như thư mục
Temp) cần được điều tra thêm.
Vùng nhớ thực thi không liên kết với module
Trong hoạt động bình thường, tất cả các vùng bộ nhớ có quyền thực thi phải
được liên kết với một module hợp lệ (DLL hoặc EXE) được liệt kê trong danh
sách module của tiến trình. Phát hiện vùng nhớ có quyền thực thi nhưng không
thuộc bất kỳ module nào là chỉ báo mạnh mẽ cho hoạt động tiêm mã. Phantom
Image là trường hợp cụ thể và rõ nét nhất của Unlinked Memory có cấu trúc PE.
Kịch bản tấn công: Shellcode được nạp vào vùng bộ nhớ được cấp phát động
(thông qua VirtualAllocEx hoặc NtAllocateVirtualMemory) và thực thi mà không
cần liên kết với bất kỳ module nào trong danh sách PEB. Phương pháp này được
sử dụng rộng rãi trong reflective DLL injection, shellcode injection, và các kỹ
thuật tương tự.
54
Phương pháp phát hiện: Duyệt qua danh sách module trong Process
Environment Block (PEB) để xây dựng bản đồ các vùng bộ nhớ hợp lệ. So sánh
các vùng bộ nhớ có quyền thực thi (từ VirtualQueryEx) với danh sách module.
Các vùng có quyền thực thi nhưng không nằm trong phạm vi địa chỉ của bất kỳ
module nào là đáng ngờ.
Sự khác biệt giữa bộ nhớ và file trên đĩa
Vùng Image Memory thường phản ánh chính xác nội dung của file
EXE/DLL tương ứng trên ổ đĩa (trừ các phần relocation hợp lệ). Sự khác biệt đáng
kể giữa nội dung trong bộ nhớ và file gốc là dấu hiệu cho thấy có sự chỉnh sửa
hoặc thay thế mã độc.
Kịch bản tấn công: Trong kỹ thuật Process Hollowing, nội dung của file EXE
hợp lệ trong bộ nhớ tiến trình bị unmapped và thay thế bằng mã độc. Kỹ thuật
Module Stomping sửa đổi nội dung của một DLL đã được tải để chèn mã độc
trong khi vẫn giữ nguyên cấu trúc module trong PEB.
Phương pháp phát hiện: Đọc nội dung file gốc từ đĩa và so sánh với nội dung
trong bộ nhớ tiến trình (sử dụng ReadProcessMemory hoặc memory dump). Tính
toán hash cho cả hai phiên bản hoặc thực hiện so sánh byte-by-byte. Cần loại trừ
các khác biệt hợp lệ như ASLR relocation và các section data có thể thay đổi. Sự
khác biệt trong code sections là chỉ báo rất mạnh cho hoạt động độc hại.
Lạm dụng section object để tiêm mã
Section objects là cơ chế của Windows cho phép chia sẻ bộ nhớ giữa các tiến
trình. Một số kỹ thuật tiêm mã tiên tiến sử dụng section objects để chèn mã độc
mà không cần sử dụng các API phổ biến như WriteProcessMemory, giúp tránh bị
phát hiện bởi các giải pháp bảo mật.
Cơ chế khai thác: Kẻ tấn công tạo section object chứa mã độc bằng
NtCreateSection, sau đó ánh xạ section này vào cả tiến trình cục bộ (để ghi mã
độc) và tiến trình từ xa (để thực thi) bằng NtMapViewOfSection. Vì dữ liệu được
chia sẻ giữa hai view, việc ghi vào view cục bộ sẽ tự động xuất hiện trong view
của tiến trình từ xa mà không cần WriteProcessMemory.
55
Phương pháp phát hiện: Kiểm tra thông tin về các section trong không gian
địa chỉ tiến trình bằng cách sử dụng NtQueryVirtualMemory với
MemoryMappedFilenameInformation. Giám sát các thay đổi quyền truy cập hoặc
nội dung của vùng Mapped Memory. Theo dõi các lời gọi hệ thống
NtCreateSection, NtMapViewOfSection, và NtUnmapViewOfSection để phát
hiện hoạt động đáng ngờ. Các section không liên kết với file hợp lệ trên đĩa hoặc
có quyền thực thi bất thường cần được điều tra kỹ lưỡng.
Kết luận chương 2
Trên đây là một số kỹ thuật chèn mã phổ biến và các biến thể của chúng. Các
kỹ thuật này hiện tại và thậm chí trong tương lai sẽ vẫn được sử dụng phổ biến ở
hầu hết các dòng mã độc. Ở chương sau, chúng ta sẽ thực hiện mô phỏng một số
kỹ thuật trên và xây dựng công cụ phân tích bộ nhớ tiến trình có khả năng tự động
quét, phát hiện và báo cáo các vùng nhớ độc hại dựa trên tập hợp các dấu hiệu
đáng ngờ đã phân tích ở trên.
56
PHÁT TRIỂN CÔNG CỤ RÀ SOÁT BỘ NHỚ ĐỂ PHÁT
HIỆN VÙNG NHỚ ĐỘC HẠI TRONG BÀI TOÁN PHÁT HIỆN MÃ ĐỘC
Xây dựng công cụ
Lựa chọn nền tảng và thư viện kỹ thuật
Công cụ được phát triển bằng ngôn ngữ C++ sử dụng framework MFC nhằm
xây dựng giao diện trực quan, thân thiện và tích hợp tốt với môi trường Windows.
MFC cung cấp các lớp hỗ trợ tạo cửa sổ, bảng danh sách, nút bấm… giúp
trực quan hóa thông tin tiến trình, vùng nhớ, và kết quả phân tích. Bên cạnh đó,
C++ cho phép truy cập cấp thấp đến các API của hệ điều hành Windows để phân
tích sâu bộ nhớ tiến trình.
Để thực hiện các tác vụ phân tích bộ nhớ, công cụ đã tích hợp và sử dụng
một loạt các thư viện và API hệ thống của Windows:
Win32 API: Đây là nhóm API nền tảng, được sử dụng cho các tác vụ
cơ bản như liệt kê và tương tác với bộ nhớ của tiến trình. Các hàm
chính bao gồm:
o CreateToolhelp32Snapshot: Liệt kê các tiến trình và mô-đun
đang chạy.
o VirtualQueryEx: Truy vấn thông tin về một vùng nhớ của tiến
trình khác.
o ReadProcessMemory / WriteProcessMemory: Đọc và ghi dữ
liệu vào không gian bộ nhớ của một tiến trình.
NTDLL (Native API): Để truy cập các cấu trúc dữ liệu nội bộ và
không được công bố chính thức của hệ điều hành, công cụ sử dụng các
hàm trong ntdll.dll. Điều này cho phép thu thập thông tin chi tiết hơn,
chẳng hạn như truy cập vào khối môi trường tiến trình (PEB - Process
Environment Block) và khối môi trường luồng (TEB - Thread
Environment Block) thông qua các hàm như
NtQueryInformationProcess và NtReadVirtualMemory.
57
Windows Security API: Nhóm API này chủ yếu được khai thác để
kiểm tra tính hợp lệ của chữ ký số (Digital Signature) trên các mô-đun
(.dll) và tệp thực thi (.exe). Đây là một bước quan trọng để xác minh
tính toàn vẹn và nguồn gốc của các tệp được nạp vào bộ nhớ.
Hashing (CryptoAPI): Được sử dụng để tạo và so sánh giá trị băm
(hash) của các vùng mã lệnh (PE sections) trong bộ nhớ với tệp thực
thi gốc tương ứng trên đĩa.
Tóm lại, MFC giúp xây dựng giao diện, còn các API cấp thấp của Windows
cho phép đọc, phân tích và kiểm tra tính toàn vẹn của bộ nhớ tiến trình để phát
hiện dấu hiệu tiêm mã độc.
Sơ đồ hoạt động
Để nhanh chóng phát hiện process injection, mã độc tồn tại trong bộ nhớ, em
đã tạo ra một công cụ để rà soát bộ nhớ và phát hiện bất thường trong bộ nhớ.
Bằng cách ánh xạ mối quan hệ giữa các thành phần quan trọng như PEB, stack,
heaps, và cấu trúc PE trong vùng nhớ. Sau đó sử dụng các thông tin này để xác
định các điểm bất thường của bộ nhớ.
Sau khi chỉ định một tiến trình để rà soát, công cụ sẽ tiến hành liệt kê stack,
heap, luồng và các vùng nhớ của tiến trình cũng như lấy thông tin của các cấu trúc
chứa những thông tin quan trọng của luồng, tiến trình hay vùng nhớ sau đó xác
định các mối liên hệ giữa chúng.
Quy trình hoạt động cơ bản của công cụ như sau:
Bước 1: Người dùng chọn một tiến trình cần rà soát.
Bước 2: Sau khi được chỉ định, công cụ tiến hành thu thập thông tin chi tiết
về tiến trình thông qua các hoạt động sau:
Liệt kê toàn bộ các vùng stack của tất cả luồng đang hoạt động trong
tiến trình.
Liệt kê các heap được cấp phát cho tiến trình.
Liệt kê danh sách các luồng (threads) hiện đang tồn tại trong tiến trình.
58
Quét và liệt kê toàn bộ các vùng nhớ trong không gian địa chỉ của tiến
trình.
Bước 3: Công cụ trích xuất cấu trúc dữ liệu quan trọng: Công cụ thực hiện
đọc và phân tích các cấu trúc dữ liệu cốt lõi:
Process Environment Block (PEB): Chứa thông tin về process
parameters, danh sách modules, và cấu hình tiến trình
Thread Environment Block (TEB): Chứa thông tin về từng luồng bao
gồm stack base, stack limit, và last error code
PE Header: Phân tích cấu trúc PE của các module được tải để xác định
sections, permissions (quyền truy cập), và metadata (thông tin mô tả)
Bước 4: Công cụ ánh xạ mối quan hệ và phát hiện bất thường: Dựa trên dữ
liệu đã thu thập ở các bước trên, công cụ xây dựng bản đồ ánh xạ mối quan hệ
giữa các thành phần để xác định các điểm bất thường. Ví dụ các kiểm tra được
thực hiện:
Kiểm tra xem các luồng có trỏ đến vùng nhớ hợp lệ hay không
Xác minh các vùng có quyền thực thi (+X) có liên kết với module hợp
lệ trong danh sách PEB hay không
So sánh các entry point của luồng với code sections hợp lệ
Phát hiện các vùng Private Memory có quyền thực thi bất thường
Sau khi phát hiệ vùng nhớ bất thường thì công cụ sẽ ghi log cảnh báo và hiển
thị vùng nhớ nghi ngờ với các cảnh báo và được báo đỏ trên vùng nhớ hiển thị
trên công cụ.
Bước 5: Trích xuất vùng nhớ nghi ngờ: Khi công cụ kiểm tra vùng nhớ nào
có dấu hiệu đáng ngờ, công cụ sẽ tạo thư mục và trích xuất vùng nhớ nghi ngờ đó
ra thành tệp .dat lưu trong thư mục đó. Ghi lại thông tin metadata về vùng nhớ đó
bao gồm địa chỉ base, quyền truy cập vào tên file để dễ nhận diện (ví dụ: tên file
là 6692_00007FF9C38B0000_IMG.dat, tức là vùng nhớ tại địa chỉ
0x00007FF9C38B0000 của tiến trình có PID 6692, đây là vùng nhớ image
memory).
59
Ở bước 4 bên trên, với mỗi loại vùng nhớ, công cụ sẽ thực hiện các bước
kiểm tra riêng:
Khi công cụ phát hiện một vùng nhớ thuộc loại PE file (Portable
Executable), nó sẽ thực hiện kiểm tra các mục sau để phát hiện các thay đổi
bất thường trong tiến trình:
So sánh đường dẫn tệp thực thi.
Kiểm tra chữ ký số.
Kiểm tra quyền bộ nhớ.
Phát hiện sửa đổi ở phần tiêu đề và mã thực thi.
Quy trình kiểm tra vùng nhớ kiểu PE file như sau:
Bước 1: Xác định thông tin PE file
Gọi hàm GetPeFile để lấy toàn bộ thông tin PE từ vùng nhớ (PE header,
sections, ImageBase…).
Xác định đây có phải là Executable Image hay không (có thể thực thi được).
Bước 2: Kiểm tra chữ ký số
Nếu vùng nhớ là Executable Image, công cụ sẽ kiểm tra thuộc tính PeEntity
Is Signed:
Nếu không được ký số, gán nhãn cảnh báo: UNSIGNED_MODULE.
Vì mã độc thường là các module chưa được ký số hợp lệ.
Bước 3: Kiểm tra thông tin trong PEB
Kiểm tra vùng nhớ này có tồn tại trong danh sách module của PEB (Process
Environment Block) hay không:
Nếu không có entry tương ứng trong PEB, cảnh báo:
MISSING_PEB_ENTRY.
Nếu có trong PEB nhưng đường dẫn Image file path khác với FileBase
path → cảnh báo: MISMATCHING_PEB_MODULE.
→ Điều này cho thấy tiến trình đã bị thay đổi thông tin module để che giấu
mã độc.
Bước 4: Kiểm tra Header của PE trong bộ nhớ
60
o Nếu giá trị > 0, tức là Header đã bị chỉnh sửa, gán nhãn cảnh báo:
So sánh Private Size của Header section:
MODIFIED_HEADER.
→ Điều này thường xảy ra khi kỹ thuật process hollowing hoặc manual
mapping can thiệp PE header.
Bước 5: So sánh quyền truy cập giữa trên đĩa và trong bộ nhớ
Kiểm tra xem memory_basic_information.protection của PE file trong bộ
nhớ có khác với phần header section trên đĩa hay không, và Section header có cờ
IMAGE_SCN_MEM_EXECUTE (quyền thực thi) hay không.
Nếu phát hiện sự không nhất quán thì công cụ sẽ cảnh báo:
DISK_PERMISSION_MISMATCH.
→ Có thể tiến trình đã thay đổi quyền của vùng nhớ để thực thi mã trái phép.
Bước 6: Kiểm tra mã code trong vùng PE
Kiểm tra Private Size của toàn bộ vùng PE, nếu thấy lớn hơn 0 thì cảnh báo:
MODIFIED_CODE. Điều này cho thấy mã code trong file PE đã bị thay đổi so
với mã gốc trên đĩa, một dấu hiệu điển hình của code injection.
61
Hình 3.1. Sơ đồ hoạt động của công cụ khi kiểm tra vùng nhớ là PE file
Khi công cụ phát hiện một vùng nhớ có loại Mapped file, công cụ sẽ tiến
hành chuỗi bước kiểm tra để phát hiện khả năng tiêm mã độc như sau:
Bước 1: Kiểm tra quyền thực thi (PageExecutable)
Xác định xem vùng nhớ Mapped file có được cấp quyền thực thi
(PAGE_EXECUTE*) hay không. Nếu có quyền thực thi, điều này bất thường vì
các vùng Mapped file thường chỉ có quyền read-only.
Khi phát hiện, công cụ sẽ cảnh báo: EXECUTABLE_MAP. Đây là dấu hiệu
khả nghi cho thấy có thể đã tiêm mã vào vùng mapped để thực thi.
Bước 2: Kiểm tra vị trí ImageBase của vùng nhớ
Kiểm tra memory subregion flag để xác định vùng này có được đánh dấu là
base image hay không.
62
Nếu vùng được đánh dấu là base image nhưng lại nằm trong non-image
memory region, công cụ sẽ cảnh báo: image base within non-image memory
region. Điều này cho thấy mã độc có thể đã thay thế hoặc giả mạo một image hợp
lệ, một hành vi phổ biến trong kỹ thuật process hollowing hoặc manual mapping.
Bước 3: Kiểm tra EntryPoint của luồng trong vùng nhớ
Xác định EntryPoint của bất kỳ luồng (thread) nào đang nằm trong vùng
Mapped memory.
Nếu phát hiện luồng có EntryPoint nằm trong vùng Mapped file, công cụ sẽ
cảnh báo: Threat within non-image memory region. Đây là dấu hiệu rất rõ ràng
cho thấy mã độc đang được thực thi trong vùng mapped memory, không phải từ
một file PE hợp lệ trên đĩa.
Hình 3.2. Sơ đồ hoạt động của công cụ khi kiểm tra vùng nhớ là Mapped file
Khi công cụ phát hiện một vùng nhớ có loại Private Memory (Unknown),
công cụ sẽ tiến hành chuỗi bước kiểm tra để phát hiện khả năng tiêm mã độc
như sau:
Bước 1: Kiểm tra quyền thực thi (PageExecutable)
Xác định xem vùng Private Memory có được cấp quyền thực thi
(PAGE_EXECUTE*) hay không.
63
Vùng Private thường chỉ chứa dữ liệu động (heap, stack) nên không được
cấp quyền thực thi.
Nếu phát hiện có quyền thực thi, công cụ sẽ cảnh báo:
EXECUTABLE_PRIVATE. Đây là dấu hiệu rất nghi ngờ vì các kỹ thuật như
Process Hollowing, Reflective DLL Injection, Shellcode Injection thường tiêm
mã độc vào các vùng Private memory có gán quyền thực thi.
Bước 2: Kiểm tra vị trí ImageBase trong vùng nhớ
Kiểm tra memory subregion flag để xem vùng nhớ có được đánh dấu là base
image hay không.
Nếu có, nhưng vùng lại nằm trong non-image memory region (vùng Private)
thì đây là dấu hiệu bất thường.
Công cụ sẽ cảnh báo: “image base within non-image memory region”.
Điều này cho thấy mã độc có thể đã nạp thủ công một PE (manual mapping) vào
vùng Private Memory để thực thi mà không qua bộ nạp chuẩn của Windows.
Bước 3: Kiểm tra EntryPoint của luồng trong vùng nhớ
Xác định EntryPoint của bất kỳ luồng (thread) nào có địa chỉ nằm trong vùng
Private Memory.
Nếu phát hiện, công cụ sẽ cảnh báo: “Threat within non-image memory
region”. Đây là dấu hiệu rất rõ ràng cho thấy luồng đang chạy từ vùng nhớ không
hợp lệ (Private), khả năng cao là shellcode hoặc mã độc đã được tiêm.
64
Hình 3.3. Sơ đồ hoạt động của công cụ khi kiểm tra vùng nhớ Unkown
private
Thực nghiệm và đánh giá kết quả
Môi trường thử nghiệm
Để đánh giá khả năng phát hiện của công cụ đã xây dựng, em đã tiến hành
thử nghiệm trong môi trường cô lập và được kiểm soát đã được thiết lập như sau:
+ Cấu hình môi trường thử nghiệm với:
Hệ điều hành: Windows 10 x64 (phiên bản 22H2) chạy trong môi trường
máy ảo VMware Workstation.
Quyền người dùng: Administrator, bật SeDebugPrivilege để cho phép công
cụ có quyền truy cập để đọc và phân tích không gian bộ nhớ của các tiến
trình khác trên toàn hệ thống, kể cả các tiến trình có mức đặc quyền cao.
+ Công cụ hỗ trợ phân tích bao gồm:
Visual Studio 2022 được sử dụng để biên dịch công cụ phát triển cũng như
các mã độc mẫu (payloads) phục vụ cho việc thử nghiệm.
Process Hacker được dùng để theo dõi trạng thái của các tiến trình, luồng,
và các vùng nhớ trong thời gian thực, giúp đối chiếu kết quả mà công cụ
phát hiện được.
65
Các công cụ phân tích tĩnh và động: Các công cụ như IDA Pro,
pe_unmapper, và HxD được sử dụng để phân tích sâu cấu trúc của các mã
độc mẫu và kiểm chứng các dấu hiệu bất thường trong bộ nhớ.
+ Các mẫu thử nghiệm: Để đảm bảo tính toàn diện trong việc đánh giá, các
mẫu thử nghiệm được lựa chọn đa dạng, từ các mã độc đơn giản tự phát triển đến
các mẫu thực tế phức tạp:
Payload.exe: Tệp thực thi đơn giản, khi chạy sẽ hiển thị MessageBox thông
báo tiêm mã thành công.
DLL.dll: Tệp DLL đơn giản hiển thị MessageBox khi được nạp, phục vụ
cho kịch bản thử nghiệm các kỹ thuật tiêm DLL.
Mã khai thác mô phỏng những kỹ thuật tiêm tiến trình như: Process
Hollowing, Process Ghosting, Reflective DLL Injection.
Mẫu mã độc thực tế APT32: Đây là mẫu thực tế được cho là có liên quan
đến nhóm tấn công APT32. Mẫu này được sử dụng để đánh giá khả năng
của công cụ trong việc phát hiện các mối đe dọa tinh vi và đang tồn tại
ngoài thực tế.
Kịch bản thử nghiệm
Các kịch bản được thiết kế nhằm mô phỏng lại các kỹ thuật tiêm tiến trình
phổ biến, sau đó sử dụng công cụ đã xây dựng để quét tiến trình bị tiêm nhằm
kiểm tra khả năng phát hiện bất thường.
Danh sách kịch bản:
1. Process Hollowing: Tạo tiến trình svchost.exe ở trạng thái treo, tháo bỏ Image
gốc, tiêm payload.exe vào không gian bộ nhớ và resume thread.
2. Process Ghosting: Tạo tệp tạm thời đã xóa, ghi payload.exe vào và map vào
tiến trình notepad.exe trước khi tiến trình được khởi chạy hoàn toàn.
3. Reflective DLL Injection: Tiêm DLL trực tiếp vào không gian bộ nhớ của tiến
trình notepad.exe và gọi hàm export chính của DLL.
4. Mã độc APT32 (Process Injection thực tế): Thực thi mẫu mã độc APT32 trong
môi trường sandbox và sử dụng công cụ để quét phát hiện.
66
Phân tích và đánh giá kết quả
Kỹ thuật Process Hollowing
Kịch bản tấn công
Process Hollowing là kỹ thuật thay thế bộ nhớ của một tiến trình hợp lệ bằng
mã độc để che giấu hành vi thực thi. Trong thí nghiệm này, em thực hiện tiêm mã
độc vào tiến trình hợp lệ svchost.exe, từ đó thực thi payload với danh tính của tiến
trình bị thay thế.
Chuẩn bị: Tệp thực thi payload, đây là tệp được sử dụng để tiêm vào tiến
trình mục tiêu. Khi quá trình tiêm diễn ra thành công, payload sẽ kích hoạt một
MessageBox thông báo.
Hình 3.4. Tệp thực thi payload
Thực hiện tấn công
Tiến trình Process Hollowing được thực hiện với các bước sau:
1. Tạo một tiến trình mới (svchost.exe) ở trạng thái tạm dừng.
2. Gỡ bỏ (unmap) vùng nhớ của tiến trình và cấp phát bộ nhớ mới.
3. Ghi nội dung của payload.exe vào vùng nhớ tiến trình mục tiêu.
4. Cập nhật lại ngữ cảnh thực thi của tiến trình (svchost.exe) để chạy mã
độc.
5. Tiếp tục thực thi tiến trình (Resuming thread).
Tiến hành chạy chương trình Process Hollowing với các thông số:
Tiến trình mục tiêu: svchost.exe (bị giả mạo).
Tệp thực thi payload: payload.exe (được chèn vào svchost.exe).
67
Sau khi hoàn tất quá trình, payload được thực thi thành công, hiển thị
hộp thoại thông báo "Injected!", xác nhận rằng mã độc đã chạy bên trong
Tiến trình mục tiêu
tiến trình svchost.exe.
Hình 3.5. Thực hiện kỹ thuật Process Hollowing
Phát hiện kỹ thuật bằng công cụ xây dựng
Rà soát bằng công cụ đã xây dựng với tham số PID của tiến trình cần rà soát
(ở đây là tiến trình svchost.exe có PID 1400).
Hình 3.6. Kết quả rà soát kỹ thuật Process Hollowing bằng công cụ
Phát hiện:
o Công cụ hiển thị một vùng Private Memory có quyền thực thi (+X) tại
68
o ImageBase của tiến trình và Thread ID 1460 cùng trỏ về vùng private
địa chỉ 0x00000000001C0000 (hình 3.6)
này.
Hình 3.7. Luồng tồn tại trong vùng nhớ Private
o Dùng Process Hacker xác định vùng tại 0x00000000001C0000 chứa dữ
Kiểm chứng:
liệu PE hợp lệ.
69
Hình 3.8. PE file tại địa chỉ 0x1C0000
Công cụ đã tiến hành trích xuất các vùng nhớ nghi ngờ ra lưu vào thư mục
~/memdmp-11-6-2025~23.5.43/
Kiểm tra với vùng nhớ Private Memory có quyền thực thi (+X) tại địa chỉ
0x00000000001C0000. Sửa lại vùng nhớ này cho đúng format bằng
pe_unmapper (https://github.com/hasherezade/pe_unmapper) lưu lại thành file
1400_payload.exe. Khi chạy file này thì có một popup hiển thị message box
“Injected!”. Như vậy ta đã khôi phục lại được file payload ban đầu và tệp này
đúng.
70
Hình 3.9. Thực thi file được trích xuất tại địa chỉ 0x00000000001C0000.
Đánh giá: Công cụ phát hiện thành công do kỹ thuật này để lại dấu vết vùng
Private có quyền thực thi không hợp lệ.
Mô phỏng kỹ thuật Process Ghosting
Kịch bản tấn công
Trong thử nghiệm này, kỹ thuật Process Ghosting được sử dụng để thực thi
payload.exe trong vùng nhớ của notepad.exe mà không cần ghi payload trực tiếp
vào đĩa.
Thực hiện tấn công
Quá trình thực hiện Process Ghosting bao gồm các bước sau:
1. Tạo một tệp thực thi trên đĩa nhưng không đóng handle, giữ trạng thái
"pending delete".
2. Ghi dữ liệu của payload vào tệp này nhưng không để hệ điều hành nhận
diện nó là một tệp hợp lệ.
3. Tạo một tiến trình mới từ tệp đã bị ẩn này.
4. Khi tiến trình được khởi chạy, mã độc sẽ được thực thi mà không để lại dấu
vết trên hệ thống tệp.
Các tham số quan trọng trong quá trình tấn công:
Tệp thực thi mục tiêu bị giả mạo: notepad.exe.
Tệp thực thi được sử dụng để tiêm mã độc: payload.exe.
71
Khi kỹ thuật được thực hiện thành công, payload sẽ chạy bên trong tiến trình
notepad.exe, hiển thị hộp thoại MessageBox xác nhận quá trình tiêm mã đã thành
công.
Hình 3.10. Thực hiện kỹ thuật Process Ghosting
Process Ghosting tận dụng thời điểm “trước khi tiến trình khởi chạy hoàn
toàn” để đưa mã độc vào không gian nhớ của tiến trình mục tiêu mà không cần sử
dụng VirtualAlloc/VirtualAllocEx. Quy trình thường gồm: tạo tệp tạm thời ở
trạng thái chờ xóa, ghi nội dung mã độc vào tệp này, tạo một section từ tệp và ánh
xạ (map) section đó vào tiến trình mục tiêu, rồi đóng và xóa handle tệp tạm. Kết
quả là mã được thực thi trong tiến trình mục tiêu nhưng không còn file thực thi rõ
ràng trên đĩa - gọi là phantom image.
Vì không tạo vùng Private Memory +X (do dùng section mapping từ file),
dấu hiệu “Private region có quyền thực thi” - vốn dễ nhận diện trong Process
Hollowing - không xuất hiện trong Process Ghosting nữa. Do đó, việc phát hiện
trở nên khó khăn hơn nếu công cụ chỉ dựa vào phát hiện vùng Private +X.
Phát hiện kỹ thuật bằng công cụ xây dựng
Khởi chạy quét tiến trình với tham số PID (ở đây PID = 2684).
72
Hình 3.11. Kết quả rà soát kỹ thuật Process Ghosting bằng công cụ
Kết quả chạy công cụ cho thấy:
Không xuất hiện vùng Private +X (như trong Hollowing).
Công cụ báo lỗi không đọc được file từ đường dẫn Image trong vùng
memory, và đường dẫn thực thi trong PEB không khớp với vùng
Image Memory thực tế → dấu hiệu của phantom image.
o Kiểm tra thủ công bằng Process Hacker:
Quan sát vùng nghi ngờ tại địa chỉ 0x00007FF64CB60000.
73
Hình 3.12. PE file dưới địa chỉ 0x00007FF64CB60000
Vùng này chứa dữ liệu có cấu trúc PE nhưng bị chia thành 5 subregion (mỗi
subregion có quyền truy cập khác nhau).
Việc chia nhỏ và phân quyền khác nhau nhằm gây nhiễu (obfuscation) cho
nhà phân tích và công cụ tự động.
Hành vi này là đặc trưng của Process Ghosting: mã được ánh xạ theo
section/segment phức tạp chứ không phải là một Image “sạch” nạp từ file
trên đĩa.
Công cụ tự động dump toàn bộ vùng Phantom Image bên trên ra 5 file .dat
riêng biệt.
74
Hình 3.13. Công cụ thực hiện trích xuất vùng nhớ nghi ngờ ra file
Sử dụng lệnh “copy /b *.dat merged_output.dat” để gộp 5 file trên thành một
file PE hoàn chỉnh. Tiếp tục phục hồi định dạng PE hợp lệ bằng công cụ
pe_unmapper(https://github.com/hasherezade/pe_unmapper) và chạy vùng nhớ
được trích xuất này thì đây đúng là tệp mà chúng ta đã tiêm vào trước đó.
Hình 3.14. Thực thi file được trích xuất ra tại địa chỉ 0x00007FF64CB60000
của tiến trình
75
Đánh giá: Công cụ vẫn phát hiện được thông qua so sánh thông tin PEB và
vùng Image Memory, dù không có Private +X.
Mô phỏng kỹ thuật Reflect DLL Injection
Kịch bản tấn công
Kịch bản: Sử dụng Reflect DLL injection để tải lên thủ công DLL vào một
tiến trình đang chạy (có thể sử dụng chính tiến trình độc hại làm tiến trình mục
tiêu để tiêm).
Chuẩn bị: 1 DLL khi được tải thành công sẽ xuất hiện MessageBox thông
báo tấn công thành công.
Hình 3.15. Tệp DLL hiển thị Message Box
Thực hiện kỹ thuật
Thực hiện tiêm DLL vào tiến trình notepad.exe có PID 5944. Khi kỹ thuật
được thực hiện thành công, payload sẽ chạy bên trong tiến trình notepad.exe, hiển
thị hộp thoại MessageBox xác nhận quá trình tiêm mã đã thành công.
76
Hình 3.16. Thực hiện kỹ thuật reflect DLL injection
Phát hiện kỹ thuật bằng công cụ xây dựng
Hình 3.17. Kết quả rà soát kỹ thuật Reflective DLL Injection
Khi kiểm tra bộ nhớ của tiến trình PID 5944 (tiến trình được sử dụng để tải
DLL thủ công) công cụ đã phát hiện các vùng nhớ bất thường sau:
1. Unsigned module
Đây là một module chưa được ký số (unsigned), có thể là DLL được tiêm
vào tiến trình.
Vùng Primary image base chỉ có quyền đọc (R), cho thấy đây là PE được tải
vào bộ nhớ.
77
Có một thread (TID 9108) hoạt động tại vùng này, cho thấy module đang
được thực thi.
2. Thread trong non-image memory
Xuất hiện thread TID tại địa chỉ 0x00000000008B1745. Thread này đang
chạy trong vùng non-image memory với quyền RWX (Read-Write-Execute), là
một dấu hiệu điển hình của Reflective DLL Injection.
Vùng non-image memory cho phép thực thi code mà không xuất hiện trong
PE headers.
3. Abnormal private executable memory
Tại địa chỉ 0x00000000009E0000: Đây là vùng Private được cấp quyền thực
thi (+X) nhưng không phải module chuẩn của hệ thống.
Vùng này thường là nơi DLL tiêm vào bộ nhớ và chạy code.
4. Các vùng bộ nhớ khác (hợp lệ)
Hình 3.18. Các vùng nhớ khác hiển thị trên công cụ
Stack, TEB, Heap: Đây là các vùng bộ nhớ chuẩn của tiến trình, không đáng
lo ngại.
Modified code / Inconsistent +X: Các vùng Modified code và Inconsistent
+X có thể là code đã bị chỉnh sửa sau khi tải từ disk (điển hình khi DLL được tiêm
và patch trong bộ nhớ).
Kiểm tra lại vùng nhớ có quyền thực thi ở trên bằng Process Hacker:
78
Hình 3.19. PE file tại địa chỉ 0x00000000009E0000
Tiến hành Trích xuất vùng nhớ và kiểm tra bằng cách dịch ngược bằng IDA,
có thể khẳng định đây đây chính là DLL đã được chúng ta tiêm vào bên trên.
Hình 3.20. Trích xuất vùng nhớ 0x00000000009E0000 bằng công cụ
79
Hình 3.21. Dịch ngược file được trích xuất để xác minh
Kết luận: Các dấu hiệu Reflective DLL Injection trong tiến trình:
1. Thread hoạt động trong non-image memory với quyền RWX.
2. Vùng Private executable memory bất thường chứa DLL tiêm vào.
3. Module unsigned và thread liên quan đang chạy.
4. Vùng modified code hoặc inconsistent execute permission giữa disk và
memory.
Toàn bộ các kết quả trên khẳng định DLL đã được tiêm và thực thi trong tiến
trình mà không tạo file trên disk, đúng với đặc trưng của Reflective DLL Injection.
Ứng dụng kiến thức về process injection để phân tích mã độc APT32
Phân tích về kỹ thuật trong mã độc APT32
APT32 (còn gọi OceanLotus) là một nhóm tấn công mạng có tổ chức thuộc
lớp APT (Advanced Persistent Threat), hoạt động từ khoảng năm 2012 và được
chú ý nhiều tại khu vực Đông Nam Á. Nhóm này nổi bật bởi phương thức tấn
công có chủ đích, thường dùng spear-phishing, khai thác lỗ hổng và các tải trọng
chứa mã độc để xâm nhập; sau khi đã leo thang quyền hạn, APT32 thường sử
dụng các kỹ thuật ẩn mình tinh vi như process injection (Process Hollowing,
Reflective DLL Injection, v.v.), process ghosting, cùng các phương pháp tránh
phân tích (obfuscation, anti-debug/anti-VM) để duy trì truy cập lâu dài. Do khả
80
năng tùy biến mã độc và sử dụng nhiều kỹ thuật né tránh, APT32 được xem là
mối đe dọa nghiêm trọng, đòi hỏi các biện pháp phát hiện và ứng phó nâng cao,
như phân tích bộ nhớ, giám sát hành vi (ETW/Sysmon) và tích hợp giải pháp EDR
chuyên sâu.
Mẫu mã độc được thực hiện phân tích trong phần này có mã hash SHA256:
f7e7e316c6935286d9153e6b777750626d02daf23b9e7f43905bf7c6e76df7b2, là
một tệp tin ISO, chứa 3 thành phần chính:
File thực thi hợp pháp: Một ứng dụng được ký số hợp lệ, dùng làm vật
mang.
DLL độc hại: Một tệp DLL được đặt tên trùng với một trong những thư
viện mà tệp EXE hợp pháp cần nạp. Đây là thành phần thực thi mã độc
chính.
Tài liệu mồi nhử dùng để đánh lạc hướng người dùng.
Hình 3.22. Mẫu mã độc APT32
Khi người dùng thực thi tệp EXE, hệ điều hành sẽ ưu tiên nạp DLL độc hại
trong cùng thư mục, kích hoạt chuỗi tấn công.
Khi DLL độc hại libusb-1.0.dll được nạp, nó ngay lập tức phân tích các tham
số dòng lệnh để xác định luồng hành động tiếp theo.
81
Hình 3.23. Chức năng của mã độc trong libusb-1.0.dll
82
Hình 3.24. Các chế độ hoạt động của mã độc
Mã độc hoạt động với ba chế độ khác nhau như sau:
Bảng 3.1. Bảng chế độ hoạt động của mã độc
Tham số Giá trị Chế độ hoạt động của mã độc
dòng lệnh trả về
(Không có 0 Thoát (Exit)
tham số)
--verbosity 1 Chế độ Cảnh giác/Anti-Debug: Kích hoạt các cơ
chế phòng thủ để kiểm tra môi trường.
--autostart 2 Chế độ tấn công chính: Giải mã và thực thi
payload qua Process Hollowing.
83
Tham số Giá trị Chế độ hoạt động của mã độc
dòng lệnh trả về
(Tham số 0 Thoát (Exit)
khác)
+ Nếu tham số truyền vào là --verbosity, mã độc kiểm tra Anti-Debugging.
Hàm ScanForDebuggedProcesses() sẽ được chạy trong một luồng riêng để liên
tục quét hệ thống nhằm phát hiện các trình gỡ lỗi (debugger). Nếu phát hiện, mã
độc sẽ tự động dừng các hoạt động chính và chuyển sang trạng thái "ngủ đông"
(sleep(INFINITE)) để tránh bị phân tích.
+ Nếu tham số truyền vào là –autostart, mã độc thực hiện chuỗi tấn công
chính: giải mã payload AES+XOR+LZMA và thực hiện kỹ thuật tiêm tiến trình
để tiêm payload vào tệp ieframe.dll.
84
Hình 3.25. Chức năng tạo mutex và giải mã AES của mã độc
Mã độc tạo một Mutex có tên ioninja-hwc-226. Nếu Mutex đã tồn tại, mã
độc sẽ tự kết thúc, đảm bảo chỉ có một phiên bản duy nhất chạy trên hệ thống.
Sau đó mã độc thực hiện giải mã payload với giải mã AES-256 ECB với key
là C9F301E08D0F106A59E02003F5006495EC0BD67D9AF1821B3800644021B2E41B.
Sau khi giải mã AES, shellcode tiếp tục được xử lý bằng một thuật toán XOR
và giải nén LZMA.
85
Hình 3.26. Giải nén LZMA
Sau khi có được shellcode, mã độc không thực thi nó trực tiếp. Thay vào đó,
nó sử dụng một kỹ thuật Process hollowing với ieframe.dll (ieframe.dll, một thư
viện hợp pháp của Internet Explorer). Shellcode đã được giải nén
được memcpy trực tiếp vào vùng .text của ieframe.dll, thay thế mã nguồn hợp
pháp của thư viện này.
86
Hình 3.27. Kỹ thuật Process hollowing trong mẫu mã độc APT32
Shellcode trên khi thực thi sẽ tiếp tục giải nén shellcode cuối cùng bằng
LZMA.
Hình 3.28. Giải nén shellcode cuối bằng LZMA
87
Hình 3.29. Giải nén shellcode bằng LZMA trên Cyberchef
Payload cuối cùng được giải mã ra là module kết nối C2 viết bằng Rust dùng
để thiết lập kết nối với máy chủ điều khiển
http://194.87.240.39:80/static/version2324897981/frontend/HardToFind/htfr ,
nhận và thực thi các lệnh.
Như vậy, qua việc phân tích hành vi của mẫu mã độc này ta nhận thấy phải
trải qua rất nhiều bước giải mã ta mới tới được payload cuối cùng. Việc mã độc
mã hóa và ẩn giấu shellcode sau nhiều giai đoạn làm việc phát hiện bằng các
phương pháp phát hiện truyền thống rất khó khăn. Phân tiếp em sẽ phát hiện mã
độc này và trích xuất vùng nhớ nghi ngờ chứa shellcode bằng công cụ đã xây
dựng.
88
Phát hiện mã độc trên bộ nhớ bằng công cụ
Hình 3.30. Kết quả rà soát mẫu mã độc APT32 bằng công cụ
Từ kết quả chạy ta thấy:
1. Tồn tại luồng đang chạy trong vùng non-image (rất đáng nghi)
Thread (TID 4752) bắt đầu thực thi từ vùng non-image có quyền thực
thi tại địa chỉ 0x000002493F580000.
Đây là chỉ báo mạnh rằng có shellcode/PE được tiêm vào bộ nhớ
(reflective injection, shellcode injection, hoặc reflective DLL) và đang
được thực thi.
Mã trong vùng image đã bị sửa đổi : Image region
0x00007FF9C38B1000 có chứa module ieframe.dll có quyền RWX
bị gắn nhãn Modified code, nghĩa là mã trong bộ nhớ không khớp với
mã trên đĩa (PE sections bị thay đổi hoặc patching). Điều này chỉ ra
có thể ieframe.dll đã bị sửa đổi trên bộ nhớ. Phần này là hợp lý vì qua
phần phân tích mã độc APT32 trình bày ở mục trên ta đã biết được
mẫu mã độc sử dụng kỹ thuật process hollowing để tiêm shellcode vào
phần .text trong ieframe.dll.
89
2. Công cụ đã chỉ ra module libusb-1.0.dll tại BaseAddress-
0x00007FF9E50E0000 là “Unsigned module”:
Module không có chữ ký số. Một mình điều này chưa đủ để kết luận,
nhưng nhưng khi kết hợp với các chỉ báo khác (RWX non-image,
modified code, threads trong non-image) thì tăng khả năng là module
độc hại. Từ phần phân tích mã độc APT32 bên trên ta đã biết tệp dll
này là một tệp độc hại mã độc dùng để sideload DLL độc hại từ tệp
hợp pháp kyxiang.exe.
Từ kết quả trên cho thấy các chỉ báo mạnh về injection: thread đang thực thi
trong vùng non-image RWX, mã bị sửa đổi trong bộ nhớ, và module unsigned.
90
Công cụ trích xuất vùng nhớ nghi ngờ cho kết quả xác thực: nội dung trích
xuất là shellcode cuối cùng của mã độc, có chức năng kết nối tới máy điều khiển
(C&C).
Hình 3.31. Trích xuất vùng nhớ nghi ngờ chứa shellcode lưu vào trong thư mục
memdmp-11-6-2025~23.47.46
91
Mở xem hex view bằng công cụ HxD với vùng nhớ nghi ngờ là vùng private
memory nhưng có quyền thực thi tại địa chỉ 0x000002493F580000 thì nhận thấy
file được trích xuất ra bằng công cụ chính là shellcode mã độc (có chứa cấu hình
URL C2 của mã độc).
Hình 3.32. File được trích xuất ra bằng công cụ chính là shellcode mã độc
Kết luận
Như vậy, công cụ không chỉ phát hiện nhanh các dấu hiệu tiêm tiến trình mà
còn hỗ trợ trích xuất vùng nhớ nghi ngờ tức thời, rút ngắn thời gian thu thập chứng
cứ và phân tích, giúp lấy được shellcode nhanh chóng mà không cần phân tích mã
code để giải mã AES, giải nén LZMA như ở trên. Khả năng này rất quý giá trong
điều tra số và ứng phó sự cố, vì nó giúp chuyển từ phát hiện ban đầu sang phân
tích sâu (static/dynamic) một cách hiệu quả, từ đó đưa ra các biện pháp ngăn chặn
và phục hồi phù hợp.
92
Kết luận chương 3
Trong chương này, đề tài đã hoàn thành mục tiêu xây dựng và đánh giá kết
quả công cụ rà soát bộ nhớ. Để đánh giá hiệu quả, công cụ đã được tiến hành thực
nghiệm với nhiều kịch bản tiêm tiến trình khác nhau, từ các kỹ thuật mô phỏng
đến các mẫu mã độc thực tế.
Kết quả thực nghiệm cho thấy công cụ đã phát hiện thành công các kỹ thuật
tiêm tiến trình phổ biến như Process Hollowing, Process Ghosting, và Reflective
DLL Injection. Các dấu hiệu bất thường được xác định với các chỉ báo đặc trưng
như:
Vùng nhớ Private có quyền thực thi (PAGE_EXECUTE_READWRITE):
Phát hiện các vùng nhớ được cấp phát động nhưng lại chứa mã lệnh, một
đặc điểm điển hình của shellcode được tiêm vào.
Luồng thực thi từ vùng nhớ không phải là Image (Non-Image Memory
Region): Xác định các luồng có điểm bắt đầu nằm ngoài các mô-đun hợp
lệ đã được nạp từ đĩa, một dấu hiệu mạnh mẽ của mã độc được thực thi trực
tiếp trong bộ nhớ.
Mã lệnh bị sửa đổi (Modified Code): Nhận diện sự khác biệt về nội dung
giữa các vùng nhớ Mapped/Image và tệp thực thi gốc trên đĩa, chỉ ra hành
vi của các kỹ thuật như Process Hollowing.
Tính toàn vẹn của mô-đun: Phát hiện các mô-đun không có chữ ký số hợp
lệ (unsigned) hoặc sự không nhất quán giữa thông tin trong khối môi trường
tiến trình (PEB) và image thực thi, một dấu hiệu của việc nạp mô-đun bất
hợp pháp.
Đặc biệt, khi áp dụng trên mẫu mã độc thực tế liên quan đến nhóm APT32,
công cụ đã chứng minh được hiệu quả khi không chỉ phát hiện thành công các chỉ
báo tiêm tiến trình mà còn hỗ trợ trích xuất shellcode trực tiếp từ bộ nhớ để phục
vụ quá trình phân tích sâu hơn.
Kết quả thực nghiệm khẳng định công cụ có khả năng phát hiện nhanh chóng
và chính xác các kỹ thuật tiêm tiến trình thường gặp, ngay cả trong trường hợp
mã độc sử dụng kỹ thuật che giấu tinh vi (như Process Ghosting). Chức năng trích
93
xuất mã độc từ bộ nhớ đã chứng tỏ giá trị thực tiễn cao, giúp rút ngắn đáng kể thời
gian điều tra và phân tích, đồng thời tạo điều kiện thuận lợi cho việc xây dựng các
chỉ báo tấn công (Indicators of Compromise - IOCs) và các quy tắc phòng thủ.
Kết luận: Công cụ được xây dựng trong nghiên cứu này đã chứng minh hiệu
quả trong việc phát hiện và phân tích các hành vi tiêm tiến trình trên Windows.
Đây là một hướng tiếp cận thực tiễn, có khả năng mở rộng để tích hợp vào các hệ
thống giám sát và điều tra số, góp phần nâng cao năng lực phòng thủ trước các
cuộc tấn công mạng ngày càng tinh vi.
94
KẾT LUẬN
Dựa trên các mục tiêu đã đề ra, đề án đã hoàn thành việc nghiên cứu lý thuyết
đến phát triển và thử nghiệm công cụ thực tế. Cụ thể các công việc đã làm được
như sau:
Đã hoàn thành việc nghiên cứu chuyên sâu về cấu trúc vùng nhớ của tiến
trình trên hệ điều hành Windows. Kiến thức này đóng vai trò là nền tảng
cốt lõi, cho phép phân tích và nhận diện các dấu hiệu bất thường do kỹ thuật
tiêm tiến trình gây ra.
Đã tìm hiểu, phân tích và hệ thống hóa các kỹ thuật tiêm tiến trình phổ biến
o Process Hollowing
o Process Ghosting
o Process Doppelganging
o Process Herpaderping
o Reflective DLL injection
o APC injection
o Thead name-calling injection
và tinh vi, bao gồm:
Phát triển và lập trình các chương trình mô phỏng một số kỹ thuật tiêm tiến
trình.
Phân tích các mẫu mã độc thực tế ứng dụng kỹ thuật tiêm tiến trình để nắm
bắt hành vi và cơ chế hoạt động.
Xây dựng được chương trình có khả năng rà soát và phát hiện những bất
thường trong bộ nhớ của các tiến trình, qua đó xác định các vùng nhớ có
dấu hiệu chứa mã độc.
Phương hướng phát triển:
Tích hợp thêm các dữ liệu từ các nguồn giám sát hệ thống như ETW (Event
Tracing for Windows), Sysmon hoặc các bản ghi (logs) từ giải pháp EDR để nâng
cao độ chính xác trong việc phát hiện của công cụ nhằm xác định các mối đe dọa
tinh vi một cách hiệu quả hơn nữa.
95
TÀI LIỆU THAM KHẢO
1. Tài liệu tiếng Anh
[1] Balzs, B., & Peter, A. (2022). Detecting process injection with kernel-level
monitoring. Journal of Cybersecurity Research, 8(2), 33–49.
[2] Eilam, E. (2005). Reversing: Secrets of reverse engineering. Hoboken, NJ:
Wiley.
[3] Ligh, M., & Case, A. (2014). The art of memory forensics: Detecting
malware and threats in Windows, Linux, and Mac memory. Indianapolis,
IN: Wiley.
[4] Nasereddin, M., & Al-Qassas, R. (2024). A new approach for detecting
process injection attacks using memory analysis. International Journal of
Information Security. DOI:10.1007/s10207-024-00836-w.
[5] Sikorski, M., & Honig, A. (2012). Practical malware analysis: The hands-
on guide to dissecting malicious software. San Francisco, CA: No Starch
Press.
[6] Russinovich, M. E., Solomon, D. A., & Ionescu, A. (2012). Windows
internals, part 1 (6th ed.). Microsoft Press.
[7] Starink, J., Huisman, M., Peter, A., & Continella, A. (2023, October 19–
21). Understanding and measuring inter-process code injection in
Windows malware. [Conference presentation].
2. Tài liệu trực tuyến
[1] Desimone, J. (2019, June 13). Hunting in memory. Elastic Security Labs.
https://www.elastic.co/security-labs/hunting-memory
[2] Hasherezade. (2024, July 25). Thread name-calling – Using thread name
for offense. Check Point Research.
https://research.checkpoint.com/2024/thread-name-calling-using-thread-
name-for-offense/
[3] Hosseini, A. (2017, July 18). Ten process injection techniques: A technical
survey of common and trending process injection techniques. Elastic Blog.
96
https://www.elastic.co/blog/ten-process-injection-techniques-technical-
survey-common-and-trending-process
[4] Klein, A., & Kotler, I. (2019). Process injection techniques – Gotta catch
them all. Black Hat USA 2019. https://i.blackhat.com/USA-
19/Thursday/us-19-Kotler-Process-Injection-Techniques-Gotta-Catch-
Them-All.pdf
[5] MITRE ATT&CK®. (2017, May 31). Process injection (Technique
T1055). https://attack.mitre.org/techniques/T1055/
[6] Monti, E. (2011, May 16). Analyzing malware hollow processes.
Trustwave SpiderLabs Blog. https://www.trustwave.com/en-
us/resources/blogs/spiderlabs-blog/analyzing-malware-hollow-processes/
[7] Recorded Future. (2020). Top 2020 MITRE techniques.
https://www.recordedfuture.com/research/top-2020-mitre-techniques
[8] RedCanary. (2023). MITRE ATT&CK® techniques – Threat detection
report. https://redcanary.com/threat-detection-report/techniques/
[9] Sadique, M. (2020). CyberGate RAT and RedLine Stealer delivered in
ongoing AutoIt malware campaigns. Zscaler Blog.
https://www.zscaler.com/blogs/security-research/cybergate-rat-and-
redline-stealer-delivered-ongoing-autoit-malware-campaigns
[10] Secarma. (n.d.). Process injection part 1 – The theory.
https://secarma.com/process-injection-part-1-the-theory
[11] Shen, O. (2023, December 19). Novel detection of process injection using
network anomalies. Akamai Hunt Research.

