Hacking — Best OF Reverse Engineering — Part 18

Reverse Engineering — Debugging Fundamentals
The debugger concept and purpose is to test and troubleshoot another written program.
Whether the debugger is a simple script, tool or a more complex computer program the idea
is to utilize it in order see and verify the functionality of the “target” program / application
in such a form that one can see and understand via the debugger what is happening while the
“target” program / application runs and especially when it stops.
The “target” program’s / application’s code that is examined (by the debugger) might alternatively be
running on an Instruction Set Simulator (ISS). The ISS is a certain form of technique that gives the ability to halt when specific conditions are encountered but which will typically be somewhat slower than executing the code directly on the appropriate (or the same) processor.

When the “target” program / application reaches a running condition or when the program cannot normally continue due to a programming bug (what is commonly known as a “crash”) the debugger typically shows the location in the original code whether it is a source-level debugger (which gives the line or expression within the source code that resulted from the debugger’s actions.) or symbolic debugger (which displays procedure and variable names that are stored in the debugger).

The Various Debuggers
There are many debuggers available for the purpose in question, among the more common names are;
WinDbg, Valgrind, LLDB Debugger, GNU Debugger (GDB), Immunity Debugger, OllyDbg and many more. As the list is quite long and this article’s purpose is to focus on the fundamentals of the debugger concept we’ll put an emphasis on three debugger types this time: The immunity Debugger, WinDbg and OllyDbg.

The first is the Immunity Debugger. This debugger has both interfaces types; the GUI and a command line.The command line can be seen at all times on the bottom of the GUI. The Immunity Debugger can write exploits, analyze malware, and reverse engineer binary files. The base platform of this tool is a solid user interface with graphing function and a fine analysis tool built especially for heap creation. This debugger has a well-supported Python API on top of its other features.

The second debugger we’ll review is the WinDbg — this is a multipurpose tool for Microsoft’s Windows operation system. The WinDbg can be used to debug user mode applications, drivers, and the operating system itself in kernel mode.

The third and last debugger tool we’ll review is the OllyDbg. This is an x86 debugger who can trace registers, recognizes procedures, API calls, switches, tables, constants and strings, as well as locate routines from object files and libraries. The main focus for this debugger is the binary code analysis which is useful when the source code is unavailable.

Launching the environment Pre-Requisites

* Microsoft windows XP/Vista/7 machine.

* Immunity Debugger — http://debugger.immunityinc.com/

* Vulnerable FTP Server — http://frogteam.gozure.com/FTP-Server.zip

* FTP Fuzzer — http://frogteam.gozure.com/Infigo.zip

In this section we’ll show the basic actions required to work with the debugger. Prior to starting this section please note that you’ll need to establish the environment based on the prerequisites listed above. Once you’ve completed the relevant actions you should have a Windows machine with all the files from the links above, and you should have installed the Immunity Debugger which will be used during this section.

Once the machine is up and running, you may launch the Immunity Debugger.

Immunity Debugger is a debugger with functionality designed specifically for the security industry.

Once the Immunity Debugger is up and running as can be seen in the image below we can start our FTP Server and then attach the Immunity Debugger to the FTP Server process (Figure 1).

In order to attach the Immunity Debugger to the FTP Server process we’ll need to perform the following actions:

* On Windows machine, extract the ‘FTP-Server.zip’ compressed file you’ve downloaded.

* Double-click on ‘FTPServer.exe’ to start the FTP Server.

* Return to the Immunity Debugger and click on File -> Attach (or Ctrl+F1)

* On the Process list, select the “FTPServer” (TCP: 21) and click on the Attach button.

When you attach the debugger to a running process it will pause. In the Immunity Debugger upper bar, you can resume the process by click the “Play” button or create a new thread by choosing the “Restart” button and then the “Play” button (Figure 2 and Figure 3).

In order to connect and authenticate the FTP Server simply flow up on the standard procedure and type the relevant username and password (e.g. user credentials).

One should assume that these variables need to be passed from the client to the server and therefore, the program needs to store them somehow in memory. For our analysis we need to ask ourselves the following questions:

* What kind of information it should contain (user info, program info, etc…)?

* Which type of data they are able to accept (Integer, String, etc…)?

* How many characters should there be (there is a chance for Buffer-Overflow)?

* Are there any characters that the variables should ignore (Bad-Characters)?

In order to find these answers, we need to find a vulnerable FTP function or command- this can be done automatically or manually. For an easy start (which will save time) it is sometimes recommended to use automated tools. Once a “buffer-overflow” vulnerability exists, we have to find the amount of “junk data” that, when sent to the application, will overwrite the register.

Stack-based buffer overflows techniques
Users may exploit stack-based buffer overflows to manipulate the program to their advantage in one of the following ways:

* By overwriting a local variable which is near the memory’s buffer on the stack to change the behavior of the program which may benefit the attacker.

* By overwriting the return address in a stack frame. Once the function returns, execution will resume at the return address as it was specified by the attacker. Usually a user’s input fills the buffer.

* By overwriting a function pointer, or exception handler, which is subsequently executed.

