int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned int *v3; // rsi
_QWORD *v4; // rax
unsigned int v6; // [rsp+Ch] [rbp-24h]
__int64 v7; // [rsp+10h] [rbp-20h]
__int64 v8; // [rsp+18h] [rbp-18h]
__int64 v9; // [rsp+20h] [rbp-10h]
setvbuf(stdout, 0LL, 2, 0LL);
setvbuf(stdin, 0LL, 1, 0LL);
o = malloc(0x28uLL);
*((_QWORD *)o + 3) = greetings;
*((_QWORD *)o + 4) = byebye;
printf("hey, what's your name? : ", 0LL);
v3 = (unsigned int *)&v7;
__isoc99_scanf("%24s", &v7);
v4 = o;
*(_QWORD *)o = v7;
v4[1] = v8;
v4[2] = v9;
id = v7;
getchar();
func[0] = (__int64)echo1;
qword_602088 = (__int64)echo2;
qword_602090 = (__int64)echo3;
v6 = 0;
do
{
while ( 1 )
{
while ( 1 )
{
puts("\n- select echo type -");
puts("- 1. : BOF echo");
puts("- 2. : FSB echo");
puts("- 3. : UAF echo");
puts("- 4. : exit");
printf("> ", v3);
v3 = &v6;
__isoc99_scanf("%d", &v6);
getchar();
if ( v6 > 3 )
break;
((void (__fastcall *)(const char *, unsigned int *))func[v6 - 1])("%d", &v6);
}
if ( v6 == 4 )
break;
puts("invalid menu");
}
cleanup("%d", &v6);
printf("Are you sure you want to exit? (y/n)");
v6 = getchar();
}
while ( v6 != 121 );
puts("bye");
return 0;
}
__int64 echo1()
{
char s; // [rsp+0h] [rbp-20h]
(*((void (__fastcall **)(void *))o + 3))(o);
get_input(&s, 128LL);
puts(&s);
(*((void (__fastcall **)(void *, signed __int64))o + 4))(o, 128LL);
return 0LL;
}
这个题echo1中存在溢出漏洞,s只分配了0x20个字节,而可以输入128个字节。我们可以覆盖eip为我们shellcode的地址,有两个地方可以放shellcode,第一个是name,name前八个字节存在栈中,可以控制把eip覆盖为id的地址。第二个就是echo的栈中,将shell code前八个字节覆盖到esp上,eip为id的地址,我们输入name位asm(jmp esp)就可以到达shellcode。