实验?1?缓冲区溢出和恶意代码分析
1.1?实验名称
《缓冲区溢出和恶意代码分析》
1?、熟练使用恶意代码分析工具?OD?和?IDA
2?、通过实例分析,掌握缓冲区溢出的详细机理
3?、通过实例,熟悉恶意样本分析过程
第一阶段:利用?IDA?和?OD?分析?bufferoverflow?攻击实例(见实验?1 代码和样
本文件?bufferoverflow.exe)
1?、分析?bufferoverflow?实例中的关键汇编代码
2?、分析程序执行过程中寄存器和栈地址及其数据的变化(包含程序开始执行前、开始执行
时、溢出前、溢出后几个阶段)
3、解释为什么该实例中在?XP?环境下需要输入?17 个任意字符就可以绕过密码比较的判断功
能
第二阶段:分析恶意样本实例(见实验?1 代码和样本文件?example.exe)
1?、分析?example?恶意代码关键汇编代码
2?、结合汇编代码说明该恶意软件样本的主要功能
第三阶段:分析真实勒索软件样本(可选,见实验?1 代码和样本文件?radman.rar)
1?、搭建服务器,成功执行该恶意代码
2?、分析?radmant?勒索软件恶意代码关键汇编代码
3?、结合汇编代码说明该恶意软件样本的主要功能
1.4.?1 bufferoverflow?分析
首先打开?IDA_Pro?,根据函数名找到?main()函数的代码起始地址是?0x004123B0。
需要注意的是,由于?IDA_Pro 是静态编译工具,在存在重定位的情况下(比如?Windows11 操作系统的真实机)与?OllyDBG?所加载的动态内存里的地址并不一致,这时需要在打开?IDA_Pro?的时候手动更改?Image?Base?,才能与?OD?中的地址保持一致。
由于在?XP?操作系统中不存在重定位,所以?IDA_Pro?中显示的地址与?OD?中一致,因此?直接打开?OD?,将断点设置在?0x004123B0 作为程序的入口。
可以看到?main()函数是由?0x004116FE?跳转来的。
在?IDA_Pro?中使用?ctrl+x 对?main()函数不断交叉编译,可以看到调用?main()的的函数?_main_0?的调用者地址为?00412BBC?,这也正是程序的真正入口地址。设置断点。
首先执行到该断点处,然后进入call?语句。可以看到现在将要执行的地址内容是?main()?函数内容,并且?0x0012FF7C?处保存的是?main()函数的返回地址,EBP?指向地址的内容是?call 语句所在函数的?EBP?地址。之后执行到?push?ebx?上方,表明系统为局部变量分配了?0xDC (220 字节)大小的内存空间(选择显示?ASCII?数据,可以看到其中是有数据的)。
执行到?MOV?DWORD?上方,是系统对分配的内存空间进行了初始化,全部置为?CC?表?示?int?断点,这样如果有位置程序跳到这片区域就不会出现崩溃情况而是直接被中断下来。?可以看到初始化后复函数的返回地址和?EBP?依旧存在。
继续向下执行,在地址?0x004123DE?处是调用命令行输入的一个?CALL?语句(往里多步?入几层可以发现实际上是调用了?kernel32GetMessage.dll?中一个函数,用于获取命令行输入?并存放在内存的合适位置,这里的存放位置是?0x0012FF60?处)?。接着执行到?0x004123EF 位置的?CALL?语句上方,发现两句?PUSH?语句是将数据段的“?12345?”和内存中的输入压栈?(同时也可以看出我们输入的内容被存放在了?SS:[EBP-?18]?,即?0x0012FF60?处)。
继续执行来到?0x004123EF?位置的?CALL?语句,作用是比较栈顶两个元素的值是否相等,?如果相等则置?EAX?为?0(也就是输入正确字符串“?12345?”时),不等就置为?0xFFFFFFFF,?并且再接下来会把两个栈顶元素弹栈。然后,程序根据?EAX?的值是否为零决定输出的内容,?具体方式是通过对?SS:[EBP-8]赋值为?0 或?1 判断跳转位置。
可以看到,SS:EBP-8?的值决定程序的输出,这个位置距离我们输入内容的存放位置?SS:EBP-?18?只有?0x10?也就是?16?。因此当我们输入长度超过?17 个字节的内容、并保证第?17??个字节的十六进制最低位是?1?时(比如?17*“?1?”),就能够成功覆盖?SS:[EBP-8]?,让程序?输出“Welcome?”。此外,输入更长的内容还能覆盖到?pre?EBP?和返回地址,从而进行提权?等攻击。
1.4.2 example?分析
我们开始使用静态分析基础技术,研究?PE?文件结构和字符串列表。我们看到这个恶意?代码导入了一些联网功能函数、服务操作函数和注册表操作函数。在下面的列表中,我们关?注到一些有趣的字符串。
我们看到域名、注册表位置(如字符串?SOFTWARE\Microsoft(XPS;像?DOWNLOAD、UPLOAD?这样的命令字符串,以及?HTTP/1.8 字符串等。这些表明恶意代码可能是一个?HTTP 后门程序。字符串-cc?、-re?、-in?应该是一些命令行参数(例如-in?可能是?install?的缩写)。
我们尝试运行一下?example,但它看起来似乎立即删除了自身,除此以外没有别的发现。
接下来,我们使用?procmon?工具,设置一个?example.exe?进程名称上的过滤器。依然没?有任何有趣的如?writeFile?、RegSetValue?之类的事件。
但是通过深入挖掘后,我们发现了一个?Process?Create?的条目。双击该条目将看到如下?图所示的对话框,可以发现,恶意代码是通过使用"C:\WINDOWS\system32\cmd.exe?”/c?del Z:\Lab03-84.exe?>>NUL?来从系统中删去自身的。
静态分析到此就没有太多值得分析的了,接下来尝试动态分析?example。
首先,我们使用OllyDbg?调试恶意代码。我们使用F8?键step-over,直至到达地址0x403945,?此处 是对?main?函数的调用(最简单找出?main?函数位于地址?0x402AF0?的方法,是使用?IDA ?Pro)。接下来,使用?F7 键?step-into?到?main?函数调用。我们使用?F7 键和?F8?键继续向前单步,?同时注意样本的行为。
首先,恶意代码在地址?0x402AFD?查看命令行参数的数量是否等于?1?。我们没有指定任?何参数,所以检查成功,并且在地址?0x401000?处恢复运行。接下来,它试图打开注册表项?HKLM\SOFTWARE\Microsoft?XPS?,然而由于注册表项不存在,函数返回?0?,所以调用进入?0x402410 处的函数。
从?0x40240C 处?F7 进去可以看到,程序似乎在某个时刻将一个网址
"http://www.practicalmalwareanalysis.com"压入了寄存器,推测?example?是具有网络能力的恶?意代码。
0x402410 处的函数使用?GetModuleFilenameA?获取当前可执行文件的路径,并构造出一?个?ASCII?字符串:/c?del?path-to-executable>>NUL?。图?9-?1L?展示了在?OllyDbg?的寄存器面板?窗口中的这个字符串实例。注意,EDX?寄存器值是?0x12E248?,但是?OllyDbg?正确地解释它?为?ASCII?字符串指针。
恶意代码通过在?ShellExecuteA?调用中结合构造的字符串和?cmd.exe?来尝试着从硬盘上?删除自己。
综合以上信息,我推测恶意代码创建一个注册表项?HKLM\SOFTWARE\Microsoft\XPS。?Microsoft?之后的空格使得它成为一个独特的主机感染标识。它在地址?0x4011BE?处,用?EDX??寄存器指向的缓冲区内容,来填充注册表下名为?Configuration?的键值。为了找出缓冲区的 ?内容,我们在地址?0x4011BE?处设置断点,并且运行恶意代码。在寄存器面板窗口中,右键 单击?EDX?寄存器的内容,选择?Follow?in?Dump?。十六进制的转储视图显示了?4 个以?NULL???结束的字符串,随后是多个?0?,字符串包含值?ups?、http://www.practicalmalwareanalysis.com、?80?和?68。
综合以上信息,加上查阅资料,发现恶意代码构造一个?HTTP/1.0 GET?请求,并且连??接一个远程系统。这种连接不太可能被防火墙拦截,因为它是一个向外的合法?HTTP?请求。?由于我的恶意代码分析虚拟机禁用了网络,向外的连接永远不会成功,运行恶意代码就会失?败。然后,仔细跟踪反汇编列表,会看到恶意代码事实上是尝试着连接注册表键值配置中记?录的域名和端口。进一步分析反汇编代码显示,恶意代码在服务器返回的文档中搜索特殊的?字符串(反引号、单引号、反引号、单引号、反引号)?,并且用它们来表示命令控制协议。
(1)在?WINXP?中,栈是怎么分布的?栈中可以存放代码吗?
栈的结构如下。可以
(2)为什么该实例中在?XP?环境下需要输入?17?个任意字符就可以绕过密码比较的判断功
能?
17 个字符能够覆盖返回结果的判断条件。