Defeating_DEP_through_a_mapped_file.pdf

(532 KB) Pobierz
« Defeating DEP through a mapped file »
by Homeostasie (Nicolas.D)
08/08/2011
(trashomeo [at] gmail [dot] com)
Contents
1. Introduction............................................................................................................3
2. Description of the attack scenario..........................................................................4
3. Building a ROP exploit..........................................................................................7
3.1. Step 1 - Open a file containing our shellcode ......................................................................7
3.2. Step 2 - Craft mmap() parameters into the stack..................................................................9
3.2.1. ROP chaining for crafting the first argument to 0......................................................10
3.2.2. ROP chaining for crafting the second and the fourth argument to 1..........................12
3.2.3. ROP chaining for crafting the third argument to 4.....................................................13
3.2.4. ROP chaining for crafting the fifth argument to “fd” value (file descriptor).............14
3.2.5. ROP chaining for crafting the sixth argument to 0.....................................................14
3.3. Step 3 – Call mmap() and jump on the mapped area..........................................................15
4. Conclusion...........................................................................................................18
Figures
Illustration 1: Global view of the BoF skeleton..............................................................................5
Illustration 2: Registers status after the open() call.........................................................................8
Illustration 3: Stack diagram of mmap() arguments........................................................................9
Illustration 4: Status registers after open() call.............................................................................10
Illustration 5: Status registers after having crafted the first argument..........................................12
Illustration 6: Status registers after having crafted the second and the fourth arguments.............13
Illustration 7: Status registers after having crafted the third argument.........................................14
Illustration 8: Status registers after having crafted the fifth argument..........................................15
Illustration 9: Status registers after mmap() call...........................................................................16
Illustration 10: Final exploit execution.........................................................................................17
Disclaimer
This article has been only created for security and informational purpose and does not engage
my responsibility as to the usage that you decide to do with.
Defeating DEP through a mapped file
1. Introduction
I am going to talk about a way to bypass DEP (Data Execution Prevention) in local exploitation.
DEP is intended to prevent an application from executing code from a non-executable memory
region, including the stack. This helps prevent certain buffer overflow exploits. But as we know,
some methods have been already described previously. They relies on:
a classic “ret-to-libc”
copying data into executable regions
disabling DEP for the current process.
Recently, I was looking for another technique adapted to a Linux system and I thought to use
mmap() to map a local file containing our shellcode in the virtual memory and then jump on it.
ROP (Return-Oriented Programming) technique will be used to craft the function parameters.
After a web search, I did not notice any articles treating about this. That's why I took the
opportunity to describe it through a basic example in this paper. I will explain the exploit design
in detail, according to the difficulties encountered, and some tricks for overcoming them.
-3/18-
Defeating DEP through a mapped file
2. Description of the attack scenario
For this article, we use a source-code which has a common buffer overflow due to a bad usage of
the strcpy() function (because of non realized checks on the input string parameter).
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void copy(char *arg)
{
char msg[128];
strcpy(msg,arg);
printf("your argument is: %s\n",msg);
}
int main(int argc, char **argv)
{
if (argc != 2)
{
printf("Usage : prog argv1\n");
exit(1);
}
copy(argv[1]);
return 0;
}
This source-code is compiled without SSP (Stack-Smashing Protector) and the ASLR is currently
disabled.
First of all, one of the major difficulty is related to the two APIs chaining. Actually, it necessarily
open a local file with the open() function and call mmap() function with the file descriptor
returned by open().
Then, the second aspect will be to craft the input parameters knowing that NULL bytes will be
required for mmap() function. We will see further details about this approach.
Finally, we need to find useful “gadgets” to forge our attack scenario. Note that, there are no
generic way to build our ROP exploit, several solutions are possible, we should think a bit
cleverer than previously.
Before going into details, we must find out a way to build our exploit. Firstly we verify the
functions prototype.
The open() function:
int open(const char *pathname, int flags);
The return value is a file descriptor and the input parameters are the file name and the access
modes.
-4/18-
Defeating DEP through a mapped file
The mmap() function:
void *mmap(void *start, size_t length, int prot, int flags, intfd, off_t offset);
The return value is a pointer on the mapped area and the input parameters are :
the starting address (usually set to 0),
the data length to map,
the memory protection (PROT_EXEC, PROT_READ, PROT_WRITE),
the type of the mapped object (MAP_SHARED, MAP_PRIVATE),
the file descriptor
the offset.
Now we need a global view of the BoF skeleton onto the stack according to the function
parameters.
Illustration
1
Global view of the BoF skeleton
:
Well, if it looks scary, read carefully the following lines.
On the one hand, as classical buffer overflow, we had to seek the number of bytes in order to
overwrite “eip” and “ebp” registers. In this case, I need 136 bytes.
-5/18-
Zgłoś jeśli naruszono regulamin