=h2 Why look at rootkits? - They solve an interesting software engineering problem -- Maximum effect from minimum code changes -- Maximum code reuse - They highlight both strengths and weaknesses of OS design -- Modularity --- Even if a Linux kernel is compiled without loadable module support, linking against the running kernel is simple -- Self-modification --- The same mechanism that allows driver loading and stacking allows rootkitting. - They demonstrate architecture-specific systems programming tricks -- IDT modifications -- NDIS driver hooks -- DTLB and ITLB (ShadowWalker by Butler and Sparks) ------ =h2 Ye olde syscall hooking Based on the "dispatch table" design, an old OS staple - Windows "system service table" -- maps system call number to actual function address [russinovich-syscall-table.gif] (from analysis of the Sony DRM rootkit by Mark Russinovich, [http://www.sysinternals.com/blog/2005/10/sony-rootkits-and-digital-rights.html]) - Linux C (int 0x80) -- [[entry.S#L242]] [[entry.S#L575]] -- the system call dispatcher routine -- [[knark.c]] [[rootme.c]] [http://www.cs.dartmouth.edu/~cs38/2005/public_html/resources/kernel/rootkits/knark-2.4.3-release/src/] -- start reading from C, this function gets executed by the kernel after insmod or modprobe make the corresponding system call and the module gets loaded into the kernel space and linked. - C shows kernel symbols for syscalls. The C tool and others check these against known good addresses. - More examples, better design: [[adore/]] - More resources: [http://www.cs.dartmouth.edu/~cs38/2005/public_html/resources/kernel/] ------ =h2 The return of the Hook (1) The ease with which sys_call_table modifications can be found made it obsolete. However, this is by far not the only dispatch table! - Phrack 59:5 [http://www.phrack.org/show.php?p=59&a=5] showed four extra levels for redirecting execution, on the path from filename to actual binary: sys_execve -> do_exec -> open_exec -> load_*_binary ... "classic" -> "obvious" -> "waiter" -> "nexus" [[stories/classic.c]] [[stories/obvious.c]] [[stories/waiter.c]] [[stories/nexus.c]] =code /* * This structure defines the functions that are * used to load the binary formats that linux * accepts. */ struct linux_binfmt { struct linux_binfmt * next; struct module *module; int (*load_binary)(struct linux_binprm *, \ struct pt_regs * regs); int (*load_shlib)(struct file *); int (*core_dump)(long signr, struct pt_regs * regs, \ struct file * file); unsigned long min_coredump; /* minimal dump size */ }; =cut ...and change the load_binary handler. Or core_dump, for more perplexity. - intercept execution in dynamic linker, during process setup, by the pattern of mmaps [[stories/lord.c]] =code # cat /proc/23767/maps 08048000-080b0000 r-xp 00000000 03:09 12 /bin/bash 080b0000-080b4000 rw-p 00067000 03:09 12 /bin/bash 080b4000-08106000 rwxp 00000000 00:00 0 40000000-40015000 r-xp 00000000 03:09 32657 /lib/ld-2.2.2.so 40015000-40016000 rw-p 00014000 03:09 32657 /lib/ld-2.2.2.so 40016000-40017000 r--p 00000000 03:0a 49835 /usr/share/locale/en/LC_IDENTIFICATION ... 4001a000-4001b000 r--p 00000000 03:0a 49836 /usr/share/locale/en/LC_NAME =cut - No need to keep the executable in the filesystem. ------ =h2 The return of the Hook (2) ... or try another set of tables, in Virtual File System layer (VFS). Eliminates the need for syscall pointer modifications. When a file is read: sys_read [[read_write.c#L312]] -> vfs_read [[read_write.c#L222]] =code ... if (file->f_op->read) ret = file->f_op->read(file, buf, count, pos); =cut So: [[adore-ng/adore-ng.c]] Further developments: disk drivers (stackable in Windows) ------ =h2 More points of injection - Infected loadable kernel modules (LKMs) -- init_module first loads its own code, then the actual module -- [http://www.phrack.org/show.php?p=61&a=10] - The Interrupt Descriptor Table (int 0x80 and others, [entry.S]) -- Obtain control on recovery from faults -- [http://www.phrack.org/show.php?p=59&a=4] -- Protective patches are also possible: [[Kfence.c]] - GRUB, the boot loader (or LILO) -- Fake filesystem contents, map files [http://www.phrack.org/show.php?p=63&a=10] - Injection into kernels that do not support LKMs -- Write access to C is enough, linking is standard ELF -- Silvio Cesare, [http://vx.netlux.org/lib/vsc07.html] and several Phrack papers ------ =h2 Back in Windows land - Syscalls numbers change, only userland API are fixed (kernel32.dll, ntdll.dll) -- makes dynamically linked API hijacking more useful (the Import Address Table, IAT) [[butler-hoglund-dc12.ppt]] (slides 6--16) - Different thread/process model affects process hiding concerns -- Scheduling is thread-based, reporting is process-based. Process list is fair game? [[butler-hoglund-dc12.ppt]] (slides 30,34) "Fu" rootkit, "DKOM" - Different kernel self-modification conventions -- dummy preamble instructions for easier hooking! (mov edx, edx) =code 8b ff mov edi, edi 55 push ebp 8b ec mov ebp, esp ... =cut Why? Because the following is exactly 5 bytes: =code e9 xx xx xx xx jmp xx.xx.xx.xx =cut -- but: very limited in 64bit version [http://www.microsoft.com/whdc/driver/kernel/64bitPatching.mspx] - Filter drivers -- Device drivers support stacking in any order. -- Both rootkits and antiviruses can use this (e.g., Sony CD-ROM filter) ------ =h2 Hide-and-seek in Windows land - Debuggers and monitors used API to examine memory -- NtReadVirtualMemory() -- ... but it can be hooked to show pristine picture (no detour) -- "Hacker Defender" [http://hxdef.czweb.org/]. On Windows hooking: [http://hxdef.czweb.org/knowhow.php] -- Livekd (sysinternals) introduces its own kernel driver, takes a snapshot of kernel memory More details: Joanna Rutkowska, [http://invisiblethings.org], "Rootkits Detection on Windows Systems", "System Virginity Verifier" ------ =h2 ShadowWalker - Rootkits must conceal their own code -- Make the scanner see things that are not there -- Subvert virtual memory by desynchronizing ITLB and DTLB [2005-rootkits2-1.jpg] [2005-rootkits2-2.jpg] (Images from [http://www.securityfocus.com/print/infocus/1851], more details there) -- Presented at BlackHat and Defcon 2005: [http://www.blackhat.com/presentations/bh-usa-04/bh-us-04-butler/bh-us-04-butler.pdf]