0x01 Analysis
rootkit is another challenge about kernel exploits after syscall.
After connected to host, I found that the kernel load rootkit module at boot.
1 | [ 3.337631] rootkit: module license 'unspecified' taints kernel. |
Then, I use ida to disassembly the rootkit.ko.
The module disable write protection, and replace original syscall such as sys_open
to sys_open_hooked
by write syscall table(0xc15fa020
).
The sys_open_hooked
syscall will check whether the string of the filename has a flag
substring.
If there not, then the original sys_open is called.
If there is, it returns a fd
with a value of -1
, then the file opening failed.
Of cource, other sys_call such as sys_symlink
will failed also.
1 | /tmp # ln -s ../flag ./ |
0x02 Solution
Thanks to pwnable.kr, we are login as root :), mean that we have permission to load a custom kernel module by command insmod
.
1 | /tmp # uname -r |
I tried to compile a new kernel module to restore the original sys_open address to the sys_call_table, but it failed, because of some reason(maybe my GCC is too new, maybe the kernel 3.7.1 is too old, I really don’t know).
So, I decided to patch the .ko
file directly:
- Patching the module name, so that the kernel allows the new module be loaded.
- Patching the flag string, then opening the flag file will no longer trigger substring verification.
- Patching the way to get the original
sys_open
address, because thesys_open
address in syscall table was modified by the module rootkit.
module name
1 | sed 's/rootkit/tiktoor/g' -i rootkit.ko |
flag string
1 | sed 's/flag/galf/g' -i rootkit.ko |
get the original sys_open
/proc/kallsysms
have symbols of dynamically loaded modules as well static code, we should read sys_open
address from /proc/kallsyms
instead of the syscall table.
1 | /tmp # cat /proc/kallsyms | grep sys_open |
So, patching
1 | mov eax, dword ptr [0C15FA034h] ; syscall_table[5] ; 0xc15fa020 + 0x14 |
to
1 | mov eax, 0xc1158d70 ;B8 70 8D 15 C1 |
1 | sed 's/\xa1\x34\xa0\x5f\xc1/\xb8\x70\x8d\x15\xc1/g' -i rootkit.ko |
0x03 Others
After load the module with insmod ***.ko
, I finally got the flag.
But there are two things need to be mentioned:
- It seems that
busybox sed
doesn’t support\x
escape… So we need to send the patchedko
to host. - The flag is a compressed file… :)