scemu

X86 32位仿真器,用于安全地模拟ShellCode

特征

  • 📦rust safety,对恶意软件有利。
    • 所有的依赖都in rust。
    • 没有unsafe{}块。
  • ⚡非常快的仿真(比unicorn快得多)
    • 3 000 000指令/秒
    • 100,000条指令/第二次打印每条指令-vv。
  • 提供iced-x86 rust反编译器库。
  • 迭代检测器
  • 内存和寄存器跟踪
  • 彩色的
  • 在特定的时刻停下来,探索或者修改它
  • 105项指示得到执行
  • 112个WINAPI实现了5个DLLs
  • 所有Linux系统调用
  • SEH链
  • 向量异常处理程序
  • PEB,TEB结构
  • 内存分配器
  • 与INT 3反应。
  • 未调试的cpuid
  • 具有已知有效载荷的测试:
    • Metasploit ShellCode
    • Metasploit 编码器。
    • Cobalt Strike
    • shellgen
    • guloader (目前还不完全,但是比调试器更远)

      TODO

      ```shell
  • more fpu
  • mmx
  • 64 bits
  • scripting? ```

    使用

    ```shell SCEMU 32bits emulator for Shellcodes 0.2.5 @sha0coder

USAGE: scemu [FLAGS] [OPTIONS]

FLAGS: -e, —endpoint perform communications with the endpoint, use tor or vpn! -h, —help Prints help information -l, —loops show loop interations, it is slow. -m, —memory trace all the memory accesses read and write. -n, —nocolors print without colors for redirectin to a file >out -r, —regs print the register values in every step. -V, —version Prints version information -v, —verbose -vv for view the assembly, -v only messages, without verbose only see the api calls and goes faster

OPTIONS: -b, —base

set base address for code -c, —console select in which moment will spawn the console to inspect. -C, —console_addr
spawn console on first eip = address -a, —entry
entry point of the shellcode, by default starts from the beginning. -f, —filename set the shellcode binary file. -i, —inspect monitor memory like: -i ‘dword ptr [ebp + 0x24] -M, —maps select the memory maps folder -R, —reg trace a specific register in every step, value and content -s, —string
monitor string on a specific address

  1. ```shell
  2. 用于 Shellcodes 0.2.5 的 SCEMU 32 位仿真器
  3. @sha0coder
  4. 用法:
  5. scemu [标志] [选项]
  6. 标志:
  7. -e, --endpoint 与端点进行通信,使用tor或vpn
  8. -h, --help 打印帮助信息
  9. -l, --loops 显示循环交互,它很慢
  10. -m, --memory 跟踪所有内存访问读写
  11. -n, --nocolors 打印不带颜色以重定向到文件 >out
  12. -r, --regs 打印每一步的寄存器值
  13. -V, --version 打印版本信息
  14. -v, --verbose -vv 用于查看程序集,-v 仅消息
  15. 选项:
  16. -b, --base <ADDRESS> 设置代码的基地址
  17. -c, --console <NUMBER> 选择在哪个时刻生成要检查的控制台
  18. -C, --console_addr <ADDRESS> 在第一个 eip = 地址上生成控制台
  19. -a, --entry <ADDRESS> shellcode的入口点,默认从头开始
  20. -f, --filename <FILE> 设置 shellcode 二进制文件
  21. -i, --inspect <DIRECTION> 监控内存,例如:-i 'dword ptr [ebp + 0x24]
  22. -M, --maps <PATH> 选择内存映射文件夹
  23. -R, --reg <REGISTER> 在每一步跟踪一个特定的寄存器,值和内容
  24. -s, --string <ADDRESS> 监控特定地址上的字符串

一些用例

