第二次课,文件校验(预习)

hash 计算接口 Crypto API (证书,对称加密,非对称加密,编码和解码)
CryptAcquireContext
CryptCreateHash
CryptReleaseContext
CryptHashData
CryptDestroyHash
CryptGetHashParam

注册表操作接口
RegEnumKeyEx
RegEnumValueW
RegOpenKeyExW
RegQueryValueExW
RegQueryInfoKeyW

服务注册表的路径:\HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services

AutoRuns 和 AutoRuncs 下载地址
https://learn.microsoft.com/zh-cn/sysinternals/downloads/autoruns

目标:
1、在上次课的基础上把所有枚举出来的进程以及进程模块的文件hash值[MD5 sha-1,sha256]计算出来;存在父进程id的进程一并把父进程信息给关联起来一并输出;涉及运行中文件的打开,可以考虑先复制到其他地方再读取内容进行计算。
2、使用注册表接口,把注册表中的服务信息枚举出来,并输出关联的二进制路径,思考一下使用服务接口枚举的服务和注册表枚举的服务如何关联。
3、使用注册表接口,枚举当前计算启动项信息,启动项注册表路径自己查阅资料。
扩展内容:可以在进程,模块hash的基础上增加文件签名校验:参考内容链接:https://blog.csdn.net/StanfordZhang/article/details/8255605

1、hash CRC32–开销比较小 ,MD5,SHA1,SHA256 --运行开销,自定义的简单hash ,oxxxdxg.exe 长度,第一个字符是0 第四个字符是d 第六个是g 存在碰撞的可能。FFFFXAC VALUE ^ KEY = ENCODE;ENCODE ^ KEY = VALUE;

1231234535–》calc_proc—>data_spect

运行时解密。

框架原始的串 --》calc——proc -》FFFFXAC ollydbg.exe

注册表,这个就是WINDOWS 自带的数据库,或者说是一个配置库。

自启动

总结:白名单技术。云查(网络接口)

先给三个代码

1、在上次课的基础上把所有枚举出来的进程以及进程模块的文件hash值
[MD5 sha-1,sha256]计算出来;存在父进程id的进程一并把父进程信息给关联起来一并输出;
涉及运行中文件的打开,可以考虑先复制到其他地方再读取内容进行计算。
//第一部分计算

#include 
#include 
#include 
#include 
#include 
#include 
#include
#include
#include 

// 计算文件的哈希值
std::string CalculateHash(const wchar_t* filePath, const char* hashAlgorithm)
{
    std::string hashValue;

    HANDLE hFile = CreateFile(filePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
    if (hFile != INVALID_HANDLE_VALUE)
    {
        HCRYPTPROV hProv = NULL;
        HCRYPTHASH hHash = NULL;

        if (CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
        {
            if (CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash))
            {
                const DWORD bufferSize = 8192;
                BYTE buffer[bufferSize];
                DWORD bytesRead;

                while (ReadFile(hFile, buffer, bufferSize, &bytesRead, NULL) && bytesRead > 0)
                {
                    CryptHashData(hHash, buffer, bytesRead, 0);
                }

                DWORD cbHashSize = 0;
                DWORD hashSize = sizeof(DWORD);
                if (CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&cbHashSize, &hashSize, 0))
                {
                    std::vector<BYTE> hashBuffer(cbHashSize);

                    if (CryptGetHashParam(hHash, HP_HASHVAL, &hashBuffer[0], &cbHashSize, 0))
                    {
                        char hexChar[] = "0123456789ABCDEF";
                        hashValue.reserve(2 * cbHashSize);

                        for (DWORD i = 0; i < cbHashSize; ++i)
                        {
                            hashValue.push_back(hexChar[hashBuffer[i] >> 4]);
                            hashValue.push_back(hexChar[hashBuffer[i] & 0xF]);
                        }
                    }
                }

                CryptDestroyHash(hHash);
            }

            CryptReleaseContext(hProv, 0);
        }

        CloseHandle(hFile);
    }

    return hashValue;
}

