Emulating Netcat and connecting to bind shells

E

Eduardo Tongson

Hello folks,

I am creating some exploits written in Ruby. Most of my payloads are
TCP bind shells, Netcat works well for connecting to those bind
shells. But I thought, why not connect to the shell directly from Ruby
immediately after sending the payload. Currently I use this snippet
from a Ruby standard library sample I found somewhere:

"""
s = TCPsocket.open(host,port)
STDOUT.flush
while gets( )
s.write($_)
print(s.readline)
end
s.close
"""

Works, but is very limited compared to Netcat. Return only one line
(for example after an "ls"). One strange thing is that it hangs when I
send "cd /". No output and subsequent commands are not processed. "/"
and "cd" are OK. Metasploit has its own library for this kind of
stuff. I think it is called Metasploit Rex. Looking at the sources I
see some references to Rex::IO::Stream. I find it complex and I would
like to avoid something that needs external libraries.

Can the above snippet be improved? Is there a better way of emulating
Netcat? Is it possible to use Net::Telnet? Thanks everyone.

Eduardo Tongson
 
M

M. Edward (Ed) Borasky

Eduardo said:
Hello folks,

I am creating some exploits written in Ruby. Most of my payloads are
TCP bind shells, Netcat works well for connecting to those bind
shells. But I thought, why not connect to the shell directly from Ruby
immediately after sending the payload. Currently I use this snippet
from a Ruby standard library sample I found somewhere:

"""
s = TCPsocket.open(host,port)
STDOUT.flush
while gets( )
s.write($_)
print(s.readline)
end
s.close
"""

Works, but is very limited compared to Netcat. Return only one line
(for example after an "ls"). One strange thing is that it hangs when I
send "cd /". No output and subsequent commands are not processed. "/"
and "cd" are OK. Metasploit has its own library for this kind of
stuff. I think it is called Metasploit Rex. Looking at the sources I
see some references to Rex::IO::Stream. I find it complex and I would
like to avoid something that needs external libraries.

Can the above snippet be improved? Is there a better way of emulating
Netcat? Is it possible to use Net::Telnet? Thanks everyone.

Eduardo Tongson

I'm not at all familiar with "netcat", but if it's like most open-source
utilities, it probably has an internal library that you could interface
directly to Ruby.
 
D

Douglas Wells

Hello folks,

I am creating some exploits written in Ruby.

Hopefully those exploits are for good purposes, not bad. In any
case, your issues here are basic socket usage, so we'll address
them anyways.
Most of my payloads are
TCP bind shells, Netcat works well for connecting to those bind
shells. But I thought, why not connect to the shell directly from Ruby
immediately after sending the payload. Currently I use this snippet
from a Ruby standard library sample I found somewhere:

You haven't given us any indication of what facilities of netcat
you think are advantageous for your purposes, so I won't comment
on that. But, I will note that unless you're doing something much
more complicated than talking to a shell, simple use of ruby sockets
should suit your purposes.
s = TCPsocket.open(host,port)
STDOUT.flush
while gets( )
s.write($_)
print(s.readline)
end
s.close

Works, but is very limited compared to Netcat. Return only one line
(for example after an "ls"). One strange thing is that it hangs when I
send "cd /". No output and subsequent commands are not processed. "/"
and "cd" are OK.

I'm not sure why you would only get one line from ls, but maybe
that's part of your larger problem. Let's look particularly at
your complaint about "cd /". The problem here is almost certainly
that the prompt ($PS1 in Bourne-derived shells) is *not* sending
a New-Line, but your use of s.readline requires a New-Line before
it will return to you. Thus, you're in deadlock situation.

Fixing this can be done in various ways.

First, you can just asynchronous stream the data in both directions.
By this, I mean that you can just ignore the data coming from the
remote shell and just send the data that you (a priori) know needs
to be sent.

If you do need to act based upon the returned data, you still have
a couple of alternatives. For any of this, however, I'd recommend
that you switch to using the socket primitives directly and avoid
the higher-level write/readline type of methods. (See the ruby
socket documentation on recv and send.) It's not that you can't
do the work from IO objects, just that things will be easier to
understand and have less "magic" going on between you and the
remote system.

So, you could use a "go-ahead" mechanism. (See the early telnet
documents for a full explanation of this, e.g., RFC 854.) For
example, you could have the remote shell always send some token,
say '@', when it's done. Then you could wait for this before
sending data.

Beyond that level of solution, you probably need to run multiple
threads in your client side, in a manner analogous to what you
would do hen interacting with a local child process via the IO.popen
method. In this case you would have one thread examining data
read from the remote shell and sending state change information
to another thread, which would be sending the relevant data. See
examples for popen -- but remember that most examples of use of
popen will not be handling the problem with the lack of a New-Line.
You could also look at user-side telnet implementations, but here
it will be difficult to see the strategy amongst all the details
of character set translation and option negotiation.

Metasploit has its own library for this kind of
stuff. I think it is called Metasploit Rex. Looking at the sources I
see some references to Rex::IO::Stream. I find it complex and I would
like to avoid something that needs external libraries.

Sorry, never had occasion to look at them.
Can the above snippet be improved? Is there a better way of emulating
Netcat? Is it possible to use Net::Telnet? Thanks everyone.

See above.
Eduardo Tongson

- dmw
 
E

Eduardo Tongson

My exploits are only for 'educational' purposes. I will look into
using raw sockets as you suggested. Thanks Douglas.
 

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top