I found this simple ncat so I did some enhancements on it and add some comments in it as well.
#!/usr/bin/rubyrequire 'optparse'require 'ostruct'require 'socket'​class Stringdef red; colorize(self, "\e[1m\e[31m"); enddef green; colorize(self, "\e[1m\e[32m"); enddef cyan; colorize(self, "\e[1;36m"); enddef bold; colorize(self, "\e[1m"); enddef colorize(text, color_code) "#{color_code}#{text}\e[0m" endend​​class NetCat​## Parsing options#def parse_opts(args)@options = OpenStruct.newopts = OptionParser.new do |opts|opts.banner = "Usage: #{__FILE__}.rb [options]"opts.on('-c', '--connect',"Connect to a remote host") do@options.connection_type = :connectendopts.on('-l', '--listen',"Listen for a remote host to connect to this host") do@options.connection_type = :listenendopts.on('-r', '--remote-host HOSTNAME', String,"Specify the host to connect to") do |hostname|@options.hostname = hostname || '127.0.0.1'endopts.on('-p', '--port PORT', Integer,"Specify the TCP port") do |port|@options.port = portendopts.on('-v', '--verbose') do@options.verbose = :verboseendopts.on_tail('-h', '--help', "Show this message") doputs optsexitendend​beginopts.parse!(args)rescue OptionParser::ParseError => errputs err.messageputs optsexitendif @options.connection_type == nilputs "[!] ".red + "No Connection Type specified"puts optsexitendif @options.port == nilputs "[!] ".red + "No Port specified to #{@options.connection_type.to_s.capitalize}"puts optsexitendif @options.connection_type == :connect && @options.hostname == nilputs "[!] ".red + "Connection type connect requires a hostname"puts optsexitendend​## Socket Management#def connect_socketbeginif @options.connection_type == :connect# Clientputs "[+] ".green + "Connecting to " + "#{@options.hostname}".bold + " on port " + "#{@options.port}".bold if @options.verbose == :verbose@socket = TCPSocket.open(@options.hostname, @options.port)else# Serverputs "[+] ".green + "Listing on port " + "#{@options.port}".bold if @options.verbose == :verboseserver = TCPServer.new(@options.port)server.listen(1)@socket = server.acceptprint "-> ".cyanendrescue Exception => eputs "[!] ".red + "Error [1]: " + "#{e}"exitend​end​## Data Transfer Management#def forward_datawhile trueif IO.select([],[],[@socket, STDIN],0)socket.closeend​# Send command if done from receiving upto 2-billions bytesbeginwhile (data = @socket.recv_nonblock(2000000000)) != ""STDOUT.write(data)print "-> ".cyanendexitrescue Errno::EAGAIN# http://stackoverflow.com/questions/20604130/how-to-use-rubys-write-nonblock-read-nonblock-with-servers-clientsend​beginwhile (data = STDIN.read_nonblock(2000000000)) != ""@socket.write(data)endexitrescue Errno::EAGAIN# http://stackoverflow.com/questions/20604130/how-to-use-rubys-write-nonblock-read-nonblock-with-servers-clientsrescue EOFErrorexitend​# Get all remote system socket(STDIN, STDOUT, STDERR) To my STDINIO.select([@socket, STDIN], [@socket, STDIN], [@socket, STDIN])end​end​## Run Ncat#def run(args)parse_opts(args)connect_socketforward_dataendendncat = NetCat.newncat.run(ARGV)
To listen
ruby ncat.rb -lvp 443
To connect
ruby ncat.rb -cv -r RHOST -p 443
Again from Hood3dRob1n a standalone [RubyCat][3] which supports password protection for bind shell.