if (major_number < 0) { printk(KERN_ALERT "Registering char device failed with %d\n", major_number); return major_number; }
printk(KERN_INFO "I was assigned major number %d.\n", major_number); printk(KERN_INFO "Create device with: 'mknod /dev/pwn-college-char c %d 0'.\n", major_number); return0; }
输出:
1 2 3
/ # insmod hello_dev_char.ko [ 310.758676] I was assigned major number 248. [ 310.759132] Create device with: 'mknod /dev/pwn-college-char c 248 0'.
~/Desktop/kernel/pwnkernel/src $ ./attack [ 1780.024894] Device opened. [ 1780.029412] Got ioctl argument 28673! before uid: 1000 after uid: 0 # <====== grant superuser! [ 1780.029791] Granting root access! [ 1780.032075] Device closed. [ 1780.035175] attack (89) used greatest stack depth: 14080 bytes left ~/Desktop/kernel/pwnkernel/src $
如何寻找commit_creds
直接寻找符号
1
$ cat/proc/kallsyms # 可以打印出内核所有符号地址,包括函数
1 2
# cat /proc/kallsyms | grep 'commit_creds' ffffffff810842b0 T commit_creds
在关闭ASLR或者古老版本的内核中,上述函数地址是可以预测的
调试
泄露,和用户态一样
sandbox
sandbox和seccomp密切相关。我们首先看看他在那里实现。事实上还是在之前的process control block里面。flags中有一个比特指示是否开启了seccomp
源码
1 2 3 4 5 6 7 8 9 10 11
structtask_struct { // LOTS of stuff, including conststructcred __rcu *cred; structthread_infothread_info; } structthread_info { unsignedlong flags; /* low level flags */ u32 status; /* thread synchronous flags */ }; // flags is a bit field that, among many other things, holds a bit named TIF_SECCOMP