Windows Ring3层注入——LSP劫持注入(SPI网络过滤器注入)(八)

Windows Ring3层注入——LSP劫持注入(SPI网络过滤器注入)(八)

LSP劫持注入知识背景

LSP(Layered Service Provider ,分层服务提供者):

  • LSP是一个安装在winsock目录中的DLL程序
    应用程序通过winsock2进行网络通信时,会调用ws2_32.dll的导出函数(如connect、accept等)。而后端通过LSP实现这些函数的底层,简单来说就是调用winsock2提供的函数时会调用对应的LSP提供的SPI函数.

SPI(Service Provider Interface,服务器提供者接口):

  • SPI是由分层服务提供者(LSP)导出的供ws2_32.dll调用的系列函数
    SPI是Winsock2提供的一项新特性,通过它可以借助实现一个LSP对现有的传输服务提供者进行扩展。
    Winsock2 SPI支持用户提供传输者名称空间两种类型的服务提供者。

在这里插入图片描述

LSP劫持注入注入原理

1.因为Winsock服务体系符合Windows开放服务体系,所以它支持第三方服务提供者插入到其中。
2.只要上层和下层的边缘支持Winsock2 SPI,即可向他们中间安装第三方提供者程序
3.普通开发者一般都是开发SPI的LSP(分层服务提供者),即第三方提供者,可用于监控Winsock API执行,
HOOK Winsock API,甚至利用LSP技术注入DLL。
4.基础协议(TCP、UDP、原始)的提供者其实就是DLL,编写分层协议提供者就是在编写DLL,然后安装在Winsock目录上,让系统上的所有使用基础协议的网络程序调用

  • LSP注入的原理大概可以概括为只要将我们编写的LSP DLL安装到系统网络协议链中,那么所有基于Winsock实现的程序都会主动加载我们的LSP DLL。我们可以利用这个特点实现对网络功能的进程的注入。

在这里插入图片描述

LSP劫持注入实现步骤

系统有一个默认的LSP,就是mswsock.dll,在自己的LSP的WSPStartup中,只要找到上层接口 (如果没有其他LSP,那么实际上就是mswsock.dll接口)并调用即可。

我们根据LSP的原理分析可知,要实现LSP的注入,大概是如下两个步骤:
1.编写一个导出WSPStartup()函数的LSP DLL。
2.编写一个安装程序,把我们编写好的LSP安装到上图体系结构中。

LIBRARY       MinWinsockSpi
DESCRIPTION   "Implements a layered service provider for TCP"
EXPORTS       WSPStartup
  • **LSP安装方法:**把安装的SPI模块信息写到注册表如下位置
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WinSock2\Parameters\Protocol_Catalog9\Catalog_Entries\000000000001
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WinSock2\Parameters\Protocol_Catalog9\Catalog_Entries\000000000002
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WinSock2\Parameters\Protocol_Catalog9\Catalog_Entries\000000000003

安装完毕,每个需要加载网络模块的进程都会加载我们的SPI模块,这样就成功实现了注入。进一步完善SPI DLL接口,就可以直接对网络数据进行控制了。

LSP劫持注入相关代码

// 要安装的LSP的硬编码,在移除的时候还要使用它
GUID  ProviderGuid = {0xd3c21122, 0x85e1, 0x48f3, {0x9a,0xb6,0x23,0xd9,0x0c,0x73,0x07,0xef}};


LPWSAPROTOCOL_INFOW GetProvider(LPINT lpnTotalProtocols)
{
	DWORD dwSize = 0;
	int nError;
	LPWSAPROTOCOL_INFOW pProtoInfo = NULL;
	
	// 取得需要的长度
	if(::WSCEnumProtocols(NULL, pProtoInfo, &dwSize, &nError) == SOCKET_ERROR)
	{
		if(nError != WSAENOBUFS)
			return NULL;
	}
	
	pProtoInfo = (LPWSAPROTOCOL_INFOW)::GlobalAlloc(GPTR, dwSize);
	*lpnTotalProtocols = ::WSCEnumProtocols(NULL, pProtoInfo, &dwSize, &nError);
	return pProtoInfo;
}

void FreeProvider(LPWSAPROTOCOL_INFOW pProtoInfo)
{
	::GlobalFree(pProtoInfo);
}


