Python——dll注入


dll攻擊原理分析

img

什么是dll

動態鏈接庫,是在微軟Windows操作系統中實現共享函數庫概念的一種方式。

這些庫函數的擴展名是 ”.dll"、".ocx"(包含ActiveX控制的庫)或者 ".drv"(舊式的系統驅動程序)。

為何有dll

由於進程的地址空間是獨立的(保護模式),當多個進程共享相同的庫時,每個庫都在硬盤和進程彼此的內存存放一份的話,對於早期的計算機來說,無疑是一種極大的浪費,於是windows系統推出了dll機制,dll在硬盤上存為一個文件,在內存中使用一個實例(instance)。

詳細如下:
在Windows操作系統中,運行的每一個進程都生活在自己的程序空間中(保護模式),每一個進程都認為自己擁有整個機器的控制權,
每個進程都認為自己擁有計算機的整個內存空間,這些假象都是操作系統創造的(操作系統控制CPU使得CPU啟用保護模式)。
理論上而言,運行在操作系統上的每一個進程之間都是互不干擾的,即每個進程都會擁有獨立的地址空間。比如說進程B修改了地址為0x4000000的數據,
那么進程C的地址為0x4000000處的數據並未隨着B的修改而發生改變,並且進程C可能並不擁有地址為0x4000000的內存(操作系統可能沒有為進程C映射這塊內存)。
因此,如果某進程有一個缺陷覆蓋了隨機地址處的內存(這可能導致程序運行出現問題),那么這個缺陷並不會影響到其他進程所使用的內存。

什么是dll注入

我們可以利用dll機制來實現進程通信或控制其他進程的應用程序。

所謂的dll注入正是是讓進程A強行加載程序B給定的a.dll,並執行程序B給定的a.dll里面的代碼,從而達到A進程控制B進程的目的

'''
注意,程序B所給定的a.dll原先並不會被程序A主動加載,但是當程序B通過某種手段讓程序A“加載”a.dll后,
程序A將會執行a.dll里的代碼,此時,a.dll就進入了程序A的地址空間,而a.dll模塊的程序邏輯由程序B的開發者設計,
因此程序B的開發者可以對程序A為所欲為。
'''

什么時候需要dll注入

'''
應用程序一般會在以下情況使用dll注入技術來完成某些功能:
  1.為目標進程添加新的“實用”功能;
  2.需要一些手段來輔助調試被注入dll的進程;
  3.為目標進程安裝鈎子程序(API Hook);
'''

dll注入的方法

'''
一般情況下有如下dll注入方法:    
    1.修改注冊表來注入dll;
    2.使用CreateRemoteThread函數對運行中的進程注入dll;
    3.使用SetWindowsHookEx函數對應用程序掛鈎(HOOK)迫使程序加載dll;
    4.替換應用程序一定會使用的dll;
    5.把dll作為調試器來注入;
    6.用CreateProcess對子進程注入dll
    7.修改被注入進程的exe的導入地址表。
'''

ps:
殺毒軟件常用鈎子來進行處理

使用SetWindowsHookEx函數對應用程序掛鈎(HOOK)迫使程序加載dll

ctypes是Python的外部函數庫,從Python2.5開始引入。它提供了C兼容的數據類型,並且允許調用動態鏈接庫/共享庫中的函數。它可以將這些庫包裝起來給Python使用。

ctypes.windll.user32下主要用到三個函數,分別是SetWindowsHookEx() 、CallNextHookEx()和
UnhookWindowsHookEx()

  消息鈎子:Windows操作系統為用戶提供了GUI(Graphic User Interface,圖形用戶界面),
