🤬
  • 1.添加参数过滤系统dll参数 2.优化当静态加载数量为1,也有动态加载时会被过滤掉的bug 3.修复hook DLLMain导致栈不平衡bug 4.优化有多个相同文件时,白程序只输出一次 5.修复相同动态加载dll记录多次bug

  • Loading...
  • maoku committed 1 month ago
    1f7908e9
    1 parent a36ce4b7
  • ■ ■ ■ ■ ■ ■
    README.md
    skipped 32 lines
    33 33   
    34 34  -l:过滤dll加载方式,1是静态加载,2是动态加载,3是静态加动态。默认值为3
    35 35   
     36 +-p:是否过滤系统dll,系统dll是指在system32或syswow64目录下存在的dll。默认为否
     37 + 
    36 38  B站地址:
    37 39   
    38 40  【一款自研的自动化挖掘白利用程序工具】 https://www.bilibili.com/video/BV1bm421n73Z/?share_source=copy_web&vd_source=c75cdcc6b49a06fd849f2d392e8e3218
    39 41   
     42 +### 版本更新日志
     43 + 
     44 +V2.0.0
     45 + 
     46 +1.添加参数过滤系统dll参数
     47 +2.优化当静态加载数量为1,也有动态加载时会被过滤掉的bug
     48 +3.修复hook DLLMain导致栈不平衡bug
     49 +4.优化有多个相同文件时,白程序只输出一次
     50 +5.修复相同动态加载dll记录多次bug
     51 + 
  • ■ ■ ■ ■ ■
    SearchAvailableExe/SearchAvailableExe.cpp
    skipped 56 lines
    57 57   }
    58 58  }
    59 59   
     60 +map<size_t, bool> fileHashMap;
    60 61  bool isUnwanted(const PResultInfo result) {
    61 62   int preSize = result->preLoadDlls.size();
    62 63   int postSize = result->postLoadDlls.size();
    skipped 2 lines
    65 66   return true;
    66 67   if ((c.bit == 32 && result->bit != 32) || (c.bit == 64 && result->bit != 64))
    67 68   return true;
    68  - if (preSize + postSize > c.dllCount)
     69 + if (preSize > c.dllCount)
    69 70   return true;
    70 71   
     72 + if (fileHashMap[result->fileHash])
     73 + return true;
     74 + fileHashMap[result->fileHash] = true;
     75 + 
    71 76   return false;
    72 77  }
    73 78   
    skipped 4 lines
    78 83   if ((c.loadType == 1 && result->loadType != 1) || (c.loadType == 2 && result->loadType != 2))
    79 84   return true;
    80 85   
     86 + int preSize = result->preLoadDlls.size();
     87 + int postSize = result->postLoadDlls.size();
     88 + 
     89 + //如果是动态加载,需要加上静态dll个数去判断
     90 + if (result->loadType == 2 && (preSize + postSize > c.dllCount))
     91 + return true;
     92 + 
     93 + if (c.isPassSystemDll && result->isSystemDll)
     94 + return true;
     95 + 
    81 96   return false;
    82 97  }
    83 98   
    skipped 34 lines
    118 133   printf(" -b,--bit: <count> Select the output bitness, supporting 32, 64, and 96 bits. The default is 96 bits, while also outputting information for 32 and 64-bit white programs.\n");
    119 134   printf(" -s,--save: <bool> Whether to save available files, default is not to save.\n");
    120 135   printf(" -l,--load: <loadType> Dll loading method, 1 for static loading, 2 for dynamic loading, and 3 for both static and dynamic loading. Default value is 3.\n");
     136 + printf(" -p,--pass: <bool> Filter system DLLs.\n");
    121 137   exit(0);
    122 138  }
    123 139   
    skipped 44 lines
    168 184   get_opt(argc, argv, OPT_TYPE_DEC, &c.bit, "b", "bit", validate_bit);
    169 185   get_opt(argc, argv, OPT_TYPE_FLAG, &c.isSaveFile, "s", "save", NULL);
    170 186   get_opt(argc, argv, OPT_TYPE_DEC, &c.loadType, "l", "load", NULL);
     187 + get_opt(argc, argv, OPT_TYPE_FLAG, &c.isPassSystemDll, "p", "pass", NULL);
    171 188   
    172 189   ostream* output = &cout;
    173 190   ofstream outputFile;
    skipped 45 lines
    219 236   *output << "程序位数: " << result->bit << " 目录是否可写: " << (result->isWrite==1 ? "是" : "否") << " Dll加载方式: " << (result->loadType == 1 ? "静态加载" : "动态加载") << endl;
    220 237   *output << "可利用DLL: " << result->exploitDllPath << endl;
    221 238   
    222  - if (result->preLoadDlls.size() + result->postLoadDlls.size() > 1) {
     239 + if ((result->loadType == 1 && result->preLoadDlls.size() > 1) || (result->loadType == 2 && result->preLoadDlls.size() + result->postLoadDlls.size() > 1)) {
    223 240   *output << "需要复制以下DLL: " << endl;
    224 241   if (result->preLoadDlls.size() > 0) {
    225 242   for (const auto& dll : result->preLoadDlls) {
    skipped 3 lines
    229 246   }
    230 247   }
    231 248   
    232  - if (result->postLoadDlls.size() > 0) {
     249 + if (result->loadType == 2 && result->postLoadDlls.size() > 0) {
    233 250   for (const auto& dll : result->postLoadDlls) {
    234 251   if (result->exploitDllPath != dll)
    235 252   *output << dll << endl;
    skipped 19 lines
  • ■ ■ ■ ■
    SearchAvailableExe/SearchAvailableExe.vcxproj.user
    1 1  <?xml version="1.0" encoding="utf-8"?>
    2 2  <Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    3 3   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    4  - <LocalDebuggerCommandArguments>-i "D:"</LocalDebuggerCommandArguments>
     4 + <LocalDebuggerCommandArguments>-i "D:\envPath\java\jdk1.8\lib\visualvm\platform\lib"</LocalDebuggerCommandArguments>
    5 5   <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
    6 6   </PropertyGroup>
    7 7   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    skipped 8 lines
  • ■ ■ ■ ■ ■ ■
    SearchAvailableExe/Tools.cpp
    skipped 150 lines
    151 151   
    152 152  void searchDll(BYTE* buffer, PResultInfo result, LPCWSTR filePath, char* dllsName, string fileDir) {
    153 153   DWORD rdataLength;
    154  - BYTE* rdata = readSectionData(buffer, &rdataLength, ".rdata");
    155  - if (rdata != 0) {
    156  - char fileFullPath[0x255] = { 0 };
    157  - strcat(fileFullPath, fileDir.c_str());
    158  - int fileDirLength = fileDir.length();
    159  - DWORD vaule, vaule1;
    160  - char* str;
    161  - int strLength;
    162  - char ch;
    163  - int index = 0;
     154 + char fileFullPath[0x255] = { 0 };
     155 + strcat(fileFullPath, fileDir.c_str());
     156 + int fileDirLength = fileDir.length();
     157 + map<string, bool> postDllMap;
     158 + char* secNames[] = {".rdata", ".rsrc"};
    164 159   
    165  - for (int i = rdataLength - 8; i > 0; --i, index = 0) {
    166  - vaule = *(PDWORD)((PBYTE)rdata + i);
    167  - vaule1 = *(PDWORD)((PBYTE)rdata + i + 4);
     160 + for (int i = 0; i < 2; i++) {
     161 + BYTE* rdata = readSectionData(buffer, &rdataLength, secNames[i]);
     162 + if (rdata != 0) {
     163 + DWORD vaule, vaule1;
     164 + char* str;
     165 + int strLength;
     166 + char ch;
     167 + int index = 0;
     168 + 
     169 + for (int i = rdataLength - 8; i > 0; --i, index = 0) {
     170 + vaule = *(PDWORD)((PBYTE)rdata + i);
     171 + vaule1 = *(PDWORD)((PBYTE)rdata + i + 4);
    168 172   
    169  - if (vaule == 0x6c6c642e)
    170  - index = 1;
    171  - else if (vaule1 == 0x6c && vaule == 0x6c0064)
    172  - index = 2;
     173 + if (vaule == 0x6c6c642e)
     174 + index = 1;
     175 + else if (vaule1 == 0x6c && vaule == 0x6c0064)
     176 + index = 2;
    173 177   
    174  - if (index > 0) {
    175  - i -= index;
    176  - ch = rdata[i];
    177  - while (((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || ch == '_' || ch == '.' || ch == '-')) {
     178 + if (index > 0) {
    178 179   i -= index;
    179 180   ch = rdata[i];
    180  - }
     181 + while (((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || ch == '_' || ch == '.' || ch == '-')) {
     182 + i -= index;
     183 + ch = rdata[i];
     184 + }
    181 185   
    182  - if (ch != 0)
    183  - continue;
     186 + if (ch != 0)
     187 + continue;
    184 188   
    185  - if (index == 1)
    186  - str = (char*)(rdata + i + 1);
    187  - else
    188  - str = ConvertWideToMultiByte((wchar_t*)(rdata + i + 2));
     189 + if (index == 1)
     190 + str = (char*)(rdata + i + 1);
     191 + else
     192 + str = ConvertWideToMultiByte((wchar_t*)(rdata + i + 2));
    189 193   
    190  - strLength = strlen(str);
    191  - if (str[strLength-1] != 'l')
    192  - continue;
     194 + strLength = strlen(str);
     195 + if (str[strLength - 1] != 'l')
     196 + continue;
    193 197   
    194  - memcpy(fileFullPath + fileDirLength, str, strLength + 1);
     198 + memcpy(fileFullPath + fileDirLength, str, strLength + 1);
    195 199   
    196  - if (filesystem::exists(filesystem::path(fileFullPath)) && containsIgnoreCase(dllsName, str) == NULL)
    197  - result->postLoadDlls.push_back(_strdup(str));
     200 + if (postDllMap[str] == false && filesystem::exists(filesystem::path(fileFullPath)) && containsIgnoreCase(dllsName, str) == NULL) {
     201 + result->postLoadDlls.push_back(_strdup(str));
     202 + postDllMap[str] = true;
     203 + }
     204 + }
    198 205   }
    199 206   }
    200 207   }
    skipped 108 lines
    309 316   return;
    310 317  }
    311 318   
     319 +size_t memorySum(LPVOID shellcode, DWORD fileSize)
     320 +{
     321 + size_t sum = 0;
     322 + for (int i = 0; i < fileSize; i+=0x10)
     323 + sum += *(size_t*)((PBYTE)shellcode + i);
     324 + return sum;
     325 +}
     326 + 
    312 327  BOOL VerifyFileSignature(LPCWSTR filePath) {
    313 328   DWORD dwEncoding, dwContentType, dwFormatType;
    314 329   HCERTSTORE hStore = NULL;
    skipped 53 lines
    368 383  
    369 384   ResultInfo* result = new ResultInfo;
    370 385   result->filePath = wstring2string(filePath);
     386 + result->isCreateWindow = false;
     387 + result->isSystemDll = false;
     388 + result->fileHash = memorySum(pbFile, dwFileSize);
    371 389  
    372 390   printImportTableInfo(pbFile, result, filePath);
    373 391   
    skipped 234 lines
    608 626   indexs[count++] = (size_t)ImportTable;
    609 627   }
    610 628   
     629 + DWORD offset = 0;
    611 630   if (!isHook && strstr(pName, "kernel32.dll") != NULL) {
    612 631   addr = getImportFuncAddr(targetBuffer, ImportTable, "ExitProcess", bit, false, NULL);
    613 632   if (addr != 0) {
    614  - repairReloc(targetBuffer, clear, 0, oep + 11);
    615  - 
    616 633   if (bit == 64) {
    617  - unsigned char hook_data[] = { 0xB9, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x15, 0xC8, 0xEF, 0x00, 0x00 };
    618  - improtFunc = addr - (oep + 11);
    619  - memcpy((char*)oep_foa_addr, hook_data, 11);
     634 + unsigned char hook_data[] = { 0x48, 0x83, 0xEC, 0x28, 0xB9, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x15, 0xC8, 0xEF, 0x00, 0x00 };
     635 + improtFunc = addr - (oep + sizeof(hook_data));
     636 + memcpy((char*)oep_foa_addr, hook_data, sizeof(hook_data));
     637 + repairReloc(targetBuffer, clear, 0, oep + sizeof(hook_data));
     638 + offset = 4;
    620 639   }
    621 640   else {
    622  - unsigned char hook_data[] = { 0x68, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x15, 0x08, 0x20, 0x40, 0x00 };
     641 + unsigned char hook_data[] = { 0x83, 0xEC, 0x14, 0x68, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x15, 0x08, 0x20, 0x40, 0x00 };
    623 642   improtFunc = imageBase + addr;
    624  - memcpy((char*)oep_foa_addr, hook_data, 11);
     643 + memcpy((char*)oep_foa_addr, hook_data, sizeof(hook_data));
     644 + repairReloc(targetBuffer, clear, 0, oep + sizeof(hook_data));
     645 + offset = 3;
    625 646   
    626  - DWORD dataRva[] = { oep + 7 };
     647 + DWORD dataRva[] = { oep + 7 + offset };
    627 648   repairReloc(targetBuffer, dataRva, 1, 0);
    628 649   }
    629 650   
    630  - *(PDWORD)(oep_foa_addr + 1) = exitCode;
    631  - *(PDWORD)(oep_foa_addr + 7) = improtFunc;
     651 + *(PDWORD)(oep_foa_addr + 1 + offset) = exitCode;
     652 + *(PDWORD)(oep_foa_addr + 7 + offset) = improtFunc;
    632 653   isHook = true;
    633 654   }
    634 655   }
    635 656   else if (!isHook && strstr(pName, "ntdll.dll") != NULL) {
    636 657   addr = getImportFuncAddr(targetBuffer, ImportTable, "NtTerminateProcess", bit, false, NULL);
    637 658   if (addr != 0) {
    638  - repairReloc(targetBuffer, clear, 0, oep + 16);
    639  - 
    640 659   if (bit == 64) {
    641  - unsigned char hook_data[] = { 0xBA, 0x00, 0x00, 0x00, 0x00, 0xB9, 0xff, 0xff, 0xff, 0xff, 0xFF, 0x15, 0xC8, 0xEF, 0x00, 0x00 };
    642  - improtFunc = addr - (oep + 16);
    643  - memcpy((char*)oep_foa_addr, hook_data, 16);
     660 + unsigned char hook_data[] = { 0x48, 0x83, 0xEC, 0x28, 0xBA, 0x00, 0x00, 0x00, 0x00, 0xB9, 0xff, 0xff, 0xff, 0xff, 0xFF, 0x15, 0xC8, 0xEF, 0x00, 0x00 };
     661 + improtFunc = addr - (oep + sizeof(hook_data));
     662 + memcpy((char*)oep_foa_addr, hook_data, sizeof(hook_data));
     663 + repairReloc(targetBuffer, clear, 0, oep + sizeof(hook_data));
     664 + offset = 4;
    644 665   }
    645 666   else {
    646  - unsigned char hook_data[] = { 0x68, 0x00, 0x00, 0x00, 0x00, 0x68, 0xff, 0xff, 0xff, 0xff, 0xFF, 0x15, 0x08, 0x20, 0x40, 0x00 };
     667 + unsigned char hook_data[] = { 0x83, 0xEC, 0x14, 0x68, 0x00, 0x00, 0x00, 0x00, 0x68, 0xff, 0xff, 0xff, 0xff, 0xFF, 0x15, 0x08, 0x20, 0x40, 0x00 };
    647 668   improtFunc = imageBase + addr;
    648  - memcpy((char*)oep_foa_addr, hook_data, 16);
     669 + memcpy((char*)oep_foa_addr, hook_data, sizeof(hook_data));
     670 + repairReloc(targetBuffer, clear, 0, oep + sizeof(hook_data));
     671 + offset = 3;
    649 672   
    650  - DWORD dataRva[] = { oep + 12 };
     673 + DWORD dataRva[] = { oep + 12 + offset };
    651 674   repairReloc(targetBuffer, dataRva, 1, 0);
    652 675   }
    653 676   
    654  - *(PDWORD)(oep_foa_addr + 1) = exitCode;
    655  - *(PDWORD)(oep_foa_addr + 12) = improtFunc;
     677 + *(PDWORD)(oep_foa_addr + 1 + offset) = exitCode;
     678 + *(PDWORD)(oep_foa_addr + 12 + offset) = improtFunc;
    656 679   isHook = true;
    657 680   }
    658 681   }
    skipped 275 lines
    934 957   
    935 958   if (!std::filesystem::exists(folderPath + "\\test.txt"))
    936 959   result->exploitDllPath = "";
     960 + 
     961 + if (std::filesystem::exists("C:\\Windows\\SysWOW64\\" + result->exploitDllPath) || std::filesystem::exists("C:\\Windows\\System32\\" + result->exploitDllPath))
     962 + result->isSystemDll = true;
    937 963   }
    938 964  
    939 965   if (!(c.isSaveFile && result->exploitDllPath != ""))
    skipped 2 lines
  • ■ ■ ■ ■ ■
    SearchAvailableExe/Tools.h
    skipped 17 lines
    18 18   
    19 19  typedef struct {
    20 20   bool isWrite;
    21  - bool isSaveFile;
    22 21   string filePath;
    23 22   string fileDir;
    24 23   int bit;
    skipped 2 lines
    27 26   vector<char*> postLoadDlls;
    28 27   string exploitDllPath;
    29 28   int loadType;
     29 + bool isSystemDll;
     30 + size_t fileHash;
    30 31  } ResultInfo, * PResultInfo;
    31 32   
    32 33  #define STRING_MAX 256
    skipped 5 lines
    38 39   int bit;
    39 40   bool isSaveFile;
    40 41   int loadType;
     42 + bool isPassSystemDll;
    41 43  } ARG_CONFIG, * PARG_CONFIG;
    42 44   
    43 45  BOOL VerifyFileSignature(LPCWSTR filePath);
    skipped 4 lines
  • Test/SearchAvailableExe32.exe
    Binary file.
  • Test/SearchAvailableExe64.exe
    Binary file.
  • Test/TestLoad_x64.dll
    Binary file.
  • Test/TestLoad_x86.dll
    Binary file.
Please wait...
Page is in error, reload to recover