+ Responder Tema
Resultados 1 al 7 de 7
  1. #1
    Coordinador Crack Team LH CronuX va por un camino distinguido Avatar de CronuX
    Fecha de Ingreso
    14 ago, 09
    Ubicación
    OllyDBG
    Mensajes
    892
    Nacionalidad
    Colombia!
    Thanks
    52
    Thanked 85 Times in 55 Posts
    Poder de Reputación
    117

    Predeterminado [ Cómo proteger tus aplicaciones ] Por Black Fenix

    [ Consejos Generales ]

    Antes de realizar una protección estos son algunos de los consejos que debes seguir, por supuesto esta lista podría ser mucho más larga, pero tampoco se trata de dar ventaja al enemigo ;-), ni de sobrecargar a los pobres proteccionistas, que ya de por si no hacen caso de los cuatro consejillos básicos.

    1) Nunca, bajo ningún concepto, utilices nombres que puedan ser sospechosos a la hora de bautizar las funciones que se encargan del sistema de protección. Por ejemplo si tu protección se basa en un número de série, no le pongas un nombre como IsRegNumValid, ya que esto habla por si sólo. Usa nombres que no levanten la menor sospecha. Es increible, que compañias de software bastante importantes, no sigan este consejo tan básico (esto es debido a que cientos de personas trabajan en un mismo proyecto y se harian la picha un lio si el sistema de protección fuera muy complicado), resulta un juego de niños desproteger sus aplicaciones más caras.

    2) No hagas que las cadenas que informan del error de protección sean cadenas constantes, ya que si lo haces así, el cracker puede encontrar las referencias a esta cadena y a partir de ahi ya es más fácil buscar el nucleo de la protección. Para evitar esto, crea las cadenas dinamicamente, o mejor aún prueba a encriptarlas.

    3) Cuando detectes un error/violación en el sistema de protección, no informes con ningún tipo de mensaje al usuario, simplemente sal del programa o haz que el sistema se cuelgue, esto hará que el cracker tenga menos puertas de entrada.

    4) Si tu sistema utiliza la fecha del sistema para ver si el periodo de evaluación a pasado, realiza siempre varias comprobaciones al inicio, y al cabo de por ejemplo 3 días, vuelve a comprobar. A ser posible nunca utilices las funciones del SO para obtener fechas, es mejor extraerla de los ficheros.

    5) Haz comprobaciones internas del ejecutable, esto es una suma de comprobación o verificación del código (CRC) que puede ser objetivo de ataques externos, haciendo esto, podrás saber si tu aplicación a sido modificada por algún cracker o incluso algún virus y actuar como indica el punto 3.

    6) Nunca uses una misma función para comprobar la validez de un numero de série, manten siempre varias copias de esta función, aunque esto signifique tener código repetido, te aconsejo que modifiques su funcionamiento aunque no su resultado, esto generará código diferente para cada función. Elige la función de una manera aleatoria. Esto dará por saco a muchos crackers, y aunque consigan parchear una función, deberán de parchear tambíen el resto.

    7) Puedes añadir trucos anti-debugging, pero no te serán de mucha ayuda a no ser que sean métodos desconocidos, ya que cualquier cracker que se precie conoce los métodos más utilizados, esto sólo le retardará unos instantes.

    8) Bajo ningún concepto utilices un sistema de protección comercial, el 99% de estos sistemas ya se ha conseguido desproteger y es relativamente fácil encontrar parches genéricos.

    9) Encripta o comprime todo o parte del código del programa, esto evitará que el cracker pueda disponer de un desensamblado que corresponda con el código verdadero del programa. No utilices compresores/encriptadores genéricos ya que en el 99% de los casos existen un descompresor/desencriptador genérico para estos compresores/desencriptadores. Descomprime/Desencripta el código, sólo cuando hayas comprobado que no se ha violado el sistema de protección, esto forzará al cracker a tener que desproteger el sistema para poder obtener el código real. Este sistema casi nunca se implementa por ser quiza muy complejo para la mayoría de programadores "profesionales", pero resulta extremadamente efectivo contra los crackers menos avanzados.

    10) Nunca uses el registro para guardar información relevante al sistema de protección. Lo mejor es guardarlos en lugares poco comunes , p. ej: archivos de bases de datos de la misma aplicación.

    11) Nunca hagas que tu sistema de protección dependa exclusivamente de una DLL externa, ya que es muy fácil crackear una DLL y luego hacerla servir para todos los programas que utilizen ese tipo de protección.Este es otro de los fallos que cometen muchos programadores, debido a su querido Windows.

    12) Procura que el sistema de protección no pueda burlarse con tan sólo cambiar el flujo del programa (es decir con tan sólo modificar un salto), realiza multiples comprobaciones, haz saltos inutiles y añade código superfluo, esto creará un clima de confusión muy desagradable para el cracker.

    13) Nunca utilizes una variable global para indicar si el programa esta registrado o no (0 o 1 es lo más típico :-)) ya que con tan solo cambiar este valor, el resto del sistema de protección se irá al garete.

    14) Si tu aplicación tiene alguna función recortada, no incluyas el código fuente dentro del programa demo, ni tampoco muestres esta función en ningún menú.

    15) Utiliza el propio código de tu protección como tabla para el cálculo de los números de registro, esto pueda resultar muy desagradable para los que suelen usar el SoftIce.

    16) Utiliza numeros de série que contengan letras y números separados por guiones, suelen ser más dificiles de crackear que los numéricos.

    17) Cuando hagas la rutina de cálculo, hazla lo más complicada posible, esto no quiere decir que el cálculo sea una chorrada. Al contrario, utiliza las instrucciones XOR,AND,SHR y RCL RCR (muy eficaces y dificiles de invertir), incluso puedes usar las instrucciones del copro para dificultar la comprensión del código.

    18) Sobre todo despues de un cálculo complejo, nunca incluyas la típica comprobación final:

    cmp reg/mem,reg/mem
    jne @NoRegistrado

    Esto es lo más sencillo de invertir, y puede sumir un buen sistema de protección en lo más ridiculo.

    19) Utiliza llamadas indirectas a tus funciones de protección (punteros a funciones, guardados en tablas) p. ej:

    mov eax,dword ptr [EDI*4+32]
    call [eax]

    en C:

    Funcion=(int *) TablaFunciones[i+32];
    Funcion();

    Esto evita que el cracker pueda encontrar las referencias a las funciones relativas al sistema de protección.

    20) Puedes ocultar los datos de la protección en archivos de sonido e imagen o de objetos 3D usando steganografía. En caso de que el cracker sea capaz de deducir donde se encuentran los datos, se verá obligado a conocer la estructura interna de estos archivos y esto dificultará durante mucho tiempo su trabajo. Puedes utilizar este sistema para identificar cada copia de tu programa y así saber de donde provino la filtración :-). Aunque esto resulta peligroso si algún trabajador de tu empresa obtiene una copia que es para uno de tus clientes y la distribuye por ahí.

    21) Analiza el código fuente de varios virus y implementa sus técnicas de protección en tus sistemas, los virus son una fuente increible de como poder proteger tu software.Encriptación, auto-modificación del código, generación de código aleatorio y un sinfín de trucos que solo puedes encontrar en estas maravillas de programas.(Esto es para los que creen que los virus sólo sirven para dar por culo).

    22) Camufla los archivos relevantes a la protección, aunque no sirve de mucho puede despistar a más de uno.
    Feliz Cracking



    Citar Citar   Share with Facebook

  2. The Following 2 Users Say Thank You to CronuX For This Useful Post:

    -Security- (07/03/2010), jeann (06/03/2010)

  3. #2
    Coordinador Crack Team LH CronuX va por un camino distinguido Avatar de CronuX
    Fecha de Ingreso
    14 ago, 09
    Ubicación
    OllyDBG
    Mensajes
    892
    Nacionalidad
    Colombia!
    Thanks
    52
    Thanked 85 Times in 55 Posts
    Poder de Reputación
    117

    Predeterminado Lección 0- "Detección de debuggers"

    [ ¿QUE ÉS UN DEBUGGER ? ]

    "Se podría definir como un sistema de software integrado en un sistema informático con el fín de identificar los errores lógicos de los programas (bugs) y proporcionar medios para enmendarlos. Tal software es utilizable al propio tiempo que se hacen funcionar los programas al objeto de que facilite información relativa a los procesos mientras estos están teniendo lugar. Un buen depurador (debugger) puede disponer de mandatos para mostrar el contenido de la memoria y de los registros, e incluso para modificarlos, y para provocar la ejecución de rutinas durante la presentación de datos importantes que faciliten el diagnóstico de fallos."

    [ ¿CÓMO PODEMOS DETECTARLOS ?]

    La detección de un debugger puede resultar complicada, aún así existen metodos muy sencillos que ofrecen buenos resultados. Algunos de estos métodos utilizan instrucciones privilegiadas y resulta complejo utilizarlos cuando nuestra aplicación se ejecuta bajo Windows en ring3 (no problem bajo DOS), esto se debe a que Windows no nos permite utilizar las instrucciones privilegiadas necesarias para completar la detección, este tipo de detecciónes solo las podremos realizar si estamos en ring0 (máximo privilegio), lo cual implica la creación de un VXD o la utilización de algún truco que nos permita entrar en ring0. Cabe destacar tambíen la proliferación de métodos que detectan exclusivamente a nuestro debugger preferido: SoftIce,uno de los más utilizados, se denomina MeltIce, también es el más conocido y es el utilizado por los creadores del SoftIce para comprobar si este está en memória, podemos encontrarlo en la DLL nmtrans.dll dentro del directorio donde se encuentra el SoftIce.

    Frente a lo que contrariamente puedas creer, la detección de un debugger no ofrece en si ningúna protección, en realidad la protección se deriva después: Que hacer una vez se ha detectado la presencia de un debugger ?Muchas aplicaciones simplemente informan al usuario mediante algun cuadro de diálogo (esto nunca se debe hacer) y después finalizan la aplicación. Otras aplicaciones son ménos "consideradas" y se limitan a finalizar la aplicación sin mostrar mensaje alguno (este es un sistema aceptable) y las hay que son más agresivas y ponen en peligro la integridad de nuestra máquina realizando un cuelgue inmediato (esto es muy peligroso y puede llegar a destruir información de otras aplicaciones), y los hay que se autodestruyen. En mi opinión ninguno de los métodos anteriores resulta efectivo, frente a estos casos,la mayoría de los crackers sospecharian lo que sucede y tomarian medidas inmediatas, lo único que ganariamos es dificultar por momentos el trabajo del cracker. Sería más efectivo actuar de la siguiente manera:

    Continuar la ejecución del programa, el cracker no sospechará que le hemos detectado y deberá investigar si desea saber con certeza que le hemos detectado. Intentar volver loco al cracker, podemos alterar el funcionamiento de la aplicación para que el cracker no encuentre lo que busca, o incluso podemos enviar comandos al debugger que desactiven los breakpoints (esto es posible si somos capaces de entrar en ring0) y al finalizar la aplicación los volvemos a activar, esto confundirá a muchos crackers y se pasarán un buen rato pensando porqué no funcionan sus breakpoints.

    /*
    Función: IsSICELoaded
    Descripción: Este método de detección es utilizado por la mayoría de compresores/encriptadores que puedes encontrar en internet, se basa en la busqueda de la firma 'BCHK' usando la INT 3 que el SoftIce intercepta para sus servicios. Funciona tanto con MS-DOS como con Windows.
    Retorna: TRUE si se detecta SoftIce
    */
    __inline bool IsSICELoaded()
    {
    _asm {
    push ebp
    mov ebp,'BCHK' // 'BCHK' -> 4243484Bh
    mov eax,4 // Función 4h
    int 3 // Llama a la Interrupción 3
    cmp al,3 // compara AL con 3
    setnz al // si no es igual, SoftIce está presente
    pop ebp
    }
    }

    El método anterior es uno de los más sencillos de implementar, se basa en el uso de la INT 3 servicio 4h, cuando se le basa el valor 'BCHK' (BoundsChecker) en EBP, esta retornará un valor diferente a 3 en AL. Los crackers suelen defenderse de este método con un breakpoint de interrupción como el siguiente:

    BPINT 3 if al==4

    Este breakpoint nos permitirá modificar el valor oportuno y así evitar la detección del SoftIce.

    /*
    Función: IsSICELoaded2
    Descripción: Método de detección muy usado por los compresores/encriptadores, se basa en la INT 41, esta interrupción es utilizada por windows para comprobar si hay un debugger instalado. Solo funciona bajo Windows.
    Retorna: TRUE si se detecta SoftIce
    */
    __inline bool IsSICELoaded2()
    {
    _asm {
    mov eax,0x4f // AX = 004Fh
    int 0x41 // INT 41 CPU - MS Windows debugging kernel - DEBUGGER INSTALLATION CHECK
    cmp ax,0xF386 // AX = F386h su hay un debugger presente
    jz SoftICE_detected
    xor eax,eax
    SoftICE_detected:
    }
    }

    El método anterior es también uno de los más sencillos de implementar, se basa en el uso de la INT 41 servicio 4fh esta retorna el valor F386h si hay un debugger presente. Los crackers suelen defenderse de este método con un breakpoint de interrupción como el siguiente:

    BPINT 41 if al==4f

    Este breakpoint nos permitirá modificar el valor oportuno y así evitar la detección de cualquier debugger que se este ejecutando.

    /*
    Función: IsSICELoaded3
    Descripción: Método de detección muy usado por los compresores/encriptadores, similar al anterior pero usando la INT 68. Solo funciona bajo Windows.
    Retorna: TRUE si se detecta SoftIce
    */
    __inline bool IsSICELoaded3()
    {
    _asm {
    mov ah,0x43
    int 0x68
    cmp ax,0xF386
    jz SoftICE_Detected
    xor eax,eax
    SoftICE_detected:
    }
    }

    Parecido al anterior pero usando la INT 68, Los crackers suelen defenderse de este método con un breakpoint de interrupción como el siguiente:

    BPINT 68 if ah==43

    /* Funcion IsSICELoaded4
    Descripción: El siguiente método sólo funciona si la aplicación se está ejecutando en modo real (MS-DOS), se basa en el uso de la Interrupción 2Fh, utilizada por Windows para obtener un punto de entrada al dispositivo VXD identificado en el registro BX, el Identificador del SoftIce es 0202h
    */

    __inline bool IsSICELoaded4()
    {
    _asm {
    xor di,di
    mov es,di
    mov ax, 1684h
    mov bx, 0202h // VxD ID of winice
    int 2Fh
    mov ax, es // ES:DI -> VxD API entry point
    add ax, di
    test ax,ax
    jnz SoftICE_Detected
    }
    }

    Los crackers suelen defenderse de este método con un breakpoint de interrupción como el siguiente:

    BPINT 2f if (ax==1684) && (bx=0202)

    // Función: IsSoftIce9xLoaded
    // Descripción: Comprueba si el controlador VXD del SoftIce para Win 9x está cargado en memória, para ello utiliza la función
    // CreateFile del API de Windows, esta función se encarga (entre otras cosas) de establecer comunicación con los
    // dispositivos VXD.
    // Retorna: TRUE si SoftIce está en memoria.

    __inline BOOL IsSoftIce9xLoaded()
    {
    HANDLE hFile;

    // "\\.\SICE" sin las secuencias de escape
    hFile = CreateFile( "\\\\.\\SICE",
    GENERIC_READ | GENERIC_WRITE,
    FILE_SHARE_READ | FILE_SHARE_WRITE,
    NULL,
    OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,
    NULL);

    // Si se retorna un handle válido, SoftIce está en memória
    if( hFile != INVALID_HANDLE_VALUE )
    {
    CloseHandle(hFile); // cierra la comunicación con el VXD
    return TRUE; // y devuelve TRUE
    }
    return FALSE; // SoftIce no detectado
    }

    // Función: IsSoftIceNTLoaded
    // Descripción: Comprueba si el controlador VXD del SoftIce para NT está cargado en memória, para ello utiliza la función
    // CreateFile del API de Windows, esta función se encarga (entre otras cosas) de establecer comunicación con los
    // dispositivos VXD.
    // Retorna: TRUE si SoftIce está en memoria.

    __inline BOOL IsSoftIceNTLoaded()
    {
    HANDLE hFile;

    // "\\.\NTICE" sin las secuencias de escape
    hFile = CreateFile( "\\\\.\\NTICE",
    GENERIC_READ | GENERIC_WRITE,
    FILE_SHARE_READ | FILE_SHARE_WRITE,
    NULL,
    OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,
    NULL);

    if( hFile != INVALID_HANDLE_VALUE )
    {
    CloseHandle(hFile);
    return TRUE;
    }

    return FALSE;
    }

    Este método se denomina MeltIce, es de los más utilizados para detectar la presencia del SoftIce pero también es uno de los más fáciles de engañar. Si te decides por usar este metodo, nunca pases la cadena que hace referencia al VXD como en el ejemplo, ya que si lo haces así, está aparecerá dentro del ejecutable como una cadena legible, por lo que solo tendremos que buscar dentro del ejecutable la cadena 'SICE' o 'NTICE' con un editor hexadecimal y reemplazarla por cualquier otro valor como 'XICE', anulando por completo nuestro sistema de protección (esto sucede la mayoría de los casos). Incluso si creamos la cadena dinámicamente caracter a caracter, siempre podemos detectar este metodo con un breakpoint condicional sobre la función CreateFile:

    BPX CreateFileA if *(esp->4+4)=='SICE' || *(esp->4+4)=='SIWV' || *(esp->4+4)=='NTIC'

    El funcionamiento de este breakpoint es sencillo, se comprueba que el primer parametro pasado a la función CreateFileA apunte a la cadena SICE o NTIC (se suma 4 para omitir la cadena '\\.\' de caracteres de longitud), si se cumple esta condición, el breakpoint se ejecuta (Notese el uso del condicional == y la operación lógica ||, similar a la sintaxis del lenguaje C).Cuando el breakpoint surta efecto, sólo deberemos modificar la cadena pasada para que contenga cualquier otro nombre que no sea un VXD de Windows.

    Puedes utilizar los metodos para detectar si hay un breakpoint sobre la función CreateFile, pero estos metodos, también pueden ser detectados. Lo cual deja a este sistema como uno de los más inocentes ante un cracker. Esto es debido a que depende de la DLL kernel32 que contiene la función CreateFileA, y los sistemas de protección que dependen de DLL externas, son como ya sabemos fáciles de detectar.

    Pues hasta aquí lo que se daba, estos son los métodos más básicos que existen para la detección del SoftIce o de cualquier otro debugger que se ejecute bajo Windows, existen algunos más, pero estos son más complicados y serán comentados en otro lección.
    Feliz Cracking



    Citar Citar   Share with Facebook

  4. The Following User Says Thank You to CronuX For This Useful Post:

    jeann (06/03/2010)

  5. #3
    Coordinador Crack Team LH CronuX va por un camino distinguido Avatar de CronuX
    Fecha de Ingreso
    14 ago, 09
    Ubicación
    OllyDBG
    Mensajes
    892
    Nacionalidad
    Colombia!
    Thanks
    52
    Thanked 85 Times in 55 Posts
    Poder de Reputación
    117

    Predeterminado Lección 1- "Cómo detectar si hay breakpoints (BPX) en tus funciones"

    [ ¿QUE ÉS UN BREAKPOINT ? ]

    "Si no sabes lo que es un breakpoint (punto de ruptura), creo que deberías mirarte los tutoriales antes de comenzar con esta lección. Aún así voy a explicar brevemente para que sirven y que son los breakpoint. Los breakpoints son una de las grandes ventajas que todo debugger brinda al cracker, mediante un breakpoint, el cracker puede establecer un punto en el cual el debugger parará la ejecución del programa, posteriormente el debugger pasará el control del programa al cracker, con lo cual este podrá examinar que es lo que sucede al llegar al punto del código donde se estableció el breakpoint. La mayor utilidad de los breakpoints es utilizarlos con funciones del API de Windows (p. ej. con MessageBoxA), esto nos permite tomar el control del programa antes de que se llame a la función del API sobre la que hayamos puesto un breakpoint. Es por eso que no es aconsejable informar al usuario de ningún error del sistema de protección mediante una función del API o de cualquier DLL externa."

    [ ¿CÓMO FUNCIONA UN BREAKPOINT ?]

    Los breakpoints (utilizaré BPX para abreviar) siempre han funcionado de la misma manera a lo largo de la larga vida de los debuggers, cuando el usuario decide establecer un BPX en alguna parte del código, este manda una instrucción al debugger (en SoftIce: bpx dirección_código) y el debugger reemplaza el primer byte del código por el código hexadecimal 'CCh', este código equivale a la instrucción INT 3, la cual genera una interrupción (la 3 en este caso). Cada vez que esta instrucción se ejecuta, se devuelve el control al debugger, este, reemplaza la INT 3 (CCh) por el byte de código que habia previamente y muestra al usuario el código actual donde se encuentra el programa. Ahora el usuario puede seguir trazando el programa si lo desea y examinar el código para cambiar el comportamiento del programa, pudiendo llegar anular nuestro sistema de protección. Esta claro que si pudieramos detectar si en nuestro código se han puesto BPX, podriamos abortar la ejecución del programa debido a una violación del sistema de seguridad (siempre debes de realizar esto sin mostrar ningún mensaje de error, mirate mis consejos).

    [ ¿CÓMO PODEMOS DETECTARLOS ?]

    Pues bien, esto lo podemos conseguir facilmente en ensamblador pero en C resulta algo más complicado, pero no por eso imposible. La teoria sería la siguiente: obtener un puntero a la función o al inicio del código que queremos comprobar, leer el primer byte de código, comprobar si es igual a 'CCh' (INT 3) y actuar en consequencia. A continuación tienes un pequeño programa realizado en C que detecta si existe algún BPX sobre la función MessageBox del API de Windows. El código a sido comprobado y funciona perfectamente compilandolo con Visual C++, no lo he probado con otros compiladores pero creo que funcionaría igual. Este código puede detectar cualquier debugger, ya que todos actuan igual, yo lo he probado con el SoftIce v4.0 para Windows 9x y funciona.
    Para comprobar el funcionamiento de este código, compila el programa, pon un BPX sobre la función MessageBoxA (bpx MessageBoxA si usas el SoftIce) y ejecuta el programa, luego prueba desactivando el breakpoint.

    #include <stdio.h>
    #include <windows.h>

    #pragma warning( disable : 4035 ) /* desactiva la generación de warnings para las funciones que aparentemente no retornan nada*/

    /* Las funciones estan declaradas como funciones __inline, esto provoca que sean compiladas como si se tratara de macros y no funciones, es decir, cada vez que en nuestro código en C llamemos a una de estas funciones, el compilador no generará ninguna llamada si no que el código se añadira cada vez que las llamemos. Esto evita que el cracker pueda parchear la función y con esto evitar que todas las llamadas para comprobar si hay un BPX fuesen inutilizadas con un solo cambio. Recomiendo hacer un uso bastante intensivo de cualquiera de estas dos funciones para complicar la vida al cracker */

    __inline bool IsBPX(void * address)
    {
    _asm {

    mov esi,address // carga la dirección de la función
    mov al,[esi] // comprueba si existe un breakpoint sobre la función
    cmp al,0xCC // esto se realiza comprobando que el primer byte de código
    // de la función sea diferente que CCh, que es el código
    // de operación de la INT 3 usada por TODO debugger
    je BPXed // si encontramos CCh, la función tiene puesto un breakpoint
    // saltamos para devolver TRUE
    xor eax,eax // FALSE,
    jmp NOBPX // no hay breakpoint

    BPXed:

    mov eax,1 // hay un breakpoint
    NOBPX:
    }
    }

    // Esta segunda versión de la función, realiza lo mismo, pero lo hace de una manera menos evidente, para que el cracker no pueda buscar posibles comparaciones
    // de un registrp con CC, en el desensamblado del código

    __inline bool IsBPX_v2(void * address)
    {
    _asm {

    mov esi,address // carga la dirección de la función
    mov al,[esi] // comprueba si existe un breakpoint sobre la función
    mov ah,0x66 // carga ah con 66h (mitad de CCh)
    add ah,ah // lo suma a si mismo dando 0xCC, y se compara
    cmp ah,al // esto se realiza comprobando que el primer byte de código
    // de la función sea diferente que CCh, que es el código
    // de operación de la INT 3 usada por TODO debugger
    je BPXed
    xor eax,eax // no hay breakpoint
    jmp NOBPX

    BPXed:

    mov eax,1 // hay un breakpoint
    NOBPX:
    }
    }

    #pragma warning( default : 4035 ) // establece la generación de warning para las funciones que no retornan valor, al valor por defecto del compilador

    void main()
    {
    void *addr;
    addr=MessageBox;

    if (IsBPX_v2(addr))
    {
    MessageBox(NULL,"Estas intentando crackear este programa?","Mensaje",MB_OK|MB_ICONEXCLAMATION);
    }
    else MessageBox(NULL,"Bien chaval pareces legal...","Mensaje",MB_OK);
    }

    Bueno, puedes ver que tampoco es tan difícil de implementar y resulta bastante efectivo, no creo que el código necesite mucha explicación ya que las partes interesantes estan perfectamente comentadas, quizá la variable addr no es necesaria pero creo que así se ve más claro. Analizemos ahora los pros y contras de este método:

    Si el cracker llega a detectar el código que causa la detección del BPX, puede crear un pequeño programa o utilizar un editor hexadecimal que busque los códigos que pertenecen a las funciones de detección y que realize las modificaciones oportunas, evitandose así tener que ir de una en una, esto es debido a que el compilador siempre generará el mismo código para las macros. Podriamos solucionar esto creando multiples versiones de las macros con instrucciones diferentes.

    El método es difícil de detectar si se utiliza una macro bien camuflada, en este caso, la primera macro es muy sencilla de encontrar debido a la instrucción cmp al,0xcc y probablemente sería poco efectiva ante un cracker poco experto.

    Existe un metodo infalible para detectar la comprobación del breakpoint que muchos crackers ignoran (ahora habrá menos :) ), si en el SoftIce colocamos un BPM (Breakpoint on Memory access) sobre la función que sospechamos, el debugger se detendrá justo después de leer el byte de código. En el ejemplo hariamos: BPM MessageBoxA R, esto le indica al Softice que detenga la ejecución si se intentan leer bytes de la función MessageBoxA.

    Como puedes comprobar, cualquier truco anti-debugging no está exento de su correspondiente truco anti-anti-debugging :=) . Pues esto es todo por ahora, habrá más en la siguiente lección.
    Feliz Cracking



    Citar Citar   Share with Facebook

  6. The Following User Says Thank You to CronuX For This Useful Post:

    jeann (06/03/2010)

  7. #4
    Coordinador Crack Team LH CronuX va por un camino distinguido Avatar de CronuX
    Fecha de Ingreso
    14 ago, 09
    Ubicación
    OllyDBG
    Mensajes
    892
    Nacionalidad
    Colombia!
    Thanks
    52
    Thanked 85 Times in 55 Posts
    Poder de Reputación
    117

    Predeterminado Lección 2- "Detección de debuggers, la historia continua"

    Para aquellos que no sepan de que va la historia les recomiendo que lean antes la lección 0, en ella encontrarán información más detallada sobre que es un debugger y cómo funciona. Esta lección pretende añadir nuevos métodos de detección de debuggers, estos métodos los considero más extraños y algunos resultan díficiles de detectar. Pero para eso estamos aquí, para mostrar en que se basan y así poder mejorarlos y si alguno de ellos se interpone en nuestro camino, ya sabes...

    METODO 1:

    Descripción: Este método se suele utilizar muy poco, aunque es bastante efectivo ya que detectará el SoftIce aunque no este en memoria, su funcionamiento es muy simple: comprueba la existencia en el registro de una de las siguientes claves, esto delatará la presencia de nuestro estimado amigo SoftIce.

    - #1 : HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall\SoftICE
    - #2 : HKEY_LOCAL_MACHINE\Software\NuMega\SoftICE

    Para comprobar la existencia de claves en el registro podemos usar la función del API RegOpenKey, RegOopenKeyEx,

    Para detectar este método podemos utilizar un breakpoint en el SoftIce tal como -> BPX _regopenkey if *(esp->8+0x13)=='tICE' || *(esp->8+0x37)=='tICE'

    METODO 2:

    Descripción: Este método es muy efectivo ya que detecta cualquier debugger, aunque solo funciona bajo Win 9x, se basa en la comparación de las direcciones donde estan los manejadores de la INT 1 y la INT 3. icy debe ser la dirección de un buffer de un mínimo de 6 bytes. El único método de detección de este método que conozco es por busqueda de los opcodes de la instrucción SIDT (0F 01) o del CMP, pero este puede tener combinaciones más diversas. Personalmente desconocía este método hasta que me encontré con el en el BlindWrite (gracias a fanega por pasarmelo), un programa de grabación de CD-R que usa este sistema. La verdad que este sistema se puede explotar mucho más ya que de su funcionamiento se deriva un fallo en el Windows que nos permitiría ejecutar código en Ring0 desde nuestra aplicación en Ring3. El fallo reside en que el area de memória donde reside la IDT (Interrupt Descriptor Table), no está protegida contra lectura/escritura, pero esto solo sucede en Win9x y no en NT. La IDT viene a ser algo así como una tabla de vectores (similar a la antigua tabla del DOS), donde se almacenan las direcciones de memória que apuntan al código que ejecuta al llamar a una interrupción.

    #include <windows.h>

    // alinea las estructuras a WORD
    #pragma pack(2)

    typedef struct _IDTGATE
    {
    unsigned short gateOffsetLow;
    unsigned short gateSelector;
    unsigned short gateFlags;
    unsigned short gateOffsetHigh;
    } IDTGATE;

    typedef struct _IDT
    {
    unsigned short idtLimit;
    IDTGATE* idtGate;
    } IDT;

    bool IsDebuggerRunning()
    {
    IDT icy;
    _asm {
    SIDT [icy];
    mov eax,dword ptr [icy.idtGate]
    add eax,0x8
    mov ebx, dword ptr [eax]
    add eax,0x10
    mov eax, dword ptr [eax]
    and eax,0x0000FFFF
    and ebx,0x0000FFFF
    sub eax,ebx
    cmp eax,0x1E
    je Sice
    xor eax,eax
    Sice:
    }
    }

    METODO 3:

    Descripción: Este método se basa en la busqueda de la cadena WINICE.BR en la memória, su funcionamiento es muy sencillo ya que es una simple busqueda en memória. Resulta muy efectivo y bien implementado puede ser difícil de detectar, aunque sabiendo la dirección de memória que se analiza se puede utilizar un BPM (breakpoint on memory access) para detectarlo. Doy las gracias a R!SC y a Stone por enseñarme este método.

    bool FindSoftIceString()
    {
    _asm {
    mov al, 'W'
    mov edi, 0x10000
    mov ecx, 0x400000-0x10000
    More:
    repnz SCASB // "W"
    jecxz NotFound
    cmp dword ptr [edi], 'CINI' // INIC
    jz Ok1

    jmp More
    Ok1:
    add edi, 4
    cmp dword ptr [edi], 'RB.E' // E.BR
    jnz More
    mov eax,1
    NotFound:
    }
    }

    METODO 4:

    Descripción: Consiste en ver si el registro de trazado DR7 contiene un valor distinto de 0,en caso afirmativo, el sistema esta bajo un debugger (Esto podemos comprobarlo si estando en SoftIce tecleamos el comando CPU). Este método se basa en los registros de trazado (Debug Registers DRx) de los Pentium para su correcto funcionamiento, la aplicación que lo utilize debe tener privilegios de Ring0, esto implica programarnos nuestro VXD o hacer uso de algún tipo de truco que nos permita pasar de Ring3 a Ring0. Existe un método que modificando la IDT nos permite redireccionar una interrupción a una dirección de código que este en nuestra aplicación, el código al ser ejecutado como una interrupción tendrá privilegios Ring0, el siguiente código de muestra como podemos implementar esto desde C. Notese que este método no funciona bajo NT, también destacar que puede utilizarse otra interrupción que no sea la del ejemplo. Si por ejemplo elejimos la INT 1, el SoftIce se irá a hacer puñetas ;), ya que él usa esta interrupción.

    void Ring0Proc()
    {
    _asm {
    mov eax, dr7 // Instrucciones privilegiadas en Ring0 :)
    iretd // Esto se ejecutará como una interrupción por lo que deberemos retornar tal y como lo hacen las interrupciones
    }
    }

    DWORD GetDebugReg7()
    {
    _IDT addr; // mirate el método 2 para ver la descripción de la estructura
    unsigned long lpOldGate; // esto es para guardar la dirección original

    _asm {
    sidt fword ptr [addr]
    mov ebx,dword ptr [addr+2]
    add ebx,8*5
    mov dx, word ptr [ebx+6] // Salva el word alto de la puerta IDT
    shl edx, 16d
    mov dx, word ptr [ebx] // word bajo
    mov [lpOldGate], edx

    mov eax, offset Ring0Proc // "instala nuestra rutina" - Que se ejecutará en Ring0
    mov word ptr [ebx], ax // word bajo
    shr eax, 16d
    mov word ptr [ebx+6], ax // word alto

    int 5 // llama a la INT 5 que es la que hemos sustituido, esto ejecutará nuestra rutina en Ring0
    cmp eax,0
    jne Sice
    xor eax,eax
    Sice:
    mov ebx, dword ptr [addr+2] // restaura la dirección original
    add ebx, 8*5
    mov edx, [lpOldGate]
    mov word ptr [ebx], dx
    shr edx, 16d
    mov word ptr [ebx+6], dx

    }
    }

    METODO 5:

    Descripción: Consiste en utilizar una función del VWIN32 que se encarga de despachar los servicios de la INT 41, a esta función se le pasan unos determinados valores que servirán para determinar la presencia del debugger. Solo funciona bajo Win9x. Para poder detectar este método podemos utilizar uno de los siguientes breakpoints: BPINT 41 if ax==4f , BPINT 30 if ax==0xF386, BPX Exec_PM_Int if eax==41 && edx->1c==4f && edx->10==002A002A o BPX Kernel32!ord_0001 if esp->4==002A002A && esp->8==4f

    push 0000004fh // función 4fh
    push 002a002ah // el word alto especifica el VXD (VWIN32), el word bajo especifica el servicio (VWIN32_Int41Dispatch)
    call Kernel32!ORD_001 // VxdCall
    cmp ax, 0f386h // número mágico devuelto por los debuggers
    jz SoftICE_detected

    METODO 6:

    Descripción: Consiste en utilizar una llamada VXD que nos permite averiguar si hay instalado el controlador de dispositivo virtual que le indiquemos, para ello podemos utilizar dos de los identificadores de los que el SoftIce dispone ( 202h o 7a5fh ). Este método solo funciona en Ring0 por lo que es bastante restrictivo a no ser que utilizemos el truco del método 4.

    mov eax, Device_ID // 202h para SICE o 7a5Fh para SIWVID VxD ID
    mov edi, Device_Name // solo se usa si no tenemos el ID del VxD, en nuestro caso será 0 (NULL)
    VMMCall Get_DDB
    mov [DDB], ecx // ecx=DDB si es dispositivo está instalado o ecx= 0 si el VxD no esta instalado
    Feliz Cracking



    Citar Citar   Share with Facebook

  8. #5
    Coordinador Crack Team LH CronuX va por un camino distinguido Avatar de CronuX
    Fecha de Ingreso
    14 ago, 09
    Ubicación
    OllyDBG
    Mensajes
    892
    Nacionalidad
    Colombia!
    Thanks
    52
    Thanked 85 Times in 55 Posts
    Poder de Reputación
    117

    Predeterminado Re: [ Cómo proteger tus aplicaciones ] Por Black Fenix

    Bueno aca me disculpo con todos he estado un poco ausente y tenia un poco olvidada la zona aca estoy para decirles que vuelvo y espero estar mas activo que antes y buscando por la red encontre este viejito pero buen material para programadores y crackers o mejor dicho seguridad de software saludos y espero que les sea util

    attt: CronuX

    Fuente: REVERSED MINDS
    Feliz Cracking



    Citar Citar   Share with Facebook

  9. #6
    Usuario jeann es una cantidad desconocida en este momento Avatar de jeann
    Fecha de Ingreso
    20 ago, 08
    Ubicación
    Venezuela
    Edad
    33
    Mensajes
    28
    Nacionalidad
    Venezuela!
    Thanks
    396
    Thanked 199 Times in 153 Posts
    Poder de Reputación
    0

    Predeterminado Re: [ Cómo proteger tus aplicaciones ] Por Black Fenix

    buen regreso, esta muy interesante todos este post
    Entusiasta del Mundo Libre GNU!!
    Mi Pagina: [Solo usuarios registrados pueden ver los links. ]
    [Solo usuarios registrados pueden ver los links. ]
    [Solo usuarios registrados pueden ver los links. ]
    [Solo usuarios registrados pueden ver los links. ]
    Citar Citar   Share with Facebook

  10. The Following User Says Thank You to jeann For This Useful Post:

    CronuX (06/03/2010)

  11. #7
    Usuario 634N será famoso muy pronto Avatar de 634N
    Fecha de Ingreso
    28 nov, 09
    Mensajes
    56
    Thanks
    42
    Thanked 3 Times in 3 Posts
    Poder de Reputación
    28

    Predeterminado Re: [ Cómo proteger tus aplicaciones ] Por Black Fenix

    super completo pero luego lo leo XD gracias
    Citar Citar   Share with Facebook

