• Viernes 19 de Abril de 2024, 21:51

Autor Tema:  Duda direcciones modo Kernel  (Leído 2439 veces)

Zirrosis

  • Miembro activo
  • **
  • Mensajes: 97
    • Ver Perfil
Duda direcciones modo Kernel
« en: Jueves 26 de Febrero de 2009, 11:51 »
0
Hola, que tal estan??

Miren, tengo una duda. Es algo curioso, estoy intentando programar un manejador de procesos tipo ProcessExplorer, con una parte a modo usuario y otra en modo kernel. Me encontré con un inconveniente al ver que los antivirus y demás programas de seguridad, hookean la SSDT para implantar todo tipo de filtros, por lo que decidí sacar la dirección real de las API's que quiero utilizar desde el disco. Todo esto me funciona, lo que me pasa es que, al crear la función MyOpenFile con la dirección real de ZwOpenFile, al realizar la llamada no me funciona, pero es curioso, no me funciona si le paso los parámetros desde modo usuario a modo kernel, si en el modulo de kernel "harcodeo" la dirección y realizo lo siguiente:

MyOpenFile = (typeZwOpenFile)0x8....;

Si me funciona. El codigo de la función para finalizar el proceso:

Código: C
  1. void KillProc(int Pid)
  2. {
  3.     NTSTATUS status;
  4.     HANDLE hProcess = 0;
  5.    
  6.     CLIENT_ID cid1 ={(HANDLE)Pid, 0};
  7.     OBJECT_ATTRIBUTES attr ={(ULONG)sizeof(OBJECT_ATTRIBUTES),0, NULL, 0, NULL,NULL};
  8.    
  9.     status = MyOpenProcess(&hProcess, PROCESS_TERMINATE, &attr, &cid1);
  10.     DbgPrint("Handle: 0x%p",hProcess);
  11.     if (status == STATUS_SUCCESS)
  12.     {
  13.         status = MyTerminateProcess(hProcess, 0);
  14.         ZwClose(hProcess);
  15.     }
  16. }
  17.  

Y aquí el código de control de IOCTL's:

Código: C
  1. Stack=IoGetCurrentIrpStackLocation(Irp);
  2.  
  3.     switch(Stack->Parameters.DeviceIoControl.IoControlCode)
  4.     {
  5.         case Kill:
  6.             iBuffer = oBuffer = Irp->AssociatedIrp.SystemBuffer;
  7.             if(oBuffer && oBuffer)
  8.             {
  9.                if(Stack->Parameters.DeviceIoControl.InputBufferLength !=0)
  10.                {
  11.                     i = atoi(iBuffer);
  12.                     KillProc(i);
  13.                     s = STATUS_SUCCESS;
  14.                }
  15.             }
  16.             break;
  17.            
  18.         case Terminate:
  19.             iBuffer = oBuffer = Irp->AssociatedIrp.SystemBuffer;
  20.             if(oBuffer && oBuffer)
  21.             {
  22.                if(Stack->Parameters.DeviceIoControl.InputBufferLength !=0)
  23.                {
  24.                     i = atoi(iBuffer);
  25.                     MyTerminateProcess = (typeZwTerminateProcess)i;
  26.                     s = STATUS_SUCCESS;
  27.                }
  28.             }
  29.             break;
  30.         case Open:
  31.             iBuffer = oBuffer = Irp->AssociatedIrp.SystemBuffer;
  32.             if(oBuffer && oBuffer)
  33.             {
  34.                if(Stack->Parameters.DeviceIoControl.InputBufferLength !=0)
  35.                {
  36.                     i = atoi(iBuffer);
  37.                     MyOpenProcess = (typeZwOpenProcess)i;
  38.                     s = STATUS_SUCCESS;
  39.                }
  40.             }
  41.             break;
  42.     }
  43.    
  44.     Irp->IoStatus.Status = STATUS_SUCCESS;
  45.     IoCompleteRequest(Irp, IO_NO_INCREMENT);
  46.     return s;
  47.  