int main()
{
    HANDLE hProcessSnap;
    PROCESSENTRY32 pe32;

    // 获取进程快照
    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hProcessSnap == INVALID_HANDLE_VALUE)
    {
        printf("创建进程快照失败!错误码:%d\n", GetLastError());
        return 1;
    }

    // 设置进程快照结构体大小
    pe32.dwSize = sizeof(PROCESSENTRY32);

    // 获取第一个进程的信息
    if (!Process32First(hProcessSnap, &pe32))
    {
        printf("获取第一个进程信息失败!错误码:%d\n", GetLastError());
        CloseHandle(hProcessSnap);
        return 1;
    }

    // 遍历进程快照,输出每个进程内的System32路径下的模块
    do
    {
        HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pe32.th32ProcessID);

        if (hProcess)
        {
            HMODULE hMods[1024];
            DWORD cbNeeded;

            // 获取模块句柄数组
            if (EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
            {
                // 获取模块路径
                for (unsigned int i = 0; i < cbNeeded / sizeof(HMODULE); i++)
                {
                    wchar_t szModuleName[MAX_PATH];

                    if (GetModuleFileNameEx(hProcess, hMods[i], szModuleName, MAX_PATH))
                    {
                        // 判断模块路径是否位于System32目录下
                        if (wcsstr(szModuleName, L"\\System32\\") != NULL)
                        {
                            std::string md5Hash = CalculateHash(szModuleName, "MD5");
                            std::string sha1Hash = CalculateHash(szModuleName, "SHA1");
                            std::string sha256Hash = CalculateHash(szModuleName, "SHA256");

                            printf("进程ID: %d\n", pe32.th32ProcessID);
                            printf("父进程ID: %d\n", pe32.th32ParentProcessID);
                            printf("模块路径: %ls\n", szModuleName);
                            printf("MD5 哈希值: %s\n",(md5Hash.empty() ? "计算失败" : md5Hash.c_str()));
                            printf("SHA1 哈希值: %s\n", (sha1Hash.empty() ? "计算失败" : sha1Hash.c_str()));
                            printf("SHA256 哈希值: %s\n\n", (sha256Hash.empty() ? "计算失败" : sha256Hash.c_str()));
                        }
                    }
                }
            }
            CloseHandle(hProcess);
        }

    } while (Process32Next(hProcessSnap, &pe32));

    CloseHandle(hProcessSnap);

    return 0;
}


//使用注册表接口,把注册表中的服务信息枚举出来,并输出关联的二进制路径
#include 
#include 
#include 

void EnumerateServices()
{
    HKEY hKey;
    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
    {
        DWORD numSubKeys;
        if (RegQueryInfoKeyW(hKey, NULL, NULL, NULL, &numSubKeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
        {
            for (DWORD i = 0; i < numSubKeys; i++)
            {
                WCHAR serviceName[MAX_PATH];
                DWORD serviceNameSize = MAX_PATH;

                if (RegEnumKeyExW(hKey, i, serviceName, &serviceNameSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
                {
                    HKEY hServiceKey;
                    if (RegOpenKeyExW(hKey, serviceName, 0, KEY_READ | KEY_WOW64_64KEY, &hServiceKey) == ERROR_SUCCESS)
                    {
                        WCHAR imagePath[MAX_PATH];
                        DWORD imagePathSize = MAX_PATH;

                        if (RegQueryValueExW(hServiceKey, L"ImagePath", NULL, NULL, reinterpret_cast<LPBYTE>(imagePath), &imagePathSize) == ERROR_SUCCESS)
                        {
                            std::wcout << "Service Name: " << serviceName << std::endl;
                            std::wcout << "Binary Path: " << imagePath << std::endl;
                            std::wcout << std::endl;
                        }

                        RegCloseKey(hServiceKey);
                    }
                }
            }
        }

        RegCloseKey(hKey);
    }
}

int main()
{
    EnumerateServices();

    return 0;
}


2、使用注册表接口,把注册表中的服务信息枚举出来,并输出关联的二进制路径,思考一下使用服务接口枚举的服务和注册表枚举的服务如何关联
#include 
#include 
#include 

void EnumerateServices()
{
    HKEY hKey;
    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
    {
        DWORD numSubKeys;
        if (RegQueryInfoKeyW(hKey, NULL, NULL, NULL, &numSubKeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
        {
            for (DWORD i = 0; i < numSubKeys; i++)
            {
                WCHAR serviceName[MAX_PATH];
                DWORD serviceNameSize = MAX_PATH;

                if (RegEnumKeyExW(hKey, i, serviceName, &serviceNameSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
                {
                    HKEY hServiceKey;
                    if (RegOpenKeyExW(hKey, serviceName, 0, KEY_READ | KEY_WOW64_64KEY, &hServiceKey) == ERROR_SUCCESS)
                    {
                        WCHAR imagePath[MAX_PATH];
                        DWORD imagePathSize = MAX_PATH;

                        if (RegQueryValueExW(hServiceKey, L"ImagePath", NULL, NULL, reinterpret_cast<LPBYTE>(imagePath), &imagePathSize) == ERROR_SUCCESS)
                        {
                            std::wcout << "Service Name: " << serviceName << std::endl;
                            std::wcout << "Binary Path: " << imagePath << std::endl;
                            std::wcout << std::endl;
                        }

                        RegCloseKey(hServiceKey);
                    }
                }
            }
        }

        RegCloseKey(hKey);
    }
}

int main()
{
    EnumerateServices();

    return 0;
}

3、使用注册表接口,枚举当前计算启动项信息
#include 
#include 
#include 

void EnumerateStartupItems()
{
    HKEY hKey;

    // 枚举HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run键的值
    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
    {
        DWORD numValues;
        if (RegQueryInfoKeyW(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &numValues, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
        {
            for (DWORD i = 0; i < numValues; i++)
            {
                WCHAR valueName[MAX_PATH];
                DWORD valueNameSize = MAX_PATH;

                BYTE data[MAX_PATH];
                DWORD dataSize = MAX_PATH;

                DWORD valueType;

                if (RegEnumValueW(hKey, i, valueName, &valueNameSize, NULL, &valueType, data, &dataSize) == ERROR_SUCCESS)
                {
                    if (valueType == REG_SZ)
                    {
                        std::wcout << "Value Name: " << valueName << std::endl;
                        std::wcout << "Binary Path: " << reinterpret_cast<WCHAR*>(data) << std::endl;
                        std::wcout << std::endl;
                    }
                }
            }
        }

        RegCloseKey(hKey);
    }

    // 枚举HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run键的值
    if (RegOpenKeyExW(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
    {
        DWORD numValues;
        if (RegQueryInfoKeyW(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &numValues, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
        {
            for (DWORD i = 0; i < numValues; i++)
            {
                WCHAR valueName[MAX_PATH];
                DWORD valueNameSize = MAX_PATH;

                BYTE data[MAX_PATH];
                DWORD dataSize = MAX_PATH;

                DWORD valueType;

                if (RegEnumValueW(hKey, i, valueName, &valueNameSize, NULL, &valueType, data, &dataSize) == ERROR_SUCCESS)
                {
                    if (valueType == REG_SZ)
                    {
                        std::wcout << "Value Name: " << valueName << std::endl;
                        std::wcout << "Binary Path: " << reinterpret_cast<WCHAR*>(data) << std::endl;
                        std::wcout << std::endl;
                    }
                }
            }
        }

        RegCloseKey(hKey);
    }
}

int main()
{
    EnumerateStartupItems();

    return 0;
}

你可能感兴趣的:(上课内容,学习)