首页
社区
课程
招聘
[原创]默默无闻·恶意代码分析Lab1
发表于: 2021-4-3 21:45 7537

[原创]默默无闻·恶意代码分析Lab1

2021-4-3 21:45
7537

参照书籍:《恶意代码分析实战》、《windows PE权威指南》;

文件来源:官网随书文件、或者附件中(文件密码:apebro);

使用工具:WinHex、CFF、StudyPE+、Exeinfo PE、Resource Hacker、Depends Walker、OD、IDA、MSDN;

这个实验使用Lab01-01.exe和Lab01-01.dll文件,使用本章描述的工具和技术来获取关于这些文件的信息;

问题

1、将文件上传至http://www.VirusTotal.com进行分析并查看报告。文件匹配到了已有的反病毒软件特征吗?

2、这些文件是什么时候编译的?

3、这两个文件中是否存在迹象说明它们是否被加壳或者混淆了?如果是,这些迹象在哪里?

4、是否有导入函数显示处了这个恶意代码是做说明的?如果是,是哪些导入函数?

5、是否有任何其他文件或基于主机的迹象,让你可以在受感染系统上查找?

6、是否有基于网络的迹象,可以用来发现受感染机器上的这个恶意代码?

7、你猜这些文件的目的是什么?

1、在官网http://www.VirusTotal.com进行文件上传;

Lab01-01.exe检测结果:

image-20210403131453873

Lab01-01.dll检测结果:

image-20210403131709508

2、使用WinHex手动分析PE头;

Lab01-01.exe分析结果:

image-20210403134056115

Lab01-01.dll分析结果:

image-20210403134707846

经过分析发现,获得的两个文件的时间戳(4D0E2FD34D0E2FE6)都非常相近。通过使用StudyPE+工具进行时间戳计算:

image-20210403135514747

image-20210403135558599

旁话:

时间戳数据并不可靠,仅仅是用来参考的。因为这个数据可以随便改。但是有些编译器对于此字段会有特殊的绝对或相对的给值。所以这个字段仅能用来参考;
关于时间戳字段,并不仅仅有这一个,还可以参考后面节区的TimeDateStamp字段;

3、使用Exeinfo PE工具进行查壳检测(关于手动查壳的讨论学习在后续的帖子进行讨论);

Lab01-01.exe分析结果:

image-20210403141507297

Lab01-01.dll分析结果:

image-20210403141530280

4、使用Depends工具查看导入函数;

Lab01-01.exe分析结果:

image-20210403142634345

CreateFileMapping():

总结:使用文件映射方式可以进行进程间共享数据;更多细节,请查看MSDN;

关于函数结尾A是因为参数使用了ANSI字符格式,更多关于Unicode字符和ANSI字符的函数,请查看《windows核心编程》

FindFirstFile():

总结:有搜索文件系统的操作;更多细节,请查看MSDN;

FindNextFile():

总结:搜索文件系统的操作;更多细节,请查看MSDN;

CopyFile:

总结:复制文件操作;更多细节,请查看MSDN;

image-20210403142702066

Lab01-01.dll分析结果:

image-20210403145453401

CreateProcess():

总结:创建进程或线程,可能涉嫌非法操作;更多细节,请查看MSDN;

Sleep():

总结:进程操作;更多细节,请查看MSDN;

image-20210403145518548

WS2_32.dllWsock32.dll两个是联网DLL,涉有一个都有可能有网络操作;

因为使用了编号导入),所以并没有显示函数名。使用其他PE工具,可能只能看见编号而看不见函数,容易误判函数数量。所以书上推荐的Dependency Walker工具是挺好用的,下方还给出了相对编号的函数名;

send()[Ordinal-19]:

总结:套接字数据发送;更多细节,请查看MSDN;

image-20210403145537918

5、使用IDA工具进行文件分析;

Lab01-01.exe分析结果:

image-20210403153119625

