-
-
[翻译]Windows进程注入: Winsock Helper Functions (WSHX)
-
发表于:
2019-8-22 09:24
8336
-
[翻译]Windows进程注入: Winsock Helper Functions (WSHX)
原文:https://modexp.wordpress.com/2019/07/27/process-injection-winsock/
翻译:玉林小学生
校对:Nxe
据MSDN手册描述,Winsock Helper函数(WSHX)在Windows Server 2003、Windows Vista及之后版本中被废弃了。但是,Helper Dll在最新的Windows 10构建中仍然被用在TCP、红外、蓝牙、Hyper-V的socket中,近几年还被用于unix套接字地址族。MSDN中已经详细描述了Helper Dll架构的细节,本文只重点关注众多利用Helper Dll进行代码重定向、进程注入的方法中的一个。某Helper Dll的配置功能长期以来一直被滥用,但本文不对其进行详细描述。
每个字符串对应一个Helper Dll,详细信息可以在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\协议\Parameters\Winsock下找到。图2展示TCPIP协议对应的详细信息。
下面是核心注入代码。想更详细了解它如何工作在这里看完整PoC。
在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Winsock\Parameters下可以看到一个传输协议的列表,如图1。
图1:Windows 10 VM支持的传输协议
每个字符串对应一个Helper Dll,详细信息可以在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\协议\Parameters\Winsock下找到。图2展示TCPIP协议对应的详细信息。
图2.传输协议配置
当通过
socket()或
WSASocket()创建一个socket,WINSOCK_HELPER_DLL_INFO结构在插入mswsock.dll!SockHelperDllListHead之前被使用注册表和导出Dll函数的地址进行填充。微软官方文档中没有记录WINSOCK_HELPER_DLL_INFO结构,但可以在网上找到一个该结构老版本的信息。该结构最新版的一些成员只能通过逆向工程来获得,所以我只能保证下面的结构描述在最新的Windows 10构建中有效。
typedef struct _WINSOCK_HELPER_DLL_INFO {
LIST_ENTRY HelperDllListEntry;
DWORD Unknown;
HANDLE DllHandle;
INT MinSockaddrLength;
INT MaxSockaddrLength;
INT MinTdiAddressLength;
INT MaxTdiAddressLength;
ULONG64 UseDelayedAcceptance;
PWINSOCK_MAPPING Mapping;
GUID ProviderGUID;
PWSH_OPEN_SOCKET WSHOpenSocket;
PWSH_OPEN_SOCKET2 WSHOpenSocket2;
PWSH_JOIN_LEAF WSHJoinLeaf;
PWSH_NOTIFY WSHNotify;
PWSH_GET_SOCKET_INFORMATION WSHGetSocketInformation;
PWSH_SET_SOCKET_INFORMATION WSHSetSocketInformation;
PWSH_GET_SOCKADDR_TYPE WSHGetSockaddrType;
PWSH_GET_WILDCARD_SOCKADDR WSHGetWildcardSockaddr;
PWSH_GET_BROADCAST_SOCKADDR WSHGetBroadcastSockaddr;
PWSH_ADDRESS_TO_STRING WSHAddressToString;
PWSH_STRING_TO_ADDRESS WSHStringToAddress;
PWSH_IOCTL WSHIoctl;
} WINSOCK_HELPER_DLL_INFO, *PWINSOCK_HELPER_DLL_INFO;
定位SockHelperDllListHead
typedef struct _WINSOCK_HELPER_DLL_INFO {
LIST_ENTRY HelperDllListEntry;
DWORD Unknown;
HANDLE DllHandle;
INT MinSockaddrLength;
INT MaxSockaddrLength;
INT MinTdiAddressLength;
INT MaxTdiAddressLength;
ULONG64 UseDelayedAcceptance;
PWINSOCK_MAPPING Mapping;
GUID ProviderGUID;
PWSH_OPEN_SOCKET WSHOpenSocket;
PWSH_OPEN_SOCKET2 WSHOpenSocket2;
PWSH_JOIN_LEAF WSHJoinLeaf;
PWSH_NOTIFY WSHNotify;
PWSH_GET_SOCKET_INFORMATION WSHGetSocketInformation;
PWSH_SET_SOCKET_INFORMATION WSHSetSocketInformation;
PWSH_GET_SOCKADDR_TYPE WSHGetSockaddrType;
PWSH_GET_WILDCARD_SOCKADDR WSHGetWildcardSockaddr;
PWSH_GET_BROADCAST_SOCKADDR WSHGetBroadcastSockaddr;
PWSH_ADDRESS_TO_STRING WSHAddressToString;
PWSH_STRING_TO_ADDRESS WSHStringToAddress;
PWSH_IOCTL WSHIoctl;
} WINSOCK_HELPER_DLL_INFO, *PWINSOCK_HELPER_DLL_INFO;
mswsock.dll!SockHelperDllListHead是一个
LIST_ENTRY结构的全局变量。定位该结构最简单、最快速方法是搜索.data段中指向堆内存的指针。进行搜索前,需要在本地创建一个“虚拟”TCP/IP 套接字来初始化该结构。一旦找到该结构,要把保存为相对虚拟地址(Relative Virtual Address)的堆指针地址加上远程进程中mswsock.dll的基地址。你可以使用
SymFromName()或
IDebugSymbols::GetOffsetByName来定位准确地址,但PoC搜索.data段来避免依赖任何调试符号。
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2019-8-22 09:28
被0sWalker编辑
,原因: 修改代码缩进