Alguien sabe a que se debe este error??

Saludos  ^_^   :beer:

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Duda direcciones modo Kernel
« Respuesta #1 en: Jueves 26 de Febrero de 2009, 12:15 »
0
Cita de: "Zirrosis"
Todo esto me funciona, lo que me pasa es que, al crear la función MyOpenFile con la dirección real de ZwOpenFile, al realizar la llamada no me funciona, pero es curioso, no me funciona si le paso los parámetros desde modo usuario a modo kernel, si en el modulo de kernel "harcodeo" la dirección y realizo lo siguiente:

Usando NtOpenFile no deberia funcionarte (esas son las direcciones que estan en la SSDT), solo en modo Usuario Nt y Zw son lo mismo.

Aca esta explicado muy bien todo el tema Nt vs Zw:
http://www.osronline.com/article.cfm?id=257
http://www.osronline.com/article.cfm?id=266

Y referencia previa: http://foro.elhacker.net/programacion_v ... ;msg882112  :P

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

Zirrosis

  • Miembro activo
  • **
  • Mensajes: 97
    • Ver Perfil
Re: Duda direcciones modo Kernel
« Respuesta #2 en: Jueves 26 de Febrero de 2009, 12:30 »
0
Al sacar la dirección de ZwOpenFile desde el disco y al listar la SSDT con el IceSword, las direcciones son las mismas, así que en teoría si lo tendría que llamar.

El problema esta en que el código no funciona si las direcciones son enviadas desde modo usuario, si no hay conexión entre modo usuario y kernel si funciona  :wacko:

Saludos  :beer:

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Duda direcciones modo Kernel
« Respuesta #3 en: Jueves 26 de Febrero de 2009, 12:41 »
0
Cita de: "Zirrosis"
Al sacar la dirección de ZwOpenFile desde el disco y al listar la SSDT con el IceSword, las direcciones son las mismas, así que en teoría si lo tendría que llamar.

Rapida comprobacion de que eso no es correcto:
0: kd> u nt!zwopenfile
nt!ZwOpenFile:
8082963c b874000000      mov     eax,74h
80829641 8d542404        lea     edx,[esp+4]
80829645 9c              pushfd
80829646 6a08            push    8
80829648 e8040e0400      call    nt!KiSystemService (8086a451)
8082964d c21800          ret     18h

0: kd> u nt!ntopenfile
nt!NtOpenFile:
808a3182 8bff            mov     edi,edi
808a3184 55              push    ebp
808a3185 8bec            mov     ebp,esp
808a3187 33c0            xor     eax,eax
808a3189 50              push    eax
808a318a 50              push    eax
808a318b 50              push    eax
808a318c 50              push    eax

0: kd> dd keservicedescriptortable
80885700  8082d450 00000000 0000011c 8082d8c4
80885710  00000000 00000000 00000000 00000000
80885720  00000000 00000000 00000000 00000000
80885730  00000000 00000000 00000000 00000000
80885740  00000002 00002710 bf80c0b6 00000000
80885750  baa78a80 f7335b60 862f064c 80a1f0c0
80885760  00000000 00000000 a16a2aa3 00000000
80885770  1c7164e3 01c99733 00000000 00000000

0: kd> dd 8082d450+0x74*4
8082d620  808a3182 808a1b3a 808fe748 8094db58
8082d630  8093fe2a 8091d41a 808f43fc 80916722
8082d640  80916386 808d33d2 8093d7fc 808ecb9c
8082d650  808f4688 80916740 809164f6 8093f744
8082d660  8096e14a 808f24ae 80920ae4 8091c72c
8082d670  8091c918 808e13da 809377ba 8089fed6
8082d680  8093f0e4 8093f0e4 80868bb6 809393ac
8082d690  8093a00c 808a2e64 808e760e 808a31b2

Como se puede observar en la SSDT, el servicio 0x74 que corresponde a OpenFile apunta a NtOpenFile.

