Tema destacado: [Overclocking] Récords de overclock del foro
Autor
|
Tema: Detectar inyecciones en procesos (Leído 3,226 veces)
|
|
Hendrix
|
Y el checksum tiene que estar en una base de datos/fichero y sería una para cada version de SO(porque puede que al cargarla tu tambien este hookeada), en este caso tambien valdría buscar los bytes por un salto. Y quizás haya tambien alguna manera de desinfectarse on-the-fly? en el mismo proceso es facil, pero desde otro proceso no se, bueno siempre se podría hookear y bypasear ReadProcessMemory, que para eso es un rootkit. Coneso tu desde tu proceso no verias ningun hook
Mi cito a mi mismo: En caso del API Hooking a nivel de usuario Evidentemente si ya metemos modo Kernel de por medio el metodo de detección ya se complica más. Para lo del chechsum no hace falta una BD. con la dirección de inicio y el tamaño de la API ya nos vale. Lo que tendríamos que hacer sería cargar la Dll en donde se encuentra la API y, dentro de un buffer, guardar el contenido de la API y luego la comparamos. Si existen cambios, la podemos sobrescribir en la posición del proceso (Como si hicieramos un Copiar&Pegar de la API sobre la del proceso). Todo eso, evidentemente, en modo usuario. Para detectar hooks desde un driver, aquí tienes un artículo que escribí en el blog oficial de elhacker.net ( aquí). Un Saludo 
|
|
|
|
|
En línea
|
"Todos los días perdemos una docena de genios en el anonimato. Y se van. Y nadie sabe de ellos, de su historia, de su peripecia, de lo que han hecho, de sus angustias, de sus alegrías. Pero al menos una docena de genios se van todos los días sin que sepamos de ellos". - Juan Antonio Cebrián
|
|
|
|
|
|
Hendrix
|
 yo me refería también en modo usuario Pues en modo usuario, a no ser que el "Rootkit" inyecte código en tu proceso, y cargando siempre la Dll original, siempre vas a obtener la "copia" de la API correcta y lo vas a poder reparar 
