恶意代码分析-第十九章-shellcode分析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_37809075/article/details/82687006

笔记

shellcode:一个可执行代码的有效载荷,包含可执行代码

加载shellcode分析:在IDApro中分析时,选择处理器类型Interl 80x86 processers,并选择32-bit disassembly

使用位置无关代码

第一条和第二条指令都是通过将EIP寄存器指定的当前位置加上一个保存在指令中的相对偏移值来计算。所以是位置无关代码

第三条指令是一个访问全局数据变量的,并不是一个位置无关代码

第四条指令是使用EBP寄存器作为一个基值,并保含一个符号的相对偏移值,是一个位置无关代码

识别执行位置:以位置无关的方法访问数据时,需要获取一个基地址指针。但x86不提供对EIP的数据访问寻址,也很难得到当前指针值-----mov exa,eip无法执行

                         1.使用call/pop指令:call指令后面跟一个pop指令滥用,这会将call后面的地址载入指定寄存器中。

pop指令将栈顶指针的地址保存在EDI。所以在pop指令执行后,EDI将包含一个指向红色框处的位置

-L user32--->确认加载user32库

-bp------------>在shellcode执行之前插入断点,允许跳过shellcode_launcher.exe程序的内容,并从shellcode二进制开始执行

设置od为即时调试器-------->Options--Just-in-time Debugging--Make od Just-in-time Debugger选项

                         2.使用fnstenv指令:当一个进程使用FPU执行浮点运算时,寄存器保存。

图示的位置保留FPU使用的最后一条CPU指令地址

fldz指令将浮点数0.0压到FPU栈上。fpu_instruction_pointer的值变成指向fldz指定的指针。FpuSaveState结构体保存到栈[esp-0ch]处,接来来pop指令将fpu_instruction_pointer值载入到EBX中,这个值指向得位置是fldz指令的位置

手动符号解析:shellcode必须动态定位这些函数,已确保它们在不同环境中都能可靠的工作,所以经常用到LoadLibrary和GetProAddress函数,这两个函数在kernel32.dll中。

                         内存中寻找kernel32.dll:

                         FS段寄存器---------->TEB结构-----+0x30----->PEB指针-----+0xc----->PEB_LDR_DATA结构体(包含三个链接LDR_DATA_TABLE结构的双向链表)---------->DllBase

                        在1处使用fs寄存器访问TEB,获取指向PEB的指针。在4处得到PEB_LDR_DATA结构体,再获取InInitializationOrderLinks链表中的第二个LDR_DATA_TABLE_ENTRY,并返回它的DllBase。

                         解析PE文件导出数据:

                         AddressOfFunctions是一个RVA的数组,指向实际导出函数

                         AddressOfNames是函数名,是一个数组,指向符号名的数组。

                         AddressOfNameOrdinals是函数序号---16位序号的数组

                        过程:AddressOfNames数组迭代查找一项和给定的一个字符串比较,找到匹配的项后这个索引称为idx

                                  在AddressOfNameOrdinals数组中使用idx索引,获取到iOrdinal值

                                  使用iOrdinal值索引AddressOfFunctions数组,获取符号的RVA

                         使用散列过的导出符号名:                      

开始通过call/pop调用获得执向db 'user32',0的位置。

通过findKernel32Base找到kernel32.dll的基地址

通过findSymbolByHash函数找到散列号为0xEC0E4E8E的函数LoadLibrary

然后通过LoadLibrary加载messageBoxA函数和exit函数

shellcode编码:一些00坏字节要处理掉,隐藏URL和IP地址,躲避网络入侵检测

空指令雪橇

只要执行到空指令雪橇,就可以滑到解码器的代码

找到shellcode:在JavaScript中,unescape函数用来将编码过的shellcode转化为可执行的二进制文件(大端显示)

                          在恶意执行文件中,查找典型的进程注入API调用找shellcode有效载荷

                          在媒体文件中,未编码的形式存在

                          搜索解码器的操作码字节

 

实验

Lab19-1

 先jmp到short loc_21F,然后call sub_208。在执行call sub_208语句时,会将00000224这里的地址压入栈。

再看sub_208处,先pop esi,这个esi就是00000224这里的地址

图像视图可以看出这里是一个循环,ecx是计数器

LODSB是块读出指令,其具体操作是把SI指向的存储单元读入累加器,其中LODSB是读入AL,然后SI自动增加或减小1或2位。当方向标志位D=0时,则SI自动增加;D=1时,SI自动减小。

SOSB是写入指令,将eax中的内容写入到esi指向的地址中

第一个loadsb读的是数据db 49h到AL寄存器,然后减41h,然后shr左移。第二个loadsb读的是数据db 4Ah到AL寄存器,然后减41h,然后加dl。第三个操作符stosb,将eax的值写入到esi指向的地址处(db 49处)。依次循环。所以这是一个解密操作。

scdbg的显示结果,对shellcode进行分析,这样就可以知道shellcode的大概流程

http://www.freebuf.com/sectool/16320.html

Lab19-2

先创建一个浏览器进程,然后对这个进程就行注入,注入得代码在lpBuffer中unk_407030

unk_407030

这里也是一个解密操作,上面是一个idc解密脚本,其中0x18F是次数

得到shellcode代码后

hash数组

hash数组处理,将函数的hash数值转化为函数的地址

将shellcode提取出来,拿scdbg分析

Lab19-3

用PDFStreamDumper工具,有一个缓冲区溢出的漏洞CVE-2008-2992

http://www.freebuf.com/sectool/1211.html

打开PDF文档时将要被运行的JavaScript脚本,

unescape函数和一个长的文本字符串来初始化攻击负载。Unescape函数的翻译方法是。

%后面跟u:那么就取出后面的4个字符,将它们转化为一个ASCII的十六进制,并且将它转化为2个字节。考虑到大端和小端的情况,输出的顺序会被交换。比如对于“%ue589%uec81”来说,转化后变为“0x89 0xe5 0x81 0xec”。

%后面没有u:则它取出后面2个字符,将他们作为一个ASCII的十六进制,并且将其翻译为1个字节。

拿IDA打开Lab19-03_sc.bin文件,这个是从pdf中提取出来的shellcode。看到只有三行代码可以被识别,然后调用了sub_17B,但在调用sub_17B,把000000D这行的地址压入到了栈中。而这些数据应该就是导入函数的hash值。

注意这段代码地址为0x183位置的call指令所调用的,其实是findKernel32Base函数,用于查找系统中的kernel32.dll的地址。而0x195位置的是findSymbolByHash函数,用于hash值的计算。然后程序在0x19D以及0x1A2的位置压入了“shell32”这个字符串,用于LoadLibrary函数的参数。

猜你喜欢

转载自blog.csdn.net/m0_37809075/article/details/82687006
今日推荐