Linux 系统调用劫持方法

合集下载

Linux内核中系统调用详解

Linux内核中系统调用详解

Linux内核中系统调用详解什么是系统调用?(Linux)内核中设置了一组用于实现各种系统功能的子程序,称为系统调用。

用户可以通过系统调用命令在自己的应用程序中调用它们。

从某种角度来看,系统调用和普通的函数调用非常相似。

区别仅仅在于,系统调用由(操作系统)核心提供,运行于核心态;而普通的函数调用由函数库或用户自己提供,运行于用户态。

随Linux核心还提供了一些(C语言)函数库,这些库对系统调用进行了一些包装和扩展,因为这些库函数与系统调用的关系非常紧密,所以习惯上把这些函数也称为系统调用。

为什么要用系统调用?实际上,很多已经被我们习以为常的C语言标准函数,在Linux 平台上的实现都是靠系统调用完成的,所以如果想对系统底层的原理作深入的了解,掌握各种系统调用是初步的要求。

进一步,若想成为一名Linux下(编程)高手,也就是我们常说的Hacker,其标志之一也是能对各种系统调用有透彻的了解。

即使除去上面的原因,在平常的编程中你也会发现,在很多情况下,系统调用是实现你的想法的简洁有效的途径,所以有可能的话应该尽量多掌握一些系统调用,这会对你的程序设计过程带来意想不到的帮助。

系统调用是怎么工作的?一般的,进程是不能访问内核的。

它不能访问内核所占内存空间也不能调用内核函数。

(CPU)(硬件)决定了这些(这就是为什么它被称作"保护模式")。

系统调用是这些规则的一个例外。

其原理是进程先用适当的值填充(寄存器),然后调用一个特殊的指令,这个指令会跳到一个事先定义的内核中的一个位置(当然,这个位置是用户进程可读但是不可写的)。

在(Intel)CPU中,这个由中断0x80实现。

硬件知道一旦你跳到这个位置,你就不是在限制模式下运行的用户,而是作为操作系统的内核--所以你就可以为所欲为。

进程可以跳转到的内核位置叫做sysem_call。

这个过程检查系统调用号,这个号码告诉内核进程请求哪种服务。

然后,它查看系统调用表(sys_call_table)找到所调用的内核函数入口地址。

linux hook系统调用函数

linux hook系统调用函数

linux hook系统调用函数
Linux的hook系统调用函数是指在系统调用执行之前或之后,
通过注入自定义代码来拦截和修改系统调用的过程。

这种机制可以用于实现一些安全措施,例如检测和防止恶意软件的行为,或者限制用户对系统资源的访问。

hook系统调用函数的实现方式有多种,其中比较常用的是使用
内核模块来实现。

内核模块可以通过注册自定义的处理函数来拦截指定的系统调用,并在需要的时候调用原始的系统调用函数或者执行自己的逻辑。

例如,可以编写一个hook系统调用函数来监控用户进程
的文件打开操作,以此来检测和防止恶意软件对系统文件的篡改。

需要注意的是,hook系统调用函数可能会对系统性能产生一定
的影响,因此应该谨慎使用。

此外,由于hook系统调用函数在内核
层面进行操作,因此编写和调试这类代码需要一定的专业知识和技能。

总之,Linux的hook系统调用函数是一种非常有用的机制,可
以为我们提供更多的安全保障和系统控制能力。

然而,在使用之前,我们需要充分了解其实现方式和潜在的影响,以确保其能够正确地工作并不会对系统性能造成过大的影响。

- 1 -。

操作系统--linux系统调用

操作系统--linux系统调用

实验报告一、理论分析(分值:20%)【从操作系统原理(理论)的角度阐述系统功能调用的过程】1、函数声明中都有asmlinkage限定词,用于通知编译器仅从栈中提取该函数的参数。

2、系统调用getXXX()在内核中被定义为sys_getXXX()。

系统调用号:在linux中,每个系统调用都赋予一个系统调用号,通过这个独一无二的号就可以关联系统调用。

