Docly Child

4.3.4.4. Staged vs Stageless payload con opciones avanzadas

Tabla de contenidos:

Stageg vs Stageless payload

Otro aspecto a destacar en los payload de Metasploit y que ya se ha comentado en puntos anteriores es la distinción entre los tipos staged y stageless. Esta diferencia suele pasar desapercibida en muchos manuales y no siempre es fácil encontrar bibliografía. En este punto se tratará de exponer de forma conceptual (*) esta diferencia junto a las opciones avanzadas en payloads, que suelen estar relacionadas con ambos tipos.

(*) Nota: Se añadirán referencias al final de la sección para quien quiera ampliar la parte más técnica, aunque en el bloque de Reverse Engineering y en el siguiente punto de Sistemas Operativos se tratará de profundizar en los fundamentos técnicos que subyacen en el proceso de explotación de una vulnerabilidad de tipo buffer overflow y como se ejecuta el código del payload en la memoria principal de la computadora.

Antes de nada, es necesario aclarar las convenciones en cuanto a la terminología empleada. La palabra en inglés stage hace referencia a etapas o fases así que puede deducirse de esto que un payload staged indica que el proceso de ejecución del payload se va a producir en fases mientras que si es stageless será lo contrario (menos fases). En los directorios de los módulos de tipo payload en Metasploit puede observarse otra distinción y es la separación entre stagers y stages (ver siguiente imagen). Por funcionamiento Metasploit tiene separadas las distintas fases en los que un payload puede operar y la combinación de ellas va a definir si se está usando un payload de tipo staged o stageless, aunque a la hora de seleccionar el payload en Metasploit esta distinción en el directorio va a ser transparente para el usuario.

Si se lista algún ejemplo del directorio de payloads se podrá observar como la parte de stagers contiene el  protocolo y forma de establecer la conexión entre target y atacante (reverse_tcp, bind_tcp…) mientras que en la parte de stages se tiene la función a desempeñar por el payload (obtener una shell, una consola de meterpreter, etc.).

				
					ls -l /usr/share/metasploit-framework/modules/payloads
				
			
Stagers y stages en directorio Metasploit

Para comprender mejor como funciona esto se puede empezar explicando de qué partes se compone un payload de tipo staged (por fases). Como se ha mencionado en los primeros párrafos y tal y como indica la imagen de arriba, las diferentes fases de ejecución de un payload staged se denominan por convención stage0, stage1, etc. En el proceso de explotación, el stage0 debería tener el menor tamaño posible y se encarga de una serie de funciones muy concretas que se describirán en los siguientes párrafos y entre las que se incluye el descargar un payload de mayor tamaño, que se corresponden con el resto de fases (stage1, stage2…). En Metasploit, el stager se corresponde al stage0, y el resto de funciones se denomina extensiones (abreviatura EXT). A diferencia de un payload staged, los de tipo stageless ignoran parte de las funciones del stage0 (o directamente no la incluyen) y el código de este ya incluye la suficiente programación con las EXT para ser ejecutado en memoria y obtener las funciones deseadas.

Para indicarle a Metasploit que tipo de payload usar conviene apreciar la parte final de los módulos, donde se incluye la referencia al protocolo y forma de comunicación (stager) y antes la función (stage: meterpreter, shell…). La distinción está en si estas dos partes vienen separadas por una barra o no (/). Si existe la barra, será un payload staged y si las dos partes están juntas será stageless. Aunque no siempre es así, muchos payloads de Metasploit admiten las dos modalidades como se indica en el siguiente gráfico:

Distinción en Metasploit entre staged y stageless payload

Volviendo al stager (o stage0), este surgió como una necesidad pues en determinados contextos de explotación el tamaño a ocupar en bytes por el payload dentro del paquete de datos que se envían al target requería ser el mínimo (teniendo en cuenta el tamaño del exploit). Además, las funciones de código que contiene el stager son en apariencia más inocuas para el sistema del target.

Viendo en detalle para un stager de tipo reverse detrás de escena, cuando el servicio vulnerable recibe la conexión, se invoca una función que contiene un búfer de pila que provocará un desbordamiento (buffer overflow). La máquina atacante (Metasploit) luego envía datos que son más grandes de lo que espera el objetivo. Estos datos contienen el stage0 y un pequeño fragmento de código específico de explotación. El código específico del exploit permite al atacante obtener control sobre una instrucción EIP[1] y redirigir la ejecución del proceso al stage0. A partir de aquí se produce lo siguiente (el proceso sería similar si hay un handler en escucha y se ejecuta el payload directamente):

[1] Una instrucción EIP dentro de un programa de software indica a la máquina cual es el siguiente segmento de código a ejecutar.

  1. El stage0 establece una conexión con Metasploit (habiendo o no handler). Este le indica al stage0 el tamaño en bytes del stage1 (payload largo) que se va a descargar.
  2. El stage0 asigna un bloque de memoria libre (función allocate buffer) de un tamaño suficiente para el stage1 y se produce la descarga de este desde Metasploit y se le pasa el control de ejecución (inyección en memoria).
  3. En función del sistema operativo o servicio de target explotado, el stage1 tomará el control y se ejecutará en la memoria. Por ejemplo para los sistemas Windows los stage1, stage2, etc. suelen ser librerías de funciones DLL que utilizan la técnica de Reflective DLL Injection para seguir con el proceso.
  4. Se pueden producir descargas de otras extensiones adicionales, negociación de encriptación en la comunicación y finalmente se establece la conexión entre Metasploit y target.

En la siguiente referencia web se puede encontrar un ejemplo de código escrito en lenguaje C para las funciones del stage0: https://www.cobaltstrike.com/blog/staged-payloads-what-pen-testers-should-know/

Ejemplo funciones de stage0

Uno de los ejemplos que se suelen utilizar más para explicar este proceso en un payload staged en Metasploit es  windows/meterpreter/reverse_tcp. Como ya se ha indicado en el punto 3 (arriba) de las funciones de un stage0, una vez se pasa el control al stage1 existen diferentes formas para seguir ejecutando las instrucciones y obtener la sesión. En el payload de Meterpreter para Windows los diferentes stage (fases) son librerías DLL que se autoejecutan en la memoria mediante Reflective DLL Injection. Las extensiones de esta versión de Meterpreter reciben el nombre de metsrv, stdapi y priv y se descargan en diferentes fases:

Extensiones Meterpreter para Windows

A continuación se indican algunas apreciaciones ya evidentes de por sí y por definición entre tipos de payload:

  • El tamaño en bytes de un payload staged es más pequeño que un stageless, pues este último contiene fragmentos de código adicionales (extensiones o stage). Como se observa en la imagen de abajo, cuando se está usando la modalidad staged el handler envía el paquete de datos con el contenido de las extensiones adicionales (Sending stage…).
Tamaño en bytes tipos de payload
  • Para los payload de tipo staged se recomienda emplear el parámetro EnableStageEncoding (yes) y StageEncoder para codificar el fragmento de datos enviado para el stage al igual que con la función –e de MSFvenom.
				
					msf (payload) > set EnableStageEncoding yes
msf (payload) > set StageEncoder <encoder>

				
			
  • Los payload de tipo stageless NO contienen siempre todas las extensiones del stage. En el caso de Meterpreter para Windows solo incluye la primera fase stage1 (metsrv). Se puede ampliar el número de extensiones a incluir en el payload con el parámetro EXTENSIONS, por ejemplo (también válido para MSFvenom):
				
					msf (payload) > set EXTENSIONS stdapi
				
			
  • Algunos inconvenientes (a parte de la diferencia de tamaño en bytes entre ambos tipos):
    • Stageless: Las funciones de un payload de tipo stageless son más susceptibles de alertar un sistema de antivirus. Además, se proporciona el código entero de las funciones que después pueden ser analizadas por la empresa de antivirus.
    • Staged: En un contexto de explotación de varios targets con un único handler receptor, el uso de un payload tipo staged conlleva mayor uso del intercambio de paquetes de datos entre Metasploit y target por la descarga de las extensiones. En sistemas de bajo banda de ancho de red o target con bajo rendimiento de computación puede significar que el proceso de explotación para obtener una sesión no se acabe finalizando.

