Add kernel file version check to avoid BSOD on Win10 x86
This commit is contained in:
parent
eaa550fa97
commit
ab9dd177b7
Binary file not shown.
Binary file not shown.
|
@ -15,6 +15,7 @@ to configure the destination path from Metasploit (see `WRITEABLE_DIR` option
|
|||
description).
|
||||
|
||||
Here is the main workflow:
|
||||
|
||||
1. Retrieve the target name (where the PE loader will be dropped).
|
||||
1. Retrieve the PE loader from the binary and write it on disk.
|
||||
1. Create a [section object](https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/section-objects-and-views)
|
||||
|
@ -26,6 +27,12 @@ Here is the main workflow:
|
|||
The source code is based on [Johnny Shaw](https://twitter.com/jxy__s)'s
|
||||
[PoC](https://github.com/jxy-s/herpaderping).
|
||||
|
||||
**This payload won't work on 32-bit Windows 10 versions from 1511 (build
|
||||
10586) to 1703 (build 15063), including Windows 10 2016 LTSB (build 14393).**
|
||||
These versions have a bug in the kernel that crashes/BugCheck the OS
|
||||
when executing this payload. So, to avoid this, the payload won't run if
|
||||
it detects the OS is one of these versions. More details [here](https://bugs.chromium.org/p/project-zero/issues/detail?id=852).
|
||||
|
||||
## Verification Steps
|
||||
Here are the steps using a Meterpreter payload on a 64-bits target:
|
||||
|
||||
|
@ -141,6 +148,12 @@ Evasion target:
|
|||
msf6 evasion(windows/process_herpaderping) > run
|
||||
|
||||
[+] raU.exe stored at /home/msfuser/.msf4/local/raU.exe
|
||||
[!] #### WARNING ####
|
||||
This payload won't work on 32-bit Windows 10 versions from 1511 (build
|
||||
10586) to 1703 (build 15063), including Windows 10 2016 LTSB (build 14393).
|
||||
These versions have a bug in the kernel that crashes/BugCheck the OS
|
||||
when executing this payload. So, to avoid this, the payload won't run if
|
||||
it detects the OS is one of these versions.
|
||||
msf6 evasion(windows/process_herpaderping) > cp /home/msfuser/.msf4/local/raU.exe /remote_share/tmp/test_x86.exe
|
||||
[*] exec: cp /home/msfuser/.msf4/local/raU.exe /remote_share/tmp/test_x86.exe
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@
|
|||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;DEBUGTRACE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
|
@ -115,9 +115,9 @@
|
|||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>bcrypt.lib;ntdll.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>DebugFull</GenerateDebugInformation>
|
||||
<AdditionalDependencies>bcrypt.lib;ntdll.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;version.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
|
@ -138,7 +138,7 @@
|
|||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>DebugFull</GenerateDebugInformation>
|
||||
<AdditionalDependencies>bcrypt.lib;ntdll.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>bcrypt.lib;ntdll.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;version.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
|
@ -165,7 +165,7 @@
|
|||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<AdditionalDependencies>bcrypt.lib;ntdll.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>bcrypt.lib;ntdll.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;version.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
|
@ -191,10 +191,10 @@
|
|||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<AdditionalDependencies>bcrypt.lib;ntdll.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>bcrypt.lib;ntdll.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;version.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
|
@ -317,13 +317,32 @@ HRESULT Herpaderp::ExecuteProcess()
|
|||
|
||||
int WINAPI wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ PWSTR, _In_ int)
|
||||
{
|
||||
HRESULT hr = Herpaderp::ExecuteProcess();
|
||||
HRESULT hr;
|
||||
|
||||
#ifndef _WIN64
|
||||
//
|
||||
// Only 32-bit version of Windows 10 is affected
|
||||
// see https://bugs.chromium.org/p/project-zero/issues/detail?id=852
|
||||
//
|
||||
hr = Utils::IsBuggyKernel();
|
||||
if (FAILED(hr))
|
||||
{
|
||||
dprintf("Process Herpaderp Failed (%S)", Utils::FormatError(hr).c_str());
|
||||
return EXIT_FAILURE;
|
||||
REPORT_AND_RETURN_HR("Checking kernel failed", hr);
|
||||
}
|
||||
if (hr == S_OK)
|
||||
{
|
||||
hr = E_ABORT;
|
||||
REPORT_AND_RETURN_HR("Kernel version on this OS is buggy and will BSOD... aborting", hr);
|
||||
}
|
||||
dprintf("Kernel is not one of the buggy one");
|
||||
#endif
|
||||
|
||||
hr = Herpaderp::ExecuteProcess();
|
||||
if (FAILED(hr))
|
||||
{
|
||||
REPORT_AND_RETURN_HR("Process Herpaderp failed", hr);
|
||||
}
|
||||
|
||||
dprintf("Process Herpaderp Succeeded");
|
||||
dprintf("Process Herpaderp succeeded");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -747,3 +747,88 @@ HRESULT Utils::GetFileName(
|
|||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#ifndef _WIN64
|
||||
//
|
||||
// Only needed for 32-bit Windows
|
||||
//
|
||||
_Use_decl_annotations_
|
||||
HRESULT Utils::GetFileVersion(LPCWSTR lptstrFilename, PFILE_VERSION ver)
|
||||
{
|
||||
DWORD dwHandle;
|
||||
DWORD dwLen = GetFileVersionInfoSizeW(lptstrFilename, &dwHandle);
|
||||
if (dwLen == 0)
|
||||
{
|
||||
REPORT_AND_RETURN_WIN32("GetFileVersion: Error getting file version info size", GetLastError());
|
||||
}
|
||||
LPVOID lpData = new LPVOID[dwLen];
|
||||
if (!GetFileVersionInfoW(lptstrFilename, 0, dwLen, lpData))
|
||||
{
|
||||
delete[] lpData;
|
||||
REPORT_AND_RETURN_WIN32("GetFileVersion: Error getting file version info", GetLastError());
|
||||
}
|
||||
VS_FIXEDFILEINFO* versionInfo;
|
||||
UINT uLen;
|
||||
if (!VerQueryValueW(lpData, L"\\", (LPVOID*)&versionInfo, &uLen))
|
||||
{
|
||||
delete[] lpData;
|
||||
REPORT_AND_RETURN_WIN32("GetFileVersion: Error getting version info", GetLastError());
|
||||
}
|
||||
|
||||
ver->MajorVersion = (versionInfo->dwProductVersionMS >> 16) & 0xFFFF;
|
||||
ver->MinorVersion = versionInfo->dwProductVersionMS & 0xFFFF;
|
||||
ver->BuildVersion = (versionInfo->dwProductVersionLS >> 16) & 0xFFFF;
|
||||
ver->RevisionVersion = versionInfo->dwProductVersionLS & 0xFFFF;
|
||||
|
||||
delete[] lpData;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
_Use_decl_annotations_
|
||||
HRESULT Utils::IsBuggyKernel()
|
||||
{
|
||||
std::wstring kernelFile;
|
||||
HRESULT hr = Utils::GetFileName("%SystemRoot%\\System32\\ntoskrnl.exe", kernelFile);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
REPORT_AND_RETURN_HR("Failed to retrieve the target filename", hr);
|
||||
}
|
||||
|
||||
FileHandle kernelHandle(kernelFile);
|
||||
kernelHandle.get() = CreateFileW(kernelFile.c_str(),
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
nullptr,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
nullptr);
|
||||
if (!kernelHandle.valid())
|
||||
{
|
||||
REPORT_AND_RETURN_WIN32("BuggyKernel: Failed to open Kernel file", GetLastError());
|
||||
}
|
||||
|
||||
FILE_VERSION ver;
|
||||
hr = GetFileVersion(kernelFile.c_str(), &ver);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
REPORT_AND_RETURN_HR("BuggyKernel: Failed getting file version", hr);
|
||||
}
|
||||
dprintf("Version of %S is %hu.%hu.%hu.%hu",
|
||||
kernelFile.c_str(),
|
||||
ver.MajorVersion,
|
||||
ver.MinorVersion,
|
||||
ver.BuildVersion,
|
||||
ver.RevisionVersion
|
||||
);
|
||||
if (ver.MajorVersion == 10 &&
|
||||
ver.MinorVersion == 0 &&
|
||||
ver.BuildVersion > 10240 &&
|
||||
ver.BuildVersion < 16299)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return S_FALSE;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -246,4 +246,22 @@ namespace Utils
|
|||
_In_ const char* sourceFileName,
|
||||
_Out_ std::wstring& finalFileName);
|
||||
|
||||
#ifndef _WIN64
|
||||
//
|
||||
// Only needed for 32-bit Windows
|
||||
//
|
||||
typedef struct _FILE_VERSION
|
||||
{
|
||||
WORD MajorVersion;
|
||||
WORD MinorVersion;
|
||||
WORD BuildVersion;
|
||||
WORD RevisionVersion;
|
||||
} FILE_VERSION, * PFILE_VERSION;
|
||||
|
||||
_Must_inspect_result_ HRESULT GetFileVersion(
|
||||
_In_ LPCWSTR lptstrFilename,
|
||||
_Out_ PFILE_VERSION ver);
|
||||
|
||||
_Must_inspect_result_ HRESULT IsBuggyKernel();
|
||||
#endif
|
||||
}
|
|
@ -180,5 +180,15 @@ class MetasploitModule < Msf::Evasion
|
|||
patch_binary(pe, 'REPLACEFILENAME', replace_path.b)
|
||||
|
||||
file_create(pe)
|
||||
if arch_suffix == 'x86'
|
||||
print_warning(
|
||||
"#### WARNING ####\n"\
|
||||
"This payload won't work on 32-bit Windows 10 versions from 1511 (build\n"\
|
||||
"10586) to 1703 (build 15063), including Windows 10 2016 LTSB (build 14393).\n"\
|
||||
"These versions have a bug in the kernel that crashes/BugCheck the OS\n"\
|
||||
"when executing this payload. So, to avoid this, the payload won't run if\n"\
|
||||
"it detects the OS is one of these versions."
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue