Buffer Overflow Analysis Lesson No. 06: W32dasm Buffer Overflow Analysis

Source: Internet
Author: User

Vulnerability Report Analysis

Learn to crack friends must have heard w32dasm this reverse analysis tool. It is a static disassembly tool that, before Ida Pro is popular, is one of the tools that the cracking community must learn to use, and it is also likened to the "dragon Slayer" of the Cracked world.

But even the "artifact" of such a cracked world is a buffer overflow loophole. It can be seen that it is in the process of cracking countless programs at the same time, its own there is a "black" risk. Then we can analyze the vulnerability report first:

####################################################################### Luigi Auriemmaapplicat Ion:w32dasm (was http://www.expage.com/page/w32dasm) Versions: <= 8.93 (8.94???)               platforms:windowsbug:buffer-overflowexploitation:localdate:24 Jan 2005author:luigi Auriemma e-mail: [email protected] web:aluigi.org############################################## ######################## #1) Introduction2) Bug3) the Code4) fix#################################################### ###################===============1) Introduction===============w32dasm is a cool and famous Disassembler/debugger Developed by ursoft.it have tons of functions and, also if it is no. longer supported by longtime, It is still widely used B Y a lot of people.#######################################################################======2) Bug======The program uses the wsprintf () function to copy the name of theimported/exported functions of the analyzed file into a buffer of only256 bytes, with the possibility for an attacker to execute mal iciouscode.#######################################################################===========3) The Code======== ===exploiting the bug is very simple, all need are to get a executableand searching for the name of an imported or exp orted function Tomodify. I have written a very, simple proof-of-concept, overwrites Thereturn address with 0XDEADC0DE:HTTP://ALUIGI.ORG/POC/W3 2dasmbof.zip#######################################################################======4) Fix======No Fix. This program is no longer supported.#######################################################################

According to the above vulnerability report, we can know that the vulnerability appears in version 8.93 and below. The vulnerability arises because the software uses the wsprintf () function to replicate the Import/export table information while analyzing the target program, and the target buffer size is only 256 bytes, giving the attacker the opportunity to execute malicious code. The way to exploit this vulnerability is simply to find an executable file (PE file) and then find its import or export table for modification.

location where the vulnerability appears

Despite the above vulnerability report, we have a general idea of the problem with the program. But like most of today's bug reports, the content of the report is still relatively small, and many things need to be examined by us to be able to confirm. And doing it yourself can deepen our understanding of the problem. Here, of course, we don't need to do research from scratch, but we're still based on the vulnerability report.

First Use ollydbg load W32dsm89.exe This program, and then press "F9" to let the program run. Because we already know that the vulnerability is due to the improper use of the wsprintf () function, so here we need to search the program for this function. You can right-click in the Disassembly code area and select "All Intermodular calls" under "Search for":


Figure 1

Then type the name of the function you want to find. But here we can see that there are a lot of wsprintf (), now we want to know which function is the location of the problem, then you can right-click on any one wsprintf (), select "Set breakpoint on every WSPRINTFA ":


Figure 2

Then, whenever there is a call to wsprintf () in the program, the breakpoint will be broken:


Figure 3

So our next step is to determine which location is out of the question, in other words, here I'm looking for a copy of the Import/export table wsprintf ().

Now we need to activate w32dasm, which is to parse an executable file, so that when it calls wsprintf (), OD will help us break down, so we can further analyze. Here I let w32dasm analysis is Strings.exe this program. After loading, the w32dasm will not move, indicating that OD has helped us break the position of the first wsprintf (). You can view the wsprintf () function for this location in OD:


Figure 4

It is obvious that because the format parameter of this wsprintf () is "%lu", which is the unsigned long integer, it is not a string to copy, so you can skip and press F9 to continue execution. Until you find the call location with the parameter '%s ':


Figure 5

It can be found that although this time the argument is character type, but edx, that is, to copy the string "C:\strings.exe" is not the function name, indicating that this position is not correct, so continue to press F9 until the address 0x0045d8db:


Figure 6

You can see the copy of the string as "Getfullpathnamea", then the basic can be sure it is here. Use the Data window to take a look at the contents of the hungry address in edx, and then pay attention to the functions in EAX, and then click F9:


Figure 7