总结:这就非常有意思了,关于0(数字零)和O(大写字母O)和1(数字一)和l(小写字母L)的混淆还是蛮多的;

猜测:假的kerne132.dll文件是用来冒充混淆,可以作为基于主机的病毒特征,是分析Malware的重要线索;

6、使用IDA工具进行文件分析;

Lab01-01.dll分析结果:

image-20210403153930521

image-20210403154348198

总结:一般情况下不太可能直接字符串能够查询到准确有用的数字,更多的时候都是被加密操作过的。所以,这个只能算是扫盲题。

7、胡说不是乱说;

回忆一下前面的操作,我们可以基本确认这两个程序是一个后门病毒。原本想小试牛刀逆一下,看了书后答案,原来Lab7还会有这个题目。那就等到那时候再详细写帖子;

分析Lab01-02.exe文件

问题

1、将Lab01-02.exe文件上传至http://www.VirusTotal.com进行分析并查看报告。文件匹配到了已有的反病毒软件特征吗?

2、是否有这个文件被加壳或混淆的任何迹象?如果是这样,这些迹象是什么?如果该文件被加壳,请进行脱壳,如果可能的话。

3、有没有任何导入函数能够暗示出这个程序的功能?如果是,是哪些导入函数,它们会告诉你什么?

4、哪些基于主机或基于网络的迹象可以被用来确定被这个恶意代码所感染的机器?

1、在官网http://www.VirusTotal.com进行文件上传;

Lab01-01.exe检测结果:

image-20210403160148067

2、使用CFFExeinfo PE工具进行查壳检测;

image-20210403160638788

image-20210403160815441

image-20210403161539751

3、使用Dependency Walker工具查看Lab01-02.exe文件的导入函数;

image-20210403161915933

image-20210403161941645

image-20210403162019151

image-20210403162038590

总结:这个程序会进行联网操作并且创建服务;

4、使用IDA工具查看;

image-20210403165659092

分析Lab01-03.exe文件

问题

1、将Lab01-03.exe文件上传至http://www.VirusTotal.com进行分析并查看报告。文件匹配到了已有的反病毒软件特征吗?

2、是否有这个文件被加壳或混淆的任何迹象?如果是这样,这些迹象是什么?如果该文件被加壳,请进行脱壳,如果可能的话。

3、有没有任何导入函数能够暗示处这个程序的功能?如果是,是哪些导入函数,它们会告诉你什么?

4、有哪些基于主机或基于网络的迹象,可以被用来确定被这个恶意代码所感染的机器?

1、在官网http://www.VirusTotal.com进行文件上传;

image-20210403170248341

2、使用CFFExeinfo PEDependency Walker工具进行查壳检测;

image-20210403171800569

image-20210403172238740

image-20210403172606946

image-20210403172926727

既然知道被加壳,我们就使用Exeinfo PE工具看看具体是哪种壳,图中显示为FSG 1.10

暂时还没到脱壳章节,书后答案显示,18章课后习题将学习手动脱壳,再详细套路;

3、暂无,后面章节续写;

4、暂无,后面章节续写;

分析Lab01-04.exe文件

问题

1、将Lab01-04.exe文件上传至http://www.VirusTotal.com进行分析并查看报告。文件匹配到了已有的反病毒软件特征吗?

2、是否有这个文件被加壳或混淆的任何迹象?如果是这样,这些迹象是什么?如果该文件被加壳,请进行脱壳,如果可能的话。

3、这个文件是什么时候被编译的?

4、有没有任何导入函数能够暗示处这个程序的功能?如果是,是哪些导入函数,它们会告诉你什么?

5、有哪些基于主机或基于网络的迹象,可以被用来确定被这个恶意代码所感染的机器?

6、这个文件在资源段中包含一个资源。使用Resource Hacker工具来检查资源,然后抽取资源。从资源中你能发现什么吗?

1、在官网http://www.VirusTotal.com进行文件上传;

image-20210403173428483

2、使用CFFExeinfo PEDependency Walker工具进行查壳分析;

image-20210403173706179

image-20210403174016949

image-20210403174339049

3、使用WinHexStudyPE+工具查看编译实现;

image-20210403174729009

image-20210403174809836

4、使用Depends Walker工具查看导入函数;

image-20210403175119537

image-20210403175133897

image-20210403175150221

总结:从advapi32.dll的函数,表明会涉及系统服务的操作,导入函数WinExecWriteFile表明会有磁盘写操作和执行操作.

5、使用IDA工具进行分析;

image-20210403182300437

image-20210403182228002

6、使用WinHexResource HackerIDA工具进行资源节查找和抽取;

image-20210403174016949

image-20210403184557176

这是四个节表的RVA,由此可见在第四个节区;

FOA=0x00004000-0x00004000+0x00004000=0x00004000

image-20210403185734545

image-20210403190700947

我们发现,此资源表只有 一个 名称命名的入口点;

image-20210403191127416

这里有一个注意的地方就是,一个目录项的大小是8字节.这个很重要,因为这里用到了union结构.

image-20210403191557584

这段感觉很难看明白,但是有技巧.

所以我们可以了解到这两个八字节的数据意思是它是个目录,目录名偏移是0x0058;

image-20210403201309754

这里非常有意思,Pascal版本的Unicode类型字符串,它的特点就是字符串开头会声明字符大小.

后四个字节0x80000018去除最高位后就是资源目录项(也就是下一层结构)的偏移0x0018,它指向的文件地址是0x00004018;

image-20210403202325034

咦,很奇怪,为什么会是0x00呢?

image-20210403202732998

由图所得,这一层只有一个ID命名的目录入口点;

image-20210403202908037

紧随其后的就是资源目录项IMAGE_RESOURCE_DIRECTORY_ENTRY结构;

由上面的结论所知,第一个4字节数据0x00000065表示:

第二个4字节数据0x80000030表示:

重点来了

image-20210403203917520

又是一个16个字节的资源目录头(IMAGE_RESOUORCE_dIRCTORY)的结构和资源目录项IMAGE_RESOURCE_DIRECTORY_ENTRY结构;

image-20210403195231486

image-20210403205912157

offsetToData0x00004060,这里要注意的是不再是一个节内偏移,而是RVA;

image-20210403184557176

​ FOA=0x00004060-0x00004000+0x00004000=0x00004060;

Size0x00004000大小的数量;

image-20210403211509641

然后从0x00004060开始,向下到0x000080600x4000大小复制出来,新建文件,就抽取出了资源节中隐藏的代码段了;

以上就是手动抽取资源节的步骤了

当然,什么年代了,当然有非常棒的工具了,这就是Resource Hacker工具了;

image-20210403211938082

再通过IDA工具分析;

image-20210403212102419

这我们就找到了书中答案所说的下载恶意代码的网络位置了.

再使用Dependency工具查看导入表 ;

image-20210403212433134

image-20210403212454059

大学开始接触逆向,但可惜囊中羞涩,报不了什么速成班,故自学了很久,走了太多的歧路。

如有不正之处,还请各位大佬指正。

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
HANDLE CreateFileMapping(
  HANDLE hFile,              // handle to file to map
  LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
                             // optional security attributes
  DWORD flProtect,           // protection for mapping object
  DWORD dwMaximumSizeHigh,   // high-order 32 bits of object size
  DWORD dwMaximumSizeLow,    // low-order 32 bits of object size
  LPCTSTR lpName             // name of file-mapping object
);
//Description:The CreateFileMapping function creates a named or unnamed file-mapping object for the specified file.
 
