API para impedir la ejecución de ejecutables.

Iniciado por HCK., 21 Abril 2016, 10:25 AM

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

HCK.

Hola chic@s. He estado buscando una API para impedir la ejecución de ejecutables a la hora de abrir un EXE. Se que existe, puesto que ciertos AV la tienen para impedir que se ejecute malware, mostrando un mensaje de tipo (No se ha podido realizar la ejecución puesto que no es una aplicación Win32 válida) o algo a sí.

Y si no existe, debe ser un hook que hace el AV a la API encargada de la ejecución de procesos, impidiendolos... Puesto que los AV trabajan en ring0 y pueden hacerlo.

Si alguien me despeja la duda, lo agradeceria mucho. :huh:

Muchas gracias.

Eleкtro

#1
Hola

Lo primero de todo, nativamente hablando no existe ningún miembro en la API de Windows para bloquear la ejecución de un proceso de forma guiada, y un Antivirus es un producto programado por grupos de varios desarrolladores profesionales, lo que pretendo decir es que el algoritmo de bloqueo se elabora e implementa con el sudor y el esfuerzo de uno mismo, otra cosa es que tal vez pueda existir una API de terceros ya desarrollada para tal propósito (una API gratuita, o de pago), podría ser, pero al menos yo jamás la he visto.

Para impedir la ejecución de un executable tienes que llevar a cabo un api-hook (si o si) de la función CreateProcess y adjuntarlo a las instancias del explorer,
y entonces, al interceptar el precall de dicha función, podrás leer sus parámetros y así detectar la petición de creación del proceso a bloquear, notificar mediante eventos lo que quieras notificar, e ignorar el precall para no crear el proceso (si hookeas otras funciones, es posible que tambén debas interceptar el postcall, y modificar el valor correspondiente que debe ser devuelto, depende de como funcione cada función, valga la redundancia).


(luego también están las funciones ShellExecute y ShellExecuteEx, pero son unos wrappers de la función CreateProcess, y también está WinExec, de la que no estoy seguro si es un wrapper pero creo que no, aunque de todas formas no hay que darle mucha importancia a WinExec ya que es una función en deshuso que solo existe por motivos de compatibilidad con aplicaciones de 16-Bit)

Tienes al menos tres librerías populares para poner en práctica el api-hooking en .Net, Nektra Deviare, EasyHook, y Detours (C/C++);
Te las he nombrado por orden de preferencia personal y de complejidad, siendo Microsoft Detours la peor opción tratándose de .Net (para eso mejor desarrollar la app en C++), EasyHook es gratuita pero muy inestable y con una infinidad de bugs reportados sin corregir, y Nektra Deviare es una librería de pago (si uno no sabe encontrar...) mucho más eficiente que EasyHook y mucho más sencilla de utilizar ...dentro de lo que cabe en esta temática de la ingeniería inversa.

Sinceramente, este tipo de trabajo es de cosecha propia, puesto que hay que invertir bastante tiempo en investigar y documentarse en general sobre el comportamiento y el tipo de valores contenidos en los parámetros de "X" función que desees hookear, de todas formas, no me cuesta nada compartir este antiguo código que desarrollé y lo guardé, el cual precisamente sirve para prohibir/evitar la ejecución de un proceso (notepad.exe) utilizando la liberría de Nektra Deviare:

Código (vbnet) [Seleccionar]
Imports Nektra.Deviare2
Imports System.IO

Public NotInheritable Class Form1

   Public WithEvents SpyMgr As NktSpyMgr
   Public Hook As NktHook

   ' CreateProcess API reference:
   ' http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425%28v=vs.85%29.aspx
   ReadOnly libName As String = "kernel32.dll"
   ReadOnly funcName As String = "CreateProcessW" ' Unicode
   ReadOnly hookFlags As eNktHookFlags = eNktHookFlags.flgOnlyPreCall Or
                                         eNktHookFlags.flgAutoHookChildProcess

   ' Processes to attach the hook.
   ReadOnly processesToAttach As IEnumerable(Of Process) =
       Process.GetProcessesByName("explorer") '.Concat(Process.GetProcessesByName("cmd"))

   Private Sub Test() Handles MyBase.Load

       Me.SpyMgr = New NktSpyMgr()
       Me.SpyMgr.Initialize()

       Me.Hook = SpyMgr.CreateHook(String.Format("{0}!{1}", libName, funcName), hookFlags)
       Me.Hook.Hook(sync:=True)

       ' It could exist more than one explorer.exe instance so...
       For Each proc As Process In processesToAttach
           Me.Hook.Attach(procOrId:=proc.Id, sync:=True)
       Next proc

   End Sub

   <MTAThread>
   Private Sub OnCreateProcess_Called(ByVal hook As NktHook,
                                      ByVal proc As NktProcess,
                                      ByVal callInfo As NktHookCallInfo) Handles SpyMgr.OnFunctionCalled

       ' Process that the hook should intercept.
       Dim processToIntercept As String = "notepad.exe"

       ' CreateProcess function params.
       Dim lpApplicationNameParam As NktParam = DirectCast(callInfo.Params(0), NktParam)
       Dim lpCommandLineParam As NktParam = DirectCast(callInfo.Params(1), NktParam)

       If Path.GetFileName(lpApplicationNameParam.Value.ToString).Equals(processToIntercept, StringComparison.OrdinalIgnoreCase) Then

           With callInfo
               If .IsPreCall Then ' Skip precall to avoid process creation/initialization.
                   .Result.Value = 1
                   .SkipCall()
               End If
           End With

       End If

   End Sub

