Bootkits brief techniques

Boot Process


MBR – master boot record

  • contains both partition table and boot code
  • determine which partition (or hard disk) to boot from
  • use BIOS INT 13h commands to load the Volume Boot Record
  • start executing VBR

mbr


VBR – volume boot record

  • test critical aspects of OS
  • load and run the BOOTMGR “bootstrap”
  • which end in load and exec Os Loader – winload.exe

vbr

Os Loader – winload.exe

  • load ntoskrnl.exe
  • Enable Paging!
  • Create PsLoadedModuleList & LOADER_PARAMETER_BLOCK

ntoskrnl.exe

  • init system via KiSystemStartup()
  • build SSDT, Page Tables
  • load hal.dll – HallInitializeBios, HallInitSystem
  • set IVT
  • load kdcom.dll
  • load SERVICE_BOOT_START drivers


Points of interest!


*main goal is get control of ntoskrnl ASAP because NTOSKRNL.EXE initialize system!!

INT13

Crucial interrupt

  • BIOS interface, initial i/o of OS!
  • INT 13h AH=02h: Read Sectors From Drive
  • INT 13h AH=03h: Write Sectors To Drive
  • INT 13h AH=41h: Check Extensions Present
  • INT 13h AH=43h: Extended Write Sectors to Drive

Commonly hooked

  • parsing read request & find pattern
  • osloader – winload.exe is next target for hook

How interrupt hook code looks like ?

  • MBR / VBR code stored at 0x0:0x7c00
  • bootstrap code from VBR copied at 0xD00:0x0
  • bootmgr rewrite most likely both pieces of memory
  • so, how can int13 hook code survive ?
    • BIOSDATA 0x40:0x13 (a.k.a. es:0x413) => base memory size in KB!
    • decrease & copy hook code to “tricky reserved” memory

reload_vbr

INT13 hook code

  • unhook
  • is INT13 read request ? (ah in (0x2, 0x42) )
  • find OS Loader (winload.exe) pattern!
  • hook OS Loader at specified point

OS Loader hook code

  • unhook
  • important structures created (PsLoadedModuleList, …)
  • copy next hook code to ntoskrnl.exe slack space
    • survive mode switching
  • hook ntoskrnl.exe

ntoskrnl.exe owned == windows owned!

  • wait till OS is initialized (if not yet, then rehook ntoskrnl.exe)
  • unhook
  • install payload
    • load rootkit to memory
      • must be disabled integrity checks
    • rewrite windows binary (explorer, winlogon, userinit, svchost, …)
    • register binary to windows startup

Advanced ‘features’

  • FileSystem parser for rewriting binary whithout support of OS Api
  • Patch (activate) malicious inactive binary
  • Create ring3-ring0 callgate
  • protect ‘reserved’ memory
  • Debug ntoskrnl.exe instead of [find pattern & hook]
  • Hook before Os fully initialized

FileSystem parser

  • introduced in Stoned
  • used in several bootkits in the wild
    • Unruy, Smytnil, Plite, MbrLoader, Guntior
  • In MBRLoader.B presented inovative idea
    • patch malicious binary back to live during boot
    • original state is non-malicious (EntryPoint on nop slide, etc…)
    • evade AV techniques (emulation, hips)
  • + :
    • no hooking needed
    • minimal interference with boot process
  • - :
    • low system control

ring3-ring0 callgate

aka how can simlpe call switch from ring3 to ring0 just to know where the callgate is ;)

FLAGS 

  • P -> Is segment present ? (1 / 0)
  • DPL -> Descriptor privilage level (ring 0 – 3)
  • DT -> Descriptor type
  • Type – > Segment type (code / data)
  • G -> Granularity (0 = 1byte; 1 = 1kb)
  • D -> Operand Size (0 = 16b, 1 = 32b)
  • Rs -> Reserved, should be 0
  • A -> Available for system use (always 0)

By realworld example


CALLGATE (0x8003F3E0)

  • Routine Address => 0x8003F000
  • Descryptor => 0x8003F3e8
  • Flags => 0xEC == 11101100 b
    • P = 1 (present)
    • DPL = 11 (ring 3)
    • Type = 01100 (0xEC default)

DESCRYPTOR (0x8003F3E8)

  • Segment Limit => 2^20 == 4GB
  • Base => 0 == user mode address!
  • Flags => 0x9A == 10011010 b
    • P = 1 (present)
    • DPL = 00 (ring0)
    • Type = 11010 (0x9a code segment)
  • Granularity => 0xC == 1100 b
    • G => 1 (1kb granularity)
    • D => 1 (32b operand size)
  • Routine (0x8003F000)
    • retn -> ret to user space code but in ring-0!!

Another trick how to hide reserved memory

first (till i know) used in malware family of rovnix
and also tested by goblin family.
Goblins first attempt to infect boot process!

INT15

  • ax = 0xe820 -> Query System Address Map
    • reports which memory address ranges are usable and which are reserved for use by the BIOS.
  • hook INT15
    • protect own data (resize queried memory -in output record- if contains bootkits data!)

why modify windows code ? -> debug instead of hooking!

SIDT - INT1 – DRx

  • Get IDT base addr
  • set own INT1 handler
  • set DRx

INT1 handler :

  • check pattern on breakpoint instruction
  • set new hw breakpoint till not specified state exec yet

patch in early state vs PatchGUARD

PatchGuard is mittigation against :

  • rewriting critical structures (IDT, GDT, SSDT)
  • Using kernel stacks not allocated by the kernel
  • Modifying or patching code contained within the kernel itself
    • kernel objects
    • kernel procedures hooks

and when you will patch in this manner BSOD will appear, because : Patching the kernel has never been supported by Microsoft … but … when you will patch before PatchGuard is active, protecting new code is exactly what will microsoft PatchGuard support! ;)

Step by step :

  • infect MBR / VBR
  • hook INT13
  • hook OSLoader
  • Patch ntoskrnl.exe, hal.dll
  • os loader load these to memory, just find it!
  • PatchGuard is your best friend, ever and ever

This article will be updated, and some additional techniques / highliths would be added.

Leave a comment

0 Comments.

Leave a Reply


[ Ctrl + Enter ]


Go To Top
Follow

Get every new post delivered to your Inbox

Join other followers: