Password Discovery and Patching by Disassembling

Table of Contents

  • Essentials
  • The Target Binary
  • Binary Hex Code Analysis
  • Custom Code Segments
  • Patching Binary

Password Discovery and Patching

Disguising the source code of an application from malicious hands isn't the ultimate way to protect it from being reverse engineered. Many layman developers consider this approach the finest, because modern reverse engineering techniques have become increasingly sophisticated, in fact robotically recognizing the sensitive information, for instance library functions, local variables, stack arguments, data types and much more that is binary using sophisticated mechanisms. Moreover, may be, in the future, reverse engineering will perhaps be able to generate code similar to that of high-level languages. Hence, this article illustrates how to subvert some of authentication mechanism, such as extracting vital information imposed in the binary file of the source code by analyzing the generated hex code itself of the target executable. However, the following approach (to be discussed is unaffected by the kind of binaries that the source code is either obfuscated or packed from).

Essentials

This article will subvert the authentication constraints of a binary by analyzing the disassembled hex code of the target binary. So, the researcher must be familiar with hex coding analysis of an executable and moreover, be aware of various sophisticated tools, such as Dumpbin, IDA pro, PE Editor, Win-Hex and so on that will be very conducive in disassembling. Finally, a moderate level of understanding about assembly language semantics would be very beneficial during extracting vital information from the target.

  • Dumpbin.exe
  • Hiew Editor

The Target Binary

In this section we will write the target binary itself because we are intent on the objective only by means of a custom created VC++ executable, instead of performing it on licensed software because our intent should neither practice offensive reverse engineering nor endorse breaking any software protection mechanism. Therefore, the following source code will be compiled into a console based executable that asks first for the correct security key in the form of a password to proceed into the system. The user is strictly provided only three attempts to enter the correct pass key, otherwise the system will debar him.

