宁波市赛线下wp
宁波市赛wp
这题很好地巩固了fmt基础,先checksec,发现保护全开
打开ida,发现是一个买蛋糕的菜单题
关键点在do_nothing和buy函数,do_nothing函数可以无限次利用格式化字符串漏洞
看buy函数,当满足条件时可以调用一个read函数,要满足a=99999999也就是图中的十六进制数,看一下a和b
发现a和b都在栈上,且a=0x32,b=0x20,那么就有一个想法,用格式化字符串漏洞改a的值满足if条件,再把b改大一点,构造栈溢出
由于这题保护全开,所以我们要先用格式化字符串漏洞泄露canary和pie基地址还有libc地址。
先来找fmt的偏移,发现从第6个参数开始可以有我们控制
如图,gdb调试断点在printf函数,停下之后ni跳过printf函数用stack 30查看栈空间,由于是64位,把第一次出现参数的那行当作第6个,则rbp前一个是canary,偏移11,rbp后面一个的main+176,在ida中按g再输入main的地址加176,跳转到了0x156a,泄露偏移13再减去这个ida里的值就可以得到pie基地址了,再来泄露libc,这里要注意并不是所有0x7f开头的libc地址都可以泄露,有些的偏移不固定,比如下面那个紫色的libc地址,第一次用的0x27泄露它就偏移不固定,反正肯定要先找有名字的libc泄露,然后调两次看偏移是否一样,一样的话那偏移就是固定的。最后确定用偏移17来泄露libc地址
用下面的exp来泄露这些信息
之后我们要给a和b来赋值,先把a和b在ida中的地址加上pie基地址,确定要写入的地址,然后遇到了难题,要给a写入99999999也就是0x05F5E0FF,这个数有点大,试了很多次,只能分开两次,每次用%hn写两个字节(%n是每次写4个字节),不知道为什么手写的payload不行,记住这个模板payload = “%{}c”.format(value).encode()+b”%9$hn”。这里贴一下exp,得时不时来认真分析exp了,
后面就正常打ret2syscall就可以了,gadgets可以从二进制文件和libc文件找,不要忘了加pie或libc基地址