Scemu模拟一个检测execve()中断的简单ShellCode:scemu:安全地模拟ShellCode执行 - 图1
我们选择一行停止,并检查内存:scemu:安全地模拟ShellCode执行 - 图2
在 linux 中模拟了近 200 万条 GuLoader win32 指令后,伪装 cpuid 和其他技巧,到达一个 sigtrap(SIG 崩溃) 以混淆调试器:scemu:安全地模拟ShellCode执行 - 图3
API加载程序上的内存转储示例:
scemu:安全地模拟ShellCode执行 - 图4
默认情况下,有几个映射,可以使用像LoadLibrary A这样的API创建更多,也可以从控制台手动创建:
scemu:安全地模拟ShellCode执行 - 图5
基于打印消息的LdrLoadDLl()仿真基本WindowsShellCode:
scemu:安全地模拟ShellCode执行 - 图6
控制台允许查看CPU当前状态的编辑:

  1. --- console ---
  2. =>h
  3. --- help ---
  4. q ...................... quit
  5. cls .................... clear screen
  6. h ...................... help
  7. s ...................... stack
  8. v ...................... vars
  9. r ...................... register show all
  10. r reg .................. show reg
  11. rc ..................... register change
  12. f ...................... show all flags
  13. fc ..................... clear all flags
  14. fz ..................... toggle flag zero
  15. fs ..................... toggle flag sign
  16. c ...................... continue
  17. ba ..................... breakpoint on address
  18. bi ..................... breakpoint on instruction number
  19. bmr .................... breakpoint on read memory
  20. bmw .................... breakpoint on write memory
  21. bc ..................... clear breakpoint
  22. n ...................... next instruction
  23. eip .................... change eip
  24. push ................... push dword to the stack
  25. pop .................... pop dword from stack
  26. fpu .................... fpu view
  27. md5 .................... check the md5 of a memory map
  28. seh .................... view SEH
  29. veh .................... view vectored execption pointer
  30. m ...................... memory maps
  31. ma ..................... memory allocs
  32. mc ..................... memory create map
  33. mn ..................... memory name of an address
  34. ml ..................... memory load file content to map
  35. mr ..................... memory read, speficy ie: dword ptr [esi]
  36. mw ..................... memory read, speficy ie: dword ptr [esi] and then: 1af
  37. md ..................... memory dump
  38. mrd .................... memory read dwords
  39. mds .................... memory dump string
  40. mdw .................... memory dump wide string
  41. mdd .................... memory dump to disk
  42. mt ..................... memory test
  43. ss ..................... search string
  44. sb ..................... search bytes
  45. sba .................... search bytes in all the maps
  46. ssa .................... search string in all the maps
  47. ll ..................... linked list walk
  48. d ...................... dissasemble
  49. dt ..................... dump structure
  50. enter .................. step into
  1. q ......................退出
  2. cls ....................清除屏幕
  3. h ......................帮助
  4. s ......................堆栈
  5. v ......................变量
  6. r ......................注册 显示所有
  7. r reg ..................显示 reg
  8. rc .....................注册更改
  9. f ......................显示所有标志
  10. fc .....................清除所有标志
  11. fz .....................切换标志为零
  12. fs .....................切换标志符号
  13. c ......................继续
  14. ba .....................地址上的断点
  15. bi .....................指令号上的断点
  16. bmr ....................读内存断点
  17. bmw ....................写入内存的断点
  18. bc .....................清除断点
  19. n ......................下一条指令
  20. eip ....................更改eip
  21. push ...................将 dword 推入堆栈
  22. pop ....................从堆栈中弹出 dword
  23. fpu ....................fpu 视图
  24. md5 ....................检查内存映射的md5
  25. seh ....................查看 SEH
  26. veh ....................查看向量执行指针
  27. m ......................内存映射
  28. ma .....................内存分配
  29. mc .....................内存创建映射
  30. mn .....................地址的内存名称
  31. ml .....................内存加载文件内容到映射
  32. mr .....................内存读取,特别是:dword ptr [esi]
  33. mw .....................内存读取,特别是:dword ptr [esi] 然后:1af
  34. md .....................内存转储
  35. mrd ....................内存读取 dwords
  36. mds ....................内存转储字符串
  37. mdw ....................内存转储宽字符串
  38. mdd ....................内存转储到磁盘
  39. mt .....................内存测试
  40. ss .....................搜索字符串
  41. sb .....................搜索字节
  42. sba ....................在所有映射中搜索字节
  43. ssa ....................在所有地图中搜索字符串
  44. ll .....................链表遍历
  45. d ......................拆卸
  46. dt .....................转储结构
  47. enter ..................步入

Cobalt Strike API加载程序与Metasploit相同,并模拟它:scemu:安全地模拟ShellCode执行 - 图7
Cobalt Strike的API调用:scemu:安全地模拟ShellCode执行 - 图8
Metasploit rshell的API调用:scemu:安全地模拟ShellCode执行 - 图9
Metasploit SGN编码器使用少量FPU隐藏多态性:scemu:安全地模拟ShellCode执行 - 图10
Metasploit shikata-ga-nai编码器,也以FPU开头:scemu:安全地模拟ShellCode执行 - 图11
显示PEB结构:

  1. =>dt
  2. structure=>peb
  3. address=>0x7ffdf000
  4. PEB {
  5. reserved1: [
  6. 0x0,
  7. 0x0,
  8. ],
  9. being_debugged: 0x0,
  10. reserved2: 0x0,
  11. reserved3: [
  12. 0xffffffff,
  13. 0x400000,
  14. ],
  15. ldr: 0x77647880,
  16. process_parameters: 0x2c1118,
  17. reserved4: [
  18. 0x0,
  19. 0x2c0000,
  20. 0x77647380,
  21. ],
  22. alt_thunk_list_ptr: 0x0,
  23. reserved5: 0x0,
  24. reserved6: 0x6,
  25. reserved7: 0x773cd568,
  26. reserved8: 0x0,
  27. alt_thunk_list_ptr_32: 0x0,
  28. reserved9: [
  29. 0x0,
  30. ...

显示PEBLDR数据结构:

  1. =>dt
  2. structure=>PEB_LDR_DATA
  3. address=>0x77647880
  4. PebLdrData {
  5. length: 0x30,
  6. initializated: 0x1,
  7. sshandle: 0x0,
  8. in_load_order_module_list: ListEntry {
  9. flink: 0x2c18b8,
  10. blink: 0x2cff48,
  11. },
  12. in_memory_order_module_list: ListEntry {
  13. flink: 0x2c18c0,
  14. blink: 0x2cff50,
  15. },
  16. in_initialization_order_module_list: ListEntry {
  17. flink: 0x2c1958,
  18. blink: 0x2d00d0,
  19. },
  20. entry_in_progress: ListEntry {
  21. flink: 0x0,
  22. blink: 0x0,
  23. },
  24. }
  25. =>

显示LDR_DATA_TABLE_ENTRY和第一个模块名

  1. =>dt
  2. structure=>LDR_DATA_TABLE_ENTRY
  3. address=>0x2c18c0
  4. LdrDataTableEntry {
  5. reserved1: [
  6. 0x2c1950,
  7. 0x77647894,
  8. ],
  9. in_memory_order_module_links: ListEntry {
  10. flink: 0x0,
  11. blink: 0x0,
  12. },
  13. reserved2: [
  14. 0x0,
  15. 0x400000,
  16. ],
  17. dll_base: 0x4014e0,
  18. entry_point: 0x1d000,
  19. reserved3: 0x40003e,
  20. full_dll_name: 0x2c1716,
  21. reserved4: [
  22. 0x0,
  23. 0x0,
  24. 0x0,
  25. 0x0,
  26. 0x0,
  27. 0x0,
  28. 0x0,
  29. 0x0,
  30. ],
  31. reserved5: [
  32. 0x17440012,
  33. 0x4000002c,
  34. 0xffff0000,
  35. ],
  36. checksum: 0x1d6cffff,
  37. reserved6: 0xa640002c,
  38. time_date_stamp: 0xcdf27764,
  39. }
  40. =>

恶意软件在异常中隐藏了一些东西:

  1. 3307726 0x4f9673: push ebp
  2. 3307727 0x4f9674: push edx
  3. 3307728 0x4f9675: push eax
  4. 3307729 0x4f9676: push ecx
  5. 3307730 0x4f9677: push ecx
  6. 3307731 0x4f9678: push 4F96F4h
  7. 3307732 0x4f967d: push dword ptr fs:[0]
  8. Reading SEH 0x0
  9. -------
  10. 3307733 0x4f9684: mov eax,[51068Ch]
  11. --- console ---
  12. =>

检查异常结构:

  1. --- console ---
  2. =>r esp
  3. esp: 0x22de98
  4. =>dt
  5. structure=>cppeh_record
  6. address=>0x22de98
  7. CppEhRecord {
  8. old_esp: 0x0,
  9. exc_ptr: 0x4f96f4,
  10. next: 0xfffffffe,
  11. exception_handler: 0xfffffffe,
  12. scope_table: PScopeTableEntry {
  13. enclosing_level: 0x278,
  14. filter_func: 0x51068c,
  15. handler_func: 0x288,
  16. },
  17. try_level: 0x288,
  18. }
  19. =>

这里我们有错误例程0x4f96f4和过滤器0x51068c。