《電子技術應用》
您所在的位置:首頁 > 通信與網(wǎng)絡 > 業(yè)界動態(tài) > 網(wǎng)絡安全編程:行為監(jiān)控HIPS

網(wǎng)絡安全編程:行為監(jiān)控HIPS

2021-07-31
來源:計算機與網(wǎng)絡安全
關鍵詞: HIPS 行為監(jiān)控

  現(xiàn)在有一種流行的防病毒軟件被稱作HIPS,中文名字為主機入侵防御系統(tǒng),比如EQ。該軟件可以在進程創(chuàng)建時、有進程對注冊表進行寫入時或有驅(qū)動被加載時,給用戶予以選擇,選擇是否攔截進程的創(chuàng)建、是否攔截注冊表的寫入、是否攔截驅(qū)動的加載等功能。

  HIPS純粹是以預防為主,比如有陌生的進程在被創(chuàng)建階段,就可以讓用戶禁止,這樣就避免了特征碼查殺的滯后性。對于殺毒軟件的特征碼查殺而言,如果殺毒軟件不更新病毒數(shù)據(jù)庫,那么依賴病毒特征碼的殺毒軟件就無法查殺新型的病毒,對新型的病毒就成為一個擺設。

  行為監(jiān)控的原理主要就是對相關的關鍵API函數(shù)進行HOOK,比如進程攔截。當一個木馬程序要秘密啟動的時候,對CreateProcessW()函數(shù)進行了HOOK,在進程被創(chuàng)建前,會詢問用戶是否啟動該進程,那么木馬的隱秘啟動就被暴露出來了。對于沒有安全知識的大眾來說,使用HIPS可能有點困難,也許仍然會讓木馬運行。因為不是每個使用計算機的人都對計算機有所了解,計算機對于他們而言可能只用來打游戲或看電影。這該如何做呢?現(xiàn)在通常使用的方法就是使用白庫和黑庫,也就是所謂的白名單和黑名單。在進程被創(chuàng)建時,把要創(chuàng)建的進程到黑白庫中去匹配,然后做相應的動作,或者放行,或者攔截。

  下面來實現(xiàn)一個應用層下的簡單的進程防火墻、注冊表防火墻的功能。

  1. 簡單進程防火墻

  進程防火墻指的是放行/攔截準備要創(chuàng)建的進程。進程的創(chuàng)建是依靠CreateProcessW()函數(shù)完成的。只要HOOK CreateProcessW()函數(shù)就可以實現(xiàn)進程防火墻的功能。對于注冊表來說,要對非法進程進行刪除或?qū)懭胱员礞I值進行管控,因此需要HOOK兩個注冊表函數(shù),分別是注冊表寫入函數(shù)RegSetValueExW()和注冊表刪除函數(shù)RegDeleteValueW()。由于使用了HOOK,那么就必然要涉及DLL的編寫。這里分DLL和EXE兩部分來進行詳細的介紹。

  2. 實現(xiàn)HOOK部分的DLL程序的編寫

  因為要對目標進程進行HOOK,因此要編寫DLL程序。創(chuàng)建一個DLL程序,并加入已封裝的ILHook.h頭文件和ILHook.cpp的實現(xiàn)文件。

  為了能在所有的基于消息的進程中注入自己的DLL,必須使用Windows鉤子,這樣就可以將DLL輕易地注入基于消息的進程中。代碼如下:

  #pragma data_seg(“.shared”)

  HHOOK g_hHook = NULL;

  #pragma data_seg()

  #pragma comment (linker, “.shared, RWS”)

  extern “C” __declspec(dllexport) VOID SetHookOn(HWND hWnd);

  extern “C” __declspec(dllexport) VOID SetHookOff();

  HWND g_ExeHwnd = NULL;

  LRESULT CALLBACK GetMsgProc(

  int code, // 鉤子編碼

  WPARAM wParam, // 移除選項

  LPARAM lParam // 消息

  )

  {

  return CallNextHookEx(g_hHook, code, wParam, lParam);

  }

  VOID SetHookOn(HWND hWnd)

  {

  g_ExeHwnd = hWnd;

  SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, g_hInst, 0);

  }

  VOID SetHookOff()

  {

  UnhookWindowsHookEx(g_hHook);

  g_hHook = NULL;

  }

  以上函數(shù)用來定義導出函數(shù),用于加載完成HOOK功能的DLL文件。這里利用WH_ GETMESSAGE鉤子類型。

  定義3個CILHook類的對象,分別用來對CreateProcessW()函數(shù)、RegSetValueExW()函數(shù)和RegDeleteValueW()函數(shù)進行掛鉤。具體定義如下:

  CILHook RegSetValueExWHook;

  CILHook CreateProcessWHook;

  CILHook RegDeleteValueWHook;

  HOOK部分是在DllMain()函數(shù)中完成的,具體代碼如下:

  BOOL APIENTRY DllMain( HANDLE hModule,

  DWORD ul_reason_for_call,LPVOID lpReserved)

  {

  switch ( ul_reason_for_call )

  {

  case DLL_PROCESS_ATTACH:

  {

  g_hInst = (HINSTANCE)hModule;

  RegSetValueExWHook.Hook(“advapi32.dll”,

  “RegSetValueExW”,(PROC)MyRegSetValueExA);

  RegDeleteValueWHook.Hook(“advapi32.dll”,

  “RegDeleteValueW”,(PROC)MyRegDeleteValueW);

  CreateProcessWHook.Hook(“kernel32.dll”,

  “CreateProcessW”,(PROC)MyCreateProcessW);

  break;

  }

  case DLL_PROCESS_DETACH:

  {

  RegSetValueExWHook.UnHook();

  RegDeleteValueWHook.UnHook();

  CreateProcessWHook.UnHook();

  if ( g_hHook != NULL )

  {

  SetHookOff();

  }

  break;

  }

  }

  return TRUE;

  }

  放行/攔截部分是給用戶選擇的,那么就要給出提示讓用戶進行選擇,至少要給出放行/攔截的類型,比如是注冊表寫入或是進程的創(chuàng)建,還要給出是哪個進程進行的操作。要把這個信息反饋給用戶,這里定義一個結(jié)構體,將該結(jié)構體的信息發(fā)送給用于加載DLL的EXE文件,并讓EXE給出提示。結(jié)構體定義如下:

  typedef struct _HIPS_INFO

  {

  WCHAR wProcessName[0x200];

  DWORD dwHipsClass;

  }HIPS_INFO, *PHIPS_INFO;

  定義一些常量用來標識放行/攔截的類型,具體如下:

  #define HIPS_CREATEPROCESS 0x00000001L

  #define HIPS_REGSETVALUE 0x00000002L

  #define HIPS_REGDELETEVALUE 0x00000003L

  將這些定義好以后,就可以開始完成HOOK函數(shù)了。這里主要給出CreateProcessW()函數(shù)的HOOK實現(xiàn)。其余兩個函數(shù)的HOOK實現(xiàn),請大家自行實現(xiàn)。具體代碼如下:

  BOOL

  WINAPI

  MyCreateProcessW(

  __in_opt LPCWSTR lpApplicationName,

  __inout_opt LPWSTR lpCommandLine,

  __in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes,

  __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,

  __in BOOL bInheritHandles,

  __in DWORD dwCreationFlags,

  __in_opt LPVOID lpEnvironment,

  __in_opt LPCWSTR lpCurrentDirectory,

  __in LPSTARTUPINFOW lpStartupInfo,

  __out LPPROCESS_INFORMATION lpProcessInformation

  )

  {

  HIPS_INFO sz = { 0 };

  if ( wcslen(lpCommandLine) != 0 )

  {

  wcscpy(sz.wProcessName, lpCommandLine);

  }

  else

  {

  wcscpy(sz.wProcessName, lpApplicationName);

  }

  sz.dwHipsClass = HIPS_CREATEPROCESS;

  COPYDATASTRUCT cds = { NULL, sizeof(HIPS_INFO), (void *)&sz };

  BOOL bRet = FALSE;

  if ( SendMessage(FindWindow(NULL, “Easy Hips For R3”),

  WM_COPYDATA,GetCurrentProcessId(),(LPARAM)&cds) != -1 )

  {

  CreateProcessWHook.UnHook();

  bRet = CreateProcessW(lpApplicationName, lpCommandLine,

  lpProcessAttributes, lpThreadAttributes,

  bInheritHandles, dwCreationFlags,

  lpEnvironment, lpCurrentDirectory,

  lpStartupInfo, lpProcessInformation);

  CreateProcessWHook.ReHook();

  }

  return bRet;

  }

  這里使用了一個SendMessage()函數(shù),該函數(shù)用來發(fā)送一個WM_COPYDATA消息,將結(jié)構體傳給了加載DLL的EXE程序,使EXE程序把提示顯示給用戶。

  SendMessage()函數(shù)的功能非常強大,其定義如下:

  LRESULT SendMessage(

  HWND hWnd,

  UINT Msg,

  WPARAM wParam,

  LPARAM lParam

 ?。?/p>

  該函數(shù)的第一個參數(shù)是目標窗口的句柄,第二個參數(shù)是消息類型,最后兩個參數(shù)是消息的附加參數(shù),根據(jù)消息類型的不同而不同。

  以上代碼就是DLL程序的全部了,剩下兩個對注冊表操作的HOOK函數(shù),由大家自己完成。

  3. 行為監(jiān)控前臺程序的編寫

  先來看一下程序能達到的效果,再講解程序EXE部分的實現(xiàn)代碼,如圖1和圖2所示。

圖1  程序主界面

  圖2  攔截提示框

  從上面兩個圖可以看出,程序的確是可以攔截進程的啟動的。當單擊“允許”按鈕后,進程會被正常創(chuàng)建;當單擊“取消”按鈕后,進程將被阻止創(chuàng)建。這就是最終要完成的功能,來看看主要的實現(xiàn)代碼。

  EXE的部分主要就是如何來啟動行為監(jiān)控功能,以及如何接收DLL程序通過SendMessage()函數(shù)發(fā)出的消息給用戶彈出提示框。進行攔截的部分已經(jīng)在DLL程序中通過HOOK實現(xiàn)了,所以重點也就在界面上和消息的接收上。

  先看如何啟動和停止行為的監(jiān)控。具體代碼如下:

  typedef VOID (*SETHOOKON)(HWND);

  typedef VOID (*SETHOOKOFF)();

  void CHipsDlg::OnBtnOn()

  {

  在此處添加處理程序的代碼

  m_hInst = LoadLibrary(“EasyHips.dll”);

  SETHOOKON SetHookOn = (SETHOOKON)GetProcAddress(m_hInst, “SetHookOn”);

  SetHookOn(GetSafeHwnd());

  FreeLibrary(m_hInst);

  m_BtnOn.EnableWindow(FALSE);

  m_BtnOff.EnableWindow(TRUE);

  }

  void CHipsDlg::OnBtnOff()

  {

  在此處添加處理程序的代碼

  m_hInst = GetModuleHandle(“EasyHips.dll”);

  SETHOOKOFF SetHookOff = (SETHOOKOFF)GetProcAddress(m_hInst, “SetHookOff”);

  SetHookOff();

  CloseHandle(m_hInst);

  FreeLibrary(m_hInst);

  m_BtnOn.EnableWindow(TRUE);

  m_BtnOff.EnableWindow(FALSE);

  }

  從代碼中不難看出,直接調(diào)用了DLL的兩個導出函數(shù),就可以開啟自己的打開。在關閉時為什么調(diào)用了CloseHandle()函數(shù)和FreeLibrary()函數(shù)呢?把FreeLibrary()函數(shù)去掉,然后單擊“停止”監(jiān)控行為,但還是處在被監(jiān)控的狀態(tài)下。因為恢復Inline Hook是在DLL被卸載的情況。因此,在卸載時,調(diào)用GetModuleHandle()獲得本進程的DLL句柄后,雖然CloseHandle()了,但是只是減少了對DLL的引用計數(shù),并沒有真正釋放,必須再次使用FreeLibrary()函數(shù)才可以使DLL被卸載,從而恢復Inline Hook。

  EXE程序接收DLL消息的代碼如下:

  BOOL CHipsDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)

  {

  // 在此處添加處理程序的代碼

  CTips Tips;

  PHIPS_INFO pHipsInfo = (PHIPS_INFO)pCopyDataStruct->lpData;

  wcscpy(Tips.sz, pHipsInfo->wProcessName);

  Tips.DoModal();

  int nNum = m_HipsReports.GetItemCount();

  CString Str;

  Str.Format(“%d”, nNum);

  m_HipsReports.InsertItem(nNum, Str);

  SYSTEMTIME StTime;

  GetLocalTime(&StTime);

  Str.Format(“%04d/%02d/%02d %02d:%02d:%02d”,

  StTime.wYear,StTime.wMonth,StTime.wDay,

  StTime.wHour,StTime.wMonth,StTime.wSecond);

  m_HipsReports.SetItemText(nNum, 1, Str);

  Str.Format(“%S”, Tips.sz);

  m_HipsReports.SetItemText(nNum, 2, Str);

  switch ( pHipsInfo->dwHipsClass )

  {

  case HIPS_CREATEPROCESS:

  {

  Str = “進程創(chuàng)建”;

  break;

  }

  case HIPS_REGSETVALUE:

  {

  break;

  }

  case HIPS_REGDELETEVALUE:

  {

  break;

  }

  }

  m_HipsReports.SetItemText(nNum, 3, Str);

  Str.Format(“%s”, Tips.bRet ? “放行” : “攔截”);

  m_HipsReports.SetItemText(nNum, 4, Str);

  if ( Tips.bRet )

  {

  return 0;

  }

  else

  {

  return -1;

  }

  return CDialog::OnCopyData(pWnd, pCopyDataStruct);

  }

  這部分代碼就是對WM_COPYDATA消息的一個響應,整個代碼基本是對界面進行了操作。在代碼中有一個CTips類的對象,這個類是用來自定義窗口的。該窗口就是用來提示放行和攔截的窗口,其主要代碼如下:

  void CTips::OnBtnOk()

  {

  // 在此處添加處理程序的代碼

  bRet = TRUE;

  EndDialog(0);

  }

  void CTips::OnBtnCancel()

  {

  // 在此處添加處理程序的代碼

  bRet = FALSE;

  EndDialog(0);

  }

  DLL程序中的SendMessage()函數(shù)的返回要等待WM_COPYDATA的消息結(jié)束,并從中獲得返回值來決定下一步是否執(zhí)行,因此這里只要簡單地返回TRUE或FALSE即可。

  對于行為監(jiān)控就介紹這么多。這個例子演示了如何通過Inline Hook達到對進程創(chuàng)建、注冊表操作的管控。當然,這里的代碼并不能管控所有的進程,而且這里的行為監(jiān)控過于簡單,很容易被惡意程序突破。這里主要是通過實例來完成對行為監(jiān)控原理的介紹,希望可以起到拋磚引玉的作用。




電子技術圖片.png

本站內(nèi)容除特別聲明的原創(chuàng)文章之外,轉(zhuǎn)載內(nèi)容只為傳遞更多信息,并不代表本網(wǎng)站贊同其觀點。轉(zhuǎn)載的所有的文章、圖片、音/視頻文件等資料的版權歸版權所有權人所有。本站采用的非本站原創(chuàng)文章及圖片等內(nèi)容無法一一聯(lián)系確認版權者。如涉及作品內(nèi)容、版權和其它問題,請及時通過電子郵件或電話通知我們,以便迅速采取適當措施,避免給雙方造成不必要的經(jīng)濟損失。聯(lián)系電話:010-82306118;郵箱:aet@chinaaet.com。