Skip to main content

Attacking Network Device PART - 6

Return Oriented Programming 


Introduction 

 Since 1988, the Morris Worm stack overflow has been a nightmare for developers. Several countermeasures have been created to avoid this kind of attack. Compilers are pioneers in developing such techniques. 

  Sadly, few programmers know very much about compilers' options as they usually compile programs with inherited procedures. For instance, the very well known GCC compiler has a stack protection with the fstack-protector option [1]. 

  In the middle of the past decade, manufacturers introduced the No-eXecute (NX) bit which prevents the execution of code beyond the text area of a program. When this bit is ON, the processor sends a signal to the Operating System (OS). In addition, it is also necessary for the Operating System to be instructed to stop the code execution. In Windows, this is achieved by activating the Data Execution Prevention.

    Readers must be aware that the NX bit does not prevent stack overflow and only prevents the execution of injected code. So, if you are able to exploit such a vulnerability, you are completely free to write anything you like in the stack. However, a clever hacker may think…. “Of course, I can’t execute code but I can alter the normal flow of execution, making the program go to another address by means of overwriting the return address located in the stack”.

As a concept of proof, we will work with this simple program:

 
#include <ctype.h>

#include <stdio.h>

#include <string.h>

int tabla[5] = {91, 92, 93, 94, 95};

 {

 FILE *fd; 

    int in1,in2;

        int arr[20];

   char var[20]; 

if (argc !=2){

 printf(mensaje0,*argv); 

return -1; 

  } 

   fd = fopen(argv[1],"r");

    if(fd == NULL)

  {
 
   fprintf(stderr,mensaje1); 

  return -2;

  } 

  memset(var,7,sizeof(var));

 memset(arr,6,20*sizeof(int));

 while(fgets(var,20,fd)) 

  { 

 in1 = atoll(var); 

 fgets(var,20,fd); 

 in2 = atoll(var);

 /* fill array */ 

 arr[in1]=in2;

 //printf("%d - %d\n", arr[in1], tabla[in1]); 

 if (arr[in1] != tabla[in1])

   { 

    printf("Sorry values are no correct!\n"); 

     return ; 

   } 

     printf("Correct”. The process follows\n"); 

   printf(“Your are in the core of the program\n”); 

    return; 

  } 

  }


  Code Logic The program reads a file with 2 lines; each line contains a number (in1 & in2), in1 is used as the index. If the value contained in the cell table[in1] is equal to in2, then the process is OK and will continue; otherwise, the process terminates. 

In a real environment, the table will be out of the program, even encrypted or secured with another security measure; but for us, this is not relevant because the only matter we must deal with is the return address. 

 Readers may wonder at these odd initializations: 

memset(var,7,sizeof(var));

 memset(arr,6,20*sizeof(int));


  They are only just a trick to make these values more visible in the stack area. And this is what happens when parameter values contained in the file are: 2 (in the first line) and 93 (in the second line): 

  Now, we start the program under Ollydbg [2] and we should make a breakpoint when jumping depending on the values in the parameter file. When parameters are set correctly, the following snapshot should appear. Take a look: 

 
  As shown, the program jumps to 0x4017F2 and follows the normal execution (in this example, the normal execution is only a message). If the data is not correct, a “Data are not correct....” message appears. Afterwards, control is transferred to address 0x40180C. Now, let's take a look at the stack:

  

  Due to special initializations, it's easy to locate the variable areas. We focus on address 0x22FF2C; this is a return address and we can be 90% sure this return address would be used for RET instruction at address 0x40180C. We put another breakpoint in this address for it to continue execution until this point as shown: 



Great!!! ESP points to address 0x22FF2C. This is our target!!!. 

  What to do next? We must overwrite this address with value 0x4017F2, directly addressing the normal part of the program. This entry in the stack is in an offset of 6 above our work areas. The program does not check values in parameter so if we changed the first parameter to a value of 26, we can overwrite this entry. The second value must be 0x4017F2 in decimal: 4200434