|
|
|
|
|
En línea
|
"Todos los días perdemos una docena de genios en el anonimato. Y se van. Y nadie sabe de ellos, de su historia, de su peripecia, de lo que han hecho, de sus angustias, de sus alegrías. Pero al menos una docena de genios se van todos los días sin que sepamos de ellos". - Juan Antonio Cebrián
|
|
|
biribau
Desconectado
Mensajes: 181
|
a ver, igual estoy un poco espeso  , pero si en cada proceso hookeas loadlibrary puedes parchear las apis en tiempo de carga, luego hookeas toda la historia de crear procesos para poder hookear loadlibrary en cada proceso nuevo que se cree. Con esto todos los procesos del sistema tienen hookeada loadlibrary, cada libreria que se llame kernel32 pongamos, le parcheamos el hook a la funcion que queramos, luego ven la misma libreria todos, y en todos esta el hook!, luego necesitarías el checksum a priori, porque sino el checksum de la api parcheada es el mismo que el checksum de la misma api en otro proceso porque tambien se parcheo. Esto se puede hacer todo en user mode
|
|
|
|
|
En línea
|
|
|
|
bizco
Desconectado
Mensajes: 698
|
Pues se lee en disco y problema solucionado.
|
|
|
|
|
En línea
|
|
|
|
biribau
Desconectado
Mensajes: 181
|
Pues se lee en disco y problema solucionado.
Touché 
|
|
|
|
|
En línea
|
|
|
|
biribau
Desconectado
Mensajes: 181
|
Pues se lee en disco y problema solucionado.
Touché  No coño, también se puede hookear la lectura de ficheros, jajaja, hoy estoy lento
|
|
|
|
|
En línea
|
|
|
|
|
Hendrix
|
a ver, igual estoy un poco espeso  , pero si en cada proceso hookeas loadlibrary puedes parchear las apis en tiempo de carga. Losp rocesos, al iniciarse no usan LoadLibrary para cargar las Dll's que van a usar, lo carga el loader de Windows leyendo la IAT del archivo a ejecutar. Con esto todos los procesos del sistema tienen hookeada loadlibrary, cada libreria que se llame kernel32 pongamos, le parcheamos el hook a la funcion que queramos, luego ven la misma libreria todos, y en todos esta el hook! Para que todos los procesos tengan el hook en una API, tienes que inyectar codigo/dll en dicho proceso para que lo hookee, ya que cada proceso se va a iniciar con la Dll "limpia" (ya que los hooks son en memoria, no en disco, donde serian de forma permanente). Advertencia - mientras estabas escribiendo, fueron publicadas 2 respuestas. Probablemente desees revisar tu mensajePues se lee en disco y problema solucionado. Exacto, en memoria no te hace falta transformar direcciones virtuales a físicas (reales), cosa que tendrás que hacer si lo lees en disco... Advertencia - mientras estabas escribiendo, fueron publicadas 2 respuestas. Probablemente desees revisar tu mensajeNo coño, también se puede hookear la lectura de ficheros, jajaja, hoy estoy lento Pues llamas directamente a NtOpenFile, que seguro que si no hay rootkit en modo kernel no te lo Hookea  Un Saludo 
|
|
|
|
|
En línea
|
"Todos los días perdemos una docena de genios en el anonimato. Y se van. Y nadie sabe de ellos, de su historia, de su peripecia, de lo que han hecho, de sus angustias, de sus alegrías. Pero al menos una docena de genios se van todos los días sin que sepamos de ellos". - Juan Antonio Cebrián
|
|
|
bizco
Desconectado
Mensajes: 698
|
Exacto, en memoria no te hace falta transformar direcciones virtuales a físicas (reales), cosa que tendrás que hacer si lo lees en disco...
No hay que transformar nada, hablo de leer los bytes correspondientes a la funcion.
|
|
|
|
|
En línea
|
|
|
|
biribau
Desconectado
Mensajes: 181
|
Losp rocesos, al iniciarse no usan LoadLibrary para cargar las Dll's que van a usar, lo carga el loader de Windows leyendo la IAT del archivo a ejecutar.
Ya, pero usan createprocess, el proceso es asi: partimos de todos los procesos del sistema hookeados(supuesto) cada vez que se llama createprocess(que esta hookeado) en el nuevo proceso tras cargarlo, inyectamos el hook, y hookeamos todo(tirando de loadlibrary y getprocaddress por ejemplo, no se cargaron con loadlibrary sino el loader de windows, pero antes de que empiece a ejecutarse nosotros ya estamos inyectados) todos los procesos han de ser creado de otro proceso, como todos estaban hookeados el nuevo tambien por lo descrito anteriormente Pues llamas directa mente a NtOpenFile, que seguro que si no hay rootkit en modo kernel no te lo Hookea  NtOpenFile no la puedes hookear? yo creo que puedes todo menos cualquier cosa que sea solo para modo privilegiado, las Zw*
|
|
|
|
|
En línea
|
|
|
|
|
Hendrix
|
Exacto, en memoria no te hace falta transformar direcciones virtuales a físicas (reales), cosa que tendrás que hacer si lo lees en disco...
No hay que transformar nada, hablo de leer los bytes correspondientes a la funcion. Exacto, pero para localizar dichos bytes, si sabes que por ejemplo la API MessageBoxExA carga en (me lo invento) 74000C3E, tendrás que obtener el offset inicial "real" en donde la API empieza dentro del fichero. RVA (relative virtual address). In an image file, the address of an item after it is loaded into memory, with the base address of the image file subtracted from it. The RVA of an item almost always differs from its position within the file on disk (file pointer).
In an object file, an RVA is less meaningful because memory locations are not assigned. In this case, an RVA would be an address within a section (described later in this table), to which a relocation is later applied during linking. For simplicity, a compiler should just set the first RVA in each section to zero.
VA (virtual address). Same as RVA, except that the base address of the image file is not subtracted. The address is called a “VA” because Windows creates a distinct VA space for each process, independent of physical memory. For almost all purposes, a VA should be considered just an address. A VA is not as predictable as an RVA because the loader might not load the image at its preferred location.
Advertencia - mientras estabas escribiendo, una nueva respuesta fue publicada. Probablemente desees revisar tu mensaje. Ya, pero usan createprocess, el proceso es asi: partimos de todos los procesos del sistema hookeados(supuesto) cada vez que se llama createprocess(que esta hookeado) en el nuevo proceso tras cargarlo, inyectamos el hook, y hookeamos todo(tirando de loadlibrary y getprocaddress por ejemplo, no se cargaron con loadlibrary sino el loader de windows, pero antes de que empiece a ejecutarse nosotros ya estamos inyectados) todos los procesos han de ser creado de otro proceso, como todos estaban hookeados el nuevo tambien por lo descrito anteriormente Todo lo que te e comentado anteriormente, parte de que el programa "reparador" no es esté hookeado, evidentemente  NtOpenFile no la puedes hookear? yo creo que puedes todo menos cualquier cosa que sea solo para modo privilegiado, las Zw* Cuando me referí a Nt me referí a la API NtOpenFile que es una API nativa (Zw es solo un "alias" de esta, aquí lo explica perfectamente: http://ivanlef0u.nibbles.fr/repo/windoz/Nt_vs_Zw.txt). Un Saludo 
|
|
|
|
|
En línea
|
"Todos los días perdemos una docena de genios en el anonimato. Y se van. Y nadie sabe de ellos, de su historia, de su peripecia, de lo que han hecho, de sus angustias, de sus alegrías. Pero al menos una docena de genios se van todos los días sin que sepamos de ellos". - Juan Antonio Cebrián
|
|
|
bizco
Desconectado
Mensajes: 698
|
Exacto, pero para localizar dichos bytes, si sabes que por ejemplo la API MessageBoxExA carga en (me lo invento) 74000C3E, tendrás que obtener el offset inicial "real" en donde la API empieza dentro del fichero.
Para eso se lee el fichero, no hay que hacer ninguna conversion. yo leo los primeros bytes de la funcion en disco.
|
|
|
|
|
En línea
|
|
|
|
biribau
Desconectado
Mensajes: 181
|
Todo lo que te e comentado anteriormente, parte de que el programa "reparador" no es esté hookeado, evidentemente  Ah! pero un rootkit aunque sea user mode no es tan "atento" con nosotros. Yo sólo digo cómo en un sistema infectado por uno puede ser imposible sin salir de user mode escapar de su "ilusión" de normalidad Evidentemente si no esta hookeado tienes razon en todo NtOpenFile no la puedes hookear? yo creo que puedes todo menos cualquier cosa que sea solo para modo privilegiado, las Zw* Link roto. Si no estoy equivocado no son exactamente lo mismo, puedes compararlas en ntroskrnl, las Nt* son para ser llamadas desde user land, saltan a ring 0 con sysenter. Las Zw* proveen el mismo servicio pero para drivers y son para ser llamadas desde modo privilegiado, no se si implica salto de privilegio o alguna interrupcion... tendría que mirarlo. Supongo que la gestión de memoria y de argumentos para ambas podría "de" cambiar, ya que en modo usuario no deberias de poder comprometer el sistema y en un driver sí. Un Saludo  Un saludo, hombre! donde han quedado mis modales  Exacto, pero para localizar dichos bytes, si sabes que por ejemplo la API MessageBoxExA carga en (me lo invento) 74000C3E, tendrás que obtener el offset inicial "real" en donde la API empieza dentro del fichero.
Para eso se lee el fichero, no hay que hacer ninguna conversion. yo leo los primeros bytes de la funcion en disco. En esto me pierdo, para que se necesita la direccion en la que va a ser cargada? las dll de sistema no son relocalizables(relocatables)... oh si?
|
|
|
|
|
En línea
|
|
|
|
|
Hendrix
|
Ah! pero un rootkit aunque sea user mode no es tan "atento" con nosotros. Yo sólo digo cómo en un sistema infectado por uno puede ser imposible sin salir de user mode escapar de su "ilusión" de normalidad Evidentemente si no esta hookeado tienes razon en todo
Para estos entornos, sería conveniente que nuestra aplicación guardase en su codigo, las copias del codigo de la API's a usar y las reparase si estuvieran dañadas, o de lo contrario, hacer como dijo ctlon, leer desde disco y repararlo. Link roto. Si no estoy equivocado no son exactamente lo mismo, puedes compararlas en ntroskrnl, las Nt* son para ser llamadas desde user land, saltan a ring 0 con sysenter. Las Zw* proveen el mismo servicio pero para drivers y son para ser llamadas desde modo privilegiado, no se si implica salto de privilegio o alguna interrupcion... tendría que mirarlo. Supongo que la gestión de memoria y de argumentos para ambas podría "de" cambiar, ya que en modo usuario no deberias de poder comprometer el sistema y en un driver sí. Aqui tienes el link, el punto del final sobra http://ivanlef0u.nibbles.fr/repo/windoz/Nt_vs_Zw.txtLo que comentas sobre las diferencias de Nt* con Zw* son correctas, yo me referia a llamar directamente a las direcciones en modo kernel de las API's. Mira este código de ejemplo: #include <windows.h> #include <stdio.h> typedef struct _LSA_UNICODE_STRING { USHORT Length; USHORT MaximumLength; PVOID Buffer; } LSA_UNICODE_STRING, *PLSA_UNICODE_STRING; typedef LSA_UNICODE_STRING UNICODE_STRING, *PUNICODE_STRING; typedef DWORD (CALLBACK* RTLANSISTRINGTOUNICODESTRING)(PVOID, PVOID,DWORD); RTLANSISTRINGTOUNICODESTRING RtlAnsiStringToUnicodeString; typedef DWORD (CALLBACK* RTLFREEUNICODESTRING)(PVOID); RTLFREEUNICODESTRING RtlFreeUnicodeString; typedef DWORD (CALLBACK* ZWLOADDRIVER)(PVOID); ZWLOADDRIVER ZwLoadDriver; int LoadDriver(char * szDrvName, char * szDrvPath) { char szSubKey[200], szDrvFullPath[256]; LSA_UNICODE_STRING buf1; LSA_UNICODE_STRING buf2; int iBuffLen; HKEY hkResult; char Data[4]; DWORD dwOK; iBuffLen = sprintf(szSubKey,"System\\CurrentControlSet\\Services\\%s",szDrvName); szSubKey[iBuffLen]=0; dwOK = RegCreateKey(HKEY_LOCAL_MACHINE,szSubKey,&hkResult); if(dwOK!=ERROR_SUCCESS) return false; Data[0]=1; Data[1]=0; Data[2]=0; Data[3]=0; dwOK=RegSetValueEx(hkResult,"Type",0,4,(const unsigned char *)Data,4); dwOK=RegSetValueEx(hkResult,"ErrorControl",0,4,(const unsigned char *)Data,4); dwOK=RegSetValueEx(hkResult,"Start",0,4,(const unsigned char *)Data,4); GetFullPathName(szDrvPath, 256, szDrvFullPath, NULL); printf("Loading driver: %s\r\n", szDrvFullPath); iBuffLen = sprintf(szSubKey,"\\??\\%s",szDrvFullPath); szSubKey[iBuffLen]=0; dwOK=RegSetValueEx(hkResult,"ImagePath",0,1,(const unsigned char *)szSubKey,iBuffLen); RegCloseKey(hkResult); iBuffLen = sprintf(szSubKey,"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\%s",szDrvName); szSubKey[iBuffLen]=0; buf2.Buffer = (PVOID)szSubKey; buf2.Length = iBuffLen; RtlAnsiStringToUnicodeString(&buf1,&buf2,1); dwOK = ZwLoadDriver(&buf1); RtlFreeUnicodeString(&buf1); iBuffLen=sprintf(szSubKey,"%s%s\\Enum","System\\CurrentControlSet\\Services\\",szDrvName); szSubKey[iBuffLen]=0; RegDeleteKey(HKEY_LOCAL_MACHINE,szSubKey); iBuffLen=sprintf(szSubKey,"%s%s\\Security","System\\CurrentControlSet\\Services\\",szDrvName); szSubKey[iBuffLen]=0; RegDeleteKey(HKEY_LOCAL_MACHINE,szSubKey); iBuffLen=sprintf(szSubKey,"%s%s","System\\CurrentControlSet\\Services\\",szDrvName); szSubKey[iBuffLen]=0; RegDeleteKey(HKEY_LOCAL_MACHINE,szSubKey); iBuffLen=sprintf(szSubKey,"\\\\.\\%s",szDrvName); szSubKey[iBuffLen]=0; return true; } int main(int argc, char *argv[]) { printf("Load driver with ZwLoadDriver( )\r\n"); printf("Date: 8th May 2007\r\n"); printf("Modifed by: GaRY <wofeiwo_at_gmail_dot_com>\r\n\r\n"); if(argc != 3) { printf("Usage: %s <DriverFilename> <DriverPath>\r\n", argv[0]); exit(-1); } HMODULE hNtdll = NULL; hNtdll = LoadLibrary( "ntdll.dll" ); if ( !hNtdll ) { printf( "LoadLibrary( NTDLL.DLL ) Error:%d\n", GetLastError() ); return false; } RtlAnsiStringToUnicodeString = (RTLANSISTRINGTOUNICODESTRING) GetProcAddress( hNtdll, "RtlAnsiStringToUnicodeString"); RtlFreeUnicodeString = (RTLFREEUNICODESTRING) GetProcAddress( hNtdll, "RtlFreeUnicodeString"); ZwLoadDriver = (ZWLOADDRIVER) GetProcAddress( hNtdll, "ZwLoadDriver"); if(LoadDriver(argv[1], argv[2]) == false) return false; return true; } Sirve para cargar un driver llamando a ZwLoadDriver (Muchos AntiVirus dejan (o dejaban) cargar drivers de esta manera, pero los bloqueaban al cargarlos "normalmente" (creando el servicio y demás)). Este código llama directamente a la API ZwLoadDriver. En teoría el Rootkit no podría hookear dicha llamada ya que previamente hemos reparado nuestra LoadLibrary y GetProcAddress y una vez las tenemos limpias, cargamos esta librería y llamamos. De esta manera nos evitamos pasar por ciertas librerías que son más propensas a contener hooks en modo usuario (Kernel32.dll, User32.dll, etc.). Pero bueno, si reparamos los hooks no hacer falta hacer tanto tinglado  Un Saludo
|
|
|
|
|
En línea
|
"Todos los días perdemos una docena de genios en el anonimato. Y se van. Y nadie sabe de ellos, de su historia, de su peripecia, de lo que han hecho, de sus angustias, de sus alegrías. Pero al menos una docena de genios se van todos los días sin que sepamos de ellos". - Juan Antonio Cebrián
|
|
|
|
|
|
|