Cita de: "Zirrosis"
El problema esta en que el código no funciona si las direcciones son enviadas desde modo usuario, si no hay conexión entre modo usuario y kernel si funciona  :wacko:

Esta explicado en el articulo que deje: en tu IOCTL el Previous Mode es User (1), entonces la funcion que estas llamando NtOpenFile procedera a comprobar los parametros que en este caso son de modo Kernel con lo cual dara una excepcion (controlada) y retornara el error correspondiente (comproba el eax que devuelve). Desde el driver entry tu Previous Mode es Kernel (0) entonces los parametros no se comprueban, se confia en los modulos de modo Kernel.

Tenes que usar la correcta ZwOpenFile asi el Previous Mode es el adecuado, ZwOpenFile termina llamando a NtOpenFile despues de, entre otras cosas, poner el Previous Mode a Kernel (0).

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

Zirrosis

  • Miembro activo
  • **
  • Mensajes: 97
    • Ver Perfil
Re: Duda direcciones modo Kernel
« Respuesta #4 en: Jueves 26 de Febrero de 2009, 13:09 »
0
De acuerdo, y como se obtendria la dirección de ZwOpenFile desde disco???

Actualmente estoy usando este metodo: http://www.rootkit.com/newsread.php?newsid=176

El cual me da las direcciones de Nt*

O se podria modificar el previous mode de otra manera??

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Duda direcciones modo Kernel
« Respuesta #5 en: Jueves 26 de Febrero de 2009, 13:25 »
0
Cita de: "Zirrosis"
De acuerdo, y como se obtendria la dirección de ZwOpenFile desde disco???

Tanto ZwOpenFile como ZwOpenProcess y ZwTerminateProcess estan exportadas, para obtener la direccion no tenes mas que llamar a MmGetSystemRoutineAddress. Si queres hacerlo del disco si o si no tenes mas que parsear el PE y trabajar con la tabla de exportacion ... ninguna de las dos te evitaria un inline hook ...

Cita de: "Zirrosis"
O se podria modificar el previous mode de otra manera??

Si, al menos dos maneras:

A. Efectuando la misma logica que Zw en Kernel (a la antigua es mas facil, con int):
Pseudo_ZwOpenFile:
    mov   eax, 74h
    lea   edx, [esp+4]
    int   2Eh
    ret   18h

El numero del servicio varia, lo podes conseguir de NTDLL.dll que siempre exporta todas las funciones existentes. Que yo sepa no es posible implementarla en x64.

B. Ejecutando el codigo en un hilo diferente, ya sea directa (PsCreateSystemThread) o indirectamente (work item). Esta manera es la mas limpia.

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

Zirrosis

  • Miembro activo
  • **
  • Mensajes: 97
    • Ver Perfil
Re: Duda direcciones modo Kernel
« Respuesta #6 en: Jueves 26 de Febrero de 2009, 19:24 »
0
Muchas gracias, eres una biblioteca andante!!!

Porque no trabajas para MS??? seguro que sabes más que algunos de los que trabajan hay....

Saludos y gracias Eternal!!!  :beer:  :beer:  :beer:

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Duda direcciones modo Kernel
« Respuesta #7 en: Jueves 26 de Febrero de 2009, 20:21 »
0
Cita de: "Zirrosis"
Muchas gracias, eres una biblioteca andante!!!

De nadas  B)

Cita de: "Zirrosis"
Porque no trabajas para MS??? seguro que sabes más que algunos de los que trabajan hay....

Principalmente por estar en USA  :devil: Igual donde trabajo hay gente ex-Microsoft y viceversa  :beer:

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

Zirrosis

  • Miembro activo
  • **
  • Mensajes: 97
    • Ver Perfil
Re: Duda direcciones modo Kernel
« Respuesta #8 en: Jueves 26 de Febrero de 2009, 22:43 »
0
Y se puede saber donde trabajas??? (Por MP si quieres).

Hay gente de Microsoft que trabaja desde España...

Lo dicho, muchas gracias  ^_^  :beer: