49

With a netcat listener like:

nc -l <port> < ~/.bashrc

I can grab my .bashrc on a new machine (doesn't have nc or LDAP) with:

cat < /dev/tcp/<ip>/<port> > ~/.bashrc

My question is: Is there a way to mimic the capabilities of nc -l <port> in my first line with /dev/tcp instead of nc?

The machines I'm working on are extremely hardened lab/sandbox environment RHEL (no ssh, no nc, no LDAP, no yum, I can't install new software, and they are not connected to the internet)

Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
h3rrmiller
  • 13,235

5 Answers5

57

Unfortunately it's impossible to do with just bash. /dev/tcp/<ip>/<port> virtual files are implemented in the way that bash tries to connect to the specified <ip>:<port> using connect(2) function. In order to create listening socket, it would have to call bind(2) function.

You can check this by downloading bash sources and looking at it. It is implemented in lib/sh/netopen.c file in _netopen4 function (or _netopen6, which also supports IPv6). This function is used by wrapper function netopen from the same file, which in turns is directly used in file redir.c (redir_special_open function) to implement this virtual redirection.

You have to find some other application that can create listening socket on your machine.

  • 1
    +1 the bash allows to create the client socket but the server socket you can use nc or can be implemented with perl or c, in fact server process will loop accepting connections and spawning processes or creating threads or it can accept only one connection by one – Nahuel Fouilleul Oct 04 '12 at 19:36
  • 2
    @NahuelFouilleul: That is not entirely correct. You can process a lot of clients with just one thread/process using so called "asynchronious" or "event driven" network programming (try googling for select() function and how it can be used in network programming). In many cases it's much better (faster) way of accepting a lot of clients. – Krzysztof Adamski Oct 04 '12 at 19:50
  • Thanks I didn't though of this solution – Nahuel Fouilleul Oct 04 '12 at 20:12
  • 4
    This is what xinetd is for. It does the listening, and spawns your arbitrary process/script for any incoming connections. With it, anything can become a TCP/IP server. –  Jan 23 '16 at 23:33
30

If Perl is installed (as it will be on a RHEL machine):

perl -MIO::Socket::INET -ne 'BEGIN{$l=IO::Socket::INET->new(
  LocalPort=>1234,Proto=>"tcp",Listen=>5,ReuseAddr=>1);
  $l=$l->accept}print $l $_' < ~/.bashrc

would work, unless a local firewall doesn't allow incoming connections to 1234.

If socat is installed:

socat -u - tcp-listen:1234,reuseaddr < ~/.bashrc

If zsh is installed:

zmodload zsh/net/tcp
ztcp -ld3 1234 && # start listening socket on fd 3
  ztcp -ad4 3 && # accept connection on fd 4
  ztcp -c 3 && # close the listening socket that is no longer needed
  cat < ~/.bashrc >&4 && # send the data
  ztcp -c 4 # close the communication socket to tell the other end we're finished
  • Shouldn't the last ztcp -c 4 command read 3? Otherwise great info, great tip. – dza Jul 17 '16 at 11:28
  • @dezza, see edit. The socket on fd 3 wasn't being closed indeed (though it would have been when the script terminates). We need to close the socket on fd 4 so the other end gets an EOF. – Stéphane Chazelas Jul 17 '16 at 11:36
4

There isn't a way to listen because listening is not in bash as Adamski pointed out.

But you don't need to listen on the client so you don't need netcat on the client to transfer files, for example:

## To send a file to the locked down computer: 
 ## Local server where you do have netcat 
cat ~/.bashrc | nc -l -q 1 -p 8998

 ## Remote locked down computer without netcat
cat < /dev/tcp/local.server.ip.addr/8998 > latest.bashrc 

## To grab a file from the locked down computer: 
 ## First - on the local server run 
nc -l -p 8998 -q 1 > remote.bashrc < /dev/null 

 ## Then on the locked down computer run: 
cat ~/.bashrc > /dev/tcp/local.server.ip.addr/8998 0<&1 2>&1
Adam D.
  • 462
0

You can use D. J. Bernstein's ucspi-tcp, see http://cr.yp.to/ucspi-tcp.html

  • Instead of just saying "you can use (this link)", a proper answer here would say "obtain (this software) from (here), install it using (these steps), then run it using (these options)" ... in order to answer the question, which was "Is there a way to mimic the capabilities of nc -l in my first line with /dev/tcp instead of nc?" – Jeff Schaller Sep 13 '20 at 13:26
-4

you can do that as you said, asking /dev/tcp, with bash:

</dev/tcp/host/port

if it runs immediately, it's listening, either way it times out

Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
  • 4
    No. You definitely didn't test this and if you did you must not understand the results. Your suggestion would open the socket (not listen) and redirect into whatever command you ran. A correct answer has already been found (almost 6 years ago...) so I'm not sure why you chose to necro this question. – h3rrmiller May 08 '18 at 04:05