So, we must see the message first, which is telling us that the input is not correct. Afterwards, because we have changed the value of the return address, messages will tell us your data are correct as follows:  




We can take advantage of a vulnerability without injecting code and the exploit works even while the program is running in a system with Data Execution Prevention.

 One Step More...

   The explained technique above is only one way for exploiting a buffer overflow but there are more ways.

 Another way is called return-to-libc. With ret2libc, we change the return address with the address of a system function and its parameters. Usually a calling to system() function. The latter technique I had explained is called return chaining.


We have identified the following instructions, each one is followed by RET instruction: 

● pop a 

 ● pop c 

● mov [ecx], eax. 

  Also, there is a RET leading program at the address: 0x684a0f4e.  


These instructions extract value on the top of the stack. And the following RET extracts value which transfers control to: 



  This set of values is called “gadget”; a patient hacker can recollect a large set of instructions' addresses followed by a ret and make a catalogue. Then by combining the needed values, he can execute instructions as if the code is being injected. 



Conclusion 

 In this article, I introduced how easy a hacker can exploit a stack overflow in an NX bit protected system and the other protections that we must not neglect as well such as compiler options and Address Space Layer Randomization (ASLR). Only when these protections are working together, we must think about a hardened programming environment.

Popular posts from this blog

Haking On Demand_WireShark - Part 5

Detect/Analyze Scanning Traffic Using Wireshark “Wireshark”, the world’s most popular Network Protocol Analyzer is a multipurpose tool. It can be used as a Packet Sniffer, Network Analyser, Protocol Analyser & Forensic tool. Through this article my focus is on how to use Wireshark to detect/analyze any scanning & suspect traffic. Let’s start with Scanning first. As a thief studies surroundings before stealing something from a target, similarly attackers or hackers also perform foot printing and scanning before the actual attack. In this phase, they want to collect all possible information about the target so that they can plan their attack accordingly. If we talk about scanning here they want to collect details like: • Which IP addresses are in use? • Which port/services are active on those IPs? • Which platform (Operating System) is in use? • What are the vulnerabilities & other similar kinds of information. • Now moving to some popular scan methods and ho

Bypassing Web Application Firewall Part - 2

WAF Bypassing with SQL Injection HTTP Parameter Pollution & Encoding Techniques HTTP Parameter Pollution is an attack where we have the ability to override or add HTTP GET/POST parameters by injecting string delimiters. HPP can be distinguished in two categories, client-side and server-side, and the exploitation of HPP can result in the following outcomes:  •Override existing hardcoded HTTP parameters  •Modify the application behaviors   •Access and potentially exploit uncontrollable variables  • Bypass input validation checkpoints and WAF rules HTTP Parameter Pollution – HPP   WAFs, which is the topic of interest, many times perform query string parsing before applying the filters to this string. This may result in the execution of a payload that an HTTP request can carry. Some WAFs analyze only one parameter from the string of the request, most of the times the first or the last, which may result in a bypass of the WAF filters, and execution of the payload in the server.  Let’s e

Bypassing Web Application Firewall Part - 4

Securing WAF and Conclusion DOM Based XSS DOM based XSS is another type of XSS that is also used widely, and we didn’t discuss it in module 3. The DOM, or Document Object Model, is the structural format used to represent documents in a browser. The DOM enables dynamic scripts such as JavaScript to reference components of the document such as a form field or a session cookie, and it is also a security feature that limits scripts on different domains from obtaining cookies for other domains. Now, the XSS attacks based on this is when the payload that we inject is executed as a result of modifying the DOM environment in the victim’s browser, so that the code runs in an unexpected way. By this we mean that in contrast with the other two attacks, here the page that the victim sees does not change, but the injected code is executed differently because of the modifications that have been done in the DOM environment, that we said earlier. In the other XSS attacks, we saw the injected code was