Buffer Overflow Analysis Lesson No. 03: The use of buffer overflow

Source: Internet
Author: User

Preface

Last time we discussed the principle of buffer overflow, and this time we need to use this principle to construct conditions to exploit this vulnerability.

In fact, the use of buffer overflow vulnerability is mainly to solve the following three problems:

1. Pinpoint the location of the return address

2. Find a suitable address for overwriting the original return address

3, write shellcode to the corresponding buffer

This time we will combine the experimental procedures to solve the above three problems, to achieve the use of loopholes.

pinpoint the location of the return address

The first step in buffer overflow utilization is the need for us to pinpoint the location of the return address. Since our program is relatively simple this time, we are able to determine the location of the return address by using the Error prompt dialog box.

We first run the Overruntest_2.exe, after the last analysis we know that because the return address is overwritten, and the new address is an invalid address, so that the main function after the completion of the execution of the command is not known, so there is an error dialog box. In general, we either click Send Error Report, or click Don't send, but this time we choose click here to display in blue font. Then select "To view technical information about the error report, click here" and the Error Report content dialog box pops up:


Figure 1

in this report, two places are more important. One is "code", which is the error code. Here is "0xc0000005", which indicates a buffer overflow error occurred. Another is "address", that is, the location of the error, here is "0x00006579", and in conjunction with the last OD analysis, we know that because this is a nonexistent address, resulting in a program error.

With OD, we can easily figure out the location of the return address, what if there is no OD? For this experimental procedure, because I first input "Jiangye" time, the program does not have problems, and the second input "Jiangyejiangye" when the error, the error content is "0x00006579" This address has a problem, and we will translate this address into English letters, You can see that "0x65" stands for "E", while "0x79" represents "Y". It's exactly the last two letters of the long string of characters I entered. Since the address is represented by 4 bytes, for this program, if I assign the global variable name to "Jiangyejiangxxxx", then the last four "X" will just overwrite the return address, and the preceding 12 characters can be any character. Then we've solved the first problem with buffer exploits--pinpointing the location of the return address.

But here's another thing to note is that the local variables in our program, that is, the buffer is only 8 bytes, so it is easy to be filled, so it can be easily positioned, but if the buffer space is very large, how to locate it? You can't just keep testing it with "Jiangyejiangye ...". In fact, there are many ways to locate the overflow position, here can tell you a convenient way for beginners to understand, we can use a long list of different characters to test, such as:

testcode[]= "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ"

test with 26 English uppercase characters and 26 lowercase characters, which is a total of 52 letters, so that you can validate 52 bytes of buffer space at a time. This modifies the size of our local variable array to 80 bytes, and then validates it with this method. First Test a paragraph of the above characters, the visible program does not change, then we add a paragraph, into 104 characters to verify that the error message has been popped up at this time dialog box:


Figure 2

After the address can be found, its value is 0x6a696867, note that our system is small-side display, that is, the actual characters should be 0x67, 0x68, 0x69, 0x6a. Then convert it to a letter, you can know is G, H, I, J, because we here are using two rounds of verification characters, the first round is 52 characters, plus the second round of the first 26 upper case characters, is 78 characters, and then the lowercase letter g is preceded by 6 characters, that is 84 characters, Note that there is also a 4-byte ebp, so the size of the buffer we are verifying is 80 bytes of space.

For some other methods of judging the size of the buffer space, we will explain it later in the actual analysis. I think we can now understand this approach. Even the punctuation on the keyboard can be added to the Testcode, which can be arranged in the order of the ASCII code table, so that more space is verified at once.

look for an appropriate address to overwrite the original return address

What we need to do now is to determine what address the last four "X" in "jiangyejiangxxxx" should be. Here we cannot create an address out of thin air, but should be based on a legitimate address. Of course, we can find a lot of suitable address through the observation in OD, but this method is not universal, after all, it is not convenient to find an exact address. There are many ways to solve this problem, but the most common and classic is the "jmp ESP" approach, which is to jump with a springboard.