当用户空间的进程执行一个系统调用的时候,这个系统调用号就被用来指明到底要执行哪个系统调用;进程不会提及系统调用的名称。

系统调用号一旦分配就不能再有任何变更(否则编译好的应用程序就会崩溃),如果一个系统调用被删除,它所占用的系统调用号也不允许被回收利用。

Linux 有一个"未使用"系统调用sys_ni_syscall(),它除了返回-ENOSYS外不做任何其他工作,这个错误号就是专门针对无效的系统调用而设的。

内核记录了系统调用表中所有已注册过的系统调用的列表,存储在sys_call_table中。

它与体系结构有关,一般在entry.s中定义。

这个表中为每一个有效的系统调用指定了唯一的系统调用号。

3、Makefile控制着整个内核的编译,在每个子目录下调用编译.c 文件,生成.o文件,生成新的内核。

会把新编译的sys_hello内核加入到系统调用中。

系统调用表geditsyscall_32.tbl中加入354 i386 hello sys_hello,当系统调用时可以在调用表中找到系统调用的号。

4、在syscalls.h中添加定义的内容的引用函数。

5、编译执行结果。

二、设计与实现(分值:30%)【阐述在Linux中添加系统功能调用的方法】1、在内核目录下创建hello文件夹 mkdir hello2、进入hello文件夹 cd hello3、创建hello.c的文件 vim hello.c4、加入代码#include <linux/kernel.h>asmlinkage long sys_hello(void){printk(“Hello world\n”);return 0;}5、在hello文件夹下添加Makefile文件 vim Makefile在文件里添加 obj-y := hello.o6、返回内核的根目录中,打开Makefile文件,在842行添加代码 vim Makefile 将core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/改为core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ hello/ 7、打开系统调用表 cd arch/x86/syscallsVim syscall_32.tbl在文件最后一行添加354 i386 hello sys_hello8、在调用函数名的文件中加入添加的函数cd include/linux/Vim syscalls.hasmlinkage long sys_hello(void);9、进行编译cd /usr/src/linux-3.16/sudo make menuconfigsudo make oldconfigmake -j410、安装编译好的内核sudo make modules_install installshutdown -r now重启后选择新的内核载入测试uname -r11、编写测试文件hello.c#include <stdio.h>#include <linux/kernel.h>#include <sys/syscall.h>#include <unistd.h>int main(){printf("%ld\n", syscall(354));return 0;}12、编译测试gcc -o hello.c hello./hello.outdmesg三、实验结果(分值:10%)【对实验结果进行简要分析和说明】测试文件调用系统调用号354,并且将返回结果0输出,dmesg可以将开机显示结果输出查看。

Linux系统调用详细全过程

Linux系统调用详细全过程
方法分配和释放内存。
6
系统命令、内核函数
系统调用与系统命令

系统命令相对API来说,更高一层。每个系统命令
都是一个执行程序,如ls命令等。这些命令的实现
调用了系统调用。
系统调用与内核函数


系统调用是用户进入内核的接口层,它本身并非内
核函数,但是它由内核函数实现。
进入内核后,不同的系统调用会找到各自对应的内
常,CPU便被切换到内核态执行内核函
数,转到了系统调用处理程序的入口:
system_call()。
int $0x80指令将用户态的执行模式转变为内
核态,并将控制权交给系统调用过程的起点
system_call()处理函数。
4
system_call()函数
system_cal()检查系统调用号,该号码告诉内核
SYMBOL_NAME(sys_exit)
.long
.longSYMBOL_NAME(sys_read)
SYMBOL_NAME(sys_fork)
.long
.longSYMBOL_NAME(sys_write)
SYMBOL_NAME(sys_read)
.long
.longSYMBOL_NAME(sys_open)
SYMBOL_NAME(sys_write)
.long
.long
…… SYMBOL_NAME(sys_open)
……
……
……
.long
SYMBOL_NAME(sys_getuid)
.long SYMBOL_NAME(sys_getuid)
* 4
+
21
系统调用的返回
当服务例程结束时,system_call( ) 从eax

Linux系统调用劫持:技术原理、应用及检测

