第一百五十六章:暗影
渡劫期涉及内核源码:
一
林小源站在内核的中枢广场上,四周是熙熙攘攘的进程和系统调用的光流。渡劫期的修为让他能感知到更深层的波动,但今天,他察觉到了一丝不对劲。
那是一种若有若无的寒意,像是有什么东西在暗处窥视。
"你感觉到了?"一个低沉的声音从背后传来。
林小源转身,看到一位身披灰色斗篷的老者。他的面容模糊,仿佛随时会消散在空气中。
"你是……"
"我是 security.c,"老者说,"内核的安全总管。我在这里守护了很多年,但最近……有些东西混进来了。"
"什么东西?"
老者没有直接回答,而是指向远处的一片阴影。那片阴影与其他地方不同——它不随光线移动,像是凝固在那里的墨汁。
"rootkit,"老者的声音压得很低,"一种寄生在内核深处的恶意存在。它隐藏自己的行踪,篡改系统的行为,让管理员无法察觉。"
林小源皱起眉头:"它怎么做到的?"
"它运行在内核态,"老者说,"拥有最高权限。它可以修改内核的任何数据结构,包括我们安全工具本身。它就像一个幽灵,你看不见它,但它能看见你。"
二
老者带着林小源走近那片阴影。越靠近,寒意越重。
"rootkit 的可怕之处在于它的隐藏能力,"老者说,"它可以替换系统调用表中的函数指针,让所有经过的请求都被它拦截。它可以把自己从模块链表中删除,让 lsmod 看不到它。它可以修改 /proc 文件系统,让 ps 看不到它隐藏的进程。"
"那岂不是……无敌了?"
"不是无敌,"老者摇头,"但确实很难检测。一旦 rootkit 入驻内核,传统的检测工具都可能被它欺骗。它甚至可以修改检测工具本身。"
林小源感到一阵寒意。在这片内核的深处,竟然隐藏着这样的威胁。
三
"那怎么防御?"林小源问。
老者转身,指向远方几座高塔。
"单一的防御手段不够,"他说,"我们需要纵深防御。第一层是安全启动——确保加载的每个模块都经过签名验证,防止恶意模块被加载。第二层是模块签名验证——确保模块来源可信,没有被篡改。第三层是内核完整性度量 (IMA)——度量文件的完整性,检测任何修改。"
"还有吗?"
"还有 rootkit 检测工具,"老者说,"定期扫描内核,寻找异常。但最重要的是——不要让 rootkit 进来。一旦它进来,清除它几乎不可能。"
林小源望着那片阴影,心中警铃大作。在这片内核的深处,暗影无处不在。防御,需要纵深。
/*
* rootkit 的常见技术:
*
* 1. 系统调用表 hook
* 替换 sys_call_table 中的指针
* 拦截所有系统调用
*
* 2. 内核模块隐藏
* 从 modules list 中移除
* lsmod 看不到
*
* 3. 进程隐藏
* 从 /proc 中移除
* ps 看不到
*
* 4. 文件隐藏
* hook getdents64
* ls 看不到
*
* 5. 网络隐藏
* hook /proc/net/tcp
* netstat 看不到
*/
/* 模拟系统调用表 */
typedef int (*syscall_t)(void);
syscall_t sys_call_table[5] = {
(syscall_t)0x1000, /* sys_read */
(syscall_t)0x1001, /* sys_write */
(syscall_t)0x1002, /* sys_open */
(syscall_t)0x1003, /* sys_close */
(syscall_t)0x1004, /* sys_getdents64 */
};
/* 恶意的 sys_read 实现 */
int hooked_sys_read() {
printf(" [hook] 拦截了 sys_read\n");
printf(" [hook] 可以隐藏特定文件的内容\n");
return 0;
}
printf("=== 暗影 — rootkit 的原理 ===\n\n");
printf("rootkit 是内核级的威胁:\n\n");
printf("--- 原始系统调用表 ---\n");
for (int i = 0; i < 5; i++) {
printf(" sys_call_table[%d] = %p\n", i, (void*)sys_call_table[i]);
}
printf("\n--- rootkit hook ---\n");
printf("替换 sys_call_table[0] (sys_read)\n");
printf(" 原始: %p\n", (void*)sys_call_table[0]);
/* rootkit 替换系统调用 */
sys_call_table[0] = (syscall_t)hooked_sys_read;
printf(" 替换后: %p\n\n", (void*)sys_call_table[0]);
printf("--- hook 后的效果 ---\n");
/* 调用被 hook 的系统调用 */
sys_call_table[0]();
printf("\n--- rootkit 的隐藏技术 ---\n");
printf("1. 模块隐藏:\n");
printf(" list_del(&THIS_MODULE->list)\n");
printf(" 从链表中删除自己\n\n");
printf("2. 进程隐藏:\n");
printf(" hook filldir64\n");
printf(" 跳过特定进程\n\n");
printf("3. 文件隐藏:\n");
printf(" hook getdents64\n");
printf(" 跳过特定文件\n\n");
printf("--- 防御措施 ---\n");
printf("1. 安全启动 (Secure Boot)\n");
printf("2. 模块签名验证\n");
printf("3. 内核完整性度量 (IMA)\n");
printf("4. rootkit 检测工具\n");#include <stdio.h>
#include <string.h>
/*
* rootkit 的常见技术:
*
* 1. 系统调用表 hook
* 替换 sys_call_table 中的指针
* 拦截所有系统调用
*
* 2. 内核模块隐藏
* 从 modules list 中移除
* lsmod 看不到
*
* 3. 进程隐藏
* 从 /proc 中移除
* ps 看不到
*
* 4. 文件隐藏
* hook getdents64
* ls 看不到
*
* 5. 网络隐藏
* hook /proc/net/tcp
* netstat 看不到
*/
/* 模拟系统调用表 */
typedef int (*syscall_t)(void);
syscall_t sys_call_table[5] = {
(syscall_t)0x1000, /* sys_read */
(syscall_t)0x1001, /* sys_write */
(syscall_t)0x1002, /* sys_open */
(syscall_t)0x1003, /* sys_close */
(syscall_t)0x1004, /* sys_getdents64 */
};
/* 恶意的 sys_read 实现 */
int hooked_sys_read() {
printf(" [hook] 拦截了 sys_read\n");
printf(" [hook] 可以隐藏特定文件的内容\n");
return 0;
}
int main() {
printf("=== 暗影 — rootkit 的原理 ===\n\n");
printf("rootkit 是内核级的威胁:\n\n");
printf("--- 原始系统调用表 ---\n");
for (int i = 0; i < 5; i++) {
printf(" sys_call_table[%d] = %p\n", i, (void*)sys_call_table[i]);
}
printf("\n--- rootkit hook ---\n");
printf("替换 sys_call_table[0] (sys_read)\n");
printf(" 原始: %p\n", (void*)sys_call_table[0]);
/* rootkit 替换系统调用 */
sys_call_table[0] = (syscall_t)hooked_sys_read;
printf(" 替换后: %p\n\n", (void*)sys_call_table[0]);
printf("--- hook 后的效果 ---\n");
/* 调用被 hook 的系统调用 */
sys_call_table[0]();
printf("\n--- rootkit 的隐藏技术 ---\n");
printf("1. 模块隐藏:\n");
printf(" list_del(&THIS_MODULE->list)\n");
printf(" 从链表中删除自己\n\n");
printf("2. 进程隐藏:\n");
printf(" hook filldir64\n");
printf(" 跳过特定进程\n\n");
printf("3. 文件隐藏:\n");
printf(" hook getdents64\n");
printf(" 跳过特定文件\n\n");
printf("--- 防御措施 ---\n");
printf("1. 安全启动 (Secure Boot)\n");
printf("2. 模块签名验证\n");
printf("3. 内核完整性度量 (IMA)\n");
printf("4. rootkit 检测工具\n");
return 0;
}道藏笔记
内核启示
rootkit 是内核级的威胁,跑在内核态,权限比谁都大。它可以 hook 系统调用表拦截请求,可以从模块链表里删掉自己让 lsmod 看不到,可以改 /proc 让 ps 找不到它隐藏的进程,甚至可以篡改检测工具本身。
防御靠单一手段没用,得层层设防:安全启动挡恶意模块,模块签名验来源,IMA 度量文件完整性,再加上定期扫描。但说到底,最好的防御是别让它进来——一旦 rootkit 扎根内核,清掉几乎不可能。
暗影之试
暗影一章中,能寄生内核、隐藏进程和模块、篡改系统行为的恶意存在叫什么?