FFFTPのソースコードです。
Revisão | 1d38d1729082dfaadf5a9e2c1b16afc6789aaceb (tree) |
---|---|
Hora | 2011-10-10 19:23:00 |
Autor | s_kawamoto <s_kawamoto@user...> |
Commiter | s_kawamoto |
Add process protection levels (--protect-high by default but --protect-medium and --protect-low mainly for halfway signed modules).
@@ -234,21 +234,37 @@ int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLi | ||
234 | 234 | |
235 | 235 | // プロセス保護 |
236 | 236 | #ifdef ENABLE_PROCESS_PROTECTION |
237 | - BOOL bProtect; | |
237 | + DWORD ProtectLevel; | |
238 | 238 | char* pCommand; |
239 | 239 | char Option[FMAX_PATH+1]; |
240 | - bProtect = FALSE; | |
240 | + ProtectLevel = PROCESS_PROTECTION_NONE; | |
241 | 241 | pCommand = lpszCmdLine; |
242 | 242 | while(pCommand = GetToken(pCommand, Option)) |
243 | 243 | { |
244 | 244 | if(strcmp(Option, "--protect") == 0) |
245 | 245 | { |
246 | - bProtect = TRUE; | |
246 | + ProtectLevel = PROCESS_PROTECTION_DEFAULT; | |
247 | + break; | |
248 | + } | |
249 | + else if(strcmp(Option, "--protect-high") == 0) | |
250 | + { | |
251 | + ProtectLevel = PROCESS_PROTECTION_HIGH; | |
252 | + break; | |
253 | + } | |
254 | + else if(strcmp(Option, "--protect-medium") == 0) | |
255 | + { | |
256 | + ProtectLevel = PROCESS_PROTECTION_MEDIUM; | |
257 | + break; | |
258 | + } | |
259 | + else if(strcmp(Option, "--protect-low") == 0) | |
260 | + { | |
261 | + ProtectLevel = PROCESS_PROTECTION_LOW; | |
247 | 262 | break; |
248 | 263 | } |
249 | 264 | } |
250 | - if(bProtect) | |
265 | + if(ProtectLevel != PROCESS_PROTECTION_NONE) | |
251 | 266 | { |
267 | + SetProcessProtectionLevel(ProtectLevel); | |
252 | 268 | if(!InitializeLoadLibraryHook()) |
253 | 269 | { |
254 | 270 | MessageBox(NULL, MSGJPN321, "FFFTP", MB_OK | MB_ICONERROR); |
@@ -1755,6 +1771,15 @@ static int AnalyzeComLine(char *Str, int *AutoConnect, int *CmdOption, char *unc | ||
1755 | 1771 | else if(strcmp(Tmp, "--protect") == 0) |
1756 | 1772 | { |
1757 | 1773 | } |
1774 | + else if(strcmp(Tmp, "--protect-high") == 0) | |
1775 | + { | |
1776 | + } | |
1777 | + else if(strcmp(Tmp, "--protect-medium") == 0) | |
1778 | + { | |
1779 | + } | |
1780 | + else if(strcmp(Tmp, "--protect-low") == 0) | |
1781 | + { | |
1782 | + } | |
1758 | 1783 | #endif |
1759 | 1784 | else |
1760 | 1785 | { |
@@ -55,7 +55,7 @@ BOOL HookFunctionInCode(void* pOriginal, void* pNew, void* pBackupCode, BOOL bRe | ||
55 | 55 | BOOL HookFunctionInIAT(void* pOriginal, void* pNew); |
56 | 56 | #endif |
57 | 57 | HANDLE LockExistingFile(LPCWSTR Filename); |
58 | -BOOL FindTrustedModuleMD5Hash(void* pHash); | |
58 | +BOOL FindTrustedModuleSHA1Hash(void* pHash); | |
59 | 59 | BOOL VerifyFileSignature(LPCWSTR Filename); |
60 | 60 | BOOL VerifyFileSignatureInCatalog(LPCWSTR Catalog, LPCWSTR Filename); |
61 | 61 | BOOL GetSHA1HashOfModule(LPCWSTR Filename, void* pHash); |
@@ -96,9 +96,10 @@ _CryptCATAdminCalcHashFromFileHandle p_CryptCATAdminCalcHashFromFileHandle; | ||
96 | 96 | #define MAX_TRUSTED_FILENAME_TABLE 16 |
97 | 97 | #define MAX_TRUSTED_MD5_HASH_TABLE 16 |
98 | 98 | |
99 | +DWORD g_ProcessProtectionLevel; | |
99 | 100 | DWORD g_LockedThread[MAX_LOCKED_THREAD]; |
100 | 101 | WCHAR* g_pTrustedFilenameTable[MAX_TRUSTED_FILENAME_TABLE]; |
101 | -BYTE g_TrustedMD5HashTable[MAX_TRUSTED_MD5_HASH_TABLE][16]; | |
102 | +BYTE g_TrustedMD5HashTable[MAX_TRUSTED_MD5_HASH_TABLE][20]; | |
102 | 103 | |
103 | 104 | // 以下フック関数 |
104 | 105 | // フック対象を呼び出す場合は前後でSTART_HOOK_FUNCTIONとEND_HOOK_FUNCTIONを実行する必要がある |
@@ -169,19 +170,15 @@ HMODULE WINAPI h_LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFla | ||
169 | 170 | hLock = LockExistingFile(lpLibFileName); |
170 | 171 | FreeLibrary(hModule); |
171 | 172 | } |
172 | - if(GetModuleHandleW(lpLibFileName)) | |
173 | + if((g_ProcessProtectionLevel & PROCESS_PROTECTION_LOADED) && GetModuleHandleW(lpLibFileName)) | |
173 | 174 | bTrusted = TRUE; |
174 | 175 | } |
175 | 176 | if(!bTrusted) |
176 | 177 | { |
177 | - if(LockThreadLock()) | |
178 | + if(hLock) | |
178 | 179 | { |
179 | - if(hLock) | |
180 | - { | |
181 | - if(IsModuleTrusted(lpLibFileName)) | |
182 | - bTrusted = TRUE; | |
183 | - } | |
184 | - UnlockThreadLock(); | |
180 | + if(IsModuleTrusted(lpLibFileName)) | |
181 | + bTrusted = TRUE; | |
185 | 182 | } |
186 | 183 | } |
187 | 184 | if(bTrusted) |
@@ -370,7 +367,7 @@ HANDLE LockExistingFile(LPCWSTR Filename) | ||
370 | 367 | } |
371 | 368 | |
372 | 369 | // DLLのハッシュを検索 |
373 | -BOOL FindTrustedModuleMD5Hash(void* pHash) | |
370 | +BOOL FindTrustedModuleSHA1Hash(void* pHash) | |
374 | 371 | { |
375 | 372 | BOOL bResult; |
376 | 373 | int i; |
@@ -378,7 +375,7 @@ BOOL FindTrustedModuleMD5Hash(void* pHash) | ||
378 | 375 | i = 0; |
379 | 376 | while(i < MAX_TRUSTED_MD5_HASH_TABLE) |
380 | 377 | { |
381 | - if(memcmp(&g_TrustedMD5HashTable[i], pHash, 16) == 0) | |
378 | + if(memcmp(&g_TrustedMD5HashTable[i], pHash, 20) == 0) | |
382 | 379 | { |
383 | 380 | bResult = TRUE; |
384 | 381 | break; |
@@ -395,6 +392,7 @@ BOOL VerifyFileSignature(LPCWSTR Filename) | ||
395 | 392 | GUID g = WINTRUST_ACTION_GENERIC_VERIFY_V2; |
396 | 393 | WINTRUST_FILE_INFO wfi; |
397 | 394 | WINTRUST_DATA wd; |
395 | + LONG Error; | |
398 | 396 | bResult = FALSE; |
399 | 397 | ZeroMemory(&wfi, sizeof(WINTRUST_FILE_INFO)); |
400 | 398 | wfi.cbStruct = sizeof(WINTRUST_FILE_INFO); |
@@ -404,7 +402,12 @@ BOOL VerifyFileSignature(LPCWSTR Filename) | ||
404 | 402 | wd.dwUIChoice = WTD_UI_NONE; |
405 | 403 | wd.dwUnionChoice = WTD_CHOICE_FILE; |
406 | 404 | wd.pFile = &wfi; |
407 | - if(WinVerifyTrust((HWND)INVALID_HANDLE_VALUE, &g, &wd) == ERROR_SUCCESS) | |
405 | + Error = WinVerifyTrust((HWND)INVALID_HANDLE_VALUE, &g, &wd); | |
406 | + if(Error == ERROR_SUCCESS) | |
407 | + bResult = TRUE; | |
408 | + else if((g_ProcessProtectionLevel & PROCESS_PROTECTION_EXPIRED) && Error == CERT_E_EXPIRED) | |
409 | + bResult = TRUE; | |
410 | + else if((g_ProcessProtectionLevel & PROCESS_PROTECTION_UNAUTHORIZED) && (Error == CERT_E_UNTRUSTEDROOT || Error == CERT_E_UNTRUSTEDCA)) | |
408 | 411 | bResult = TRUE; |
409 | 412 | return bResult; |
410 | 413 | } |
@@ -416,6 +419,7 @@ BOOL VerifyFileSignatureInCatalog(LPCWSTR Catalog, LPCWSTR Filename) | ||
416 | 419 | GUID g = WINTRUST_ACTION_GENERIC_VERIFY_V2; |
417 | 420 | WINTRUST_CATALOG_INFO wci; |
418 | 421 | WINTRUST_DATA wd; |
422 | + LONG Error; | |
419 | 423 | bResult = FALSE; |
420 | 424 | if(VerifyFileSignature(Catalog)) |
421 | 425 | { |
@@ -435,7 +439,12 @@ BOOL VerifyFileSignatureInCatalog(LPCWSTR Catalog, LPCWSTR Filename) | ||
435 | 439 | wd.dwUIChoice = WTD_UI_NONE; |
436 | 440 | wd.dwUnionChoice = WTD_CHOICE_CATALOG; |
437 | 441 | wd.pCatalog = &wci; |
438 | - if(WinVerifyTrust((HWND)INVALID_HANDLE_VALUE, &g, &wd) == ERROR_SUCCESS) | |
442 | + Error = WinVerifyTrust((HWND)INVALID_HANDLE_VALUE, &g, &wd); | |
443 | + if(Error == ERROR_SUCCESS) | |
444 | + bResult = TRUE; | |
445 | + else if((g_ProcessProtectionLevel & PROCESS_PROTECTION_EXPIRED) && Error == CERT_E_EXPIRED) | |
446 | + bResult = TRUE; | |
447 | + else if((g_ProcessProtectionLevel & PROCESS_PROTECTION_UNAUTHORIZED) && (Error == CERT_E_UNTRUSTEDROOT || Error == CERT_E_UNTRUSTEDCA)) | |
439 | 448 | bResult = TRUE; |
440 | 449 | } |
441 | 450 | free(wci.pbCalculatedFileHash); |
@@ -635,31 +644,34 @@ BOOL IsSxsModuleTrusted(LPCWSTR Filename) | ||
635 | 644 | } |
636 | 645 | |
637 | 646 | // DLLを確認 |
638 | -// ハッシュが登録されている、Authenticode署名がされている、またはWFPによる保護下にあることを確認 | |
639 | 647 | BOOL IsModuleTrusted(LPCWSTR Filename) |
640 | 648 | { |
641 | 649 | BOOL bResult; |
642 | - BYTE Hash[16]; | |
650 | + BYTE Hash[20]; | |
643 | 651 | bResult = FALSE; |
644 | - if(GetMD5HashOfFile(Filename, &Hash)) | |
652 | + if(LockThreadLock()) | |
645 | 653 | { |
646 | - if(FindTrustedModuleMD5Hash(&Hash)) | |
647 | - bResult = TRUE; | |
648 | - } | |
649 | - if(!bResult) | |
650 | - { | |
651 | - if(VerifyFileSignature(Filename)) | |
652 | - bResult = TRUE; | |
653 | - } | |
654 | - if(!bResult) | |
655 | - { | |
656 | - if(IsSxsModuleTrusted(Filename)) | |
657 | - bResult = TRUE; | |
658 | - } | |
659 | - if(!bResult) | |
660 | - { | |
661 | - if(SfcIsFileProtected(NULL, Filename)) | |
662 | - bResult = TRUE; | |
654 | + if(GetSHA1HashOfFile(Filename, &Hash)) | |
655 | + { | |
656 | + if(FindTrustedModuleSHA1Hash(&Hash)) | |
657 | + bResult = TRUE; | |
658 | + } | |
659 | + if(!bResult) | |
660 | + { | |
661 | + if((g_ProcessProtectionLevel & PROCESS_PROTECTION_BUILTIN) && VerifyFileSignature(Filename)) | |
662 | + bResult = TRUE; | |
663 | + } | |
664 | + if(!bResult) | |
665 | + { | |
666 | + if((g_ProcessProtectionLevel & PROCESS_PROTECTION_SIDE_BY_SIDE) && IsSxsModuleTrusted(Filename)) | |
667 | + bResult = TRUE; | |
668 | + } | |
669 | + if(!bResult) | |
670 | + { | |
671 | + if((g_ProcessProtectionLevel & PROCESS_PROTECTION_SYSTEM_FILE) && SfcIsFileProtected(NULL, Filename)) | |
672 | + bResult = TRUE; | |
673 | + } | |
674 | + UnlockThreadLock(); | |
663 | 675 | } |
664 | 676 | return bResult; |
665 | 677 | } |
@@ -739,8 +751,13 @@ HMODULE System_LoadLibrary(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) | ||
739 | 751 | return r; |
740 | 752 | } |
741 | 753 | |
742 | -// ファイルのMD5ハッシュを取得 | |
743 | -BOOL GetMD5HashOfFile(LPCWSTR Filename, void* pHash) | |
754 | +void SetProcessProtectionLevel(DWORD Level) | |
755 | +{ | |
756 | + g_ProcessProtectionLevel = Level; | |
757 | +} | |
758 | + | |
759 | +// ファイルのSHA1ハッシュを取得 | |
760 | +BOOL GetSHA1HashOfFile(LPCWSTR Filename, void* pHash) | |
744 | 761 | { |
745 | 762 | BOOL bResult; |
746 | 763 | HCRYPTPROV hProv; |
@@ -752,7 +769,7 @@ BOOL GetMD5HashOfFile(LPCWSTR Filename, void* pHash) | ||
752 | 769 | bResult = FALSE; |
753 | 770 | if(CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_FULL, 0) || CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)) |
754 | 771 | { |
755 | - if(CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) | |
772 | + if(CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash)) | |
756 | 773 | { |
757 | 774 | if((hFile = CreateFileW(Filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE) |
758 | 775 | { |
@@ -764,7 +781,7 @@ BOOL GetMD5HashOfFile(LPCWSTR Filename, void* pHash) | ||
764 | 781 | { |
765 | 782 | if(CryptHashData(hHash, (BYTE*)pData, Size, 0)) |
766 | 783 | { |
767 | - dw = 16; | |
784 | + dw = 20; | |
768 | 785 | if(CryptGetHashParam(hHash, HP_HASHVAL, (BYTE*)pHash, &dw, 0)) |
769 | 786 | bResult = TRUE; |
770 | 787 | } |
@@ -782,22 +799,22 @@ BOOL GetMD5HashOfFile(LPCWSTR Filename, void* pHash) | ||
782 | 799 | } |
783 | 800 | |
784 | 801 | // DLLのハッシュを登録 |
785 | -BOOL RegisterTrustedModuleMD5Hash(void* pHash) | |
802 | +BOOL RegisterTrustedModuleSHA1Hash(void* pHash) | |
786 | 803 | { |
787 | 804 | BOOL bResult; |
788 | - BYTE NullHash[16] = {0}; | |
805 | + BYTE NullHash[20] = {0}; | |
789 | 806 | int i; |
790 | 807 | bResult = FALSE; |
791 | - if(FindTrustedModuleMD5Hash(pHash)) | |
808 | + if(FindTrustedModuleSHA1Hash(pHash)) | |
792 | 809 | bResult = TRUE; |
793 | 810 | else |
794 | 811 | { |
795 | 812 | i = 0; |
796 | 813 | while(i < MAX_TRUSTED_MD5_HASH_TABLE) |
797 | 814 | { |
798 | - if(memcmp(&g_TrustedMD5HashTable[i], &NullHash, 16) == 0) | |
815 | + if(memcmp(&g_TrustedMD5HashTable[i], &NullHash, 20) == 0) | |
799 | 816 | { |
800 | - memcpy(&g_TrustedMD5HashTable[i], pHash, 16); | |
817 | + memcpy(&g_TrustedMD5HashTable[i], pHash, 20); | |
801 | 818 | bResult = TRUE; |
802 | 819 | break; |
803 | 820 | } |
@@ -808,18 +825,18 @@ BOOL RegisterTrustedModuleMD5Hash(void* pHash) | ||
808 | 825 | } |
809 | 826 | |
810 | 827 | // DLLのハッシュの登録を解除 |
811 | -BOOL UnregisterTrustedModuleMD5Hash(void* pHash) | |
828 | +BOOL UnregisterTrustedModuleSHA1Hash(void* pHash) | |
812 | 829 | { |
813 | 830 | BOOL bResult; |
814 | - BYTE NullHash[16] = {0}; | |
831 | + BYTE NullHash[20] = {0}; | |
815 | 832 | int i; |
816 | 833 | bResult = FALSE; |
817 | 834 | i = 0; |
818 | 835 | while(i < MAX_TRUSTED_MD5_HASH_TABLE) |
819 | 836 | { |
820 | - if(memcmp(&g_TrustedMD5HashTable[i], pHash, 16) == 0) | |
837 | + if(memcmp(&g_TrustedMD5HashTable[i], pHash, 20) == 0) | |
821 | 838 | { |
822 | - memcpy(&g_TrustedMD5HashTable[i], &NullHash, 16); | |
839 | + memcpy(&g_TrustedMD5HashTable[i], &NullHash, 20); | |
823 | 840 | bResult = TRUE; |
824 | 841 | break; |
825 | 842 | } |
@@ -44,10 +44,30 @@ EXTERN_HOOK_FUNCTION_VAR(LoadLibraryExW) | ||
44 | 44 | |
45 | 45 | #endif |
46 | 46 | |
47 | +// ロード済みのモジュールは検査をパス | |
48 | +#define PROCESS_PROTECTION_LOADED 0x00000001 | |
49 | +// モジュールに埋め込まれたAuthenticode署名を検査 | |
50 | +#define PROCESS_PROTECTION_BUILTIN 0x00000002 | |
51 | +// サイドバイサイドのAuthenticode署名を検査 | |
52 | +#define PROCESS_PROTECTION_SIDE_BY_SIDE 0x00000004 | |
53 | +// WFPによる保護下にあるかを検査 | |
54 | +#define PROCESS_PROTECTION_SYSTEM_FILE 0x00000008 | |
55 | +// Authenticode署名の有効期限を無視 | |
56 | +#define PROCESS_PROTECTION_EXPIRED 0x00000010 | |
57 | +// Authenticode署名の発行元を無視 | |
58 | +#define PROCESS_PROTECTION_UNAUTHORIZED 0x00000020 | |
59 | + | |
60 | +#define PROCESS_PROTECTION_NONE 0 | |
61 | +#define PROCESS_PROTECTION_DEFAULT PROCESS_PROTECTION_HIGH | |
62 | +#define PROCESS_PROTECTION_HIGH (PROCESS_PROTECTION_BUILTIN | PROCESS_PROTECTION_SIDE_BY_SIDE | PROCESS_PROTECTION_SYSTEM_FILE) | |
63 | +#define PROCESS_PROTECTION_MEDIUM (PROCESS_PROTECTION_HIGH | PROCESS_PROTECTION_LOADED | PROCESS_PROTECTION_EXPIRED) | |
64 | +#define PROCESS_PROTECTION_LOW (PROCESS_PROTECTION_MEDIUM | PROCESS_PROTECTION_UNAUTHORIZED) | |
65 | + | |
47 | 66 | HMODULE System_LoadLibrary(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags); |
48 | -BOOL GetMD5HashOfFile(LPCWSTR Filename, void* pHash); | |
49 | -BOOL RegisterTrustedModuleMD5Hash(void* pHash); | |
50 | -BOOL UnregisterTrustedModuleMD5Hash(void* pHash); | |
67 | +void SetProcessProtectionLevel(DWORD Level); | |
68 | +BOOL GetSHA1HashOfFile(LPCWSTR Filename, void* pHash); | |
69 | +BOOL RegisterTrustedModuleSHA1Hash(void* pHash); | |
70 | +BOOL UnregisterTrustedModuleSHA1Hash(void* pHash); | |
51 | 71 | BOOL UnloadUntrustedModule(); |
52 | 72 | BOOL InitializeLoadLibraryHook(); |
53 | 73 | BOOL EnableLoadLibraryHook(BOOL bEnable); |
@@ -67,11 +67,12 @@ BOOL LoadOpenSSL() | ||
67 | 67 | if(g_bOpenSSLLoaded) |
68 | 68 | return FALSE; |
69 | 69 | #ifdef ENABLE_PROCESS_PROTECTION |
70 | + // 同梱するOpenSSLのバージョンに合わせてSHA1ハッシュ値を変更すること | |
70 | 71 | // ssleay32.dll 1.0.0e |
71 | 72 | // libssl32.dll 1.0.0e |
72 | - RegisterTrustedModuleMD5Hash("\x8B\xA3\xB7\xB3\xCE\x2E\x4F\x07\x8C\xB8\x93\x7D\x77\xE1\x09\x3A"); | |
73 | + RegisterTrustedModuleSHA1Hash("\x4E\xB7\xA0\x22\x14\x4B\x58\x6D\xBC\xF5\x21\x0D\x96\x78\x0D\x79\x7D\x66\xB2\xB0"); | |
73 | 74 | // libeay32.dll 1.0.0e |
74 | - RegisterTrustedModuleMD5Hash("\xA6\x4C\xAF\x9E\xF3\xDC\xFC\x68\xAE\xCA\xCC\x61\xD2\xF6\x70\x8B"); | |
75 | + RegisterTrustedModuleSHA1Hash("\x01\x32\x7A\xAE\x69\x26\xE6\x58\xC7\x63\x22\x1E\x53\x5A\x78\xBC\x61\xC7\xB5\xC1"); | |
75 | 76 | #endif |
76 | 77 | g_hOpenSSL = LoadLibrary("ssleay32.dll"); |
77 | 78 | if(!g_hOpenSSL) |