End Class


PD: El algoritmo cumple su función dentro de lo esperado, pero yo no soy ningún experto de la ingeniería inversa, quiero decir, que no se si el procedimiento controla todas las posibilidades en las que podría crearse un proceso, así que no lo tomes como un "código perfecto" en absoluto, sino más bien como un "algo por donde empezar".

PD2: En ese código que he mostrado existe una vulnerabilidad que se puede explotar facilmente (salta a la vista), y es que puedes cambiarle el nombre al notepad.exe por loquesea.exe para poder ejecutarlo (o al revés, para bloquearlo), esto está justificado, pues es solo un ejemplo demostrativo de técnicas de api-hooking, no de protección antiviral xD, pero si quieres un nivel de seguridad más eficiente, entonces se me ocurre que podrías realizar una comparación byte a byte entre los bytes del proceso seleccionado a bloquear, y los bytes del proceso que intenta ser creado para determinar si se trata del mismo archivo indiferentemente del nombre del archivo, y así decidir si el proceso debe ser creado o no.

Saludos








HCK.

Buah, eres un p*to máquina ;-) (con perdón por la expresión). Yo me temía tambien que el asunto pasaba por hacer un hook a la llamada de la API, puesto que he visto que los antivirus trabajan así a la hora de llamar algún proceso al que después impedirán su ejecución.
Tampoco conocía otro método de hacerlo, pero casi siempre suele haber mas de una forma de hacer lo mismo, pero en este caso no. Lo mismo me ocurre con la librería Nektra.Deviare  :), tampoco la conocía, pero ahora sabiéndolo puedo indagar mas en ella y ver todas sus posibilidades.

Te agradezco mucho todo, pero mucho mas el hacerme conocer la libreria, que siempre me pongo a cacharrear con lo que me enseñas y a final de cuenta lo que aprendo es lo que mas vale de la experiencia.

De todas maneras, el código cumple su función y esta chulo, pero por si alguna vez lo implementas en algo muy serio, decir que un RunPE se salta el método.

Siempre lo digo, y nunca me canso... Si necesitas ayuda con algo, mandame un MP y si te puedo ayudar lo haré.

Muchas gracias compañero  :P

ThunderCls

Sumando un poco mas a la respuesta de Elektro (si es que se puede...muy buena intervención  ;-)) es bueno aclarar (aunque esta claro que es solo demostrativo el code) que el método que ha expuesto Elektro es un método que trabaja a nivel de usuario (Ring3) y bien sencillo de sobrepasar, sobre todo para los malware writers que se buscan la vida de las formas mas complicadas e innovadoras para ejecutar sus creaciones, ademas que muchos usan también API's mas cerca del kernel directamente ej NtCreateProcess/ZwCreateProcess, etc (la linea descendiente de llamadas es mas profunda) y la mas indicada no seria CreateProcess sino ZwCreateSection, pero bueno... Por otra parte tambien es de aclarar que se debería hacer el hook no solo en "explorer.exe" sino a todos los procesos activos y los nuevos que se creen en adelante para tener controlados todos los posibles escenarios donde se pudiera ejecutar el "malware".
Mencionas a los AV, bueno, pues no creo que exista un solo AV que se respete que no utilice un driver para estas cosas. Los drivers trabajan con un nivel muy superior de privilegios en el sistema (Ring0) y por ende pueden hacer lo que se les venga en gana. Hay un muy buen articulo + code al respecto que te recomiendo echarle un ojo si asi lo deseas:

http://www.codeproject.com/Articles/11985/Hooking-the-native-API-and-controlling-process-cre

Igual si no quieres ir tan profundo puedes seguir por la ruta de soluciones a nivel de usuario. Si sabes algo de Pascal este code esta muy bien también y solo te tocaría pasarlo a NET o lo que desees  :rolleyes:

http://forum.madshi.net/viewtopic.php?t=1736

Saludos
-[ "...I can only show you the door. You're the one that has to walk through it." – Morpheus (The Matrix) ]-
http://reversec0de.wordpress.com
https://github.com/ThunderCls/