// 描述:CreateFileMapping函数为指定的文件创建一个命名的或未命名的文件映射对象。
HANDLE CreateFileMapping(
  HANDLE hFile,              // handle to file to map
  LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
                             // optional security attributes
  DWORD flProtect,           // protection for mapping object
  DWORD dwMaximumSizeHigh,   // high-order 32 bits of object size
  DWORD dwMaximumSizeLow,    // low-order 32 bits of object size
  LPCTSTR lpName             // name of file-mapping object
);
//Description:The CreateFileMapping function creates a named or unnamed file-mapping object for the specified file.
 
// 描述:CreateFileMapping函数为指定的文件创建一个命名的或未命名的文件映射对象。
 
 
HANDLE FindFirstFile(
  LPCTSTR lpFileName,  // pointer to name of file to search for
  LPWIN32_FIND_DATA lpFindFileData
                       // pointer to returned information
);
 
//Description:The FindFirstFile function searches a directory for a file whose name matches the specified filename. FindFirstFile examines subdirectory names as well as filenames.
 
// 描述:FindFirstFile函数的作用是:在一个目录中搜索文件名与指定文件名匹配的文件。FindFirstFile检查子目录名和文件名。
HANDLE FindFirstFile(
  LPCTSTR lpFileName,  // pointer to name of file to search for
  LPWIN32_FIND_DATA lpFindFileData
                       // pointer to returned information
);
 
//Description:The FindFirstFile function searches a directory for a file whose name matches the specified filename. FindFirstFile examines subdirectory names as well as filenames.
 
// 描述:FindFirstFile函数的作用是:在一个目录中搜索文件名与指定文件名匹配的文件。FindFirstFile检查子目录名和文件名。
 
BOOL FindNextFile(
  HANDLE hFindFile,  // handle to search
  LPWIN32_FIND_DATA lpFindFileData
                     // pointer to structure for data on found file
);
 
//Description:The FindNextFile function continues a file search from a previous call to the FindFirstFile function. 
 
// 描述:FindNextFile函数继续从先前调用的FindFirstFile函数进行文件搜索。
BOOL FindNextFile(
  HANDLE hFindFile,  // handle to search
  LPWIN32_FIND_DATA lpFindFileData
                     // pointer to structure for data on found file
);
 
//Description:The FindNextFile function continues a file search from a previous call to the FindFirstFile function. 
 
// 描述:FindNextFile函数继续从先前调用的FindFirstFile函数进行文件搜索。
 
BOOL CopyFile(
  LPCTSTR lpExistingFileName,
                          // pointer to name of an existing file
  LPCTSTR lpNewFileName,  // pointer to filename to copy to
  BOOL bFailIfExists      // flag for operation if file exists
);
 
//Description:The CopyFile function copies an existing file to a new file.
 
// 描述:CopyFile函数的作用是将一个现有文件复制到一个新的文件中。
BOOL CopyFile(
  LPCTSTR lpExistingFileName,
                          // pointer to name of an existing file
  LPCTSTR lpNewFileName,  // pointer to filename to copy to
  BOOL bFailIfExists      // flag for operation if file exists
);
 
//Description:The CopyFile function copies an existing file to a new file.
 
// 描述:CopyFile函数的作用是将一个现有文件复制到一个新的文件中。
 
 
BOOL CreateProcess(
  LPCTSTR lpApplicationName,
                         // pointer to name of executable module
  LPTSTR lpCommandLine,  // pointer to command line string
  LPSECURITY_ATTRIBUTES lpProcessAttributes,  // process security attributes
  LPSECURITY_ATTRIBUTES lpThreadAttributes,   // thread security attributes
  BOOL bInheritHandles,  // handle inheritance flag
  DWORD dwCreationFlags, // creation flags
  LPVOID lpEnvironment,  // pointer to new environment block
  LPCTSTR lpCurrentDirectory,   // pointer to current directory name
  LPSTARTUPINFO lpStartupInfo,  // pointer to STARTUPINFO
  LPPROCESS_INFORMATION lpProcessInformation  // pointer to PROCESS_INFORMATION
);
//Description:The CreateProcess function creates a new process and its primary thread. The new process executes the specified executable file.
 