As you can see, the name of the function that is about to be copied into the buffer is saved in eax, and the last function name is saved in edx, which is also confirmed by the data window. So here we can be sure that the wsprintf () is here.

analyzing the buffer space where the vulnerability occurredThe address of the buffer to which the function name is to be copied is stored in the first parameter of the wsprintf () function, also in edx, which has a value of EBP-FC, that is, 0X0065BEE0-0X0FC, which is 0x0065bde4 at this address. Then the size of this buffer is 0x0fc+0x04 (EBP) =0x100, which is the decimal 256. This is consistent with the size of the buffer in the vulnerability description.


Figure 8

It can be seen that the location where the return address is saved is 0x0065bee4, and normally, when the program call is complete, it jumps to the 0X00457EC0 location to continue execution. Analysis to this point, the use of loopholes is very clear. According to our previous lesson, the first way to do this is to overwrite the 256 bytes of buffer space below four bytes into jmp ESP, and then write shellcode to the bottom of the return address. The second way is to write the shellcode directly into the buffer and then overwrite the return address with the address of the beginning of the buffer. So which way is more suitable for w32dasm, need further analysis to be able to know.

manually parse the import table

For this program, to be able to exploit this vulnerability, we can construct a malformed executable that constructs a function name that is located in the Import/export table very long, so that if the user uses W32DASM to load the malformed file that we construct, it can trigger the vulnerability and do whatever it wants on the target system. So before I implant the shellcode, I think it is necessary to give you a brief explanation of the knowledge of the imported table in the PE structure.

Code or data that uses other DLL executables in an executable file, called Import or input. When the PE file needs to run, it is loaded into memory by the system, and the Windows loader locates all the imported functions or data and fills in the contents of the executable file to be used at a location. This positioning needs to be done using an import table of the executable file. The import table holds the module name of the DLL used and the imported function name or function ordinal.

The structure that describes the imported table is Image_import_descriptor, and each DLL that is imported corresponds to a image_import_descriptor structure. In other words, the imported DLL file is a one-to-image_import_descriptor relationship. Image_import_descriptor is an array in the file, but the import information does not explicitly indicate the number of imported tables, but rather ends with a image_import_descriptor of all "0" in an import table. The structure that corresponds to the import table is defined as follows:

