首页 > 编程语言 >恶意代码分析实战 lab 20-1 20-2 20-3 C++恶意代码分析,难度提升

恶意代码分析实战 lab 20-1 20-2 20-3 C++恶意代码分析,难度提升

时间:2023-08-02 18:38:04浏览次数:30  
标签:调用 20 函数 对象 恶意代码 程序 mov C++ sub

本次实验我们将会分析lab20-1,lab20-2文件。先来看看要求解答的问题
Lab20-1需要回答的问题如下
Q1.在0x401040处的函数采用了什么参数?
Q2.哪个URL被用来调用URLDownloadToFile?
Q3.这个程序做了什么事情?

在实验任务一当中我们来分析lab20-1

首先载入IDA

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_函数调用

第一个call是在401008,是一个对new操作符的调用,表明它正在创建一个对象==》这个对象的大小为4字节,可以推断应该是一个char * 的变量(指向URL http://www.practicalmalwareanalysis.com)!使用IDA F5编译成C看看:

 

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_this指针_02

 可以看到,IDA识别出来是this call。

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_逆向分析_03

接着通过mov指令,对象的引用被赋给var_8,var_4

在401019处,var_4赋给了ecx,说明它将被作为函数调用的this指针传递进去。

指向URL http://www.practicalmalwareanalysis.com的指针,随后被存储在对象的开头位置,之后调用sub_401040

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_函数调用_04

 

在401044处看到ecx中的this指针被访问,并赋给var_4,接着是其他参数入栈,之后就是调用URLDownloadToFile。为了获得将要使用的url参数,this指针在401050处被读取(var_4赋给eax),随后在401053处访问了存储在对象中的第一个数据元素(在main中可知第一个元素就是url字符串),并将其压入401055处的栈中(将URl字符串压入栈中)

我分析了上述代码,应该是长成如下的样子(真正的url download我没有调用):

#include <stdio.h>

char* aHttpWwwPractic = "http://www.practicalmalwareanalysis.com/cpp.html";

struct MyObj {
public:
	char *x; 
	
	void run() {
		// run url download to file
		// URLDownloadToFile(x, ....)
		printf("url download file: %s\n", x);
	}
};
 
void main() {	
	MyObj *p = new MyObj();
	p->x = aHttpWwwPractic;
	p->run();

	return;
}

为啥是struct而不是class?因为class在调用new的时候是会调用构造函数的,struct不会!上述代码反汇编的样子:

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_字符串_05

 

 

Q1.在0x401040处的函数采用了什么参数?
A1.在0x401040地址处的函数并不带任何参数,但它在ECX中传递了一个对象索引,含义为this指针

Q2.哪个URL被用来调用URLDownloadToFile?
A2.对URLDownloadToFile函数的调用使用http://www.practicalmalwareanalysis.com/cpp.html 作为URL参数值。

Q3.这个程序做了什么事情?
A3.这个程序从远程服务器下载文件,并把它存储到本地系统的C:\tempdownload.exe中。

 

 

接下来我们开始分析lab20-2
Lab20-2需要回答的问题如下:
Q1.在这个程序中,你可以从有趣的字符串中了解到什么?
Q2.导入函数表告诉你关于这个程序的什么信息?
Q3.在0x4011D9处创建对象的目的是什么?它有什么虚函数吗?
Q4.哪个函数可能被在0x401349处的call [edx]指令 调用?
Q5.如何简易地搭建这个恶意代码所预料的服务器,不用连接到互联网,就能完整地分析这个恶意代码呢?
Q6.这个程序的目的是什么?
Q7.在这个程序中实现虚函数调用的目的是什么?

Peview载入

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_this指针_06

这里看到了home ftp client,ftp的一个网址,这表明这个程序可能是一个ftp客户端程序==》ida里open subviews strings即可看到。

Q1.在这个程序中,你可以从有趣的字符串中了解到什么?

A1.最有趣的字符串是ftp. practicalmalwareanalysis.com和Home ftp client, 这表明这个程序很可能是FTP客户端软件。

查看其导入函数

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_逆向分析_07

FindNextFile,FindFirstFile表明可能会搜索系统上的文件

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_函数调用_08

一些ftp相关的函数更增强了我们的猜测

Q2.导入函数表告诉你关于这个程序的什么信息?

A2. 这一程序导入了函数FindFirstFile和FindNextFile, 这表明这个程序很可能会搜索受害主机的文件系统。而导入了函数InternetOpen、InternetConnect、FtpSetCurrentDirectory与FtpPutFile,这告诉我们这一恶意代码会上传受害主机的文件到一个远程FTP服

接下来载入IDA

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_函数调用_09

401521处调用WSAStartup初始化win32网络功能

401533调用gethostname获取主机名,获取的结果存在name变量,这里将其重命名为local_hostname

接着将C:\*压栈,调用了sub_401000,跟入

看到了循环结构

在循环之前

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_逆向分析_10

看到了FIndFirstFile

在循环结构里面

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_逆向分析_11

有FindNextFile

加之传入的参数

我们可知这是在搜索C盘下的文件

在循环里看到很多字符串操作函数

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_this指针_12

那么我们分析下程序在搜索什么

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_逆向分析_13

strncmp将操纵字符串与.doc比较,如果找到了doc后缀的文件,则往左边走

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_this指针_14

4011db调用new操作符来创建一个对象,然后开始初始化对象,对象存储在var_15
4011f2到401204将虚函数表写入对象的起始偏移处
因为new操作符创建对象之后off_4060dc马上被写入到对象中,所以我们知道这是一个虚函数表

双击查看off_4060dc

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_字符串_15

可以看到它保存了指向sub_401440地址的函数指针

 

==》验证下new一个抽象类以后是否如此。==》不应该有ctor函数吗?这个没有很是奇怪。。。。==》说明是struct!里面有virtual函数。

 

我们给sub_401440重命名为docObject_Func1

doc文件对象创建之后

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_字符串_16

跳转到4011f2,然后执行到loc_401222,然后跳到loc_40132f

回到sub_401000

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_字符串_17

如果没有找到doc文件,则往右边走,继续查看文件是否已pdf后缀结束。如果是的话,往左边走

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_逆向分析_18

同样通过new创建一个不同类型的对象,在off_4060D8有一个不同的虚函数表

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_this指针_19

给sub_401380重命名为docObject_Func2

pdf文件对象被创建之后来到4012b1

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_函数调用_20

然后执行到40132f,和doc对象被创建之后所执行的位置是一样的

回到sub_401000,如果不是pdf也不是doc,则会来到4012da

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_this指针_21

会创建一个其他类型的对象来表示所有其他的文件类型

给off_406030处的

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_字符串_22

重命名为otherfunc

最后也会来到40132f

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_函数调用_23

可以看到会引用存储在var_148变量中的对象,调用它在虚函数表中的第一个函数指针
这里注意一下,0x401349处的call指令,待会儿回到第4个问题会用到

我们先来看pdf对象调用的函数。

也就是4060d8处的函数,即Object_Func2

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_this指针_24

调用InternertOpen函数初始化互联网连接,然后InternetConnect建立到ftp.pracitcalmalware.com的FTP连接

之后调用FtpSetCurrentDirectory改变ftp当前路径到pdfs目录,并开始上传文件到远程服务器,将文件名用主机名和序号填充成%s-%d.pdf的格式

再查看doc的

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_this指针_25

双击跟入

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_字符串_26

可以看到基本上和pdf的处理差不多,不过这里是改变ftp当前路径到docs目录,上传doc文件到远程服务器

再来看看4060e0的otherfunc

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_字符串_27

这个函数没做什么

所以我们知道恶意代码只是上传doc和pdf文件

 

里面有一段虚函数的本质代码,需要理解多态的核心才能明白,我梳理出来应该类似如下:

#include <stdio.h>


struct Runner {
	int what_ever; //default sizeof is 8 == 4 + v_table_ptr(4)

	virtual void run() {
		printf("default upload\n");
	}
};

struct DocRunner: public Runner {
public:	
	void run() {	
		printf("doc upload\n");
	}
};
 

struct PdfRunner: public Runner {
public:	
	void run() {	
		printf("pdf upload\n");
	}
};


void main() {	
	Runner *p = NULL;
	if ("is doc") {
		p = new DocRunner;
	} else if ("is pdf") {
		p = new PdfRunner;
	} else {
		p = new Runner;
	}	
	p->run();
	
	delete p;
	return;
}

 本质上就是利用多态完成了pdf和doc的上传。运行的逻辑对应如下:

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_逆向分析_28

在vc6里我们看下虚表的填充逻辑(我的因为不是正版vc6,可能和原书作者的有差异):

32:           p = new DocRunner;
0040108D   push        8
0040108F   call        operator new (00401480)
00401094   add         esp,4
00401097   mov         dword ptr [ebp-18h],eax
0040109A   mov         dword ptr [ebp-4],0
004010A1   cmp         dword ptr [ebp-18h],0
004010A5   je          main+64h (004010b4)
004010A7   mov         ecx,dword ptr [ebp-18h]
004010AA   call        @ILT+0(DocRunner::DocRunner) (00401005)

看下DocRunner::DocRunner其内在实现,

DocRunner::DocRunner:
00401200   push        ebp
00401201   mov         ebp,esp
00401203   sub         esp,44h
00401206   push        ebx
00401207   push        esi
00401208   push        edi
00401209   push        ecx
0040120A   lea         edi,[ebp-44h]
0040120D   mov         ecx,11h
00401212   mov         eax,0CCCCCCCCh
00401217   rep stos    dword ptr [edi]
00401219   pop         ecx
0040121A   mov         dword ptr [ebp-4],ecx
0040121D   mov         ecx,dword ptr [ebp-4]
00401220   call        @ILT+5(Runner::Runner) (0040100a) ==》填充虚表,这里面填充的是父类的run函数
00401225   mov         eax,dword ptr [ebp-4]
00401228   mov         dword ptr [eax],offset DocRunner::`vftable' (0042502c) ==》再填充一次虚表,这里面填充的是子类的run函数
0040122E   mov         eax,dword ptr [ebp-4]
00401231   pop         edi
00401232   pop         esi
00401233   pop         ebx
00401234   add         esp,44h
00401237   cmp         ebp,esp
00401239   call        __chkesp (00401970)
0040123E   mov         esp,ebp
00401240   pop         ebp
00401241   ret

 

我们进去看下Runner::Runner:

Runner::Runner:
00401360   push        ebp
00401361   mov         ebp,esp
00401363   sub         esp,44h
00401366   push        ebx
00401367   push        esi
00401368   push        edi
00401369   push        ecx
0040136A   lea         edi,[ebp-44h]
0040136D   mov         ecx,11h
00401372   mov         eax,0CCCCCCCCh
00401377   rep stos    dword ptr [edi]
00401379   pop         ecx
0040137A   mov         dword ptr [ebp-4],ecx
0040137D   mov         eax,dword ptr [ebp-4]
00401380   mov         dword ptr [eax],offset Runner::`vftable' (00425054) ==》看到了吧,实际上虚表填充的是父类的函数!
00401386   mov         eax,dword ptr [ebp-4]
00401389   pop         edi
0040138A   pop         esi
0040138B   pop         ebx
0040138C   mov         esp,ebp
0040138E   pop         ebp
0040138F   ret
我们看下上面两个函数的内容:

填充父类的default upload runner函数:

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_函数调用_29

 在覆盖子类的upload runner函数

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_this指针_30

 好了,理解上面的本质以后,就可以回答下面的问题了。

 

Q3.在0x4011D9处创建对象的目的是什么?它有什么虚函数吗?
A3.在0x00401ID9地址创建的对象是一个 .doc文件。这个对象在偏移0x00401440 地址处有一个虚函数,它将把文件上传至远程FTP服务器。

Q4.哪个函数可能被在0x401349处的call指令调用?
A4.在0x00401349处的虚函数调用将调用在0x00401380、0x00401440 的一个虚函数。

Q6.这个程序的目的是什么?
A6.这个程序会搜索受害主机的硬盘驱动器,并上传所有doc和.pdf后缀的文件到远程FTP服务器上。
而这里为什么要用虚函数呢?因为使用虚函数可以使这段代码修改或扩展时更加容易,在需要添加对不同文件类型支持时,只需要简单地实现一个新对象并修改对象创建后的代码即可
Q7.在这个程序中实现虚函数调用的目的是什么?
A7.实现虚拟函数调用的目的是让代码对不同文件类型执行不同的上传函数

 

下面是运行时模拟:

下载一个ftp服务器,启动

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_逆向分析_31

注意给其上传的权限,上图中设置了访问目录为c盘根目录

在c盘根目录创建两个空的文件夹,分别为docs,pdfs,可以再新建两个文件,注意后缀名pdf和doc

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_逆向分析_32

在启动apatedns(需要安装.net环境才能运行),他可以将响应DNS请求设置为任何你指定的IP地址。

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_函数调用_33

我们如下所示,在current gateway设置为127.0.0.1,然后启动20-2.exe

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_逆向分析_34

如上所示,看到会请求ftp.malwareanalysis.com

此时查看c盘根目录下的docs文件夹

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_字符串_35

以及pdfs文件夹

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_函数调用_36

其文件名也印证了我们前面在IDA中的分析。
Q5.如何简易地搭建这个恶意代码所预料的服务器,不用连接到互联网,就能完整地分析这个恶意代码呢?
A5.这一恶意代码会使用高层API函数连接到一个远程的FTP服务器,我们可以下载并建立一个本地FTP服务器,并将DNS请求重定向至这一服务器,以充分分析该恶意代码。

 

 

 

本次实验我们将会分析lab20-03文件。先来看看要求解答的问题
Q1.你可以在这个程序中得到什么有意思的字符串?
Q2.导入函数表告诉你关于这个程序的什么信息?
Q3.在0x4036F0处,存在一个以字符串Config error作为输入的函数调用,其后跟着一些指令,然后是一个对CxxThrowException的调用。除这个字符串外,这个函数还用到其他参数了吗?这个函数返回了什么?从这个函数被使用的上下文中,你可以得到哪些信息?
Q4.在0x4025C8处的switch表中的6个项都做了什么?
Q5.这个程序的目的是什么?

载入IDA,打开string窗口

这里有趣的东西有很多,从这些字符串中可以猜测其功能。比如:

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_this指针_37

看到了http get,post命令及内容

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_逆向分析_38

建立socket,与远程机器交互,发送信息和查看响应

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_字符串_39

上传文件,下载文件,创建进程等

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_逆向分析_40

搜集主机信息

仅仅通过这些字符串,我们大概就能猜出,这个程序是一个后门程序,使用HTTP GET和POST命令来构建C&C,支持上传文件,下载文件,创建新进程,以及调查受害者主机等功能。
Q1.你可以在这个程序中得到什么有意思的字符串?
A1.有几个看起来像是错误消息的字符串(Error sending Http post, Error sending Http get,Error reading response,等等)告诉我们,这个程序将会使用HTTP GET和POST命令

再查看imports窗口

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_字符串_41

这些WS2_32导入函数说明这个程序会在网络中通信

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_字符串_42

CreateProcess说明这个程序可能会启动另一个进程
Q2.导入函数表告诉你关于这个程序的什么信息?
A2.几个WS2_32中的导入函数告诉我们,这个程序会在网络上进行通信。CreateProcess 导入函数表明,这个程序可能会启动另一个进程。

切换到View-A

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_逆向分析_43

main中调用了0x403be0,跟入

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_逆向分析_44

在403c08通过new操作符创建一个新对象,并在寄存器eax中返回了一个指向新对象的指针。之后将对象指针移入ecx寄存器

在403c22函数调用时被用做this指针,config.dat作为该函数的参数

说明sub_401ee0是前面创建对象所属类的一个成员函数。

跟入sub_401ee0

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_函数调用_45

在401ef7将保存指针的ecx值赋给esi

在401efe通过new操作符创建另一个新对象

之后调用该对象的一个函数sub_403180

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_字符串_46

调用CreateFile,FileName参数值为config.dat。我们猜测这个函数是从磁盘读取配置文件,如果该文件可以被打开则执行jnz loc_4031d5,往右走.如果没有打开成功,则往左走,将Config error字符串做为参数传递给sub_4036f0

sub_4036f0也使用ecx寄存器作为this指针,使用this指针的对象引用存储在栈上的var_AC变量里。

之后var_AC赋给eax,在4031d0看到,该对象被传递给了CxxThreadException函数

所以我们知道,sub_4036f0是异常对象的一个成员函数,我们推测这个函数在使用Config error初始化一个异常

这样一种模式—一个带着错误字符串参数的函数调用后是一个CxxThrowException,表明这个函数在初始化一个异常,这个模式在接下来的分析中如果出现,我们就可以很快进行分析了

Q3.在0x4036F0处,存在一个以字符串Config error作为输入的函数调用,其后跟着一些指令,然后是一个对CxxThrowException的调用。除这个字符串外,这个函数还用到其他参数了吗?这个函数返回了什么?从这个函数被使用的上下文中,你可以得到哪些信息?

A3.在0x4036F0地址调用的函数除了一个字符串外,不带任何参数,但ECX寄存器中包含了对象的this指针。我们知道包含这一函数的对象是一个异常对象,因为这个对象在后面被用于CxxThrowException函数的一个参数。通过上下文环境我们可以得知0x4036F0地址的函数初始化了一个异常对象,而异常对象中存储了一个字符串来描述到底引发了何种异常。

如果config.dat打开成功,走右边

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_逆向分析_47

会通过ReadFile从config.dat中读取数据,然后存储在创建的对象中

回到上一层函数,继续分析

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_this指针_48

eax赋给了esi
eax中是指向第二次创建的对象的指针
也就是说第二次创建的对象的指针被保存在第一次创建的对象中
之后是一系列硬编码的url路径,以及两个硬编码的整数
之后的mov eax,esi返回了一个指向第一次创建的对象的指针。这个对象似乎存储了程序所有全局数据。
我们基本知道sub_401ee0做的工作:从一个文件加载配置信息,然后初始化一个对象,并存储程序的全局数据。

返回上层函数

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_函数调用_49

在进入循环之前,调用了usb_401f80,跟入

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_this指针_50

跟入sub_403d50

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_字符串_51

可见,这是用于建立socket连接的

返回上层函数,继续分析

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_逆向分析_52

跟入sub_402ff0

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_this指针_53

该函数用于获取主机信息

返回上层,跟入sub_404ed0

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_函数调用_54

跟入sub_404ef0

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_函数调用_55

从字符串可见这是进行了http post请求

返回sub_401f80

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_逆向分析_56

跟入sub_404b10

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_字符串_57

从字符串来看该函数是用于检测响应

跟入sub_4015c0

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_this指针_58

这个函数是用于检查参数编码的

所以我们大概知道sub_401f80的作用了:向远程主机发送信息,并检查响应,如果符合,则进入循环

注意这个循环的最后jmp是无条件跳转,而且循环中没有计数器,意味着这是一个无限循环

在循环中调用了loc_402410和sleep

跟入loc_402140

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_this指针_59

调用了sub_403d50,这个函数之前分析过,是用于建立socket连接的

继续往下

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_函数调用_60

跟入sub_404cf0

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_逆向分析_61

这是用于发送http get请求的

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_函数调用_62

之后看到两个代码块,当响应不符合特定格式标准时它们会引发异常

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_this指针_63

之后看到了拥有6个选项的switch语句
用于决定switch的值存储在esi+4,该值被赋给eax
0FFFFFF9F转换是-61h
之后就是将eax寄存器值减去0x61
如果结果不小于5,则不进行任何switch跳转
0x61+5=0x66
这样就可以确保值处于0x61到0x66即ascii的a到f
也即是说,为a到f之间任一,才会实现switch跳转

双击off_4025c8

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_字符串_64

可以看到6个可能的选择位置

双击loc_402561看看第一处

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_字符串_65

调用delete运算符,然后立即返回

接着分析第二处

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_字符串_66

调用了su_4025e0,跟入

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_逆向分析_67

其将字符串转为数字,调用sleep函数后返回

接着分析第三处

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_逆向分析_68

跟入sub_402f80

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_逆向分析_69

跟入sub_402ef0

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_逆向分析_70

调用了CreateProcess创建进程

分析第四处

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_逆向分析_71

跟入sub_402ba0

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_this指针_72

跟入sub_402a20

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_函数调用_73

调用CreateFile,WriteFile,将从C&C服务器获取到的http相应写到磁盘上

分析第五处

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_逆向分析_74

跟入sub_402c70

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_函数调用_75

跟入sub_4027e0

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_this指针_76

通过http post命令,将从文件读取的数据上传到远程服务器

分析第六处

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_函数调用_77

跟入sub_402d30

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_字符串_78


恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_逆向分析_79

从其关键的函数调用可知,这是用于获取受害者主机信息

恶意代码分析实战  lab 20-1 20-2 20-3 C++恶意代码分析,难度提升_函数调用_80

之后调用sub_404b10将结果发给C&C服务器
总结一下,这个程序会读取配置文件,从而确定C&C服务器,发送控制信号至远程C&C服务器,并根据服务器端不同的响应,实现了几个不同的后门功能。

 

 

Q4.在0x4025C8处的switch表中的6个项都做了什么?
A4. Switch 表的6个条目实现了6种不同的后门命令: NOP、休眠、执行一个程序、下载文件、上传一个文件,以及调查受害主机
Q5.这个程序的目的是什么?
A5.该程序实现了一个后门,它使用HTTP作为命令通道,并具备启动程序、下载或上传文件,以及收集受害主机信息的能力。

参考:
1.《恶意代码分析实战》

 

标签:调用,20,函数,对象,恶意代码,程序,mov,C++,sub
From: https://blog.51cto.com/u_11908275/6941498

相关文章

  • C++逆向分析——友元、内部类、命名空间和static
    友元友元可以理解为:朋友、元素;老师认为这个友元是C++中的一个垃圾,因为友元的存在破坏了面向对象的封装性,不推荐使用,之所以有这个章节是因为有人不了解这个概念。注意:在一些新版本的C++编译器里面已经不再提供类似于友元这样的特性了。大家都知道在C++中对象的私有成员,外部是无法访......
  • C++逆向分析——对象拷贝
    对象拷贝我们通常存储对象,都用数组、列表之类的来存储,那如下所示我们使用数组来存储对象,但是在工作中发现这个数组不够用了,就需要一个更大的数据,但我们重新创建一个数组还需要把原来的数据复制过来;在C语言中可以使用函数来进行拷贝,直接拷贝内存,在C++中实际上跟C语言要做的事情是一......
  • C++逆向分析——模版
    模版假设有一个冒泡排序的函数:voidSort(int*arr,intnLength){inti,k;for(i=0;i<nLength;i++){for(k=0;k<nLength-1-i;k++){if(arr[k]>arr[k+1]){inttemp=arr[k];arr[k]=arr[k+1];arr[k+1]=temp;}}}}但是这个冒......
  • C++逆向分析——运算符重载
    运算符重载现在有一个类,其中有一个函数用于比较2个类的成员大小:#include<stdio.h>classNumber{private:intx;inty;public:Number(intx,inty){this->x=x;this->y=y;}intMax(Number&n){returnthis->x>n.x&&this->y......
  • C++逆向分析——多态和虚表
    虚表上一章了解了多态,那么我们来了解一下多态在C++中是如何实现的。了解本质,那就通过反汇编代码去看就行了,首先我们看下非多态的情况下的反汇编代码:然后再来看下多态情况下的反汇编代码:很明显这里多态的情况下会根据edx间接调用,而非多态则会直接调用。那么我们来看下间接调用的流程......
  • C++逆向分析——继承与封装
    面向对象程序设计之继承与封装之前已经学习过继承和封装了,但是要在实际开发中使用,光学语法和原理是不够的,在设计层面我们需要做一些优化。如下代码是继承的例子:#include<stdio.h>classPerson{public:intAge;intSex;voidWork(){printf("Person:Work()"......
  • C++逆向分析——引用
    voidmain(){intx=1;int&ref=x;ref=2;printf("%d\n",ref);return;}反汇编代码:intx=1;00724A5FC745F401000000movdwordptr[x],1int&ref=x;00724A668D45F4lea......
  • C++逆向分析——类成员的访问控制
    类成员的访问控制课外→好的编程习惯:定义与实现分开写,提升代码可读性。如下代码,Student这个类的所有成员我们都可以调用,但是我们不想让被人调用Print1这个方法该怎么?structStudent{intage;intsex;voidPrint1(){printf("FuncPrint1");}voidPrint(){......
  • C++逆向分析——new和delete new[]和delete[]
    在堆中创建对象我们可以在什么地方创建对象?全局变量区,在函数外面在栈中创建对象,也就是函数内在堆中创建对象注意:之前一直提到的堆栈实际上是两个概念->堆、栈,我们之前所讲的就是栈,从本章开始要严格区分。在C语言中,我们可以通过一个函数去申请一块内存,就是malloc(N);申请的这一块内存......
  • C++逆向分析——继承
    继承structPerson{intage;intsex;};structTeacher{intage;intsex;intlevel;intclassId;};如上代码中可以看见,Teacher类与Person类都存在着相同的2个成员age和sex,那么这就相当于重复编写了,我们可以通过继承的方式避免这样重复的编写(当前类名称:要......