免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
聚合网络安全,存储安全技术文章,融合安全最新讯息
点击蓝字 · 关注我们
前言
恶意代码分析是安全从业人员非常重要的一个技能。
参考书籍:<<恶意代码分析实战>>
<<Windows核心编程>>
<<加密与解密>>
相关知识点
shellcode是指一个原始可执行代码的有效载荷。shellcode代码不能依赖于windows加载器在普通程序启动时所执行的如下动作:
将程序布置在它首选的内存位置
如果它不能被加载到首选的内存位置,那么需要应用地址重定向
加载需要的库,并解决外部依赖
位置无关代码(PIC)是指不适应硬编码地址来寻址指令或数据的代码。
shellcode就是位置无关代码,它不能假设自己在执行时会被加载到一个特定的内存位置
call sub_401000 E8 C1 FF FF FF
jnz short loc_401044 75 0E
mov edx,dword_407030 8B 15 30 70 40 00
mov edx,[ebp-4] 8B 45 FC
这里面第三个不是位置无关,在shellcode调用这种常量的时候可以用call/pop或者fnstenv
call/pop:
当一个call指令被执行时,处理器将call后面的指令地址压到栈上,然后转到被请求的位置进行执行。当这个函数执行完成后,会执行一个ret指令,将返回地址弹出栈的顶部,并将它载入指令指针寄存器中。这样做的结果是执行刚好返回到call后面的指令
shellcode可以通过一个在call指令后面立刻执行pop指令滥用这种通常约定,这会将紧跟call后面的地址载入指定寄存器中
fnstenv指令:
x87浮点单元(FPU)在普通x86架构中提供了一个隔离的执行环境。它包含一个单独的专用寄存器集合,当一个进程正在使用FPU执行浮点运算时,这些寄存器需要由操作系统在上下文切换时保存。
FpuSavaState{
uint32_t control_word;
uint32_t status_word;
uint32_t tag_word;
uint32_t fpu_instruction_pointer;
uint16_t fpu_instruction_selector;
uint16_t fpu_opcode;
uint32_t fpu_operand_pointer;
uint16_t fpu_operand_selector;
uint16_t
};
TEB查找法:
在NT内核系统中,fs寄存器指向TEB结构,TEB+0X30偏移处指向PEB(Process Environment Block)结构,PEB+0x0c偏移处指向PEB_LDR_DATA结构,PEB_LDR_DATA+0x1c偏移处存放着程序加载的动态链接库地址,第一个指向Ntdll.dll,第2是Kernel32.dll
在DLL文件中获取API地址:
在DLL基址+3ch偏移处获取e_lfanew的地址,即可得到PE文件头
在PE文件头的78h偏移处得到函数导出表的地址
在导出表的1ch偏移处获取AddressOfFunctions的地址,在导出表的20h偏移处获取AddressOfNames的地址,在导出表的24h偏移处获取AddressOfNameOrdinalse的地址
对于API的名字对比一般都是先采用Hash算法对其进行处理
Lab19-1
将bin文件放入IDA中,可以看到前面在自增,又清零,所以这段忽略不计,看到跳转。
LODSB:
从 ESI 指向的内存地址加载一个字节
STOSB:
将 AL的内容存入由 EDI 中偏移量指向的内存位置
看到这一段代码,可以判断是在做shellcode解码,我们来看一下它的运行流程。
以224为例,先将224传入,然后224-41,然后左移4位,然后再导入下一个225,减去41,两者相加,然后ecx作为计数器,每次减一,然后这里cx传入的是18Dh,因此这里要进行18Dh次
这里写一个idc脚本,因为这里每次是两个地址,所以步幅要设为2,又因为要运行18D次,所以要18D*2,最终的比较是31A
可以看到这里是先跳到了最后,目的是为了把url利用call/pop传入。
然后再利用TEB查找法
之后再利用hash和kernel32中寻找得到的进行对比,成功就传入。
0EC0E4E8Eh
LoadLibraryA
0B8E579C1h
GetSystemDirectory
78B5B983h
TerminateProcess
7B8F17E6h
getcurrentProcess
0E8AFE98h
WinExec
702F1A36h
URLDownloadToFileA
由此可以得知道,该shellcode的功能是下载exe并运行保存在系统目录中。
Lab19-2
无壳,放入IDA中查看,可以看到先获取了debug权限
查找默认浏览器的位置
启动浏览器
将shellcode注入。
这里可以看到shellcode是通过异或0xE7解码
用ida的Hex窗口提取到winhex
winhex异或解码。
然后放入ida中修补。
可以看到最后存放了api hash的值
EC0E48Eh
16B3FE72h
78B5B983h
7B8F17E6h
3BFCEDCBh
0ADF509D9h
60AAF9ECh
0
这里用的还是TEB查找法。
然后通过LoadLibrary导入ws2_32.dll
然后这里创建了一个与一个内网地址192.168.200.2的通信
创建了一个进程cmd与远程地址交互
Lab19-3
拿到pdf之后放到pdfstreamdumper
可以看到利用的漏洞
可以看到js形式的exp
将payload放入解码脚本中
生成的文件放入ida
手动修复之后,可以看到对于的api hash数组,这里可以看到还是利用call/pop加载
0EC0E4E8Eh //LoadLibrary
16B3FE72h //CreateProcessA
78B5B983h //TerminateProcess
7B8F17E6h //GetCurrentProcess
5B8ACA33h //GetTempPathA
0BFC7034Fh //SetCurrentDirectoryA
7C0017A5h //CreateFileA
0DF7D9BADh //GetFileSize
76DAo8ACh //GetFileSize
10FA6516h //SetFilePointer
0E80791Fh //WriteFile
0FFD97FBh //CloseHandle
0C0397ECh //GlobalFree
7CB922F6h //GlobalAlloc
1BE1BB5Eh //ShellExecuteA
0C602h //PDF file size
106Fh // file #1 size
0A000 //File #1 size
0B06Fh //File #2 offset
dd 144Eh // File #2 size
1
这里是查找kernel32.dll
这里是查找api hash
这里用LoadLibrary导入shell32
然后通过文件大小循环判断pdf中的恶意样本位置
如果判断成功,读取创建文件并运行。
然后创建打开第二个文件,运行再退出,用于混淆视听。
原文始发于微信公众号(Th0r安全):PC端恶意代码分析Lab19.1-3:shellcode分析
评论