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)

2

5 Answers 5

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.

4
  • 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 Oct 4, 2012 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. Oct 4, 2012 at 19:50
  • Thanks I didn't though of this solution Oct 4, 2012 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, 2016 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
2
  • Shouldn't the last ztcp -c 4 command read 3? Otherwise great info, great tip.
    – dza
    Jul 17, 2016 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. Jul 17, 2016 at 11:36
3

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
1
  • This is a fantastic summary. Thanks!
    – likebike
    Jun 30, 2021 at 1:36
0

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

1
  • 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 <port> in my first line with /dev/tcp instead of nc?"
    – Jeff Schaller
    Sep 13, 2020 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

1
  • 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 8, 2018 at 4:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .