首页
论坛
课程
招聘
[调试逆向] [病毒木马] [原创]默默无闻·恶意代码分析Lab6
5天前 1238

[调试逆向] [病毒木马] [原创]默默无闻·恶意代码分析Lab6

5天前
1238

系列往期:

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

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


工具说明

参照书籍:《恶意代码分析实战》;

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

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

Lab6-1

在这个实验中,你将分析在文件Lab06-01.exe中发现的恶意代码;

  • 习惯吧,拿到文件先用ExeInfo PE查壳;

image-20210405155120562

 

结果无壳;

 

问题

1、由main函数调用的唯一子过程中发现的主要代码结构是什么?

  • 使用IDA打开程序;

image-20210405160134778

 

main函数开始找第一个调用sub_401000,双击进函数一探究竟;

  • 进入Graph View宏观查看,很显然是一个if结构;

image-20210405160453794

  • 仔细查看一下具体结构,使用了IneternetGetConnectedState函数以及两个成功与失败的字符串;

image-20210405161550501

  • 如果IneternetGetConnectedState函数如果有连接,返回1,否则返回0;

  • 返回值与0比较:

    • 如果函数返回为1ZF0,CF置0,PF置1,OF置0;
      • 运行00401017处,显示Scuess字符串的程序块;
    • 如果函数返回为0ZF1,CF置0,PF置0,OF置0;
      • 跳转到loc_40102B,显示Error字符串的程序块;

image-20210405163543162

2、位于0x40105F的子过程是什么?

  • 双击跳转到0x40105F处;

image-20210405160819432

 

看这个函数传递的参数是一个字符串;

 

这里我盲猜是一个printf函数,为了验证,我们可以写一个例程进行反汇编;

1
2
3
4
5
6
#include <stdio.h>
int main()
{
    printf("hello World\n");
    return 0;
}

再使用IDA反汇编找到printf函数一直看下去,找到如下页面;

 

image-20210405165219662

 

看眼熟不。所以基本上可以判断,是一个printf函数。

 

要说一句的是,我是编译成Realeass版本,而不是Debug版本,后者调试信息太多了,不适用对比

3、这个程序的目的是什么?

  • 综上所述,这个程序是检查是否有一个可用Internet连接;
    • 如果找到,就打印Success:……
    • 否则打印Error 1.1: ……;

Lab6-2

分析在文件Lab06-02.exe中发现的恶意代码;

  • 同上,拿到文件先用ExeInfo PE查壳;

image-20210405165904626

 

结果无壳;

 

问题:

1、main函数调用的第一个子过程执行了什么操作?

  • 使用IDA打开程序;

image-20210405170130995

  • 双击进程序;

image-20210405170338806

  • 依旧是一个if语句,而且仍然使用的是InternetGetConnectedState函数,进入Graph View视图看的更清晰;

image-20210405170556878

 

返回值与0比较:

  • 如果函数返回为1ZF0,CF置0,PF置1,OF置0;
    • 运行00401017处,显示Scuess字符串的程序块;
  • 如果函数返回为0ZF1,CF置0,PF置0,OF置0;
    • 跳转到loc_40102B,显示Error字符串的程序块;

2、位于0x40117F的子过程是什么?

  • 双击sub_40117F进入函数;

image-20210405171013786

  • 又看到一个亲切的点;

image-20210405171104393

 

不解释了,又是一个printf函数(如有问题看Lab06-1);

3、被main函数调用的第二个子过程做了什么?

  • 回到main函数;

image-20210405171513799

  • 双击第二个函数,sub_401040;

image-20210405171756508

 

image-20210405172031255

  • 查询MSDN看看这些函数的功能;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 初始化应用程序对Win32 Internet函数的使用。
HINTERNET InternetOpen(
    IN LPCSTR lpszAgent,
    IN DWORD dwAccessType,
    IN LPCSTR lpszProxyName,
    IN LPCSTR lpszProxyBypass,
    IN DWORD dwFlags
);
// 开始读取完整的FTP、Gopher或HTTP URL。如果使用的URL包含由空格分隔的相对URL和基URL,则首先使用InternetCanonicalizeUrl。
HINTERNET InternetOpenUrl(
    IN HINTERNET hInternetSession,
    IN LPCSTR lpszUrl,
    IN LPCSTR lpszHeaders,
    IN DWORD dwHeadersLength,
    IN DWORD dwFlags,
    IN DWORD dwContext
);
// 从InternetOpenUrl、FtpOpenFile、GopherOpenFile或HttpOpenRequest函数打开的句柄读取数据。
BOOL InternetReadFile(
    IN HINTERNET hFile,
    IN LPVOID lpBuffer,
    IN DWORD dwNumberOfBytesToRead,
    OUT LPDWORD lpNumberOfBytesRead
);
// internetCloseHeadle很显然就是关闭句柄,我就不再赘述了,有兴趣可以查一下MSDN;
  • 理一下程序过程;

image-20210405173844899

 

image-20210405174003035

  • 先打开网络;
  • 然后通过URL下载文件;
  • 再对下载的文件通过loc_4010E5处的函数进行解析;

我们重点来看看loc_4010E5处的解析规则;

 

image-20210405174548869

 

选定字符使用r键进行转换后;

 

image-20210405174652517

  • <!--是标准的HTML的注释开始的部分;(在网页中,注释只有在源码处能看到);
  • 在这个子程序中有一个贯彻始终的Buffer的数组,选定后,摁ctl+k,查看定义大小;

image-20210405175105079

 

image-20210405175300577

 

选择拉取后发现,共0x200也就是512个字节;

 

image-20210405175726903

 

回到这个函数,我们发现,如果前面四个字符都匹配的话,会将第五个字符传给al,也就是函数的返回值;

  • 所以我们可以判断此函数的功能就是找到注释正文开始的地方将字符串首地址返回;

  • 由标注出的被调用函数来看,这个函数的功能是从www.practicalmalwarenalysis.com下载了网页,并且解析;

4、在这个子过程中使用了什么类型的代码结构?

 

image-20210405180813125

 

很显然,这是一个多层if的结构;

5、在这个程序中有任何基于网络的指示吗?

  • 根据查看字符串窗口;

image-20210405181233215

6、这个恶意代码的目的是什么?

 

综上所述:

  • 首先判断是否有可用的Internet连接:
    • 如果不存在就停止运行;
    • 否则程序会使用一个用户代理下载网页:
      • 该网页包含了<!--开始的注释;
      • 程序解析其后的字符;
        • 将解析出来的字符串格式输出到屏幕,格式为Success : Parsed command is X
          • 其中X`就是解析出来的字符;
        • 如果解析成功,程序会休眠60秒,然后终止运行;

Lab6-3

在这个实验中,我们会分析在文件Lab06-03.exe中发现的恶意代码;

 

问题:

1、比较在main函数与实验6-2的main函数的调用。从main中调用的新的函数是什么?

  • 经过对比,sub_401130处的函数是新出现的;

image-20210405211259010

1
2
3
0x401000();        // 检查Internet连接;
0x401040();        // 下载网页并解析HTML注释;
0x401271();        // printf;

2、这个新的函数使用的参数是什么?

 

image-20210405211529032

  • call上方是两个push,所以是有两个参数;

  • 因为函数传参是从右往左进行压栈;

    • 所以函数可以看作sub_401130(ecx,eax)

      image-20210405212815439

1
2
+ `ecx`中存放的是`byte`的`var_8(是IDA给命名的)`;
+ `eax`中存放的是dword的`argv`;

仅仅到这里就够了吗?真的是逼死强迫症,我们还是试着找一下var_8argv[0]两个具体是啥;

 

image-20210405213736941

  • jnz指令如果是ZF=0,就进行跳转;
  • 继续向上看,test指令;
    • 两个操作数按位and操作;
      • 结果为0,ZF=1
        • 结果不为0,ZF=0
      • SF为结果的最高位;
      • 结果的低八位中,1的个数是偶数,PF=1
        • 否则,PF=0;

image-20210405214759495

  • 可以看见,eax是符号位扩展后的sub_401040()的返回值;

image-20210405215132034

 

还记得var_20C是啥么?没错,就是从HTML注释中解析出的字符串首字符;

 

所以var_8就是HTML注释中解析出的字符串首字符

 

image-20210405220435448

 

再看argv是入口函数的参数,所以应该是用户输入;

  • 上面没有,那我们就往下找找,双击进入sub_401130

image-20210405223224950

  • 点击lpExistingFileName查看引用关系;

image-20210405223442278

 

又传给了CopyFileA()函数,上神器MSDN瞅瞅;

1
2
3
4
5
6
7
8
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
);
  • 看传参是(从左往右数第一个)lpExistingFileName
  • 要不咱再看看这个是啥类型吧;

image-20210405224336582

 

原来是个指向字符串的指针;

 

至于书上答案说:argv就是Argv[0],是一个对当前运行程序名字,也就是Lab06-03.exe的字符串引用。可惜的是,我并没有搜到Lab06-03.exe这个字符串。所以我还是坚信是入口函数人为输入的字符串。如果有哪个大佬能指出问题所在,感激不尽;

3、这个函数包含的主要代码结构是什么?

 

image-20210405225441767

  • 很显然,这是一个典型的switch结构;

4、这个函数能够做什么?

 

image-20210405225734003

 

看到一个很亲切的数字61h,这就是ASCll码中的a

  • 再点进跳转表0ff_4011F2看看情况;

image-20210405225958673

 

紧凑的,由此可见,switch判断的就是指令字符arg_0是否为abcde

 

然后根据选择的不同,执行不同的功能;

 

image-20210405230326518

 

image-20210405230410157

 

switch功能列表如下所示除了b的参数字符串没找到

 

(a):调用CreateDirectory,参数是C:\\Temp,如果目录不存在,就创建一个;

 

(b):调用CopyFile,两个参数,一个源文件,一个目的文件。此处功能将Lab06-03.exe(没找到这个字符串)复制为C:\Temp\cc.exe;

 

(c):调用DeleteFile,参数是C:\\Temp\\cc.exe,如果该文件存在就删除;

 

(d):在windows注册表中设置一个值,获得持久性运行。此处是将注册表键Software\Microsoft\Windows\CurrentVersion\Run\Malware的值设置为C:\Temp\cc.exe

 

(e):休眠100秒;

 

(default):打印Error 3.2:Not a valid command provided

5、在这个恶意代码中有什么本地特征吗?

 

image-20210405231347857

 

可以将这些作为本地特征;

6、这个恶意代码的目的是什么?

  • 使用if结构,检查是否是存在一个可用的Internet连接。
    • 不存在,程序终止;
  • 下载一个网页,解析出注释后面的第一个字符,根据这个字符操作;
    • (a);
    • (b);
    • (c);
    • (d);
    • (e);

Lab6-4

在这个实验中,我们会分析在文件Lab06-04.exe中发现的恶意代码;

 

问题:

1、在实验6-3和6-4的main函数中的调用之间的区别是什么?

 

image-20210405232814534

 

多了些间接调用,感觉是加了其他结构;

2、什么新的代码结构已经被添加到main中?

 

image-20210405233240195

 

加了循环操作;

  • 书上说是for循环,这个我个人觉得并不绝对。众所周知,forwhiledo{}while以及goto结构都是互通的。因为编译器会经过优化,将原本的for语句换成上面的任何一个形式;

3、这个实验的解析HTML的函数和前面实验中的那些有什么区别?

  • 找到解析HTML函数0x401040;

image-20210405233928008

 

这里出现了一个之前没用遇见的字符串Internet Explorer 7.50/pma%d

 

调用了下方是_sprintf函数;

 

sprintf返回存储在缓冲区中的字节数,不包括结束的null字符。swprintf返回存储在缓冲区中的宽字符数,不包括结束的null宽字符;

 

image-20210405235214974

 

传入字符串参数经过sprintf–>InternetOpenA最终赋值给了InternetOpenUrlAhInternet字段;

4、这个程序会运行多久?(假设它已经链接到互联网)

  • 回到main循环,进行查看;

image-20210405235910754

  • 首先sub_401000是个联网检测,既然假设连接上了,那就直接向下跳转;

image-20210406000111617

  • 判断通过后,开始了循环;

image-20210406000323334

  • jge是带符号内容前者大于后者,则跳转结束,否则向下执行;
  • 5A0h等于十进制的1440
  • 继续向下走,就是sub_401040函数,解析HTML函数,没啥好说的,继续向下;

image-20210406001544899

  • 因为sub_4012B5printf函数、sub_401150switch,都可以直接跳过,直到我们要找的Sleep时间函数;
  • 看一看call上面的值,0EA60h也就是十进制60000,单位毫秒,等于1分钟;
  • 所以每次循环是睡眠一分钟,共循环1440次,共计24小时;

5、在这个恶意代码中有什么新的基于网络的迹象吗?

 

image-20210406002448122

 

此字符串是一个User-Agent,包含了一个计数器,记录了该程序运行了多久;

6、这个恶意代码的目的是什么?

  • 首先判断是否有可用的Internet连接:
    • 如果不存在就停止运行;
  • 设置循环终点,1440;
    • 否则程序会使用一个独特用户代理下载网页:
      • 该网页包含了<!--开始的注释;
        • 程序解析其后的字符;
        • 将解析出来的字符根据switch进行操作:
          • (a);
          • (b);
          • (c);
          • (d);
          • (e)

总结

第三篇了,感觉渐渐找到点感觉了

 

帖子中有所不足之处,还请看贴大佬指点一下,让我进步快一些;


安卓应用层抓包通杀脚本发布!《高研班》2021年6月班开始招生!

最后于 3天前 被平头猿小哥编辑 ,原因:
上传的附件:
收藏
点赞2
打赏
分享
最新回复 (4)
雪    币: 1849
活跃值: 活跃值 (4675)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
kanxue 活跃值 8 3天前
2
0
建议将件Lab06-01.exe,RAR加个密码以附件形式上传论坛一份,方便其他人学习,谢谢分享!
雪    币: 1480
活跃值: 活跃值 (901)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
平头猿小哥 活跃值 3天前
3
0
kanxue 建议将件Lab06-01.exe,RAR加个密码以附件形式上传论坛一份,方便其他人学习,谢谢分享!
OK,马上上传文件链接;
雪    币: 1849
活跃值: 活跃值 (4675)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
kanxue 活跃值 8 3天前
4
0
平头猿小哥 OK,马上上传文件链接;

若文件不大,直接上传附件,建议RAR加个密码,附上密码。

其他几篇的附件也上传一下。


雪    币: 1480
活跃值: 活跃值 (901)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
平头猿小哥 活跃值 3天前
5
0
kanxue 建议将件Lab06-01.exe,RAR加个密码以附件形式上传论坛一份,方便其他人学习,谢谢分享!
已全部上传附件,密码帖子开头注明,感谢大佬的认可;
游客
登录 | 注册 方可回帖
返回