恶意代码分析实战 Lab 9-2 习题笔记

Lab 9-2

问题


1.在二进制文件中,你看到的静态字符串是什么?

解答: 我们先查看一下静态字符串的在IDA中,这里用IDA来查看比较方便点

恶意代码分析实战 Lab 9-2 习题笔记

这里显示了在二进制文件中的静态字符串


2.当你运行这个二进制文件时,会发生什么?

解答: 运行我就不运行了,书上说了运行之后立刻就退出了,所以还要重置虚拟机,懒得做了,运行会发生的就是立刻退出了这个函数

下面开始二进制分析

这里我用的是吾爱**版的OD,这个比较好使(可以很好的显示中文),唯一缺点就是无法调字体

恶意代码分析实战 Lab 9-2 习题笔记

函数从开始运行,到这里会调用第一个不是系统函数的函数,叫00401F08,我们可以进去看看是什么

这个函数没有什么分析的价值,是函数的堆初始化函数

恶意代码分析实战 Lab 9-2 习题笔记

然后下一个不是系统调用的函数是这个

恶意代码分析实战 Lab 9-2 习题笔记

一个叫00401D5D的函数

然后进来之后的第一个调用是这个

恶意代码分析实战 Lab 9-2 习题笔记

一个叫004023C0的函数,我们进去看看

恶意代码分析实战 Lab 9-2 习题笔记

这里我们注意到这个函数有个GetStartupInfoA,这个MSDN中是这样说的

检索调用进程创建时指定的STARTUPINFO结构的内容

这个也是初始化函数,还没有到main函数

然后下一个函数

紧接的就是下一个函数

恶意代码分析实战 Lab 9-2 习题笔记

这里调用了GetCommandLineA这个函数

这个函数是获得用户输入的命令参数的

我们可以看到这个函数调用完之后

恶意代码分析实战 Lab 9-2 习题笔记

EAX的值马上就变成了我们当前目录的,也就是argv[0]的值

然后下一个函数是

恶意代码分析实战 Lab 9-2 习题笔记

这个叫004019DE的函数

函数进来的第一个调用是GetEnvironmentStringsW

恶意代码分析实战 Lab 9-2 习题笔记

MSDN中,我们可以看到返回值

Return value
If the function succeeds, the return value is a pointer to the environment block of the current process.

If the function fails, the return value is NULL.

然后我们能运行OD查看这个函数的执行结果

恶意代码分析实战 Lab 9-2 习题笔记

这个EAX的值是个指针,我们去查看这个地址上的值

恶意代码分析实战 Lab 9-2 习题笔记

这里就是我们运行这个文件所在的PATH

恶意代码分析实战 Lab 9-2 习题笔记

然后下面就是下一个调用,这次调用的是GetEnvironmentStrings,这个和上面那个函数差不多,我们看看返回值,不过这里被jmp跳转了,这个函数不会被执行

然后就会一直在这里做循环,这个循环是一次比较每个字符的操作

恶意代码分析实战 Lab 9-2 习题笔记

然后这里一直运行下去就会结束了

然后我们按照书上的做法,在main函数的开始(0x401128)放一个断点,然后运行

然后这样我们就进来了main函数

恶意代码分析实战 Lab 9-2 习题笔记

函数的第一个调用是GetModuleFileNamed这个,我们看看返回值

注意看入参

恶意代码分析实战 Lab 9-2 习题笔记

这时候的入参PathBuffer已经变成12FC80了,我们跳到那个内存地址上

恶意代码分析实战 Lab 9-2 习题笔记

这里还是0,然后我们运行调用

这个地址马上变了,然后我们查看值,就是我们这个文件所在的目录

恶意代码分析实战 Lab 9-2 习题笔记

然后下一个调用

恶意代码分析实战 Lab 9-2 习题笔记

这里我们在IDA中找找对应,防止走丢

恶意代码分析实战 Lab 9-2 习题笔记

这个函数在IDA中已经标识出来,是_strrchr,这个函数是个C++的函数,用来查找字符的

恶意代码分析实战 Lab 9-2 习题笔记

我们注意到上面push了两个参数入栈

最后一个push入栈的是ecx,然后看看值

恶意代码分析实战 Lab 9-2 习题笔记

ECX在这里的值是这个可执行文件的绝对路径,也就是要源字符串,然后我们的要查找的字符是5Ch这个东西也就是\这个字符

然后这个函数的返回值就是指向最后一个\字符的位置,我们运行看看

恶意代码分析实战 Lab 9-2 习题笔记

和我们预想的一样,这个函数返回了最后一个\字符的位置

然后继续下一个调用

恶意代码分析实战 Lab 9-2 习题笔记

IDA中对应的是

恶意代码分析实战 Lab 9-2 习题笔记

这是一个字符串比较的函数_strcmp

这里两个入参是ecxeax,我们看看这两个值是多少

恶意代码分析实战 Lab 9-2 习题笔记

这个字符串就是书中那个被混淆的字符串

然后另一个字符串的话,我们回到上面创建字符串那里,然后运行到这些赋值完成

恶意代码分析实战 Lab 9-2 习题笔记

我们知道0x0在二进制的世界就是代表字符串结束的那个\0字符,所以我们在ebp上查找这两个字符

此时的ebp这里写代码片

恶意代码分析实战 Lab 9-2 习题笔记

然后我们右键在内存中找到这个地址

第一个字符串的地址是

恶意代码分析实战 Lab 9-2 习题笔记

也就是12FF80-1B0=‭12FDD0‬

恶意代码分析实战 Lab 9-2 习题笔记

这里你也可以看见下一个字符串是ocl.exe

如果我们用这种方法去找下一个0x0隔开的第二个字符串的话

恶意代码分析实战 Lab 9-2 习题笔记

这个值就是ebp-0x1A0也就是

12FF80-1A0=‭12FDE0‬

也就是刚刚那个下面的位置

恶意代码分析实战 Lab 9-2 习题笔记

然后继续分析刚刚函数

恶意代码分析实战 Lab 9-2 习题笔记

这里将两个字符进行比较

恶意代码分析实战 Lab 9-2 习题笔记

程序预期的程序名字应该是ocl.exe这个字符

然后调用完之后用test判断一下返回值

恶意代码分析实战 Lab 9-2 习题笔记

如果返回值是0的话,就一个je跳转,否则就结束函数

然后下面mov edx, 0x1,将edx赋值为1

然后测试一下,这里注定是不会跳转的

然后继续调用WSAStartup函数,这是调用winsock dll之前的初始化步骤

恶意代码分析实战 Lab 9-2 习题笔记

我们看看12FDE8存了什么

什么也没有

恶意代码分析实战 Lab 9-2 习题笔记

调用完函数之后就变成这样了

恶意代码分析实战 Lab 9-2 习题笔记

然后函数下一步准备进行这个操作

恶意代码分析实战 Lab 9-2 习题笔记

初始化了一个TCPsocket

这些操作都做完之后,就会准备调用这个函数了

恶意代码分析实战 Lab 9-2 习题笔记

我们在IDA里面看看

恶意代码分析实战 Lab 9-2 习题笔记

这个函数在IDA里面并没有很好的显示出来,估计不是一个常用的C函数

然后我们进入这个函数分析看看

函数之前的一个入参是这个

恶意代码分析实战 Lab 9-2 习题笔记

此时eax的值是

恶意代码分析实战 Lab 9-2 习题笔记

我们也是进入这个函数看看

这个函数最后会返回一个0Ch如果你用的是这个字符串的话

恶意代码分析实战 Lab 9-2 习题笔记

在函数将要返回的最后,这个字符串通过各种变换之后,将网站变了出来

恶意代码分析实战 Lab 9-2 习题笔记

恶意代码分析实战 Lab 9-2 习题笔记

恶意代码分析实战 Lab 9-2 习题笔记

所以这个函数的作用应该就是个网址的

然后下面的函数准备开始连接这个网址

恶意代码分析实战 Lab 9-2 习题笔记

这里函数连接失败,因为这个网址不存在,所以这里会结束连接,并做一些清理工作

恶意代码分析实战 Lab 9-2 习题笔记

然后注意这里会sleep一个30000ms的时间

我们这里重新执行这个代码,然后在判断那里不要跳转关闭连接

这里我们就用上我们的DNS fakeInetsim,这里将机器的DNS设置我们DNS fake的ip,然后DNS fake就会将这个代码请求的域名返回成我们的inetsim的地址,然后下面就是这个恶意代码去连接这个inetsim

这里我们设置DNS fake了之后,这里的gethostbyname()就返回正确了

恶意代码分析实战 Lab 9-2 习题笔记

红线显示我们就会跳过closesocket这个函数

然后我们下一个函数

恶意代码分析实战 Lab 9-2 习题笔记

这个函数是ntohs,这是个网络初始化函数

ntohs函数将u_short从TCP / IP网络字节顺序转换为主机字节顺序(这在英特尔处理器上是小端的)

然后下一个函数不出所料就是connect

恶意代码分析实战 Lab 9-2 习题笔记

然后我们连接成功之后,就会遇到下一个函数

然后我们进去看看

然后我们进入发现了一个函数的调用,但是OD并没有标注这个函数,我们第一感觉是要看看这个是不是系统函数调用,然后我们用IDA来打开看看

恶意代码分析实战 Lab 9-2 习题笔记

这个函数在IDA里面标注是_memset这个函数

这是函数的初始化函数,不用管

然后又遇到个函数,我们也是看IDA

恶意代码分析实战 Lab 9-2 习题笔记

IDA0040102C这个地方(也就是上面那个函数的下面),是这个函数

恶意代码分析实战 Lab 9-2 习题笔记

这个也是初始化函数,我们不理他

然后下面一个函数就开始创建一个进程了

恶意代码分析实战 Lab 9-2 习题笔记

恶意代码分析实战 Lab 9-2 习题笔记

ODLastError我们可以看到,这个创建进程的函数创建进程成功了

然后下一个函数就是这个

恶意代码分析实战 Lab 9-2 习题笔记

WaitForSingleObject 函数用来检测 hHandle 事件的信号状态,当函数的执行时间超过 dwMilliseconds 就返回,但如果参数 dwMilliseconds 为 INFINITE 时函数将直到相应时间事件变成有信号状态才返回,否则就一直等待下去,直到 WaitForSingleObject 有返回直才执行后面的代码

所以这里会一直等待相应的时间,这个事件是hObject=7C81D63B这个东西

然后这个函数做完这些就会返回了

然后这个函数就可以命名为这个

恶意代码分析实战 Lab 9-2 习题笔记

CreateProcessAndWaitSignal,当然,这是我的个人命名方式,这个函数会创建一个进程来处理和服务器的连接,然后主进程继续执行

这里有个技巧,就是直接将sleepnop填充了,省的它执行浪费时间

然后这里函数又会跳回到原来初始化socket那个地方

恶意代码分析实战 Lab 9-2 习题笔记

这里我们刚刚分析少了一个地方就是ntohs这个函数的的入参,这里的入参是

恶意代码分析实战 Lab 9-2 习题笔记

从这里可以看出来,这个是个定值,0x270Fh=9999d

所以这里它会去连接恶意域名的9999端口

然后我们这里是第二遍执行,这里connect的返回值是-1d,因为我们的inetsim并没有开9999端口

然后这里就这样一直循环连接,书中的提示是在这里会有一个反向shell的创建

恶意代码分析实战 Lab 9-2 习题笔记

也就是_memset这个地方

恶意代码分析实战 Lab 9-2 习题笔记

这里这个地方的,这里已隐藏模式创建了一个cmd.exe的窗口

这里是哪里指示这是个隐藏的窗口,这里隐藏窗口并不是在这里创建

恶意代码分析实战 Lab 9-2 习题笔记

是这里,这里设置了wShowWindow这个选项为SW_HIDE

然后在这里

恶意代码分析实战 Lab 9-2 习题笔记

设置了hStdInputhStdErrorhStdOutput三个值都为一个套接字,也就是我们刚刚连接那个套接字

所以到这里,这个代码基本分析完毕了,这个代码没前一个那么复杂和庞大


3.怎样让这个恶意代码的攻击载荷(payload)获得运行

解答: 将这个代码的名字改为ocl.exe


4.在地址0x00401133处发生了什么?

解答: 在地址那里是将一个一个字符赋值的过程

恶意代码分析实战 Lab 9-2 习题笔记

这里的0代表了字符串结束符\0


5.传递给子列程(函数)0x401089的参数是什么?

解答: 这个函数的参数在OD中可以很清晰的看出来

恶意代码分析实战 Lab 9-2 习题笔记

就是那个加密的字符串


6.恶意代码使用的域名是什么?

解答: 这个恶意域名其实就是上一个问题的返回值

恶意代码分析实战 Lab 9-2 习题笔记

也就是那个作者的域名哈哈哈


7.恶意代码使用什么编码函数来混淆域名?

解答: 这个可以试着分析分析看,书上说是异或加密的,我们试着分析看看

函数在开始的时候,第一个调用的函数是_strlen这个

恶意代码分析实战 Lab 9-2 习题笔记

