Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - The Swash

#71
Hola,

Hoy les traigo un pequeño análisis que le hice a este packer y bueno, también lo desempacamos!
Es mi primer unpacking y espero sepan disculparme los errores técnicos que dicho documento pueda tener.

Disfrutadlo!

Descarga:
https://dl.dropbox.com/u/26610132/Estudio%20y%20desempaquetado%20RDG%20PolyPack%20por%20The%20Swash.rar

Un saludo,
Iván Portilla.
#72
Hola,

En la web de karmany seguramente pudiste ver un documento que he referenciado "Ejemplo de infección con TLS" pero no es exactamente lo mismo. Este artículo acompaña como información al código que es mostrado como un modelo de infección.

Un saludo,
Iván Portilla.
#73
Hola,

Bueno chicos vengo a compartir con vosotros la primera entrada que hago en un blog el cual ahora administro y escribo, vamos esta sigue siendo mi comunidad pero es la primera entrada que hago. Espero les sea de utilidad y bueno a leer :)

Esta entrada es sobre algo que me llevó un poco de esfuerzo y unos cuantos días de pruebas y pruebas para que funcione. Se trata sobre el "Thread Local Storage" que es un directorio de los ejecutables de Microsoft Windows que hace parte de la estructura PE.

¿Que nos dice la documentación oficial sobre el Thread Local Storage?
Cito traduciendo:
CitarLa sección ".tls" proporciona soporte al PE y COFF de almacenamiento local de subprocesos estáticos. TLS es una clase de almacenamiento especial que Windows soporta con el que objetos de datos no son automáticos (estáticos), sin embargo es local a cada hilo que se ejecuta. Por lo tanto cada hilo puede tener un valor diferente para cada variable declarada mediante el uso de TLS.

Si nos apoyamos en lo que conocemos, podemos decir simplemente que es una rutina que sirve para inicializar los valores de objetos estáticos. Dichos valores se deben inicializar antes de la ejecución del programa y he aquí el porqué se ejecutan antes que el punto de entrada del ejecutable.

Miremos su "estructura" y con seguridad veremos algo que aprovechar:
struct Thread_Local_Storage
{
    DWORD: RawDataStartVA;
    DWORD: RawDataEndVA;
    DWORD: AddressOfIndex
    DWORD: AddressOfCallBacks;
    DWORD: SizeOfZeroFill;
}


Hablemos de algunos campos de su estructura, antes que nada recalco que los 4 primeros campos son direcciones virtuales.

  • RawDataStartVA: La dirección de inicio de la plantilla TLS. La plantilla es un bloque que es utilizado para inicializar la infor-mación TLS. El sistema copia todo de estos datos cada vez que un hilo es creado.
  • RawDataEndVA: La dirección del último byte de la información del TLS excepto para el relleno de ceros.
  • AddressOfIndex: El lugar que recibe el índice del TLS que el loader asigna. Esta ubicación es una sección de datos ordinaria por lo que se puede dar un nombre simbólico que sea ac-cesible al programa.
  • AddressOfCallBacks: Puntero a la serie de funciones TLS. El fin de la matriz se identifica por que la última entrada tiene valor nulo.
  • SizeOfZeroFill: El tamaño en bytes de la plantilla.
  • Characteristics: Reservado.

Los dos primeros campos son utilizados para delimitar la información con la cual inicializar, pero ¿Nosotros vamos a inicializar información?
No, nosotros vamos a aprovecharnos de la estructura y de dos campos suyos (AddressOfIndex y AddressOfCallBacks). Principalmente del segundo que corresponderá a un puntero a una matriz de direcciones que a cada dirección corresponde una función que se ejecutará para "inicializar información".
He aquí un pequeño gráfico para que les quede más claro:

Si nos vamos entendiendo entonces tendréis claro que no queremos inicializar objetos, pero queremos aprovechar que podemos ejecutar alguna rutina antes de que siquiera se ejecute la primera instrucción del programa, he aquí un método de infección que tiene ya su tiempo pero yo no conozco un ejemplar.

Teoría de una ¿infección?
Primero me gustaría aclarar unos detalles acerca de los "requerimientos" de una estructura TLS.
El campo AddressOfIndex debe encontrarse referenciado en una sección con permisos de lectura y escritura puesto que el "loader" de Windows tratará de escribir en él y en caso de no poder nos dará un lindo "ACCESS VIOLATION ON WRITTING". Garantizada la posibilidad de escritura en este campo tenemos casi todo, nos resta referenciar el puntero de AddressOfCallBacks que apuntará a una matriz de direcciones de 4 bytes, las cuales cada es una función distinta que se ejecutará, debéis recordar que el final de estas direcciones será un DWORD nulo.

