2

I am currently trying to perform a return-to-libc attack against a locally run program. Here are the steps I did:

  1. I calculated the bytes needed to overwrite the saved return address

  2. I used a buffer overflow to overwrite the saved return address with the address of a "pop rdi ; ret" gadget so that I can call system() with the string "/bin/sh" as an argument (the program is 64 bit)

  3. After the overwritten return address I put the address of the string "/bin/sh", so that the "pop rdi" instruction would pop the address of "/bin/sh" into the rdi register

  4. After that I put the address of the system function in libc (ASLR is off, so the address is static)

To summarize, the stack looks like this:

padding|address_of_pop_rdi|address_of_binsh|address_of_system_in_libc

All of the addresses are converted using the p64() method of python lib pwntools

Whenever I run the exploit, the program crashes with a SIGSEGV (segmentation fault), which leads me to believe that the padding length is incorrect, but here is the weird thing:

When I step through the exploit using GDB, I can see that the saved rip is set correctly to the address of the pop_rdi gadget. When I step further I can see, that the address of "/bin/sh" is popped correctly into the RDI register. When I step even further, I can see the system function being executed. No matter how many times I step further, the program never crashes with a SIGSEGV. Execution just stops at some point, which I think is because the program is waiting for a shell command to be entered.

Has anyone else run into this porblem? Is there maybe some protection enabled which automatically terminates the program because an exploit is detected? The binary has no canaries, no PIE but runs NX.

I appreciate any help I can get, because I am dead lost

I can provide screenshots if needed

Thanks in advance!

1
  • welcome - it may help to specify your runtime and dev environment, compiler flags, etc Commented Sep 5, 2024 at 18:13

1 Answer 1

2

There is a great chance that this crash is caused by the movaps instruction inside the system function. movaps require the stack to be aligned to 16-byte. And when you rop to the system function, the stack may not aligned propertly.

reference from Why movaps causes segmentation fault?

From Intel® 64 and IA-32 architectures software developer’s manual, MOVAPS specification:

MOVAPS—Move Aligned Packed Single-Precision Floating-Point Values

...

When the source or destination operand is a memory operand, the operand must be aligned on a 16-byte (128-bit version), 32-byte (VEX.256 encoded version) or 64-byte (EVEX.512 encoded version) boundary or a generalprotection exception (#GP) will be generated.

You can check it out by examine the crash point and the exit code with gdb.

To solve this problem, you can add and use a gadget to adjust the stack, e.g. ret, or simply skip the first push rsp instruction of the system function (note: if you do it this way, the process with crash when the system function return, since stack is no longer balanced).

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.