IRB es un interprete interactivo de Ruby que le permite a un desarrollador ingresar comandos y bloques de código que posteriormente serán ejecutados por Ruby, se trata de una forma bastante sencilla de integrar lógica computacional en un interprete de linea de comandos. Estos conceptos básicos se indican en esta entrada con un único objetivo: Comprender las bases del funcionamiento de IRB de Ruby para poder ejecutar funciones de Scripting en MetaSploit Framework sobre maquinas comprometidas y con una sesión meterpreter.
Para ejecutar IRB solamente es necesario tener instalado Ruby y posteriormente desde linea de comandos ejecutar:
>irb irb(main):001:0> |
Posteriormente existen una serie de operaciones, funciones y objetos que pueden ser utilizados dentro del interprete incluyendo también, la declaración y ejecución de funciones
irb(main):001:0> puts «Hello» Hello=> nilirb(main):002:0> a = 3 ** 2 => 9 irb(main):003:0> b = 45 => 45 irb(main):004:0> c = 3 + 3 => 6 irb(main):005:0> d = 3 * 2 => 6 irb(main):006:0> Math.sqrt(a+b+c+d) => 8.12403840463596 irb(main):007:0> def funcionPropia irb(main):008:1> puts «Hola» irb(main):009:1> end => nil irb(main):010:0> funcionPropia Hola => nil irb(main):011:0> def funcionParametros(parametro) irb(main):012:1> puts «Hello» irb(main):013:1> puts «Parametro #{parametro}» irb(main):014:1> end => nil irb(main):015:0> funcionParametros(«arg1») Hello Parametro arg1 => nil irb(main):016:0> def manejoStrings(parametro = «queen») irb(main):017:1> puts «#{parametro.capitalize}» irb(main):018:1> end => nil irb(main):019:0> manejoStrings Queen => nil |
Como se puede ver en las instrucciones anteriores, el uso de este interprete es muy sencillo y bastante similar a la ejecución de Python en modo interprete (con algunas pequeñas diferencias sintácticas) como se puede ver, se pueden realizar operaciones matemáticas y declaración de funciones con y sin parámetros con la palabra reservada “def”, por otro lado, en Ruby la ejecución de cualquier instrucción siempre retorna un resultado, en este caso concreto algunas instrucciones como la declaración de una función simplemente retornan “nil” lo cual es normal.
Además de lo expuesto anteriormente, Ruby es un lneguaje de programación orientado a objetos similar a Java, C++, .NET, etc. También es posible declarar clases e instanciar objetos como estructuras de datos complejas.
irb(main):001:0> class Personairb(main):002:1> def initialize(nombre = «Daniel», apellidos =»Jans», edad=»45″, sexo=»Si, encantado»)irb(main):003:2> @nombre = nombre
irb(main):004:2> @apellidos = apellidos irb(main):005:2> @edad = edad irb(main):006:2> @sexo = sexo irb(main):007:2> end irb(main):008:1> def saluda irb(main):009:2> puts «Hola #{@nombre} #{@apellidos}» irb(main):010:2> puts «Como estas?» irb(main):011:2> end irb(main):012:1> end => nil irb(main):013:0> objeto = Persona.new() => #<Persona:0x7f087c212790 @edad=»45″, @apellidos=»Jans», @nombre=»Daniel», @sexo=»Si, encantado»> irb(main):014:0> objeto.saluda Hola Daniel Jans Como estas? => nil irb(main):031:0> class Persona irb(main):032:1> attr_accessor :nombre irb(main):033:1> end => nil irb(main):023:0> objeto.respond_to?(«nombre») => true irb(main):024:0> objeto.respond_to?(«saluda») => true irb(main):025:0> objeto.respond_to?(«apellidos») => false irb(main):026:0> objeto.respond_to?(«to_s») => true irb(main):027:0> objeto.to_s => «#<Persona:0x7f087c212790>» |
Hasta este punto, se han indicado algunas características adicionales en IRB relacionadas con programación orientada a objetos, en concreto en las primeras lineas se declara una clase que es una plantilla que puede ser instanciada posteriormente (instancia = objeto utilizable), luego sobre una instancia de dicha clase se pueden invocar los métodos declarados con el fin de obtener resultados. Si por alguna razón se desea modificar la clase, como por ejemplo para permitir que un atributo sea directamente accedido por una instancia, simplemente se indica nuevamente las instrucciones de creación de la clase. Finalmente es posible utilizar el método heredado “respond_to” para saber cuales métodos o atributos pueden ser invocados desde la instancia de un objeto dado.
Todo lo anterior es muy útil, sin embargo, a efectos prácticos resulta difícil programar de este modo, resulta mucho mas sencillo y eficiente utilizar un editor de texto normal, por esta razón desde IRB se pueden ejecutar scripts *.rb que contienen todas las instrucciones linea por linea y las ejecuta de modo secuencial como lo hacen prácticamente todos los lenguajes de programación por ejemplo, todo lo anterior puede resumirse (y extenderse) a lo siguiente
#!/usr/bin/env ruby class Personaattr_accessor :nombre attr_accessor :apellidos attr_accessor :listado def initialize(nombre = «Daniel», apellidos =»Jans», edad=»45″, sexo=»Si, encantado») @nombre = nombre @apellidos = apellidos @edad = edad @sexo = sexo end def saluda puts «Hola #{@nombre} #{@apellidos}» puts «Como estas?» end def miselanea if @listado.respond_to?(«each») and @listado.respond_to?(«join») @listado.each do |elemento| puts(«Elemento Ingresado: #{elemento}») @elementos = «#{@listado.join(«# «)}» end end puts «#{@elementos}» if @nombre.respond_to?(«capitalize») puts(«Hola: #{@nombre.capitalize}») end end end if __FILE__ == $0 objeto = Persona.new objeto.nombre=»Joshi» objeto.apellidos=»Josh» objeto.listado=[«Manzana»,»Limon»,»Fresa»,»Maracuya»,»Platano»,»Mango»] objeto.salida objeto.miselanea end |
El script anterior puede guardarse en un fichero con extensión *.rb por ejemplo, puede llamarse, “test.rb”. Ahora bien, la mayor parte del código de este script corresponde a los comandos anteriormente indicados desde IRB, sin embargo, hay algunas cosas adicionales que no se habían indicado anteriormente, en concreto interesa saber que el atributo “@listado” es un array de objetos, que posteriormente se pueden recorrer utilizando un ciclo “do” y cada uno de los elementos se va concatenando a una cadena final con todos los elementos contenidos en el listado y finalmente es interesante la parte final del script donde se indica el uso de la variable global de Ruby «__FILE__» la cual continúe solamente el fichero que se encuentra en ejecución, mientras que “$0” indica el fichero en ejecución actual, por lo tanto la condición anterior siempre se cumplirá y se encargará de instanciar e invocar los métodos de la clase anteriormente creada.
Para ejecutar el script anterior, se puede utilizar el comando “ruby” o el interprete “irb” en cualquiera de los dos casos el resultado será el mismo, solamente que con el interprete se verá como cada una de las lineas del script es cargada y procesada
>ruby test.rbHola Joshi Josh
Como estas? Elemento Ingresado: Manzana Elemento Ingresado: Limon Elemento Ingresado: Fresa Elemento Ingresado: Maracuya Elemento Ingresado: Platano Elemento Ingresado: Mango Manzana# Limon# Fresa# Maracuya# Platano# Mango Hola: Joshi |
Esta ha sido una introducción sobre IRB que permitirá comprender mejor el lenguaje de programación Ruby, lo que posteriormente será de gran ayuda a la hora de crear módulos, scripts e incluso exploits en MetaSploit Framework.