这个_strlen会计算输入的字符的长度

恶意代码分析实战 Lab 9-2 习题笔记

然后函数的返回值是0xCh也就是12d

然后函数就会做下面这些操作

恶意代码分析实战 Lab 9-2 习题笔记

这里的esp是存储着加密字符串的地址

恶意代码分析实战 Lab 9-2 习题笔记

这个地址我们找一下

恶意代码分析实战 Lab 9-2 习题笔记

add esp, 0x4这个操作之前,esp的值是0012FB54这个,加了0x4之后就是0012FB58

然后就会指向stack里面的下一个值

恶意代码分析实战 Lab 9-2 习题笔记

这个地址上的栈存储着0012FD8E这个值

然后下面的local.65的值是ebp-0x104ebp0012FC64,最后结果的地址就是0012FB60

恶意代码分析实战 Lab 9-2 习题笔记

然后这个地址的值就变成了C

然后下一个变量是local.66的地址是是ebp-0x108,也就是0012FB5C

这里给这个变量赋值为0

然后就是一个无条件跳转JMP,然后跳转到了下面这里

恶意代码分析实战 Lab 9-2 习题笔记

这里我们刚刚上面才赋值local.660,然后调用cmp指令,注意这个0x20是恶意代码作者写进去的,不是根据strlen计算得到的

然后这个跳转有点变态,跳转条件是SF=OF

这里的SF是符合标志位,如果结果为负数则其值为1,如果为正数,则为0

然后OF是溢出标志位,溢出的话,值则为1,否则为0cmp函数的其实是减运算,只是值不保存

我们这里的local.66=0,减去0x20之后,值为负数,SF=1,值没有溢出,OF=0,所以SF<>OF,这里不会跳转

恶意代码分析实战 Lab 9-2 习题笔记

然后将入参arg.2的值赋值给了edx,我们看看这个入参是多少

恶意代码分析实战 Lab 9-2 习题笔记

然后这里我们看看内存和栈中的值

栈中的指示像是个指针,但是这个指针地址比较大,感觉不太可能有这么大的指针,在内存中一跳,就会发现这个内存地址不存在

恶意代码分析实战 Lab 9-2 习题笔记

下一步是一个add操作

恶意代码分析实战 Lab 9-2 习题笔记

这里将local.66的值和edx相加,edx值不变

下一步就是一个movsx指令,将值带符号扩展之后赋值给ecx

恶意代码分析实战 Lab 9-2 习题笔记

原来的值部署54160646h嘛,movsx只看后八位也就是46=‭01000110‬,第一个字符是0,所以这个扩展之后就是00000046h

然后一个moveax的值赋值成为0

恶意代码分析实战 Lab 9-2 习题笔记
现在ecx的值已经变成46h

下一个指令是cdq,这是将eax扩展成为edx:eax的方法,没做这个操作之前的eax0x0hedx0012FD90,做了这个操作之后,连同edx都被赋值成了0

恶意代码分析实战 Lab 9-2 习题笔记

恶意代码分析实战 Lab 9-2 习题笔记

idiv当除数是 32 位的时候,(现在就是),然后local.65还是等于0xCh

恶意代码分析实战 Lab 9-2 习题笔记

然后这里的除数是local.65,被除数是edx:eax,也就是edx:eax/local.65这个意思

结果的商存储在eax里面,然后余数存储在edx里面,注意这里是带符号的除法

OD里面做完这个指令之后,EAXEDX并没有变化

恶意代码分析实战 Lab 9-2 习题笔记

这里将加密字符串赋值给eax,然后带符号扩展edx

恶意代码分析实战 Lab 9-2 习题笔记

最终的edx变成了0x31h

然后是这样的

恶意代码分析实战 Lab 9-2 习题笔记

然后将这个值传递给这里之后就跳转了

恶意代码分析实战 Lab 9-2 习题笔记

这里分析时候实在看不懂,算了,不分析算法了


8.恶意代码在0x0040106E处调用CreateProcessA函数的意义是什么?

书上的解答是

恶意代码设置stdoutstderrstdin的句柄到socket(被用在CreateProcessASTARTUPINFO结构中)。由于cmd作为CreateProcessA的参数调用,因此通过绑定一个套接字与命令shell来创建逆向shell

大概意思就是说这个shell是通过这个CreateProcessASTARTUPINFO来绑定stdoustderrstdincmd上的,只有这样才能把这些东西绑定在cmd

本文完