Listing 1

  1. #include <stdio.h>  
  2. #include <string.h>  
  3.   
  4. #define SIZE 100  
  5. #define PASSWORD ********  
  6.   
  7. int main ()  
  8. {  
  9.   
  10. int count=0;  
  11. char buff [SIZE]=" ";  
  12. char passwd[ ]=PASSWORD;  
  13.   
  14.     printf ("\nWelcome to Console!!\n[You may have only 3 unsuccessful login attempts!]\n");  
  15.     for (;;)  
  16.     {  
  17.     printf ("\Attempt =%d",count+1);  
  18.     printf ("\nEnter the Password:");  
  19.   
  20.     fgets (&buff [0], SIZE,stdin);   
  21.   
  22.         if (strcmp(&buff[0] , &passwd[0]))  
  23.         {  
  24.         printf ("Invalid Password: Try Again\n");            
  25.         }  
  26.         else  
  27.         {  
  28.             break;  
  29.         }  
  30.   
  31.         if (++count>2)  
  32.         {  
  33.             printf ("\nAccess Denied");  
  34.             return -1;  
  35.         }  
  36.     }   
  37.     printf ("Congratulations!!: Valid Credentials\n");  

However, we have advertently concealed the correct password key in the source code to create a real-time impression of breaking a software protection constraint, where even the author or audience of this article doesn't know the password. In fact, mentioning the source of the target binary here is redundant in this scenario, since we are learning one of the subverting mechanisms where we don't have the access to the source code. Even so, the source code might be helpful for those viewers who are not proficient enough in developing their own application to apply the tactics as discussing in this paper.

After compiling this source code using any compiler like VC++.NET, or Borland C++ and so on, the final console based executable is generated as in the following where it requires the password first, to access ahead of the features. However, I have provided the source code of this binary. But here, forget everything; it is just for the researcher's convenience. Imagine that the user gets only the final executable and when he tries to run this console based application without having the actual pass key, he eventually wouldn't be able to proceed as in the following:



Figure 1: Password hit and miss in Target Binary

Suppose you don't possess the actual source code of this application for some reason and unfortunately, you have lost the pass key, then how can you utilize the features of this application, since critical data is at risk and your business is halted altogether in the absence of the pass key. In this critical situation, the Dumpbin.exe utility could be the real savior that is capable of “disassembling” the binary into hex code, so that crucial information can be obtained through the analysis of the hex code, in case the source code is not obfuscated.

Binary Hex Code Analysis

Here, I am not claiming 100% efficiency or accuracy of this approach, but suppose the reference password is stored somewhere in the program and isn't encoded in some artful manner unfortunately, then, it can be found by simply looking at the binary code. By inspecting all the text strings, especially those that look like a password, we'll quickly find the required password and easily "open" the application's next level.

Binary hex code analysis by dumping its contents is a significant initial step in reverse engineering, because understanding the internal contents of the target executable is conducive, in terms of gaining an overview of what the program does and what other components it interacts with. There are numerous executable-dumping tools available, for example the DUMPBIN.EXE utility is a great tool for working from a command shell. It can dump all sorts of valuable evidence about a binary, imports and exports, section information, disassembly of the code and much more. You name it, DUMPBIN can probably do it. Overall, it allows you to examine the contents of a Microsoft PE/COFF file.

Command 1: dumpbin.exe

Note

Hereby, we shall explore, or try to obtain, significant information from the target binary by applying the DUMPBIN utility various underlying options.

Dependency on External Lib

DUMPBIN was shipped with VC++ in Microsoft Visual Studio and combines the functionality of the Microsoft development tools including LIB, LINK and EXEHDR. Thus, DUMPBIN can parse a suspect binary to offer crucial information about the file format and structure, embedded symbolic information, as well as the library files required by the program. To identify an unknown binary file's dependencies, query the target file with DUMPIN, using the “/DEPENDENTS” option as in the following:

> dumpbin /dependents PwdAnalysis.exe

Command 2: Binary dependents



Binary Header Information

The DUMPBIN /headers option displays only the header information pertaining to COFF header files and section header files. Here's the headers detail for the PwdAnalysis executable file:

> dumpbin /headers PwdAnalysis.exe

Command 3: Binary headers



Code Segments Enumeration

The DUMPBIN /summary option enumerates all the code segments information employed in the binary. However, some of them are generated by-default.

> Debug>dumpbin /summary PwdAnalysis.exe

Command 4: code segments detail




This is totally up to the hacker or researcher's intellectualism of which section they pick up to analyze since these segments contain very helpful data. The PwdAnalysis.exe file contains 7 underlying code segments. Each one contains significant data and has distinguishable importance as in the following.

Segments Description
.text It contains the executable instruction codes and is shared among every process running the same binary.
.bss It holds un-initialized global and static variables. The size that BSS will require at runtime is recorded in the object file, but the BSS doesn't take up any actual space in the object file.
.data It usually has READ/WRITE permissions, contains the initialized global and static variables and their values.
.reloc It keeps information required for relocating the image when loading.
.rdata It contains constants and string literals.

Disassembling Binary Code

The DUMPBIN utility /disasm command-line option produces a disassembled listing of the object file in assembly language syntax much like as IDA pro. The /disasm option can be to investigate compiled programs and can be applied when analyzing "pseudo-compiled" code. If you look closely at the disassembled code, you'll easily determine the flow of execution as well as identify a couple of stored string values as in the following.

> dumpbin /DISASM PwdAnalysis.exe

Command 5: Disassembled code of Binary




Password Disclosing by Examine Raw Data

A binary file typically contains essential string reference values that are very useful for figuring out the flow of execution, as well as conducive while cracking. Let's assume that the reference password is stored in the raw data section, hence, obtain the raw data section information by /SECTION:.rdata along with /RAWDATA:BYTES as in the following:

> dumpbin /RAWDATA:BYTES /SECTION:.rdata PwdAnalysis.exe > analysis



Figure 2: analysis file dump in Hex Editor

Here in the previous figure, we have successfully identified the significant pass key information from the raw data as "kmaraj" in the hex code form too.

Obtaining Precise Information

Although dumpbin.exe with /ALL option produces considerable output, the problem with this approach is that an EXE file contains all the routines from the language's standard library that the linker has combined into the application. Therefore, such extra information makes the job tedious by creating an overwhelming amount of confusion and when analyzing compiler output. Fortunately, you can eliminate all the unnecessary information. Run DUMPBIN on your object (OBJ) files rather than your executable files. Here is the output of DUMPBIN with the /all option when you supply *.obj as the command-line parameter:

> dumpbin /All PassAuth.obj > analysis


The following result shows only the underlying string values contained in the binary with their memory address.



Figure 3: Significant information in OBJ

Further, we can easily detect the original pass key along with other necessary information conducive when modifying the hex values of the corresponding memory segments as in the following.

Figure 4: password in OBJ file



Adding Custom Code Segments

We can slightly hinder the disassembly and displaying of the underlying string reference values in the raw data section, since typically this section is the prime matter of interest. Instead, you can add custom code segments and place vital information there. Here, we are creating custom .Secure code to protect password information from being displayed in raw bytes as in the following.

Listing 2

  1. #include <stdio.h>  
  2. #include <string.h>  
  3.   
  4. #define SIZE 100  
  5. #define PASSWORD *********  
  6.   
  7. #pragma data_seg (".Secure")  
  8.   
  9. char passwd[ ]=PASSWORD;  
  10.   
  11. #pragma data_seg ()  
  12. #pragma comment(linker, "/SECTION:.Secure,RWS")  
  13.   
  14. int main ()  
  15. {  
  16.   
  17.   int count=0;  
  18.   char buff [SIZE]=" ";  
  19.   …  

Now, there is no password information displaying in the data section except other string reference and the hacker's attack has been stopped. In fact, we have shielded the crucial information by placing it in custom segments.

> dumpbin /RAWDATA:BYTES /SECTION:.rdata PwdAnalysis.exe > analysis



Figure 5: password discovering after adding code segments

But wait! Don't jump to conclusions so early. You can still obtain such information. First, ensure the list of sections in the file by displaying them using DUMPBIN. Here, as you can observe in the results, there is an extra code segment .Secure created. Maybe it contains something interesting.



Figure 6: Secure Code segment

Now, pay attention only to the .Secure section. Specify it in the /Section option in the DUMPBIN when displaying raw data bytes as in the following.

> dumpbin /RAWDATA:BYTES /SECTION:.Secure PwdAnalysis.exe

Bingo! There's the password! And we thought we hid it. It's certainly possible to put confidential data into a section of non-initialized data (.bss), the service RTL section (.rdata), or even into the code section (.text). Because typically not everyone will look there for the vital information and such allocation won't disturb the functioning of the program.



Figure 7: password in .Secure block


If the password could have been written in Unicode somewhere in the source code, or it was ciphered using any cryptic algorithm, the search would be somewhat more complicated, since not all such utilities support this encoding. But it'd be rather native to hope that this obstacle will stop a hacker for long. So, we have obtained the password only by means of the DUMBIN utility. On behalf of this value, you can enter into the application the next level as in the following:



Figure 8: Output

Patching Binary

As yet in the previous section, we found the password by examining the raw bytes, in pursuit of stored vital string reference values in the .Secure code section. But, how tiresome it is to enter the password each time you start the program! What if, the program accepted any password or there is no need to enter a password.

Let's consider the .Secure data section once again where the password is stored. We just need to determine the location of the password in memory. Its address will be stored by the pointer.



Figure 9: Getting offset of password

Here, we can easily conclude that the password is located at 0x419000, so the pointer to it also must equal to 0x419000. Let's search the disassembled code at 0x419000 using a text editor, you found something interesting as in the following:



Figure 10: Reference of 0x419000 methods

Note


Next, focus on understanding the goal of the 0x04110A5 function. It's apparent that this function checks the password.



Figure 11: 0x04110A5 method

Further, the TEST EAX, EAX instruction checks if the value returned by the function equals zero. If it does then the following JZ instruction jumps to the line 0x041149B that led us to the "Invalid password" string as in the following:



Figure 12: TEST instruction

We are almost there. There are two approaches to foil the password protection. If we replace TEST EAX, EAX with an XOR EAX, EAX instruction then the EAX register will always contain zero. Then you will surely enter into the next level in the program, no matter what password is entered. So, in the HIEW, go to 0x041147E, press F3 for edit, then hit Enter and change the instruction TEST to XOR. After that, don't forget to save the changes by the F9 key.



Figure 13: TEST to XOR

Or, if we replace the JZ instruction with JNE, the program will reject the real password as invalid and all incorrect passwords will be accepted as valid.



Figure 14: JZ instruction

Here again, go to 0x41149C, press F3 for edit and then hit Enter and change the instruction JZ to JNE. After that, don't forget to save the changes with F9.



Figure 15: JZ to JNE

Finally, restart the program and enter anything as a password and see the result. The password protection has failed as in the following:



Figure 16: Patched EXE

Conclusions

This article provided a detailed overview of disassembling binary code via the DUMPBIN utility. It shows various underlying switches, for instance, /DISASM, /Summary and so on that are very beneficial when producing crucial information. However, there are overwhelming tactics of bypassing and code de-compilation of native binary, especially using IDA Pro, WinDbg, SoftICE and so on. But this article describes the process of obtaining the password information very simply, if they is a string somewhere in the source code in an unencrypted form. Finally, by analyzing the code instruction using the HIEW tool that contains the password matching related code, we have subverted the password protection constraints permanently. Thereafter, we re in no matter what the pass key the user enters.

References
  1. Book Reference: Identifying Malicious Code using Reverse Engineering
  2. http://cboard.cprogramming.com/c-programming/160693-encrypt-decrypt-input-string-%5Bhelp-please%5D.html
  3. Book chapter: Practical Reverse Engineering
  4. Book chapter: write_great_code_volume_2

Next Recommended Readings