Chinaunix首页 | 论坛 | 博客
  • 博客访问: 914460
  • 博文数量: 119
  • 博客积分: 2493
  • 博客等级: 大尉
  • 技术积分: 2363
  • 用 户 组: 普通用户
  • 注册时间: 2012-06-03 14:00
文章分类

全部博文(119)

文章存档

2013年(19)

2012年(100)

分类: LINUX

2012-07-16 13:06:46


1,系统调用日志收集系统的意义。
       系统调用是用户获取系统服务的唯一入口,因此对系统调用的安全调用直接关系到系统
的安全,假如有用户恶意不断地调用系统调用,将会导致系统负载增加,所以如果能收集到时谁
调用了一些危险的系统调用,以及调用系统调用的时间和其他信息,将有助于系统管理员进行事
后追踪,从而提高系统的安全性。
--------------------------------------------------------------
2,系统调用日志收集系统总体框架图。
 
-----------------------------------------------------------
3,系统调用日志收集系统的实现。(以linux-2.6..39.4为例)

        3.1,添加系统调用号.
         位置:arch/x86/include/asm/unistd_32.h
        #define  __NR_syscall_audit   345
        #define  __NR_myaudit         346
        #ifdef   __KERNEL__

        #define  NR_syscalls   347
---------------------------------------------------------- 
       3.2,在系统调用表中添加相应的表项。
        .long    sys_syscall_audit
        .long    sys_myaudit
-----------------------------------------------------------
       3.3,修改系统调用入口。(有两个入口,syscall_call和sysenter)
        位置:arch/x86/kernel/entry_32.S
        主要是在系统调用的两个入口进行监控,发现调用了如下四个系统调用(getpid,sysinfo,fork,execv)
将会执行sys_syscall_audit函数

  1. syscall_call:
  2.     call *sys_call_table(,%eax,4)
  3.     movl %eax,PT_EAX(%esp)        # store the return value
  4. #如下位添加代码
  5. #----------------------------------------------------
  6.     cmpl $20,0x2c(%esp) #getpid()
  7.     je myauditsys
  8.     cmpl $116,0x2c(%esp) #sysinfo()
  9.     je myauditsys
  10.     cmpl $2,0x2c(%esp) #fork
  11.     je myauditsys
  12.     cmpl $11,0x2c(%esp) #execv
  13.     je myauditsys
  14. #-----------------------------------------------
  1. syscall_exit:
  2.     LOCKDEP_SYS_EXIT
  3.     ...
  4.     jne syscall_exit_work
  5. #如下位添加代码
  6. #------------------------------------------------
  7.     jmp restore_all
  8. myauditsys:
  9.     pushl %eax
  10.     pushl 0x30(%esp)
  11.     call sys_syscall_audit
  12.     popl %eax
  13.     popl %eax
  14.     jmp syscall_exit
  15. #------------------------------------------------
  16. restore_all:
  17.     TRACE_IRQS_IRET
  1. sysenter_do_call:
  2.     ...
  3.     movl %eax,PT_EAX(%esp)
  4.    #如下为添加代码
  5. /*--------------------------------------------------------*/
  6.     cmpl $20,0x2c(%esp) #getpid()
  7.     je enter_audit
  8.     cmpl $116,0x2c(%esp) #sysinfo()
  9.     je enter_audit
  10.     cmpl $2,0x2c(%esp) #fork
  11.     je enter_audit
  12.     cmpl $11,0x2c(%esp) #execv
  13.     je enter_audit
  14. come_back:
  15. /*--------------------------------------------------------*/
  1. sysenter_exit:
  2.     ....
  3.     ENABLE_INTERRUPTS_SY***IT
  4. /*--------------------------------------------------------*/
  5.     jmp sysenter_audit
  6. enter_audit:
  7.     pushl %eax
  8.     pushl 0x30(%esp)
  9.     call sys_syscall_audit
  10.     popl %eax
  11.     popl %eax
  12.     jmp come_back
  13. /*--------------------------------------------------------*/
--------------------------------------------------------------------------------------------
       3.4,添加系统调用的服务例程。
      在arch/x86/kernel/下面添加文件myaudit.c
    该文件中实现了系统调用的服务例程,但这儿实现的服务例程都只有一个接口,
真正的实现将在模块中实现,这样是为了方便调试,避免了多次编译内核。这儿主要
是通过两个全局变量(my_auditmy_sysaudit)与内核模块之间建立了联系。

  1. /**
  2.  * myaudit.c
  3.  */

  4. #include <linux/proc_fs.h>
  5. #include <linux/init.h>
  6. #include <linux/types.h>
  7. #include <linux/sched.h>
  8. #include <asm/current.h>

  9. void (*my_audit)(int, int) = 0;

  10. asmlinkage void sys_syscall_audit(int syscall_number, int return_value)
  11. {
  12.     if (my_audit) {
  13.         return (*my_audit)(syscall_number, return_value);
  14.         printk("IN KERNEL: %s(%d), syscall: %d, return: %d\n", current->comm, (int)current->pid, syscall_number, return_value);
  15.         //printk("IN KERNEL: %s\n", current);
  16.     } else {
  17.         printk("my_audit is empty!\n");
  18.     }
  19.     return ;
  20. }

  21. int (*my_sysaudit)(u8, u8*, u16, u8) = 0;

  22. asmlinkage int sys_myaudit(u8 type, u8 *us_buf, u16 us_buf_size, u8 reset)
  23. {
  24.     if (my_sysaudit) {
  25.         return (*my_sysaudit)(type, us_buf, us_buf_size, reset);
  26.         printk("IN KERNEL: my system call sys_myaudit() working...\n");
  27.     } else {
  28.         printk("my_sysaudit is empty!\n");
  29.     }
  30.     return 0;
  31. }
----------------------------------------------------------------------------------------------
       3.5,修改makefile。位置:arch/x86/kernel/Makefile
 
  1. obj-y            := process_$(BITS).o signal.o entry_$(BITS).o myaudit.o
----------------------------------------------------------------------------------------------
       3.6,导出全局变量。(不导出的话,内核模块将对其不可见)
            修改arch/x86/kernel/i386_ksyms_32.c文件,在其末尾追加:

  1. EXPORT_SYMBOL(my_audit);
  2. EXPORT_SYMBOL(my_sysaudit);
----------------------------------------------------------------------------------------------
        3.7,声明全局变量。
             修改:include/linux/module.h 添加:

  1. extern void (*my_audit)(int,int);
  2. extern int (*my_sysaudit)(u8,u8*,u16,u8);






       
             
   
    
阅读(2021) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~