You are on page 1of 12

Linux x64 NX Bypass

(ret2libc + ROP)

LAB 11

© 2019 Caendra Inc. | Hera for XDS | Linux x64 NX Bypass (ret2libc + ROP) 1
SCENARIO
In this lab you will continue to learn x64 Linux exploitation. Both the Operating System
(Ubuntu 16) and the target binary are 64-bit. The stack is not executable (NX is enabled).
You will have to find a way around it.

You can connect to the lab machine via SSH. The target IP is 172.16.172.153

In case you need root-level access for debugging, the user below is able to run sudo.

The SSH credentials are the following.

Username: xdev
Password: xdev

GOALS
• Discover vulnerabilities in the binary
• Utilize ret2libc and ROP
• Spawn an interactive bash shell

WHAT YOU WILL LEARN


• Exploiting 64-bit buffer overflows
• Utilizing ROP during buffer overflows
• Chaining ret2libc with ROP

© 2019 Caendra Inc. | Hera for XDS | Linux x64 NX Bypass (ret2libc + ROP) 2
RECOMMENDED TOOLS
• Gdb / gdb-peda
• ROPgadget
• Text editor
• Kali linux

NETWORK CONFIGURATION &


CREDENTIALS
• Penetration tester’s Subnet: 172.16.172.0/24

• Vulnerable machine: 172.16.172.153

• Connection Type: SSH

ssh xdev@172.16.172.153
password: xdev

© 2019 Caendra Inc. | Hera for XDS | Linux x64 NX Bypass (ret2libc + ROP) 3
TASKS
TASK 1: CONNECT TO THE COMPROMISED MACHINE
AND EXAMINE THE TARGET BINARY
The target binary is named bypass_nx and is available in the xdev user’s Desktop directory.
As your first task, try to identify vulnerabilities within the binary.

Remember that:

1. The stack is not executable (NX is enabled)


2. The binary features no additional protections
3. ASLR must be disabled. To do so, execute:
sudo bash -c "echo 0 > /proc/sys/kernel/randomize_va_space"

TASK 2: FURTHER EXAMINE THE BINARY AND IDENTIFY


A STRATEGY TO BYPASS NX
As you have figured out in Task 1, we can overwrite the return address. As the stack is not
executable, we can try returning to interesting functions. This time, we will not follow the
traditional ret2libc approach. Specifically, we will enhance the traditional ret2libc approach
with ROP.

Try to find a ROP gadget within the binary itself, where we will return first in order for the
argument’s address to be popped into an appropriate register. Then, the function will be
called.

Hints:

1. Leverage the system() function (ASLR is disabled, so its address is predictable(


2. The rdi register can accommodate the system’s argument
3. Try searching for occurrences of “/bin/sh” within the binary

© 2019 Caendra Inc. | Hera for XDS | Linux x64 NX Bypass (ret2libc + ROP) 4
TASK 3: CREATE A POC EXPLOIT AND LAUNCH IT
It is time to combine all the above into a working exploit.

© 2019 Caendra Inc. | Hera for XDS | Linux x64 NX Bypass (ret2libc + ROP) 5
SOLUTIONS

© 2019 Caendra Inc. | Hera for XDS | Linux x64 NX Bypass (ret2libc + ROP) 6
Below, you can find solutions for each task. Remember though that you can follow your
own strategy (which may be different from the one explained in the following lab).

TASK 1: CONNECT TO THE COMPROMISED MACHINE


AND EXAMINE THE TARGET BINARY
Let’s start by interacting with the binary. We see that it accepts user input once and then
exits.

Let’s see how this program copes with overly large inputs. Gdb-peda’s pattern create will
be used to create an overly long input.

Let’s execute ulimit -c unlimited first and then provide the binary with the above input.

© 2019 Caendra Inc. | Hera for XDS | Linux x64 NX Bypass (ret2libc + ROP) 7
It looks like we managed to crash the target binary. Let’s utilize the dumped core file to
identify if we were able to overwrite the return address.

Like in the Linux x64 Basic Stack Overflow lab, we receive no conclusive information about
the rip register. Let’s see the state of the other registers. Maybe we will have to utilize the
rbp as we did on that lab.

Indeed, rbp seems to contain a portion of our sent buffer/payload. Let’s use it to calculate
the offset.

The offset to overwrite rip is 104 (96 + 8).

© 2019 Caendra Inc. | Hera for XDS | Linux x64 NX Bypass (ret2libc + ROP) 8
TASK 2: FURTHER EXAMINE THE BINARY AND IDENTIFY
A STRATEGY TO BYPASS NX
If you recall, ret2libc attacks in 32-bit binaries require setting up a fake stack frame. Based
on that fake stack frame a function in libc is called and any parameters are passes to it. Such
a function could be system() with a parameter of “bin/sh”

In 64-bit binaries though, function parameters are passed in registers. RDI, RSI, RDX, RCX,
R8 and R9 hold the first six parameters. Any further parameter is passed on the stack. Before
returning to an interesting function, 64-bit binaries require that the respective function
parameters are loaded in the aforementioned registers. We can do that through ROP. More
on that in just a bit.

Let’s focus for now on interesting functions. Attach gdb to bypass_nx, execute run but don’t
provide any input, just press ctrl+c.

Now, let’s see where system() is located, as follows.

Let’s note its address down. Be reminded that ASLR is not enabled.

© 2019 Caendra Inc. | Hera for XDS | Linux x64 NX Bypass (ret2libc + ROP) 9
In order for system to be exploitable, we need to pass it an “/bin/sh” argument.

Let’s check for “/bin/sh” occurrences within the binary. Quit gdb and attach to bypass_nx
again. Then, proceed as follows.

Luckily, there are “/bin/sh” occurrences within the binary (this ensures predictability).

Let’s now write the first “/bin/sh”’s address down. We will pass “/bin/sh” as an argument to
system to obtain a shell.

© 2019 Caendra Inc. | Hera for XDS | Linux x64 NX Bypass (ret2libc + ROP) 10
Finally, it’s time to search for a ROP gadget within the binary, where we will return first in
order for the argument’s address to be popped into the rdi register Then, the function will
be called.

This can done with the help of ROPgadget done, as follows.

(Execute cd ~ to find the ROPgadget tool’s directory)

Let’s also note this address down.

TASK 3: CREATE A POC EXPLOIT AND LAUNCH IT


All the above, can be incorporated into a working exploit, as follows.

#!/usr/bin/env python

from struct import *

buf = ""
buf += "A"*104 # junk
buf += pack("<Q", 0x0000000000400693) # pop rdi; ret;
buf += pack("<Q", 0x4006e8) # pointer to "/bin/sh"
buf += pack("<Q", 0x7ffff7a52390) # address of system()

f = open("payload.txt", "w")
f.write(buf)

To test the exploit above, transfer it to the remote machine and then execute it using the
double cat trick, as follows.

© 2019 Caendra Inc. | Hera for XDS | Linux x64 NX Bypass (ret2libc + ROP) 11
© 2019 Caendra Inc. | Hera for XDS | Linux x64 NX Bypass (ret2libc + ROP) 12

You might also like