// 将LSP安装到UDP协议提供者之上
int InstallProvider(WCHAR *wszDllPath)
{
	WCHAR wszLSPName[] = L"外挂LSP";	// 我们的LSP的名称
	int nError = NO_ERROR;

	LPWSAPROTOCOL_INFOW pProtoInfo;
	int nProtocols;
	WSAPROTOCOL_INFOW UDPLayeredInfo, UDPChainInfo; // 我们要安装的UDP分层协议和协议链
	DWORD dwUdpOrigCatalogId, dwLayeredCatalogId;

	// 在Winsock目录中找到原来的TCP协议服务提供者,我们的LSP要安装在它之上
	// 枚举所有服务程序提供者
	// 注意下面我们是安装到TCP上的
	pProtoInfo = GetProvider(&nProtocols);
	for(int i=0; i<nProtocols; i++)
	{
		if(pProtoInfo[i].iAddressFamily == AF_INET && pProtoInfo[i].iProtocol == IPPROTO_TCP)
		{
			memcpy(&UDPChainInfo, &pProtoInfo[i], sizeof(UDPLayeredInfo));
			// 
			UDPChainInfo.dwServiceFlags1 = UDPChainInfo.dwServiceFlags1 & ~XP1_IFS_HANDLES;  
			// 保存原来的入口ID
			dwUdpOrigCatalogId = pProtoInfo[i].dwCatalogEntryId;
			break;
		}
	}  

	// 首先安装分层协议,获取一个Winsock库安排的目录ID号,即dwLayeredCatalogId
	// 直接使用下层协议的WSAPROTOCOL_INFOW结构即可
	memcpy(&UDPLayeredInfo, &UDPChainInfo, sizeof(UDPLayeredInfo));
	// 修改协议名称,类型,设置PFL_HIDDEN标志
	wcscpy(UDPLayeredInfo.szProtocol, wszLSPName);
	UDPLayeredInfo.ProtocolChain.ChainLen = LAYERED_PROTOCOL;		// LAYERED_PROTOCOL即0
	UDPLayeredInfo.dwProviderFlags |= PFL_HIDDEN;
	// 安装
	if(::WSCInstallProvider(&ProviderGuid, 
					wszDllPath, &UDPLayeredInfo, 1, &nError) == SOCKET_ERROR)
		return nError;
	// 重新枚举协议,获取分层协议的目录ID号
	FreeProvider(pProtoInfo);
	pProtoInfo = GetProvider(&nProtocols);
	for(int i =0; i<nProtocols; i++)
	{
		if(memcmp(&pProtoInfo[i].ProviderId, &ProviderGuid, sizeof(ProviderGuid)) == 0)
		{
			dwLayeredCatalogId = pProtoInfo[i].dwCatalogEntryId;
			break;
		}
	}

		// 安装协议链
	// 修改协议名称,类型
	WCHAR wszChainName[WSAPROTOCOL_LEN + 1];
	swprintf(wszChainName, L"%ws over %ws", wszLSPName, UDPChainInfo.szProtocol);
	wcscpy(UDPChainInfo.szProtocol, wszChainName);
	if(UDPChainInfo.ProtocolChain.ChainLen == 1)
	{
		UDPChainInfo.ProtocolChain.ChainEntries[1] = dwUdpOrigCatalogId;
	}
	else
	{
		for(int i=UDPChainInfo.ProtocolChain.ChainLen; i>0 ; i--)
		{
			UDPChainInfo.ProtocolChain.ChainEntries[i] = UDPChainInfo.ProtocolChain.ChainEntries[i-1];
		}
	}
	UDPChainInfo.ProtocolChain.ChainLen ++;
	// 将我们的分层协议置于此协议链的顶层
	UDPChainInfo.ProtocolChain.ChainEntries[0] = dwLayeredCatalogId; 
	// 获取一个Guid,安装之
	GUID ProviderChainGuid;
	if(::UuidCreate(&ProviderChainGuid) == RPC_S_OK)
	{
		if(::WSCInstallProvider(&ProviderChainGuid, 
					wszDllPath, &UDPChainInfo, 1, &nError) == SOCKET_ERROR)
					return nError;
	}
	else
		return GetLastError();



		// 重新排序Winsock目录,将我们的协议链提前
	// 重新枚举安装的协议
	FreeProvider(pProtoInfo);
	pProtoInfo = GetProvider(&nProtocols);

	DWORD dwIds[20];
	int nIndex = 0;
	// 添加我们的协议链
	for(int i=0; i<nProtocols; i++)
	{
		if((pProtoInfo[i].ProtocolChain.ChainLen > 1) &&
					(pProtoInfo[i].ProtocolChain.ChainEntries[0] == dwLayeredCatalogId))
			dwIds[nIndex++] = pProtoInfo[i].dwCatalogEntryId;
	}
	// 添加其它协议
	for(int i=0; i<nProtocols; i++)
	{
		if((pProtoInfo[i].ProtocolChain.ChainLen <= 1) ||
				(pProtoInfo[i].ProtocolChain.ChainEntries[0] != dwLayeredCatalogId))
			dwIds[nIndex++] = pProtoInfo[i].dwCatalogEntryId;
	}
	// 重新排序Winsock目录
	nError = ::WSCWriteProviderOrder(dwIds, nIndex);

	FreeProvider(pProtoInfo);
	return nError;
}

void RemoveProvider()
{	
	LPWSAPROTOCOL_INFOW pProtoInfo;
	int nProtocols;
	DWORD dwLayeredCatalogId;

	// 根据Guid取得分层协议的目录ID号
	pProtoInfo = GetProvider(&nProtocols);
	int nError;
	for (int i = 0; i < nProtocols; i++)
	{
		if (memcmp(&ProviderGuid, &pProtoInfo[i].ProviderId, sizeof(ProviderGuid)) == 0)
		{
			dwLayeredCatalogId = pProtoInfo[i].dwCatalogEntryId;
			break;
		}


		if (i < nProtocols)
		{
			// 移除协议链
			for (i = 0; i < nProtocols; i++)
			{
				if ((pProtoInfo[i].ProtocolChain.ChainLen > 1) &&
					(pProtoInfo[i].ProtocolChain.ChainEntries[0] == dwLayeredCatalogId))
				{
					::WSCDeinstallProvider(&pProtoInfo[i].ProviderId, &nError);
				}
			}
			// 移除分层协议
			::WSCDeinstallProvider(&ProviderGuid, &nError);
		}
	}
}


int binstall = 1;
void main()
{
	WCHAR szBuf[MAX_PATH] = {0};
	CHAR  szSel[6] = {0};
	GetCurrentDirectoryW(MAX_PATH, szBuf);
	wcscat(szBuf, L"\\LSPWG.dll");
	printf("install  or uninstall lsp: \"y\" or \"n\": ");
	scanf("%s",szSel);
	if (strcmp(szSel, "y") == 0)
	{
		binstall = 1;
	}
	else
		binstall = 0;

	if(binstall)
	{
		if(InstallProvider(szBuf) == ERROR_SUCCESS)
		{
			printf(" Install successully \n");
		}
		else
		{
			printf(" Install failed \n");
		}
	}
	else
		RemoveProvider();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值