Linux系统调用劫持:技术原理、应用及检测

Linux系统调用劫持:技术原理、应用及检测
时金桥;方滨兴;胡铭曾;李斌
【期刊名称】《计算机工程与应用》
【年(卷),期】2003(039)032
【摘要】系统调用劫持是黑客入侵系统后保留后门常用的一项技术.文章提出了利用可装入内核模块修改系统调用表和中断描述符表两种实现Linux系统调用劫持的方法,探讨了系统调用劫持技术在rootkit、入侵检测等方面的应用,并给出了利用kmem进行系统调用劫持检测的一般方法.该文的分析基于Intel x86平台上的2.4内核.
【总页数】4页(P167-170)
【作者】时金桥;方滨兴;胡铭曾;李斌
【作者单位】哈尔滨工业大学国家计算机信息内容安全重点实验室,哈尔滨,150001;哈尔滨工业大学国家计算机信息内容安全重点实验室,哈尔滨,150001;哈尔滨工业大学国家计算机信息内容安全重点实验室,哈尔滨,150001;哈尔滨工业大学国家计算机信息内容安全重点实验室,哈尔滨,150001
【正文语种】中文
【中图分类】TP393.08
【相关文献】
1.基于Linux系统调用的主机入侵检测系统的设计 [J], 吴彦波;林中
2.基于系统调用的Linux系统入侵检测技术研究 [J], 贾春福;钟安鸣;周霞;田然;段
雪涛
3.Linux系统调用劫持的检测方法 [J], 任幸东;王剑
4.劫持Linux系统调用封杀Core Dump漏洞攻击 [J], 王畅;薛素静
5.Linux木马检测技术分析与系统调用权限验证法 [J], 钱昌明;黄皓
因版权原因,仅展示原文概要,查看原文内容请购买。

linux文件系统的系统调用命令

linux文件系统的系统调用命令

linux文件系统的系统调用命令Linux文件系统的系统调用命令Linux是一个开源的操作系统,提供了许多强大且灵活的系统调用命令来管理文件系统。

本文将深入探讨Linux文件系统的系统调用命令,包括创建、删除、重命名、复制和移动文件,以及设置文件权限和属性等功能。

一、文件系统简介在Linux系统中,文件系统是指对存储设备的管理和组织。

它使用层次结构来管理文件和目录,允许用户在存储设备上创建、访问和操作文件。

文件系统的目的是提供一种有效和可靠的方式来组织和存储数据。

二、系统调用命令Linux系统提供了一系列的系统调用命令,可以通过调用这些命令来操作文件系统。

1.创建文件创建文件是文件系统中的常见操作。

在Linux中,可以使用open系统调用命令来创建文件。

open命令的语法如下:int open(const char *pathname, int flags, mode_t mode);pathname:指定文件的路径和名称。

flags:指定文件的打开模式,如O_RDONLY(只读)、O_WRONLY (只写)、O_RDWR(读写)等。

mode:指定文件的权限模式。

open命令返回一个文件描述符,以便在后续的操作中引用该文件。

2.删除文件删除文件是通过unlink系统调用命令实现的。

unlink命令的语法如下:int unlink(const char *pathname);pathname:指定要删除的文件的路径和名称。

3.重命名文件重命名文件是通过rename系统调用命令实现的。

rename命令的语法如下:int rename(const char *oldpath, const char *newpath);oldpath:指定要重命名的文件的路径和名称。

newpath:指定重命名后的文件的路径和名称。

4.复制文件复制文件是通过使用read和write系统调用命令实现的。

read命令用于从源文件中读取数据,write命令用于将数据写入目标文件。

Linux的系统调用实现机制与系统调用实例分析-Jin-Yang

Linux的系统调用实现机制与系统调用实例分析-Jin-Yang