typedef struct _IMAGE_IMPORT_DESCRIPTOR {      union {          DWORD characteristics;          DWORD originalfirstthunk;     };      DWORD TimeDateStamp;      DWORD Forwarderchain;      DWORD Name;                
For this experiment, we focused on the Originalfirstthunk field, which contains the RVA of the Import name table, or it can be understood as pointing to the location of the actual import function. This field points to a struct named Image_thunk_data, which is defined as follows:
typedef struct _IMAGE_THUNK_DATA32 {    union {        DWORD forwarderstring;         DWORD Function;                DWORD Ordinal;        DWORD addressofdata;         } U1;} Image_thunk_data32;
The member of the struct is a union, although there are several variables in the union, but because the struct contains a union, the struct is equivalent to only one member variable, but sometimes it represents a different meaning.        Each image_thunk_data corresponds to an import function in a DLL. Image_thunk_data is similar to image_import_descriptor and ends with a full "0" image_thunk_data. When the highest bit of the Image_thunk_data value is 1 o'clock, indicating that the function is imported as an ordinal, the lower 31 bits are considered an import ordinal. When the highest bit is 0 o'clock, the function is imported as a string of the function name, when its value represents an RVA and points to a IMAGE_IMPORT_BY_NAME structure:
typedef struct _IMAGE_IMPORT_BY_NAME {    WORD    Hint;    BYTE    name[1];} Image_import_by_name, *pimage_import_by_name;

The hint field in the structure represents the ordinal of the function in the exported table in the DLL to which it belongs. This value is not required and some connectors are assigned a value of 0 for this value. The Name field represents the function name of the import function, which is the object we need to modify.

Now that you know the above theoretical knowledge, the following will begin to parse the Strings.exe this program import table, here I use LORDPE this software. First open the LORDPE, then click on the right side of the "PE Editor" button to load Strings.exe this program. Then click on the "Directories" button on the right to open the "Directory Table" dialog box:


Figure 9

Here we only focus on "importtable" This line of content, click the "L" button, open the "Structure Lister" dialog box:


Figure Ten        can see the value of Originalfirstthunk is 0x00012a74, it is a relative virtual address, we need to convert it to a file offset, fortunately LORDPE gives us this feature. Back in the PE Editor dialog box, click the FLC button on the right, and then enter "12a74" in the RVA to convert:

Figure One        you can see that after the conversion, the file offset is 0x00011074, select "Hex Edit" in the lower right corner to see the hexadecimal value at that location:

FigureThe value of this position is 0X00012CBC, according to the previous analysis, since the highest bit of this number is 0, so it holds the RVA where the function name string is located, so it needs to be converted. When the conversion is complete, the resulting file offset is 0X000112BC, and the data for that location is viewed as follows:
Figurethe character parsed by the right can be known, here is the location of the import function we are looking for, the first function is just the first function we found with OD Getfullpathnamea, and the 0x01f8 in front of it is the sequence number of the function. Then the manual parsing of the imported table is complete, and the following modifications are made to it.

Implant ShellcodeI've talked about two ways to jump to shellcode, and this time I'm going to introduce another one. First, let's look at the shellcode we've written:
Char shellcode[] = "\x90\x90\x90" "\x33\xdb"//XOR Ebx,ebx "\xb7\x04"//mov bh,4 "\x2b\xe3" Sub ESP,EBX "\x33\xdb"//XOR Ebx,ebx "\x53"//push EBX "\x68\x6 9\x6e\x67\x20 "\x68\x57\x61\x72\x6e"//Push "Warning" "\x8b\xc4"//mov Eax,esp "\x "//Push EBX" \x68\x2e\x29\x20\x20 "" \x68\x20\x4a\x2e\x59 "" \x68\x21\x28\x62\x79 "" \x68\x63 \x6b\x65\x64 "" \x68\x6e\x20\x68\x61 "" \x68\x20\x62\x65\x65 "" \x68\x68\x61\x76\x65 "" \x68\x59\x6f\x75\x20 "//Push" You have been hacked! (by J.Y.) ""                               \X8B\XCC "//mov Ecx,esp" \x53 "//Push ebx" \x50 " push eax "\x51"//push ECX "\x53"//push ebx "\ Xb8\xea\x07\xd5\x77 "\xff\xd0"//Call MessageBox "\x53" "\xb8\xfa\xca\x81\x7c "\xff\xd0"//Call ExitProcess "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x9 0\x90 "" \x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90 "" \x90\x90\x90\x90\x90\x90\x90\x90\x90\ X90\x90\x90\x90\x90\x90\x90 "" \x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90 "" \x90\x90\x90\ X90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90 "" \x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\ X90\x90 "" \x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90 "" \x90\x90\x90\x90\x90\x90\x90\x90\ X90\x90\x90\x90\x90\x90\x90\x90 "" \x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90 "" \x90\x90\ X90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90 "" \x90\x90\x90\x90\x90\x90\x90\x90\x90\x90 "" \x79\x5b\ Xe3\x77 "//Return Address" \xe9\xf7\xfe\xff\xff "//JMP back

The shellcode is different from what it used to be, although I still overwrite the return address for the address of the JMP ESP, but below the return address, where the program jumps to ESP, the statement executes "\xe9\xf7\xfe\xff\xff", which is the JMP Back So what does this jmp back mean? In fact, the JMP command (E9) followed by an offset address, here I want to let the program jump a certain offset, that is, the front end of the buffer to execute instructions, where the size of the offset is "0xfffffef7". So how is this value calculated? In conjunction with the previous analysis, it is known that the address of the JMP back command is 0x0065bee4, since jmp back itself is 5, so 0x0065bee8 plus 5, or 0x0065beed, then our target address, That is, we want to jump to the position of 0X0065BDE4, then use 0x0065bde4 minus 0x0065beed, the result is 0xfffffef7. Because the computer is a small-side display, writing shellcode needs to be written in reverse. Please note that, since my function address here is a hard-coded way, so when you do the hands-on experiment, we must first obtain the real function address of their system, or use the general Shellcode we said in the last lesson.

loading malformed PE filenow open the w32dasm separately and load the malformed Strings.exe file that we modified:

FigureThe visible vulnerability has been successfully exploited by us, and after clicking "OK", the program exits normally, indicating that our experiment was successful.

Buffer Overflow Analysis Lesson No. 06: W32dasm Buffer Overflow Analysis

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.