惡意代碼的分類包括計算機病毒、蠕蟲、木馬、后門、Rootkit、流氓軟件、間諜軟件、廣告軟件、僵尸(bot) 、Exploit等等,有些技術經常用到,有的也是必然用到。
惡意代碼常見功能技術如下:進程遍歷,文件遍歷,按鍵記錄,后門,桌面截屏,文件監控,自刪除,U盤監控。知己知彼,百戰不殆。這里旨在給反病毒工程師提供參照。病毒作者請繞過。
進程遍歷
進程遍歷獲取計算機上所有進程的信息(用戶進程,系統進程),通常是為了檢索受害進程,檢測是否運行在虛擬機中,以及是否存在殺軟等,有時候反調試技術也會檢測進程名。所以在惡意代碼中進程遍歷很常見。
具體流程:
1、調用CreateToolhelp32Snapshot獲取所有進程的快照信息之所以稱為快照是因為保存的是之前的信息,該函數返回進程快照句柄。
2、調用Process32First獲取第一個進程的信息,返回的進程信息保存在PROCESSENTRY32結構體中,該函數的第一個參數是CreateToolhelp32Snapshot返回的快照句柄。
3、循環調用Process32Next從進程列表中獲取下一個進程的信息,直到Process32Next函數返回FALSE,GetLastError的錯誤碼為ERROR_NO_MORE_FILES,則遍歷結束。
4、關閉快照句柄并釋放資源
遍歷線程和進程模塊的步驟和上面的相似,線程遍歷使用Thread32First和Thread32Next,模塊遍歷使用Module32First和Module32Next。
源碼實現:
void ShowError(char *lpszText)
{
char szErr[MAX_PATH] = {0};
::wsprintf(szErr, "%s Error[%d] ", lpszText, ::GetLastError());
::MessageBox(NULL, szErr, "ERROR", MB_OK);
}
BOOL EnumProcess()
{
PROCESSENTRY32 pe32 = { 0 };
pe32.dwSize = sizeof(PROCESSENTRY32);
// 獲取全部進程快照
HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (INVALID_HANDLE_VALUE == hProcessSnap)
{
ShowError("CreateToolhelp32Snapshot");
return FALSE;
}
// 獲取快照中第一條信息
BOOL bRet = ::Process32First(hProcessSnap, &pe32);
while (bRet)
{
// 顯示 Process ID
printf("[%d] ", pe32.th32ProcessID);
// 顯示 進程名稱
printf("[%s] ", pe32.szExeFile);
// 獲取快照中下一條信息
bRet = ::Process32Next(hProcessSnap, &pe32);
}
// 關閉句柄
::CloseHandle(hProcessSnap);
return TRUE;
}
BOOL EnumThread()
{
THREADENTRY32 te32 = { 0 };
te32.dwSize = sizeof(THREADENTRY32);
// 獲取全部線程快照
HANDLE hThreadSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (INVALID_HANDLE_VALUE == hThreadSnap)
{
ShowError("CreateToolhelp32Snapshot");
return FALSE;
}
// 獲取快照中第一條信息
BOOL bRet = ::Thread32First(hThreadSnap, &te32);
while (bRet)
{
// 顯示 Owner Process ID
printf("[%d] ", te32.th32OwnerProcessID);
// 顯示 Thread ID
printf("[%d] ", te32.th32ThreadID);
// 獲取快照中下一條信息
bRet = ::Thread32Next(hThreadSnap, &te32);
}
// 關閉句柄
::CloseHandle(hThreadSnap);
return TRUE;
}
BOOL EnumProcessModule(DWORD dwProcessId)
{
MODULEENTRY32 me32 = { 0 };
me32.dwSize = sizeof(MODULEENTRY32);
// 獲取指定進程全部模塊的快照
HANDLE hModuleSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessId);
if (INVALID_HANDLE_VALUE == hModuleSnap)
{
ShowError("CreateToolhelp32Snapshot");
return FALSE;
}
// 獲取快照中第一條信息
BOOL bRet = ::Module32First(hModuleSnap, &me32);
while (bRet)
{
// 顯示 Process ID
printf("[%d] ", me32.th32ProcessID);
// 顯示 模塊加載基址
printf("[0x%p] ", me32.modBaseAddr);
// 顯示 模塊名稱
printf("[%s] ", me32.szModule);
// 獲取快照中下一條信息
bRet = ::Module32Next(hModuleSnap, &me32);
}
// 關閉句柄
::CloseHandle(hModuleSnap);
return TRUE;
}
文件遍歷
文件操作幾乎是所有惡意代碼必備的功能,木馬病毒竊取機密文件然后開一個隱秘端口,(之前在kali滲透群看到有人提問如何識別木馬,其實有一個簡單的方法,幾乎所有的木馬都要與攻擊者的主機通信的,查看打開了哪些奇怪的端口是一種方法)。
就算是再R0下,也經常會創建寫入讀取文件,文件功能經常用到。文件搜索功能主要是通過調用FindFirstFile和FindNextFile來實現。
具體流程
1、調用FindFirstFile函數,該函數接收文件路徑,第二個參數指向WIN32_FIND_DATA結構的指針。若函數成功則返回搜索句柄。該結構包含文件的名稱,創建日期,屬性,大小等信息。
該返回結構中的成員dwFileAttributes為FILE_ATTRIBUTE_DIRECTORY時表示返回的是一個目錄,否則為文件,根據cFileName獲取搜索到的文件名稱。如果需要重新對目錄下的所有子目錄文件都再次進行搜索的話,則需要對文件屬性進行判斷。若文件屬性是目錄,則繼續遞歸搜索,搜索其目錄下的目錄和文件。
2、調用FindNextFile搜索下一個文件,根據返回值判斷是否搜索到文件,若沒有則說明文件遍歷結束。
3、搜索完畢后,調用FindClose函數關閉搜索句柄,釋放資源緩沖區資源。
源碼實現:
void SearchFile(char *pszDirectory)
{
// 搜索指定類型文件
DWORD dwBufferSize = 2048;
char *pszFileName = NULL;
char *pTempSrc = NULL;
WIN32_FIND_DATA FileData = {0};
BOOL bRet = FALSE;
// 申請動態內存
pszFileName = new char[dwBufferSize];
pTempSrc = new char[dwBufferSize];
// 構造搜索文件類型字符串, *.*表示搜索所有文件類型
::wsprintf(pszFileName, "%s\*.*", pszDirectory);
// 搜索第一個文件
HANDLE hFile = ::FindFirstFile(pszFileName, &FileData);
if (INVALID_HANDLE_VALUE != hFile)
{
do
{
// 要過濾掉 當前目錄"." 和 上一層目錄"..", 否則會不斷進入死循環遍歷
if ('.' == FileData.cFileName[0])
{
continue;
}
// 拼接文件路徑
::wsprintf(pTempSrc, "%s\%s", pszDirectory, FileData.cFileName);
// 判斷是否是目錄還是文件
if (FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
// 目錄, 則繼續往下遞歸遍歷文件
SearchFile(pTempSrc);
}
else
{
// 文件
printf("%s ", pTempSrc);
}
// 搜索下一個文件
} while (::FindNextFile(hFile, &FileData));
}
// 關閉文件句柄
::FindClose(hFile);
// 釋放內存
delete []pTempSrc;
pTempSrc = NULL;
delete []pszFileName;
pszFileName = NULL;
}
按鍵記錄
收集用戶的所有按鍵信息,分辨出哪些類似于賬號,密碼等關鍵信息進行利用,竊取密碼,這里用原始輸入模型直接從輸入設備上獲取數據,記錄按鍵信息。
要想接收設備原始輸入WM_INPUT消息,應用程序必須首先使用RegisterRawInputDevice注冊原始輸入設備,因為在默認情況下,應用程序不接受原始輸入。
具體流程
1、注冊原始輸入設備
一個應用程序必須首先創建一個RAWINPUTDEVICE結構,這個結構表明它所希望接受設備的類別,再調用RegisterRawInputDevices注冊該原始輸入設備。將RAWINPUTDEVICE結構體成員dwFlags的值設置為RIDEV_INPUTSINK,即使程序不處于聚焦窗口,程序依然可以接收原始輸入。
2、獲取原始輸入數據
消息過程中調用GetInputRawData獲取設備原始輸入數據。在WM_INPUT消息處理函數中,參數lParam存儲著原始輸入的句柄。此時可以直接調用
GetInputRawData函數,根據句柄獲取RAWINPUT原始輸入結構體的數據。
dwType表示原始輸入的類型,RIM_TYPEKEYBOARD表示是鍵盤的原始輸入,Message表示相應的窗口消息。WM_KEYBOARD表示普通按鍵消息,WM_SYSKEYDOWN表示系統按鍵消息,VKey存儲鍵盤按鍵數據。
3、保存按鍵信息
GetForegroundWindow獲取按鍵窗口的標題,然后調用GetWindowText根據窗口句柄獲取標題,存儲到本地文件。
源碼實現:
惡意代碼的存在不是由于黑客之類的手段,主要還是我們開發過程中很多情況會用到這樣的技術,所以大家請利用技術做正確的事情!
另外,對于編程學習的小伙伴,如果你想更好的提升你的編程核心能力(內功)不妨從現在開始!
-
函數
+關注
關注
3文章
4366瀏覽量
64004 -
代碼
+關注
關注
30文章
4884瀏覽量
70145 -
應用程序
+關注
關注
38文章
3320瀏覽量
58610
原文標題:C/C++惡意代碼盤點(一):進程遍歷丨木馬病毒丨密碼記錄
文章出處:【微信號:cyuyanxuexi,微信公眾號:C語言編程學習基地】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
如何去防范惡意代碼攻擊呢
計算機抗惡意代碼免疫模型
Decoy:基于主動技術的惡意代碼捕獲系統
Decoy基于主動技術的惡意代碼捕獲系統
基于網頁文件代碼分類的惡意代碼檢測系統

基于主動學習的惡意代碼檢測

基于棧式自編碼的惡意代碼分類算法

結合動態行為和機器學習的惡意代碼檢測方法

基于知識蒸餾的惡意代碼家族檢測方法研究綜述

一種Attention-CNN惡意代碼檢測模型

評論