本文利用IDA分析4个简单的恶意程序,旨在基本掌握这4个恶意程序的C语言逻辑结构,同时这4个程序功能逐渐递增,循序渐进。笔者也是初学者,有些不足之处在所难免,请师傅们斧正
前言
本文利用IDA分析4个简单的恶意程序,旨在基本掌握这4个恶意程序的C语言逻辑结构,同时这4个程序功能逐渐递增,循序渐进。笔者也是初学者,有些不足之处在所难免,请师傅们斧正
详细分析
首先静态分析该exe文件,看下导入函数,其中一个调用了 WININET.dll
中的 InternetGetConnectedState
函数,这个跟其他调用 kernel32.dll
中的函数相比,显得有些特殊。
查阅文档可知,这是一个 判断本地网络连接状态的函数,连接成功返回1,连接失败返回0
互联网连接状态功能 (wininet.h) - win32 应用程序|微软文档 (microsoft.com)
BOOL InternetGetConnectedState( [out] LPDWORD lpdwFlags, [in] DWORD dwReserved );
找到了main 函数,就从这里开始分析
main
函数位于401040
,调用了401000
处的函数
跳过去看看
上面一大堆没用的是编译器生成的,不要陷入其中
看到该区段的权限是 可读/可执行,并且调用了 InternetGetConnectedState
函数
不看流程图的话大概也可以看出这是一个 if 语句的汇编代码,cmp [ebp+var_4] ,0
,根据结果跳转到不同的分支
在 View->Graphs->Flow chart
可以查看流程图,相比较于空格的 流程图,更简洁明了
这里使用cmp指令对保存了返回结果的eax寄存器与0比较,然后使用 jz 指令控制执行流。上面我们提到,当 建立网络连接时,InternetGetConnectedState
函数返回1,否则返回0. 如果结果是1,0标志位(ZF)会被清除,jz跳转到1所在的false
分支,否则跳转到true
分支
下面分析这个位于 40105f
处的子过程
其实这里是printf
函数,但是我们并没有看到一些printf函数的特征,这就需要去找一些其他的特征来证明这里是printf
函数
在调用这个函数之前,都向栈中push
了 一串 格式化字符串,并且结尾是\n
换行符,因此可以推出这里调用的函数就是 printf
上面都是是根据静态分析得出的结论,真正的结果还是要实践检验一下,确实与我们分析的结果一样
总结
这个恶意代码的主要功能就是检查是否存在 Internet
连接,存在输出1,否则输出0。
详细分析
首先还是看到这个pe文件的导入表
InternetOpenUrl: 通过FTP或 HTTP URL打开一个原始资源。如果连接成功建立,则返回一个有效的句柄,如果连接失败,则返回 NULL internetclosehandle :关闭句柄,成功关闭返回 true,否则返回false InternetReadFile: 从InternetOpenA打开的句柄读取数据 InternetGetConnectedState: 验证网络连接状态 InternetOpenA: 设置用户代理,即HTTP的 user-agent 头
看到其中的一些字符串,在结合上面调用的 api函数,不难猜出,要访问的url地址
接着来分析 main 函数
401000
处这里就不说了,和前面一样
但是401000 这里还调用的 40117f
,跳过去看看
这个结构很像前面分析的 printf
函数,那我们再往前看一看。
果然,在push入栈中也有一串格式化的字符串,基本可以确定40117f
处的函数是 printf
函数
同时,main 函数中还调用了另一个401040
函数
这里包含了所有 前面发现的 WinINet api的调用。首先调用了InternetOpen
,以初始化对WinINet
的使用。在这之前,将 Internet Explorer 7.5
push
入栈,当作 User-Agent 头部,接着调用 InternetOpenUrl
,打开该静态网页
可以看到,调用完 InternetOpenUrl
后,返回值被赋值给了hFIle,并接着与0比较,如果等于0会返回,否则跳转到40109D
,hFile被传递给InternetReadFIle
函数。
InternetReadFile
函数用于从InternetOpenUrlA
打开的网页中读取内容。在调用完后,会和0比较,如果为0,该函数会关闭句柄并终止,否则会跳转到 4010E5
,逐步比较 buffer 数组 与每个字符的值,
这里有注释会好很多
这时候就可以猜测存在 http 交互
因此大概就可以确定,如果 buffer 的前 4个字节与
接着分析 main 函数,
看到在 401173 处 ,调用了 sleep 函数,传递的参数为 0xEA60h,即60000ms,1min
总结
该恶意样本检查是否有可用的网络连接,如果不存在,终止运行,否则返回 true,使用代理去下载其中包含的一个网址中的内容,这个网址包含注释,并且将printf解析后的字符串 “success: Parsed command is %c”到屏幕,输出成功的话,会sleep一分钟。这种方式是通过注释来隐藏指令,使得恶意代码看起来像是访问正常网页。