// 描述:函数的作用是:创建一个新进程及其主线程。新进程执行指定的可执行文件。
BOOL CreateProcess(
  LPCTSTR lpApplicationName,
                         // pointer to name of executable module
  LPTSTR lpCommandLine,  // pointer to command line string
  LPSECURITY_ATTRIBUTES lpProcessAttributes,  // process security attributes
  LPSECURITY_ATTRIBUTES lpThreadAttributes,   // thread security attributes
  BOOL bInheritHandles,  // handle inheritance flag
  DWORD dwCreationFlags, // creation flags
  LPVOID lpEnvironment,  // pointer to new environment block
  LPCTSTR lpCurrentDirectory,   // pointer to current directory name
  LPSTARTUPINFO lpStartupInfo,  // pointer to STARTUPINFO
  LPPROCESS_INFORMATION lpProcessInformation  // pointer to PROCESS_INFORMATION
);
//Description:The CreateProcess function creates a new process and its primary thread. The new process executes the specified executable file.
 
// 描述:函数的作用是:创建一个新进程及其主线程。新进程执行指定的可执行文件。
 
VOID Sleep(
  DWORD dwMilliseconds   // sleep time in milliseconds
);
//Description:The Sleep function suspends the execution of the current thread for a specified interval.
 
// 描述:函数的作用是:Sleep函数在指定的时间间隔内挂起当前线程的执行。
VOID Sleep(
  DWORD dwMilliseconds   // sleep time in milliseconds
);
//Description:The Sleep function suspends the execution of the current thread for a specified interval.
 
// 描述:函数的作用是:Sleep函数在指定的时间间隔内挂起当前线程的执行。
 
int send (
  SOCKET s,             
  const char FAR * buf, 
  int len,              
  int flags             
);
//Description:The Windows Sockets send function sends data on a connected socket.
 
// 描述:函数的作用是:Windows套接字send函数在连接的套接字上发送数据。
int send (
  SOCKET s,             
  const char FAR * buf, 
  int len,              
  int flags             
);
//Description:The Windows Sockets send function sends data on a connected socket.
 
// 描述:函数的作用是:Windows套接字send函数在连接的套接字上发送数据。
 
 
 
 
 
 
 
 
 
 
SystemTimeToFileTime(...);//将系统时间转换为文件时间。
GetModuleFileNameA(...);//获取包含指定模块的可执行文件的完整路径和文件名。
CreateWaitableTimerA(...);//函数创建了一个“可等待的”计时器对象。
ExitProcess(...);//结束一个进程及其所有线程。
OpenMutexA(...);//返回一个已存在的命名互斥对象的句柄。
SetWaitableTimer(...);//激活指定的“可等待”计时器。当到期时间到达时,计时器被通知,设置
                        //计时器的线程调用可选的完成例程。
WaitForSingleObject(...);//WaitForSingleObject函数在下列情况之一发生时返回:
                            //指定的对象处于有信号状态。
                            //超时时间过期。
CreateMutexA(...);//创建一个命名的或未命名的互斥对象。
CreateThread(...);//创建一个线程,在调用进程的地址空间中执行。
SystemTimeToFileTime(...);//将系统时间转换为文件时间。
GetModuleFileNameA(...);//获取包含指定模块的可执行文件的完整路径和文件名。
CreateWaitableTimerA(...);//函数创建了一个“可等待的”计时器对象。

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2021-5-4 21:01 被平头猿小哥编辑 ,原因:
上传的附件:
收藏
免费 4
支持
分享
最新回复 (2)
雪    币: 1475
活跃值: (14652)
能力值: ( LV12,RANK:380 )
在线值:
发帖
回帖
粉丝
2
加油
2021-4-3 22:24
1
雪    币: 246
活跃值: (4427)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
3
加油
2021-4-4 11:12
1
游客
登录 | 注册 方可回帖
返回
//