Teoría:
Nosotros podemos ejecutar alguna rutina que más bien se conocen como "shellcodes" la cual ejecutará una acción. Imagínate poder descargar y ejecutar algo, o modificar el mismo ejecutable, y más. Todo legítimamente y solo porque "inicializamos" objetos. Bueno entonces os comento lo que debéis hacer:

  • Agregando la shellcode: Necesitaremos agregar en alguna parte del ejecutable la rutina que queremos que ejecute, hay opciones como crear una sección nueva, expandir y abrirnos un espacio en una sección u otras alternativas como aprovecharnos de una pequeña "indocumentación" y ejecutarnos en la cabecera del ejecutable. Por limpieza sería mucho mejor agregar una sección pero estaríamos dando referencia muy fácil a donde nos encontramos y creo que el método que utilicéis para agregar la shellcode depende de vuestros fines.
  • Agregando directorio TLS: Para que podamos realizar esto deberemos agregar la estructura ya mencionada y en caso de existir tan solo agregar una referencia a nuestra rutina en la matriz de AddressOfCallBacks. Debes tener muy presente que los campos más importantes son AddressOfCallBacks & AddressOfIndex, si ignoramos cualesquiera podemos contar con que no funcionará. El directorio se encuentra en la décima entrada de IMAGE_DATA_DIRECTORY y el tamaño de dicha estructura es 0x20 bytes.

Teoría, teoría y la práctica ¿qué?
Bueno, bueno como mi idea no es repetir artículos que ya escribí voy a darles unas herramientas entre ellas información que os dará más idea de todo esto. Añado un enlace a 3 documentos que hablan sobre el tema y además una sorpresa después de las imágenes.


Ejemplo de infección práctico-teórico con TLS:
https://dl.dropbox.com/u/26610132/TLS.rar

Tutorial del formato PE en español basado en el PECOFF:
https://dl.dropbox.com/u/26610132/Formato%20de%20ficheros%20ejecutables%20_Formato%20PE_.pdf

Documentación oficial de Microsoft sobre el PE - PECOFF:
http://msdn.microsoft.com/en-us/library/windows/hardware/gg463119.aspx

Imágenes:



Tal vez te hayas fijado en la imagen de OllyDBG y te preguntes ¿por qué ese return a NTDLL?
Bueno, pues es parte de la carga del ejecutable el lanzar la rutina que ejecute nuestro TLS así que terminada la ejecución de nuestras rutinas terminará de cargar el ejecutable y lo lanzará, por ello es que se ejecuta antes que el punto de entrada. IDA detectará que hay TLS y he ahí la imagen.
¿Y la primera imagen de qué es?
Bueno es un prototipo de un archivo que infecta a los archivos ejecutables de su mismo directorio.

¿Recuerdas que te dije que yo no conocía ejemplares?
El principal objeto de este artículo es compartir un pequeño ejemplar programado en MASM, seguramente os puede servir mucho para su estudio y bueno, es un ejemplar así que hay muchas cosas para tener en cuenta demás.

Código (asm) [Seleccionar]

; #################################################
; # Ejemplo de infección de ejecutables con TLS
; # Programado por Iván Portilla
; # Viernes, 8 de junio de 2012
; # http://reversingcode.com
; # Agradecimientos: Shaddy, Guan de dio & Lelouch 
; #################################################


Código fuente:
https://dl.dropbox.com/u/26610132/infection.asm

Hasta la próxima.

Un saludo,
Iván Portilla.
#74
Hola,

Amigo tienes un problema en el condicional, las operaciones deben estar delimitadas por paréntesis, debes operar el "=" y luego los operadores binarios. Por ejemplo:
Código (cpp) [Seleccionar]
if ((xd = xd) && (zz = zz))

Un saludo,
Iván Portilla.

Código (cpp) [Seleccionar]
#include <iostream>
int main()
{
enum Meses { enero, febrero, marzo, junio, julio, agosto};

Meses ahora;
ahora = enero;

if ((ahora == enero) || (ahora == febrero) || (ahora = (Meses)2))
std::cout << "\nEstamos en invierno.\n";

else
std::cout << "Estamos en verano.\n";
std::cin.get();
return 0;
}


