DLL劫持可用于权限维持、权限提升、进程注入,属于经久不衰的必备技能

0x01 DLL介绍

DLL是Dynamic Link Library的缩写,叫做动态链接库
一个dll文件可以由多个程序同时调用
dll的使用意义是某个大型程序在启动时和启动后,可以不加载某部分功能代码,只有用户使用时
再去调用对应功能的dll模块,从而达到减少软件启动速度的目的

0x02 DLL劫持前置知识点

劫持的方法了解到的有两种,在之前要先知道一下exe程序加载dll的知识点

exe程序在调用dll时,查找dll文件的目录优先级顺序

  • 1.程序所在目录
  • 2.程序加载目录(SetCurrentDirectory)
  • 3.系统目录即 SYSTEM32 目录
  • 4.16位系统目录即 SYSTEM 目录
  • 5.Windows目录
  • 6.PATH环境变量中列出的目录

在win7及以上系统对应dll的一个安全机制--KnownDLLs

KnownDLLs是一个注册表的名称,如果有exe程序调用的dll名称存在于此目录下,那么这个DLL会被禁止从EXE自身所在目录下调用,而只能从系统目录即SYSTEM32目录下调用

注册表位置:\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs

0x03 DLL劫持

    1. 劫持EXE应用调用的缺少的DLL(exe发出请求,在某个路径寻找对应的dll,结果对应路径不存在此dll)
    1. 劫持EXE应用正常调用的DLL(类似端口转发,使用一个恶意dll冒充原先dll,执行完恶意代码后在将请求转发到原先dll,不影响应用正常使用)

使用第一种方法劫持微信

  • 首先要找到wechat.exe发出请求后加载dll的结果为NOT FOUND的,我这里使用辅助工具Process Monitor(一款系统进程监视软件),然后再一一验证可行性
打开Process Monitor
 ↓
打开微信
 ↓
设置Process Monitor的过滤器,添加wechat.exe进程的PID将显示的其他进程过
滤掉,再添加其他一些过滤规则(见下图)
 ↓
保存结果为csv文件,目的为了用execl里的筛选,将EXE程序加载的dll单独列出来
 ↓
正常是将恶意dll改成加载的不在KnownDLLs注册表中的dll名称,放在EXE应用同目录,这里使用anhkgg师傅的批量检验,可以帮助我自动重命名文件然后执行验证的一些自动化操作
 ↓
找到目标,将恶意dll改名放入wechat.exe同目录(因为加载顺序同目录优先级最高,当然其他地方也可以)







gif效果图

使用第二种方法劫持QQ

  • 首先找到一个EXE程序加载的dll,两个硬性要求(一是exe确实加载了此dll,二是此dll不在KnownDLLs注册表中,不过既然在同目录下找到的加载dll,那肯定不在KnownDLLs里),用来中间人转发他也就是劫持,一般找小点的,小点的需要转发函数的数量会少点,查阅一些文章总算找到一个自动化的工具 dll-hijacking ,这样我就不用手动复制函数了
在QQ.exe同目录寻找目标dll
 ↓
复制目标dll到dll-hijacking工具下进行加工
 ↓
处理好的恶意dll改好原本的名字复制到QQ.exe目录下,将刚才复制的此
目录原本的dll名字改为 原名字_.dll(这样此目录就有    原名字.dll  原名字_.dll)
 ↓
启动QQ, over了







gif效果图

  • dllmain.cpp弹框代码
/*
https://itm4n.github.io/dll-proxying/
https://www.codeproject.com/Articles/17863/Using-Pragmas-to-Create-a-Proxy-DLL
to implement: hooking specific functions
*/



#include "definitions.h"
#include <thread>
#include <chrono>
#include <random>
extern "C"{
    #include   <stdlib.h>
    #include   <winsock2.h>
    #include      <stdio.h>
    #include     <windows.h>
    #include      <ws2tcpip.h>
}

using namespace   std;
#pragma comment(lib,"Ws2_32.lib")

BOOL WINAPI DllMain(
    HINSTANCE hinstDLL,   // handle to DLL module
    DWORD fdwReason,    // reason for calling function
    LPVOID lpReserved) // reserved
{
    srand(time(NULL));
    switch (fdwReason)
    {
    case  DLL_PROCESS_ATTACH:
    {
        MessageBox(NULL, "Success", "", MB_OK);
        break;
    }
    case DLL_THREAD_ATTACH:
        break;
    case DLL_THREAD_DETACH:
        break;
    case DLL_PROCESS_DETACH:
        break;
    default:
        break;
    }

    return true;

}

0x04 参考链接

https://payloads.online/archivers/2018-12-22/1
https://mp.weixin.qq.com/s?__biz=MzU2NTc2MjAyNg==&mid=2247483851&idx=1&sn=8813719d4d3ac8b20bec495fcd5f2974&chksm=fcb7834ecbc00a58da8a6408abe183e71175b442d0f02016ad3c67c9cf719927881bec14af49#rd