Como ya se ha indicado, a continuación se ofrecen algunos sitios web que se han utilizado para escribir este punto y que además incluyen información complementaria para ampliar:

Cobalt Strike: Código en C de Stager, Librerías Metasploit para DLL Injection:

Docs Metasploit: Análisis ampliado de Meterpreter Stageless:

Buffered: Artículo de tipo académico con análisis de combinación de tipos de payload, reinicio de sesiones, etc.

4.3.4.4.1. Payload y Handler opciones avanzadas

A continuación se va a describir algunos de los parámetros y opciones avanzadas de los payload y el módulo handler de Metasploit para completar este bloque:

Handler Multisesión o sesión persistente

En la combinación básica entre un payload generado con Metasploit o MSFvenom y el módulo handler, una vez se ha establecido la sesión (shell o meterpreter) si por algún motivo se interrumpe la conexión entre Metasploit y el target, aparte de perder la sesión también se va a detener el proceso iniciado por el handler (comando jobs), por lo que este ya no se podrá mantener para recibir más peticiones.

Para que esto no ocurra y mantener activo el proceso de escucha de peticiones del handler, existe el parámetro del handler ExitOnSession. Esta opción también es útil si se ha distribuido algún tipo de malware generado con MSFvenom a varios targets, permitiendo establecer y mantener múltiples sesiones con los targets, aunque se pierda alguna de ellas en algún momento.

Parámetro ExitOnSession

Como se indica en la imagen superior, este parámetro es obligatorio y por defecto está indicado como true. Si se quiere operar en modo persistente o multisesión como se ha indicado, se deberá setear la opción a false. Como se puede observar en la imagen de abajo, después de obtener una sesión de Meterpreter y salir de esta, el proceso del handler se mantienen (jobs). Comentar que se ha usado el parámetro -j junto al comando exploit para poner el proceso iniciado por el handler en segundo plano, algo que resulta útil si se plantea obtener sesiones de diferentes targets:

				
					msf exploit(multi/handler) > set exitonsession false
msf exploit(multi/handler) > exploit -j

				
			
Sesión handler persistente

Parámetro función de salida (EXITFUNC)

Dentro de las opciones básicas de algunos payloads de Metasploit está el parámetro EXITFUN, que indica que método utilizar para establecer una técnica de salida limpia dentro del servicio o proceso explotado en el target una vez ejecutado la shellcode o payload en la memoria de modo que se cree la sesión y se mantenga activo el proceso inicial si es el caso (ver punto anterior en esta misma página para obtener una perspectiva del procedimiento). Evidentemente, esta función de salida puede variar si el payload se ha ejecutado directamente en el target y existe un handler a la espera o bien se ha producido una explotación de un servicio.

Parámetro EXITFUNC

Antes de ver las diferentes opciones conviene aclarar la diferencia entre proceso (process) e hilo o subproceso (thread) en términos de la ejecución de un software en la computadora, pues ambos conceptos tienen su representación dentro de las opciones de EXITFUNC. Para simplificar mucho, una computadora puede mantener diferentes procesos activos que vendrían a ser los diferentes programas y aplicaciones en ejecución, cada uno transfiriendo al procesador (CPU) diferentes instrucciones para llevar a cabo sus funciones. Un thread (hilo) como el nombre indica, vendría a ser un subproceso, es decir, unas instrucciones o iteraciones específicas dentro del proceso para optimizar el proceso de computación en la CPU. Se volverá a estos conceptos al analizar Sistemas Operativos y postexplotación.

Task Manager (análisis de procesos) en Windows