Temas Similares

  1. Como proteger el código fuente de una web en HTML
    Por Ponchale en el foro Webmasters
    Respuestas: 2
    Último Mensaje: 12/05/2010, 08:01
  2. Día de la seguridad informática: cómo proteger el ordenador y la información personal
    Por Ponchale en el foro Seguridad Informatica y Anonimato
    Respuestas: 1
    Último Mensaje: 02/12/2009, 21:33
  3. Como proteger tu programa
    Por CronuX en el foro Windows
    Respuestas: 2
    Último Mensaje: 02/11/2009, 23:10
  4. herramienta de IBM para proteger las aplicaciones de los intrusos en la red
    Por Ponchale en el foro Seguridad Informatica y Anonimato
    Respuestas: 0
    Último Mensaje: 25/06/2009, 00:08
  5. Como el Fenix!!!
    Por darĸ angel™ en el foro Vortex
    Respuestas: 6
    Último Mensaje: 05/02/2009, 20:18

Permisos de Publicación

  • No puedes crear nuevos temas
  • No puedes responder temas
  • No puedes subir archivos adjuntos
  • No puedes editar tus mensajes
 

Familia LH:
 Foro de Programacion - GeekHispano | Foro de Conversacion - TeVeo

Afiliados:
LeVeL-23 | Comunidad Underground de Mexico | Skamasle - De Todo un Poco | Foro Arte Libre | SSW Team | El Blog del Dr. White
Comunidad RAW | Polaxia Warez | [BACK DOOR] | Portal Hacker |
TECNOHACKER | Rthacker.net | Estegano | Artehack
 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75