With a method called trampolining, if the address the user-supplied is listed as data unknown and the
location will still be stored in a register, then the return address can be overwritten with the address of an opcode (operation code, a part of a language instruction that specifies the operation which will be performed) — this will cause the execution to jump to the user supplied data.

If the location is stored in a register R, then a jump to the location containing the opcode for a jump R, call R or similar instruction, will cause execution of user supplied data. The locations of suitable opcodes, or bytes in memory, can be found in DLLs or the executable itself. Please note that the address of the opcode typically cannot contain any null characters and the locations of these opcodes can vary between applications and versions of the operating system.

Security Fuzzer
Another important term is the fuzzer. Security Fuzzer is a tool used by security professionals and professional hackers to test a parameter of an application. Typical fuzzers test an application for buffer overflows, format string vulnerabilities, and error handling.

Both fuzzer and debugger work together to detect security problems on a system, and its software.
The fuzzer provides invalid, unexpected, or random data to the inputs of the target program and then
monitors for exceptions such as failing built-in code assertions or for finding potential memory leaks.
Fuzzing is commonly used to test and exploit development tools.

More advanced fuzzers incorporate functionalities to test for directory traversal attacks, command execution vulnerabilities, SQL Injection and Cross Site Scripting vulnerabilities.

Infigo FTPStress Fuzzer is a specific fuzzer for finding vulnerabilities in FTP server products. Although it is a simple tool, it has proved its efficiency by the number of vulnerabilities discovered in different FTP server software tested with this tool.

The parameters which are used for the fuzzing process are configurable. User can precisely define which FTP commands will be fuzzed along with the size and type of the fuzzing data.

On the windows machine from before we’ll activate the “Infigo FTPStress Fuzzer” and try to crash
the FTP server:

* Extract the ‘Infigo.zip’ compressed file you’ve downloaded.

* Double-click on the ‘ftpfuzz.exe’ file.

You can try to crash the FTP Server from any other external machine and to perform this step using an instance of ftpfuzz.exe running on a different computer (Figure 5).

Once The Fuzzer is up we’ll need to find the commands that are supported by the FTP server:

* Enter the IP Address of the computer Host on which the FTP server is running (e.g. 127.0.0.1).

* Next, click on Discover button.

FTP Fuzzer detected the FTP commands supported by FTP server. See example in Figure 6.

Next we need to examine the behavior of these commands while sending “junk data”, Therefore we will configure the amount of “junk data” we want to send to the FTP server:

* Click on Config button

* On the configuration window, go to Fuzzing data tab and click Deselect All

* Check the “A” letter and then click on OK.

Assuming your Infigo Fuzzer looks like the image below, the fuzzing process can start. Click on Start button (Figure 7).

The outcome can be seen as the FTP Server has crashed (Figure 8).

The Analysis Phase
In this section we’ll review on the procedure of analyzing the log data. The normal flow of the fuzzer is to connect to the target FTP Server, get the 220 Hello Message and then, send the “A”s junk data in different amounts (1 “A” = 1 Byte) each time followed by the “FEAT” command, while the expected response is „RECV: 500" (Table 1).

Table 1. Expected Response is “RECV: 500”

Total FTP commands: 2
FTP commands to fuzz: 2
Number of Fuzz tests: 26
[ Connecting to 2.2.2.201:21… ]
[ Connected, starting fuzz process… ]
220 FreeFloat Ftp Server (Version 1.00).
[ CMD: [FEAT] FUZZ: [AAAAAAAAAAAAAAAAAAAA] SIZE: 30 ]
RECV: 500 ‘FEAT AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA’: command not understood
[ CMD: [FEAT] FUZZ: [AAAAAAAAAAAAAAAAAAAA] SIZE: 70 ]
RECV: 500 ‘FEAT AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA’: command
not understood

In order to understand what actually happened in the memory process, we can look at the diagram on the next page (Table 2).

Next we can observe that after 330 bytes of junk data sent the FTP fuzzer was not able to receive 520 bytes of junk data and disconnected.

This indicates that if we send junk data of a size between 330 and 520 bytes, the FTP server will crash (Table 3).

Now, that we know the amount of junk bytes to send to overwrite EIP register we’ll try to find the exact amount of data that will overwrite EIP register.

The Following Table Describes What Actually Happened in the Process Memory (Table 4).

After examining the FTP Fuzzer log we can return to Immunity Debugger and see what happened to the process during the fuzzing test (Figure 9).

In the Immunity Debugger main window we can see that our \x41 (“A”s) floods the memory stack until the EIP register and modified the address so it’s \x41\x41\x41\x41 (“AAAA”) as can be seen in the “Registers window” — this helped us find the “JMP” but leads to an access violation as we can see in the Immunity Debugger status bar.

To summarize our actions, we’ve found a stack-based buffer overflow in the FTP Server. In order to better understand the procedure we need to modify the exact register (4 bytes EIP in that case) with JMP value so we are able to hit an accessible register.

Originally published at https://learncybersec.blogspot.com.

Cyber Security Analyst & researcher