Linux的系统调用实现机制与系统调用实例分析姓名: 杨骏班级: 混合964 学号: 9630130 教师: 李善平一. 前言众所周知,系统调用是操作系统中必不可少的一个组成部分. 尤其对于以该操作系统作为平台进行程序设计的程序员来说,系统调用提供了该系统面向用户的编程界面, 程序中所有与系统有关的代码的实现都必须通过这些接口来完成,了解系统调用的一整套机制有十分重要的意义. 同时,在分析Linux的系统调用机制的时候,就与分析Linux其他部分的源代码一样总能发现非常巧妙的数据结构与算法,如使用了在高级语言中嵌入汇编代码来实现所有系统调用的公共入口,大大提高的系统运行的效率.本文分为两部分:第一部分详尽地分析了Linux系统调用的一整套机制,并给出流程图; 第二部分用具体的系统调用为实例对系统调用的实现代码进行分析.在阅读代码时遇到一些疑难之处,在文章中都使用了”猜测为”注明,表示该部分的分析没有充分的依据.如有错误之处,希望读者给予指正.二. 预备知识1.INTEL x86的汇编语法由于在系统调用的公共入口的代码是由汇编语言写成,而32位的INTEL x86芯片的汇编语法与传统的IBM PC/XT汇编语法有较大的差别,因此这里给出简单的说明:.特有的寄存器名eax, ebx, esp等以’e’开头的寄存器都是32位的扩展寄存器db7等为调试寄存器.特有的符号$ : 表示这是立即数%: 表示这是寄存器(): 表示用括号内的值作为地址值进行间接寻址* : 表示取出该地址下的内容.双操作数指令赋值方向与原来相反如movl $23, %eax表示将立即数23赋值给寄存器eax2.C语言中嵌入汇编代码及进行参数与返回值传递的方法C语言中嵌入汇编代码的常见格式如下:__asm__ volatile ("int $0x80": "=a" (__res): "0" (__NR_##name), "b" ((long)(arg1)),"c" ((long)(arg2)),"d" ((long)(arg3)));各种符号的含义如下:__asm__:嵌入汇编。

8第八章Linux下的系统调用

8第八章Linux下的系统调用

第八章Linux下的系统调用8.1 系统调用介绍8.1.1 引言系统调用是内核提供的、功能十分强大的一系列函数。

它们在内核中实现,然后通过一定的方式(库、陷入等)呈现给用户,是用户程序与内核交互的一个接口。

如果没有系统调用,则不可能编写出十分强大的用户程序,因为失去了内核的支持。

由此可见系统调用的地位举足轻重。

内核的主体可以归结为:⏹系统调用的集合;⏹实现系统调用的算法。

8.1.2 系统调用的实现流程这里我们通过getuid()这个简单的系统调用来分析一下系统调用的实现流程。

在分析这个程序时并不考虑它的底层是如何实现的,而只需知道每一步执行的功能。

首先来看一个例子:#include <linux/unistd.h> /* all system call need this header*/int main(){int i=getuid();printf(“Hello World! This is my uid: %d\n”,i);}#include<linux/unistd.h>是每个系统调用都必须要的头文件,当系统执行到getuid()时,根据unistd.h中的宏定义把getuid()展开。

展开后程序把系统调用号__NR_getuid(24)放入eax,然后通过执行“int $0x80”这条指令进行模式切换,进入内核。

int 0x80指令由于是一条软中断指令,所以就要看系统规定的这条中断指令的处理程序是什么。

arch/i386/kernel/traps.cset_system_gate(SYSCALL_VECTOR,&system_call);从这行程序我们可以看出,系统规定的系统调用的处理程序就是system_call。

控制转移到内核之前,硬件会自动进行模式和堆栈的切换。

现在控制转移到了system_call,保留系统调用号的最初拷贝之后,由SA VE_ALL来保存上下文,得到该进程结构的指针,放在ebx 里面,然后检查系统调用号,如果__NR_getuid(24)是合法的,则根据这个系统调用号,索引sys_call_table,得到相应的内核处理程序:sys_getuid。

Linux系统调用Hook姿势总结

Linux系统调用Hook姿势总结

Linux系统调⽤Hook姿势总结相关学习资料/?post=121http://hbprotoss.github.io/posts/li-yong-ld_preloadjin-xing-hook.html/blog/simple-ld-preload-tutorial//art/201004/195510.htm/paper/pst_WebZine/pst_WebZine_0x03/html/%5BPSTZine%200x03%5D%5B0x03%5D%5B%E9%AB%98%E7%BA%A7Linux %20Kernel%20Inline%20Hook%E6%8A%80%E6%9C%AF%E5%88%86%E6%9E%90%E4%B8%8E%E5%AE%9E%E7%8E%B0%5D.html /uid-26310563-id-3175021.html/368606/d-26/p-2/blog/panfengyun12345/19480567https:///doc/Documentation/kprobes.txt/uid-23769728-id-3198044.htmlhttps:///systemtap//3652632/1111213/368606/421862/view/336501.htm/dog250/article/details/6451762/sanbailiushiliuye/article/details/7552359⽬录1. 系统调⽤Hook简介2. Ring3中Hook技术0x1: LD_PRELOAD动态连接.so函数劫持0x2: 使⽤snoopy进⾏execve/execv、connect、init_module hook0x3: 绕过基于Linux消息队列(Message Queue)通信的Hook模块0x4: 基于PD_PRELOAD、LD_LIBRARY_PATH环境变量劫持绕过Hook模块0x5: 基于ptrace()调试技术进⾏API Hook0x6: 绕过C库LD_PRELOAD机制的技术⽅案0x7: 基于PLT劫持、PLT重定向技术实现Hook3. Ring0中Hook技术0x1: Kernel Inline Hook0x2: 利⽤0x80中断劫持system_call->sys_call_table进⾏系统调⽤Hook0x3: 获取sys_call_table的常⽤⽅法0x4: 利⽤Linux内核机制kprobe机制(kprobes, jprobe和kretprobe)进⾏系统调⽤Hook0x5: LSM(linux security module) Security钩⼦技术(linux原⽣机制)0x6: LSM Function Replace Hook劫持技术0x7: int 80中断劫持技术0x8: 利⽤从PAGE_OFFSET起始位置搜索特征码劫持system_call_sys_call_table进⾏系统调⽤hook0x9: Linux LSM(Linux Security Modules) Hook技术4. 后记1. 系统调⽤Hook简介系统调⽤属于⼀种软中断机制(内中断陷阱),它有操作系统提供的功能⼊⼝(sys_call)以及CPU提供的硬件⽀持(int 3 trap)共同完成。

Linux系统调用

Linux系统调用

Linux系统调⽤所谓系统调⽤是指操作系统提供给⽤户程序调⽤的⼀组“特殊”接⼝,⽤户程序可以通过这组“特殊”接⼝来获得操作系统内核提供的服务。

例如⽤户可以通过进程控制相关的系统调⽤来创建进程、实现进程调度、进程管理等。

在这⾥,为什么⽤户程序不能直接访问系统内核提供的服务呢?这是由于在 Linux 中,为了更好地保护内核空间,将程序的运⾏空间分为内核空间和⽤户空间(也就是常称的内核态和⽤户态),它们分别运⾏在不同的级别上,在逻辑上是相互隔离的。

因此,⽤户进程在通常情况下不允许访问内核数据,也⽆法使⽤内核函数,它们只能在⽤户空间操作⽤户数据,调⽤⽤户空间的函数。

但是,在有些情况下,⽤户空间的进程需要获得⼀定的系统服务(调⽤内核空间程序),这时操作系统就必须利⽤系统提供给⽤户的“特殊接⼝”——系统调⽤规定⽤户进程进⼊内核空间的具体位置。

进⾏系统调⽤时,程序运⾏空间需要从⽤户空间进⼊内核空间,处理完后再返回到⽤户空间。

Linux 系统调⽤部分是⾮常精简的系统调⽤(只有 250 个左右),它继承了 UNIX 系统调⽤中最基本和最有⽤的部分。

这些系统调⽤按照功能逻辑⼤致可分为进程控制、进程间通信、⽂件系统控制、系统控制、存储管理、⽹络管理、socket 控制、⽤户管理等⼏类。

在 Linux 中对⽬录和设备的操作都等同于⽂件的操作,因此,⼤⼤简化了系统对不同设备的处理,提⾼了效率。

Linux 中的⽂件主要分为 4种:普通⽂件、⽬录⽂件、链接⽂件和设备⽂件。

那么,内核如何区分和引⽤特定的⽂件呢?这⾥⽤到的就是⼀个重要的概念——⽂件描述符。

对于 Linux ⽽⾔,所有对设备和⽂件的操作都使⽤⽂件描述符来进⾏的。

⽂件描述符是⼀个⾮负的整数,它是⼀个索引值,并指向内核中每个进程打开⽂件的记录表。

当打开⼀个现存⽂件或创建⼀个新⽂件时,内核就向进程返回⼀个⽂件描述符;当需要读写⽂件时,也需要把⽂件描述符作为参数传递给相应的函数。

Linux 系统调用劫持方法

Linux 系统调用劫持方法
系统调用的替换方法
1 内核直接导出符号 18 以前的内核直接导出符号 sys_call_table,这使得在 LKM 模块中替换原有
的系统调用成为可能。具体的作法是: 保存 sys_call_table[x]中所放置的系统调用函数入口 指针(在这里 x 代表想要截获的系统调用的索引)。将自己定义的新的函数指针存入 sys_call_table[x] 。 下 面 以 sys_mk_dir 为 例 , 说 明 替 换 原 有 的 系 统 调 用 的 软 件 实 现 。 在 init_module()函数中,首先用 orig_mkdir 保存原有的 mkdir 系统调用响应函数地址。然后将 伪造的系统调用响应函数 hacked_ mkdir 的函数地址 填 入 sys_call_table[SYS_mkdir] 。 在 cleanup_module() 函 数 中 将 系 统 调 用 表 sys_call_table[]中 mkdir 系统调用对应 的项 sys_call_table[SYS_mkdir]恢复成为原有的值 orig_mkdir。主要代码如下 :
其方法是读取kmem中的内容用sidt汇编指令进行模式匹配获取idtr寄存器的值如系统调用流程图所示该寄存器指向当前中断向量表idt的基地址从该地址出发根据偏移量可以获得int0x80中断描述符所在的位置系统调用采用callsyscalltableeax4方法来实现具体的调用其机器码是0xff0x140x85这样可以通过匹配确定syscalltable地址其核心代码如下
为:c030a0f0,按下面代码示意的方法就可以实现系统调用的替换: /*声明系统调用表*/ void **sys_call_table; int init_module() { ... sys_call_table=(void**)(0xc030a0f0);//设置系统调用表的首地址 orig_mkdir = sys_call_table[SYS_mkdir];//实现 mk_dir 的替换 ... }

(cc)实现Linux系统调用劫持

(cc)实现Linux系统调用劫持

关于系统调用劫持如果一个木马要隐藏起来,不被系统管理员发现。

截获系统调用似乎是必须的。

大部分情况下,通过修改系统调用表来实现系统调用的劫持。

下面是一个典型的截获系统调用的模块:模块一:#include#include#include#include#include#include#include#include#includeMODULE_LICENSE("GPL");extern void* sys_call_table[]; /*sys_call_table is exported, so we can accessit. But in some system this will cause problem */int (*orig_mkdir)(const char *path); /*the original systemcall*/int hacked_mkdir(const char *path){return 0; /*everything is ok, but he new systemcall does nothing*/}int init_module(void) /*module setup*/{orig_mkdir=sys_call_table[SYS_mkdir];sys_call_table[SYS_mkdir]=hacked_mkdir;return 0;}void cleanup_module(void) /*module shutdown*/{sys_call_table[SYS_mkdir]=orig_mkdir;/*set mkdir syscall to the origal one*/}用这种方法实现系统调用有个前提,就是系统必须导出sys_call_table内核符号,但是在2.6内核和有些2.4内核的系统(比如redhat as 3)中,sys_call_table不再导出。

Linux系统调用劫持的检测方法

Linux系统调用劫持的检测方法

Linux系统调用劫持的检测方法任幸东;王剑【期刊名称】《信息安全与技术》【年(卷),期】2015(000)011【摘要】System caI hijacking is a subtIe and strong, harmfuI at ack techniques. In this paper, the principIe Linux system caI hijacking, on the basis of anaIysis of a method for detecting a system caI hijacking, heIping Linux server maintenance personneI to find the right method to detect at acks.%系统调用劫持是一种隐蔽性强、危害较大的攻击技术。

论文研究了Linux 系统调用劫持的原理,在此基础上分析了检测系统调用劫持的方法,帮助Linux 服务器的维护人员找到合适的方法检测攻击。

【总页数】2页(P61-62)【作者】任幸东;王剑【作者单位】国防科学技术大学通信工程系湖南长沙410072;国防科学技术大学通信工程系湖南长沙410072【正文语种】中文【相关文献】1.基于LKM系统调用劫持的恶意软件行为监控技术研究 [J], 丁庸;曹伟;罗森林2.Linux系统中基于系统调用序列的病毒检测方法研究 [J], 党华;张涛;吴灏3.Linux系统调用劫持:技术原理、应用及检测 [J], 时金桥;方滨兴;胡铭曾;李斌4.Linux下系统调用原理解析及增加系统调用的方法 [J], 胡盼盼5.劫持Linux系统调用封杀Core Dump漏洞攻击 [J], 王畅;薛素静因版权原因,仅展示原文概要,查看原文内容请购买。

Linux系统调用劫持的检测方法

Linux系统调用劫持的检测方法

Linux系统调⽤劫持的检测⽅法2019-09-16【摘要】系统调⽤劫持是⼀种隐蔽性强、危害较⼤的攻击技术。

论⽂研究了Linux系统调⽤劫持的原理,在此基础上分析了检测系统调⽤劫持的⽅法,帮助Linux服务器的维护⼈员找到合适的⽅法检测攻击。

【关键词】系统调⽤;Linux;⼊侵检测1 引⾔系统调⽤劫持是⼀种常见的rootkit实现技术。

由于运⾏在内核态,因此其具有隐蔽性强,危害⼤的特点。

对于开源操作系统Linux来说,系统调⽤劫持的⽅法更加多样。

本⽂研究了Linux下常见的系统调⽤劫持⽅式,并以此为依据介绍检测系统调⽤劫持的⼀些⽅法,为系统的维护⼈员提出⼀些建议,避免攻击者利⽤系统调⽤劫持的⽅法造成危害。

2 SCT地址的寻找⽅法在Linux系统下,系统调⽤需要由int 0x80中断实现,其中断服务程序为system_call。

⽽int 0x80的⼊⼝地址存放在IDT(Interrupt Descriptor Table 中断描述符表)中。

系统调⽤的指针存放在 SCT(System Call Table 系统调⽤表)中。

因此,实现系统调⽤替换的关键是获取IDT的地址与SCT的地址。

系统运⾏在32位的CPU中,具体实现过程分⼏步。

(1)获取IDT地址。

IDT的信息主要存放在IDTR寄存器中,这个寄存器存放了IDT的线性地址与IDT的⼤⼩信息。

可以使⽤SIDT操作获取IDTR中的数据。

这⾥使⽤⼀个结构体idtr,有两个变量base与length,类型分别为unsigned int 与unsigned short。

其中base存放了IDT的基址,length存放IDT的⼤⼩。

使⽤SIDT这条指令实现将IDTR寄存器中的内容存⼊idtr中。

(2)获取int 0x80中断处理程序system_call的地址。

获取IDT基址后,可以⽅便地获取每个中断描述符的地址。

定义结构体指针idt,以及结构体中的两个变量hoffset与loffset分别表⽰中断程序地址的⾼16位与低16位。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
extern void* sys_call_table[];/*声明使用系统本身的系统调用表*/ int (*orig_ mkdir)(const char *path); /*用于保存原始系统调用*/ int hacked_ mkdir(const char *path) { return 0; /*替换后的操作什么也不做*/ } /*初始化模块*/ int init-module(void) { orig_mkdir=sys_call_table[sys_mkdir]; sys_call_table[sys_mkdir]=hacked_mkdir; return 0; } /*卸载模块*/ void cleanup_module(void) { sys_calltable[SYS_mkdir]=oritem.map 和 vmLinux 获得 sys_call_table 地址 Linux 在 2.4.18 版本以后的内核不再导出符号 sys_call_table,我们可利用其它的方法 获得 sys_call_table 的地址,主要通过两个文件,即 vmlinuz 和 system.map,其中 vmlinuz 是 可引导的、压缩的内核,其中“vm”代表“Virtual Memory”, 通常位于/boot/vmlinuz,一般是 在编译内核时通过“make zImage”创建或 make bzImage 创建,然后通过拷贝产生,在开头部 分内嵌有 gzip 解压缩代码。由内核文件中包含的一个微型的 gzip 用于解压缩内核并引导 它;system.map 是一个特定内核的内核符号表,是当前运行的内核的 System.map 的链接。简 单 的 通 过 命 令 :grep sys_call_table /boot/System.map 或 nm vmLinux-2.4.20-8|grep sys_call_table 就可以获得 sys_call_table 的地址,然后通过硬编码的方式,如得到的地址
3 利用 dev/kmem 获得 sys_call_table 地址 在 Linux 中 kmem 是一个字符设备文件,是计算机主存的映象,可以用于测试和修改系
统,通过读取这个设备文件可以得到内存中的数据,因此,通过它可以找到 sys_call_table 的地 址。其方法是读取 kmem 中的内容,用 sidt 汇编指令进行模式匹配获取 IDTR 寄存器的值, 如系统调用流程图所示,该寄存器指向当前中断向量表 IDT 的基地址,从该地址出发根据偏 移量可以获得 int $0x80 中断描述符所在的位置,系统调用采用 call sys_call_table(,eax,4)方 法来实现具体的调用,其机器码是 0xff 0x14 0x85,这样可以通过匹配确定 sys_call_table 的 地址,其核心代码如下: asm(“sidt %0” “:=m” (idtr)) //读取 idtr 寄存器的值至 idtr 结构中 readkmem(&idt,idtr.base+8*0x80,sizeof(idt)) //从 IDT 读出 0x80 向量 // 得 到 system_call 函 数 的 地 址 sys_call_off=(idt.off2<<16)idt.off1; readkmem(buff,sys_call_off,100)//读取 system_call 函数的前 100 字节至 buff //得到 call 语句对应机器码的地址 p = (char*)memmem (sc_asm,CALLOFF,"\xff\x14\x85",3) sct=(unsigned *)(p+3) //得到 sys_call_table 的地址
系统调用的替换方法
1 内核直接导出符号 sys_call_table,利用 lkm 模块实现替换 Linux 2.4.18 以前的内核直接导出符号 sys_call_table,这使得在 LKM 模块中替换原有
的系统调用成为可能。具体的作法是: 保存 sys_call_table[x]中所放置的系统调用函数入口 指针(在这里 x 代表想要截获的系统调用的索引)。将自己定义的新的函数指针存入 sys_call_table[x] 。 下 面 以 sys_mk_dir 为 例 , 说 明 替 换 原 有 的 系 统 调 用 的 软 件 实 现 。 在 init_module()函数中,首先用 orig_mkdir 保存原有的 mkdir 系统调用响应函数地址。然后将 伪造的系统调用响应函数 hacked_ mkdir 的函数地址 填 入 sys_call_table[SYS_mkdir] 。 在 cleanup_module() 函 数 中 将 系 统 调 用 表 sys_call_table[]中 mkdir 系统调用对应 的项 sys_call_table[SYS_mkdir]恢复成为原有的值 orig_mkdir。主要代码如下 :
为:c030a0f0,按下面代码示意的方法就可以实现系统调用的替换: /*声明系统调用表*/ void **sys_call_table; int init_module() { ... sys_call_table=(void**)(0xc030a0f0);//设置系统调用表的首地址 orig_mkdir = sys_call_table[SYS_mkdir];//实现 mk_dir 的替换 ... }
相关文档
最新文档