它以事件驅動方式工作。在操作系統中借助鍵盤、鼠標、選擇菜單、按鈕、移動鼠標、改變窗口大小與位置等都是事件。
發生這樣的事件時,操作系統會把事先定義好的消息發送給相應的應用程序,應用程序分析收到的信息后會執行相應的動作。
也就是說,在敲擊鍵盤時,消息會從操作系統移動到應用程序。
所謂的消息鈎子就是在此期間偷看這些信息。以鍵盤輸入事件為例,消息的流向如下:
  1.發生鍵盤輸入時,WM_KEYDOWN消息被添加到操作系統的消息隊列中;
  2.操作系統判斷這個消息產生於哪個應用程序,並將這個消息從消息隊列中取出,添加到相應的應用程序的消息隊列中;
  3.應用程序從自己的消息隊列中取出WM_KEYDOWN消息並調用相應的處理程序。
  當我們的鈎子程序啟用后,操作系統在將消息發送給用用程序前會先發送給每一個注冊了相應鈎子類型的鈎子函數。鈎子函數可以對這一消息做出想要的處理(修改、攔截等等)。多個消息鈎子將按照安裝鈎子的先后順序被調用,這些消息鈎子在一起組成了"鈎鏈"。消息在鈎鏈之間傳遞時任一鈎子函數攔截了消息,接下來的鈎子函數(包括應用程序)將都不再收到該消息。
  像這樣的消息鈎子功能是Windows提供的最基本的功能,MS Visual Studio中提供的SPY++就是利用了這一功能來實現的,SPY++是一個十分強大的消息鈎取程序,它能夠查看操作系統中來往的所有消息。
  消息鈎子是使用SetWindowsHookEx來實現的。函數的原型如下:

HHOOK WINAPI SetWindowsHookEx(
  _In_ int       idHook,
  _In_ HOOKPROC  lpfn,
  _In_ HINSTANCE hMod,
  _In_ DWORD     dwThreadId
);

  idHook參數是消息鈎子的類型,可以選擇的類型在MSDN中可以查看到相應的宏定義。比如我們想對所有的鍵盤消息做掛鈎,其取值將是WH_KEYBOARD,WH_KEYBOARD這個宏的值是2。
  lpfn參數是鈎子函數的起始地址,注意:不同的消息鈎子類型的鈎子函數原型是不一樣的,因為不同類型的消息需要的參數是不同的,具體的鈎子函數原型需要查看MSDN來獲得。注意:鈎子函數可以在結束前任意位置調用CallNextHookEx函數來執行鈎鏈的其他鈎子函數。當然,如果不調用這個函數,鈎鏈上的后續鈎子函數將不會被執行。
  hMod參數是鈎子函數所在的模塊的模塊句柄。
  dwThreadId參數用來指示要對哪一個進程/線程安裝消息鈎子。如果這個參數為0,安裝的消息鈎子稱為“全局鈎子”,此時將對所有的進程(當前的進程以及以后要運行的所有進程)下這個消息鈎子。注意:有的類型的鈎子只能是全局鈎子。
  注意:鈎子函數應當放在一個dll中,並且在你的進程中LoadLibrary這個dll。然后再調用SetWindowsHookEx函數對相應類型的消息安裝鈎子。
  當SetWindowsHookEx函數調用成功后,當某個進程生成這一類型的消息時,操作系統會判斷這個進程是否被安裝了鈎子,如果安裝了鈎子,操作系統會將相關的dll文件強行注入到這個進程中並將該dll的鎖計數器遞增1。然后再調用安裝的鈎子函數。整個注入過程非常方便,用戶幾乎不需要做什么。
  當用戶不需要再進行消息鈎取時只需調用UnhookWindowsHookEx即可解除安裝的消息鈎子,函數的原型如下:

BOOL WINAPI UnhookWindowsHookEx(
  _In_ HHOOK hhk
);

  hhk參數是之前調用SetWindowsHookEx函數返回的HOOK變量/句柄。這個函數調用成功后會使被注入過dll的鎖計數器遞減1,當鎖計數器減到0時系統會卸載被注入的dll。

  這種類型的dll注入的優點是注入簡單,缺點是只能對windows消息進行Hook並注入dll,而且注入dll可能不是立即被注入,因為這需要相應類型的事件發生。其次是它不能進行其他API的Hook,如果想對其它的函數進行Hook,你需要再在被注入的dll中添加用於API Hook的代碼。
  dll注入代碼包含兩部分,一部分是dll的源文件,另一部分是控制台程序的源代碼。
HMODULE Hmod = LoadLibraryA("hookdll.dll");

准備工作

1、最新anocoda3.7

https://www.anaconda.com/distribution/#download-section

2、提速下載可以改變源

pip3 config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

3、安裝pywin32,安裝時指定安裝目錄,默認為C:\Python37\Lib\site-packages\

https://github.com/mhammond/pywin32/releases

4、安裝opencv-python

pip install opencv-python

5、安裝pyinstaller,依賴pyin32

pip install pyinstaller

6、ico文件准備好

ps:也可以在線制作

https://www.easyicon.net/500133-QQ_Penguin_tencent_icon.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM