【技术分享】杀软的无奈——基础工具篇(一)

  • A+
所属分类:安全文章
【技术分享】杀软的无奈——基础工具篇(一)
 
【技术分享】杀软的无奈——基础工具篇(一)

前言

杀软的无奈是我准备开始写的一个新的专题文章,主要用来分享恶意代码分析过程用到的一些方法和工具,以及shellcode编写,shellcode分析,metasploit中的shellcode编码器的实现,编码器特征码定位,编码shellcode绕过杀软检测,基于unicorn检测shellcode编码器等相关的知识。文章中讲的案例会主要集中在linux平台中的ELF文件,但是由于个人的精力和知识水平有限,文章更新的频率和质量不太敢保证。如果有地方写的不太对,希望大佬们能够积极斧正,给与一些指导和帮助。
这是这个系列的第一篇文章,俗话说万丈高楼平地起,我们第一篇主要说一下我觉得非常实用的工具,在之后的文章中我的脚本会基于这些工具开发,并不会再介绍这些基础工具的使用。
 
【技术分享】杀软的无奈——基础工具篇(一)

相关工具的介绍

  • Capstone, 全能的反编译框架
  • Keystone, 全能的编译框架
  • IDAPython, 给ida神器再插上翅膀
  • unicorn, 基于qemu的模拟执行框架(unicorn官方版本不支持SMC,我patch了一下相关代码https://github.com/wonderkun/unicorn,建议安装这个版本)
  • flare-emu, 基于unicorn的ida插件,能够快速帮你获取你不想读的代码的执行结果。

【技术分享】杀软的无奈——基础工具篇(一)

全能反汇编引擎Capstone

Capstone是一个非常优秀的反汇编框架,支持多种CPU架构的,而且提供多种语言的api接口,使用起来非常的简单方便,IDA,Radare2,Qemu等著名项目都使用了Capstone Engine。
源码地址:https://github.com/aquynh/capstone.git,官方文档: http://www.capstone-engine.org/lang_python.html
一个简单的例子如下:
from capstone import *
CODE = b"x55x48x8bx05xb8x13x00x00"
md = Cs(CS_ARCH_X86, CS_MODE_64)for i in md.disasm(CODE, 0x1000):print("%dt0x%x:t%st%st%s" %(i.id,i.address, i.mnemonic, i.op_str,i.bytes.hex()))
初始化一个Cs类,需要有两个参数,分别是平台和架构模式
【技术分享】杀软的无奈——基础工具篇(一)
md.disasm 函数需要提供两个参数,第一个参数是需要分析的bytes,第二个参数是基地址。返回一个生成器,遍历就可以得到每条指令的对象 CsInsn,它导出了与此条指令相关的很多属性,详细的解释如下:
【技术分享】杀软的无奈——基础工具篇(一)
 
【技术分享】杀软的无奈——基础工具篇(一)

全能的编译引擎Keystone

与Capstone相对应的,那必然是keystone了,keystone与capstone功能恰好恰好相反,是一个全能的支持多种架构的编译框架。源代码地址https://github.com/keystone-engine/keystone,官方文档地址https://www.keystone-engine.org/docs/tutorial.html
CODE = b"INC ecx; DEC edx" # separate assembly instructions by ; or n
try:# Initialize engine in X86-32bit mode ks = Ks(KS_ARCH_X86, KS_MODE_32) encoding, count = ks.asm(CODE)print("%s = %s (number of statements: %u)" %(CODE, encoding, count))except KsError as e:print("ERROR: %s" %e)
可以看到,跟Capstone的使用方法非常类似。
 
【技术分享】杀软的无奈——基础工具篇(一)

IDAPython

ida是逆向分析的神器,但是再加上idapython那就是给神器安装上翅膀,非常好用,关于idapython的api使用说明,可以读一下我的学习记录,里面有比较好的学习资料推荐。
 
【技术分享】杀软的无奈——基础工具篇(一)

flare-emu

是fireEye开源的一款基于unicorn,并且直接可以再ida导入使用的代码模拟执行工具,这个工具对于我们利用ida分析恶意代码或者shellcode都非常的有用,特别是复杂的加密算法,或者是恶心的自解密代码。
关于这款工具的使用说明可以参考这篇翻译文章
https://wonderkun.cc/2020/03/02/%E7%94%A8%E6%A8%A1%E6%8B%9F%E6%89%A7%E8%A1%8C%E5%AE%9E%E7%8E%B0Objective-C%E4%BB%A3%E7%A0%81%E8%87%AA%E5%8A%A8%E5%8C%96%E5%88%86%E6%9E%90/
,或者直接看源代码 https://github.com/fireeye/flare-emu,我当时修改了一个python3的版本用于支持ida7.4,
详情见我的github
https://github.com/wonderkun/flare-emu
注意: 在mac平台上,ida默认使用的python并不是是用brew安装的python3,需要手工切换一下,切换方法可以参考https://github.com/wonderkun/flare-emu#intall-on-mac
pip安装的unicorn可能不支持python3,需要自己编译安装一下unicorn。
 
【技术分享】杀软的无奈——基础工具篇(一)

unicorn

Unicorn 是一款基于qemu模拟器的模拟执行框架,支持Arm, Arm64 (Armv8), M68K, Mips, Sparc, & X86 (include X86_64)等指令集,为多种语言提供编程接口比如C/C++、Python、Java 等语言。Unicorn的DLL 可以被更多的语言调用,比如易语言、Delphi,前途无量。它的设计之初就考虑到线程安全问题,能够同时并发模拟执行代码,极大的提高了实用性。
在后续分析shellcode的过程中,会遇到大量的 self-modify-code,unicorn官方提供的版本是不支持SMC代码的,https://github.com/unicorn-engine/unicorn/issues/820,所以我参照网上的方法patch了一个版本https://github.com/wonderkun/unicorn,建议安装这个版本。就目前来看是够用的,但是官方还没有接受我的pr,具体原因未知。

虚拟内存

Unicorn 采用虚拟内存机制,使得虚拟CPU的内存与真实CPU的内存隔离。Unicorn 使用如下API来操作内存:
  • mem_map
  • mem_read
  • mem_write
使用uc_mem_map映射内存的时候,address 与 size 都需要与0x1000对齐,也就是0x1000的整数倍,否则会报UC_ERR_ARG 异常。如何动态分配管理内存并实现libc中的malloc功能将在后面的课程中讲解。

Hook机制

Unicorn的Hook机制为编程控制虚拟CPU提供了便利。
Unicorn 支持多种不同类型的Hook。
大致可以分为(hook_add第一参数,Unicorn常量):
  • 指令执行类
UC_HOOK_INTR
UC_HOOK_INSN
UC_HOOK_CODE
UC_HOOK_BLOCK
  • 内存访问类
UC_HOOK_MEM_READ
UC_HOOK_MEM_WRITE
UC_HOOK_MEM_FETCH
UC_HOOK_MEM_READ_AFTER
UC_HOOK_MEM_PROT
UC_HOOK_MEM_FETCH_INVALID
UC_HOOK_MEM_INVALID
UC_HOOK_MEM_VALID
  • 异常处理类
UC_HOOK_MEM_READ_UNMAPPED
UC_HOOK_MEM_WRITE_UNMAPPED
UC_HOOK_MEM_FETCH_UNMAPPED
调用hook_add函数可添加一个Hook。Unicorn的Hook是链式的,而不是传统Hook的覆盖式,也就是说,可以同时添加多个同类型的Hook,Unicorn会依次调用每一个handler。hook callback 是有作用范围的(见hook_add begin参数)。
python包中的hook_add函数原型如下
def hook_add(self, htype, callback, user_data=None, begin=1, end=0, arg1=0):pass
htype 就是Hook的类型,callback是hook回调用;
callback 是Hook的处理handler指针。请注意!不同类型的hook,handler的参数定义也是不同的。
user_data 附加参数,所有的handler都有一个user_data参数,由这里传值。
begin hook 作用范围起始地址
end hook 作用范围结束地址,默认则作用于所有代码。

hookcall

不同类型的hook,对应的callback的参数也是不相同的,这里只给出C语言定义。
Python 编写callback的时候参考C语言即可(看参数)。

UC_HOOK_CODE & UC_HOOK_BLOCK 的callback定义

typedef void (*uc_cb_hookcode_t)(uc_engine *uc, uint64_t address, uint32_t size, void *user_data);
  • address: 当前执行的指令地址
  • size: 当前指令的长度,如果长度未知,则为0
  • user_data: hook_add 设置的user_data参数

READ, WRITE & FETCH 的 callback 定义

typedef void (*uc_cb_hookmem_t)(uc_engine *uc, uc_mem_type type,uint64_t address, int size, int64_t value, void *user_data);
  • type: 内存操作类型 READ, or WRITE
  • address: 当前指令地址
  • size: 读或写的长度
  • value: 写入的值(type = read时无视)
  • user_data: hook_add 设置的user_data参数

invalid memory access events (UNMAPPED and PROT events) 的 callback 定义

typedef bool (*uc_cb_eventmem_t)(uc_engine *uc, uc_mem_type type,uint64_t address, int size, int64_t value, void *user_data);
  • type: 内存操作类型 READ, or WRITE
  • address: 当前指令地址
  • size: 读或写的长度
  • value: 写入的值(type = read时无视)
  • user_data: hook_add 设置的user_data参数
  • 返回值
    返回真,继续模拟执行
    返回假,停止模拟执行

【技术分享】杀软的无奈——基础工具篇(一)


- End -
精彩推荐
【技术分享】借助DefCon Quals 2021的mooosl学习
JBS工厂因网络攻击关停,真凶系REvil 勒索软件
【技术分享】vCenter Server CVE-2021-21985 RCE分析
【技术分享】MIPS架构—堆栈缓冲区溢出调试与利用
【技术分享】杀软的无奈——基础工具篇(一)
戳“阅读原文”查看更多内容

本文始发于微信公众号(安全客):【技术分享】杀软的无奈——基础工具篇(一)

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: