Skip to content

Pwanble.kr rookit

复制本地路径 | 在线编辑

基础杂项知识

1. 什么是 QEMU ?
你现在可以理解成虚拟机,以前是 ssh 连接上正常的机器,现在就是 ssh 连接上 qemu 虚拟机

2. 内核文件及 Rookit 初探,关键词: LKM, '.ko', rookit, lsmod, dmesg
非常推荐在看这篇文章前观看:https://www.freebuf.com/articles/system/54263.html
同目录下的 `lkm.md` 记录了这个网页内容。

3. 系统调用表如何获取,kallsyms 机制简单介绍
特别特别好的一篇文章:https://medium.com/bugbountywriteup/linux-kernel-module-rootkit-syscall-table-hijacking-8f1bc0bd099c

具体指令 : cat /proc/kallsyms | grep sym_call_table

4. Linux 编辑二进制文件
- xxd && Vim !
- sed (on ssh) : 但是 busybox 实现的 sed 有 BUG,不能进行十六进制数替换

分析

查看源代码可知,一些诸如 sys_open 的函数被修改了:

int initmodule()
{
  // ....
  wp();
  v0 = sct;
  *(_DWORD *)(sct + 20) = sys_open_hooked;
  *(_DWORD *)(v0 + 1180) = sys_openat_hooked;
  *(_DWORD *)(v0 + 332) = sys_symlink_hooked;
  *(_DWORD *)(v0 + 1216) = sys_symlinkat_hooked;
  *(_DWORD *)(v0 + 36) = sys_link_hooked;
  *(_DWORD *)(v0 + 1212) = sys_linkat_hooked;
  *(_DWORD *)(v0 + 152) = sys_rename_hooked;
  *(_DWORD *)(v0 + 1208) = sys_renameat_hooked;
  wp();
  v1 = (_DWORD *)_this_module[2];
  v2 = _this_module[1];
  *(_DWORD *)(v2 + 4) = v1;
  *v1 = v2;
  result = 0;
  _this_module[1] = &_this_module[1];
  _this_module[2] = &_this_module[1];
  return result;
}

sys_open_hooked 就不贴了,它就是阻止打开 flag,如果文件名中包含 flag,那么就会拒绝,否则就正常打开。

我们现在有很高的权限,然而只要想打开 flag 文件,就会被拒绝。

思路

既然是这个 rootkit 捣鬼,那把它直接从内核删掉?但由于系统没有重启,最后执行 open(flag) 还是会调用修改后的 sys_open。

所以最终的方法是,重新加载另一个模块,这个模块把 sys_open 的地址写回到 sys_call[0x5] 中去。

具体做法也很简单,已经给我们提供了 rootkis.ko ,直接把里面涉及到赋值修改 sys_open 的汇编代码改一下就行了:

From:

mov     eax, dword ptr [0C15FA034h] ; syscall_table[5]
mov     ds:sys_open, eax

To:

# 根据 kallsyms 获取 sys_open 的地址
mov     eax, 0xc1158d70     ;B8 70 8D 15 C1
mov     ds:sys_open, eax

如何改?直接对二进制文件 rootkis.ko 进行修改,然后 insmod rootkis.ko 即可。

sed 's/\xa1\x34\xa0\x5f\xc1/\xb8\x70\x8d\x15\xc1/g' -i rootkit.ko

其他问题

1. flag 乱码:使用 base64 ,之后到本机上转换,最后看看文件格式,有惊喜

2. 这个 c15fa034 是 sys_call[0x5] ,但是有个问题:它这个是物理地址吗?那为什么程序可以使用物理地址探测?

https://www.cnblogs.com/alantu2018/p/9002441.html
目前的理解:肯定是虚拟地址,不过应该所有程序内核区的虚拟地址都是固定的。