Monday, April 2, 2018

Buffer Overflow on a Web Application


- Layout for this exercise:

- Buffer Overflows and Web Applications

- Attackers use buffer overflows to corrupt the execution stack of a web application:

- By sending carefully crafted input to a web application, an attacker can cause the web application to execute arbitrary code effectively taking over the machine.

- Buffer overflow flaws can be present in both the web server or application server products that serve the static and dynamic aspects of the site, or the web application itself. 

- When web applications use libraries, such as a graphics library to generate images, they open themselves to potential buffer overflow attacks.

- Buffer overflows can also be found in custom web application code, and may even be more likely given the lack of scrutiny that web applications typically go through. 

- Buffer overflow flaws in custom web applications are less likely to be detected because there will normally be far fewer hackers trying to find and exploit such flaws in a specific application. 

2 - Exercise scenario

- In this exercise the OWASP WebGoat v5.4 version is used, loaded at a Windows 10 machine.

- Going to Buffer Overflows -> Off-by-one Overflows:

- The description of this exercise is a hotel with a web form ready to enter information for the guests registration system:

- Once the web form is filled, a Price Plan is offered to be accepted by the guest:

3 - Launching the Buffer Overflow attack

- The challenge of the exercise is to reveal information and data about VIP guests, by taking advantage of the Buffer Overflow vulnerability suffered by the application.

- The strategy is to test various character strings with different lengths (1025, 2049, 4097, ..) until you find the one that causes the buffer overflow and therefore the disclosure of confidential information stored by the vulnerable application.

- First, let's generate a string of 1025 characters with a Python interactive script:

etc ...

- Entering the string of 1025 characters at the 3 input fields:

- Accepting the Price Plans:

- However, there is no interesting output or revealed information:

- Same result would happen from entering  a string of  2^11 + 1 = 2049 characters:

- However, a different output is achieved when entering a string of 2^12 + 1 = 4097 characters:

- Entering 4097 characters all the hidden fields are revealed, containing the hard coded information related to the VIP guests:

- Restarting the lesson and entering the new data revealed for the user "Lewis", and accepting a Price Plan:

- Finally, the lesson is successfully completed:

- Checking one by one whether all the three input fields are vulnerable to the Buffer Overflow, it is easy to demonstrate that the third is the only vulnerable one.

- Entering the 4097 characters length string separately into the first two input fields (First_Name and Last_Name) nothing out of the ordinary happens:

- However, entering the malicious string into the third field (Room_Number) provokes the Buffer Overflow and the disclosure of hidden 

4 - Explanation

- General theory about Buffer Overflow vulnerabilities can be found everywhere in the Internet:

- Also,  several exercises have been presented about this topic in this blog:

Inside a microprocessor, where an application is run, the process stack of the memory  is usually divided in three regions: text (program code), data and stack buffer.

- The data region reserves space of memory for the functions of the application, and it is divided into two parts: 

      i) uninitialized data: variables initialized to zero, or just declared variables
      ii) initialized data: variables with assigned values, for instance the hardcoded VIP list 

- In our example, let's suppose that the web application is composed of 3 main functions:
  • function A: checks if the input fields are empty
  • function B: selects a price plan
  • function C: loads the hardcoded VIP list and stacks the user inputs on the buffer

- Functions A and B would be located at the uninitialized region, and function C would be at the initialized region.

- However, the initialized region where the hardcoded VIP list resides is in contact with the Buffer stack region, so this last region is prone to be rewritten or overflown if there are no clear boundaries for the funcion C.

- There are secure programming methods for checking the functions inputs buffer boundaries, like for instance BufferedInputStream for Java language, and strncpy(), fgets() for C/C++ languages.

- These secure programming methods would not admit inputs greater than the established ones by the programmer, and the application would throw error messages if the attacker tried to overflow those values.

- In our case, giving for granted that there aren't any secure programming methods enabled, to perform the Buffer Overflow let's take advantage of the fact that the size of the buffer value is usually assigned in terms of powers of 2^x bytes. For instance x=10,11,12, ...:
  • 2^10 = 1024 bytes
  • 2^11 = 2048 bytes
  • 2^12 = 4096 bytes

- As seen before, both the First_name and Last_name input fields are built with secure programming methods, but not the last one Room_Number.

- Because the attacker does not know in advance the size of the buffer, he launches and trial/error attack by entering strings of characters 1 byte longer than the potential buffer sizes, that is 1025, 2049 and 4097 bytes.

- There is no successful result with the first two trials. However, when entering 4097 bytes there is a success, because the buffer is overflown and the data below the buffer is read, revealing the VIP list.