PD: No me fijé que estaba resuelto, sabedme disculpar.
#75
Ingeniería Inversa / Re: Anti breakpoint?
4 Junio 2012, 03:37 AM
Hola,

Algún día leí algo al respecto y constaba y verificar que determinadas partes de tu "memoria" no tuviesen un 'CC = INT 3' que es lo que ponen los breakpoints. En lenguajes como C o Pascal se haría muy fácil puesto que tienes punteros.
Ahora pueda que se trate de otra cosa así que espera más opiniones.

Un saludo,
Iván Portilla.
#76
Hola,

@_Enko muchas gracias y tienes razón, la sintaxis que utilicé es correspondiente a FASM. En realidad llevaba mucho sin utilizar MASM y me he confundido de manera enorme.

@Nox muchas gracias todo me ha quedado claro y funcionando.

Un saludo a ambos,
Iván Portilla.
#77
Hola,

Hoy vengo a molestaros con una pequeña consulta y es referido a MASM, y es la siguiente:
Yo tengo un número de funciones que hice y quisiera poder hacer un solo archivo que contenga esas funciones para posteriormente incluirlo en mis otros proyectos. Mi duda recae en que mis funciones van así:

Código (asm) [Seleccionar]
proc MyFunc1, Param..

end proc


Pero no he logrado que funcione o no al menos con un include MyProcs.asm.
Creo que debo declarar de alguna forma las funciones en cabecera o algo, si alguien sabe agradecería me deis una pequeña manita.

Un saludo,
Iván Portilla.
#78
Hola,

Te explico:
Tú vas a cambiar de posición ".reloc" y ".data", el 0x1000 que ahora vale el PointerToRawData de ".reloc" sale de donde estaba ubicado ".text" recuerda que ahí es justamente donde finaliza la cabecera y empieza la primera sección.

En cuanto a lo otro:
0xA800 %(modulo, residuo) 0x200 = 0. Entonces es múltiplo.

Un saludo,
Iván Portilla.
#79
Hola,

Creo que me equivoque en unos detalles, aquí te dejo el código que estimo te debe funcionar, pero no tengo Visual Studio, yo lo compilo con MinGW.

Un saludo,
Iván Portilla.

#include <windows.h>
typedef HRESULT (WINAPI* UrlMkSetSessionOption)(DWORD dwOption, LPVOID Buffer, DWORD dwBufferLength, DWORD dwReserved);


DWORD UChange(PCHAR Variable)
{
    HANDLE DLL;
    HRESULT Result;
    DWORD ResultFunc = 0;
    UrlMkSetSessionOption _UrlMkSetSessionOption;

    DLL = LoadLibrary("urlmon.dll");
    _UrlMkSetSessionOption = (UrlMkSetSessionOption)GetProcAddress(DLL, "UrlMkSetSessionOption");

    if (_UrlMkSetSessionOption != NULL)
    {
        Result = _UrlMkSetSessionOption(0x10000001, Variable, lstrlenA(Variable), 0);
        if (Result == S_OK)
            ResultFunc = 0;
        else if(Result == E_INVALIDARG)
            ResultFunc = -1;
    }
    else
        ResultFunc = -1;

    return ResultFunc;
}


int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
// TODO: Place code here.
UChange("LOL");
return 0;
}
#80
Hola,

Paso de afán a programar la función pero no tuve tiempo de probar bien. En teoría debe funcionar, me cuentas.

Un saludo,
Iván Portilla.

#include <windows.h>
HRESULT (WINAPI * UrlMkSetSessionOption)(DWORD dwOption, LPVOID Buffer, DWORD dwBufferLength, DWORD dwReserved);


DWORD UChange(PCHAR Variable)
{
    HANDLE DLL;
    HRESULT Result;
    DWORD ResultFunc = 0;

    DLL = LoadLibraryA("urlmon.dll");
    UrlMkSetSessionOption = GetProcAddressA(DLL, "UrlMkSetSessionOption");

    if (UrlMkSetSessionOption != NULL)
    {
        Result = UrlMkSetSessionOption(0x10000001, Variable, lstrlenA(Variable), 0);
        if (Result == S_OK)
            ResultFunc = 0;
        else if(Result == E_INVALIDARG)
            ResultFunc = -1;
    }
    else
        ResultFunc = -1;

    return ResultFunc;
}