Ahora sí, viendo la descripción anterior las opciones disponibles principales serían (a parte de ninguna, que no es operativa):

  • Thread (thread): Se utiliza en una explotación de algún servicio en que la carga útil o payload se ejecuta como un subproceso dentro del proceso principal del servicio. Al ejecutarse el payload, el proceso del servicio explotado seguirá su funcionamiento habitual tras establecerse la sesión en un nuevo proceso.
  • Process (process): Recomendable usar con el handler.

Existe otra opción que es seh. Un SEH o controlador de excepciones estructurado es un sistema que permite controlar excepciones dentro del proceso de ejecución normal de las instrucciones en un proceso. Una excepción se podría dar cuando por ejemplo en determinadas secuencias de instrucciones, como la división por cero o un intento de acceder a una dirección de memoria no válida.

Opciones avanzadas payload Metasploit

Ya se ha comentado en los puntos iniciales que para los payloads de Metasploit también se pueden setear opciones avanzadas. Estos parámetros varían en función del tipo de payload, por lo que no se puede hacer un listado completo y exhaustivo que contemple todos los payload dentro del framework. Comentar también que en su mayoría no son obligatorios, y los que sí ya vienen con un valor estándar por defecto.

A continuación se lista algunos de los más comunes y que tienen una función más práctica agrupados por categoría. Las descripciones son simples traducciones en algunos casos con alguna anotación. En posteriores temas se verá en detalle y ejemplo de uso alguno de ellos (evasión, postexplotación, etc.):

Nombre

Defecto

Obligatorio

Descripción

AutoLoadStdapi            

true 

yes

Carga automáticamente la extensión stdapi.

AutoRunScript             

     

no

Un script para ejecutarse automáticamente en la creación de la sesión (puede ser una secuencia de comandos en bash o CMD).

AutoSystemInfo            

true 

yes

Captura automáticamente la información del sistema en la inicialización.

InitialAutoRunScript      

     

no

Una secuencia de comandos inicial para ejecutar en la creación de la sesión (antes de AutoRunScript).

HandlerSSLCert            

     

no

Ruta a un certificado SSL en formato PEM unificado para encriptar la transmisión de datos entre el target y Metasploit.

StagerVerifySSLCert

 

no

Verificar certificado en el stager.

PrependMigrate            

false

yes

Genera y ejecuta shellcode en un nuevo proceso.

PrependMigrateProc        

     

no

Proceso para generar y ejecutar shellcode (podría ser por ejemplo explorer.exe, svchost.exe, etc.).

ReverseAllowProxy         

false

yes

Permitir TCP inverso incluso con proxies especificados. Al volver a conectarse NO pasará a través de un proxy sino directamente a LHOST.

ReverseListenerBindAddress

     

no

La dirección IP específica para enlazar en el sistema local.

ReverseListenerBindPort   

     

no

El puerto al que vincularse en el sistema local si es diferente de LPORT. Ver práctica en https://buffered.io/posts/staged-vs-stageless-handlers/

EnableStageEncoding       

false

no

Codificar la carga útil de la segunda etapa.

StageEncoder              

     

no

Codificador para usar si se establece EnableStageEncoding.

StageEncoderSaveRegisters 

     

no

Registros adicionales para conservar en la carga útil por etapas si se establece EnableStageEncoding.

StageEncodingFallback     

true 

no

Volver a no codificar si el StageEncoder seleccionado no es compatible.

StagerRetryCount          

10

no

La cantidad de veces que el stager debe volver a intentarlo si falla la primera conexión.

StagerRetryWait           

5

no

Número de segundos para esperar el stager de etapas entre intentos de reconexión

SessionCommunicationTimeout

300

no

El número de segundos sin actividad antes de que una sesión deba eliminarse.

SessionExpirationTimeout  

604800

no

La cantidad de segundos antes de que la sesión se cierre por la fuerza.

SessionRetryTotal         

3600

no

Número de segundos de intento de reconexión por falla de red.

SessionRetryWait          

10

no

Número de segundos de espera entre intentos de reconexión.