The springboard here is the machine code of the program, they are able to jump to the address stored in a register to execute, such as JMP ESP, call ESP, jmp ecx, call eax, and so on. If the function returns, the CPU registers are directly or indirectly pointing to the beginning of the shellcode so that the element of the return address stored in the stack can be overwritten with the corresponding springboard address.

Use practical examples to illustrate this. Let's look at the normal procedure, that is, overruntest_1.exe, loading with OD, executing to the last position of the main function, i.e. the RETN statement, at which point we focus on the values stored in the ESP register:


Figure 3

It can be found that the value stored in the ESP is 0x0012ff84 this address, and in the stack this address corresponds to our return address 0x00401699, which is the position of our next statement. Then we press the F8 again, stepping, then the main function will be executed:


Figure 4

We can see that at this point we have jumped out of the main function, to the 0x00401699 position of the statement to execute, we do not have to control its implementation of the content, mainly concerned about the value of esp. It can be found that the value of ESP is changed from just 0x0012ff84 to 0x0012ff88, from the stack space, which is the next position of the value just now. Don't forget, 0x0012ff84 position formally we want to modify the location of the return address.

To summarize, we can tell that when the main function is finished, the value of ESP automatically becomes the next position of the return address, and this change in ESP is generally not affected by any situation. Now that we know this feature, we can actually modify the return address to the address saved by ESP, that is, we can have the program jump to the address saved by ESP to execute the instructions we have constructed so that the computer executes.

Of course, the above is the normal situation, that is, the return address is not destroyed, then if the return address is corrupted, ESP also has this feature? It may be possible to use OD load overruntest_2.exe This buffer overflow problem of the program, to study, first or first come to the main function of the RETN position:


Figure 5

As you can see, the address stored in ESP is the same as normal, except that the value stored in the address is different, and then F8 stepping:


Figure 6

Visible in addition to this time the Disassembly Code window is empty, other locations are not changed, especially the value of ESP, is still self-increment 4, in the Stack window, that is, the return to the address below the location. It also shows that we can use this feature of ESP to make a fuss.

So how do you get the program to jump to the location of ESP? We can use the "JMP ESP" Directive here. JMP ESP machine code is 0XFFE4, then we can write a program to find the address of this instruction in user32.dll (of course, jmp ESP exists in many dynamic link libraries, here I just take user32.dll as an example):

#include <windows.h> #include <stdio.h> #include <stdlib.h>int main () {BYTE *ptr;        int position;        HINSTANCE handle;        BOOL Done_flag = FALSE;        Handle = LoadLibrary ("user32.dll");                if (!handle) {printf ("Load DLL error!");        Exit (0);        } ptr = (byte*) handle; for (position = 0;!done_flag; position++) {try {if (ptr[posit Ion]==0xff && ptr[position+1]==0xe4) {int address = (int) pt                                R + position;                        printf ("OPCODE found at 0x%x\n", address);                }} catch (...)                        {int address = (int) ptr + position;                        printf ("END of 0x%x\n", address);                Done_flag = true;        }}getchar (); return 0;}
then run this program to find the JMP ESP:


Figure 7

As you can see, there are a lot of results listed here, and we can simply take out a result for our experiment, and here I choose the 0x77e35b79 of the penultimate row. In other words, I need to use this address to overwrite the return address of the program. This way, when the program returns, it executes the jmp ESP, jumping to the next location in the return address to execute the statement at that address.

Please note that there are many ways to get jmpesp, and different systems this address may be different, but some of the addresses are cross-system, you can search on the internet on their own.

write shellcode into the appropriate buffer

Now we can summarize the contents of the "name" array we are going to write, and after analysis we can see that it is in the form of "jiangyejinagxxxxssss ... SSSS ". The first 12 characters are any character, XXXX is the return address, here I use 0x77e35b79, and ssss ... SSSS is the code that we specifically want the computer to execute.

Since the writing of shellcode involves a lot of knowledge, I will leave this content for the next lesson to be discussed.

Buffer Overflow Analysis Lesson No. 03: The use of buffer overflow

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.