shellcode 反汇编,模拟运行以及调试方法

onlinedisassembler

https://onlinedisassembler.com 在线反汇编工具,相似于lda。功能比较单一。
html

Any.run 等平台在线分析

  1. 将shellcode保存为文件
  2. 经过以下脚本,转换shellcode为char数组
import binascii
filename = "C:\\Users\\liang\\Desktop\\工做相关\\样本\\rdpscan\\rdpscan\\ssleay32.dll"
#filename = "C:\\Users\\liang\\Desktop\\payload"

shellcode = "{"
ctr = 1
maxlen = 15

for b in open(filename, "rb").read():
    shellcode += "0x" + str(binascii.hexlify(b.to_bytes(length=1, byteorder='big')))[2:4] + ","
    if ctr == maxlen:
        shellcode += "\n"
        ctr = 0
    ctr += 1
shellcode = shellcode[:-1] + "}"
print(shellcode)
  1. 将结果复制到char shellcode处,并 经过以下vs程序加载shellcode
#include <windows.h>
#include <stdio.h>
#include <string.h>

#pragma comment(linker, "/section:.data,RWE")  

unsigned  char shellcode[] = 复制到这里

typedef void(__stdcall* CODE) ();

int main()
{

    PVOID p = NULL;
    if ((p = VirtualAlloc(NULL, sizeof(shellcode), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE)) == NULL)
        MessageBoxA(NULL, "申请内存失败", "提醒", MB_OK);
    if (!(memcpy(p, shellcode, sizeof(shellcode))))
        MessageBoxA(NULL, "写内存失败", "提醒", MB_OK);

    CODE code = (CODE)p;

    code();
    return 0;
}
  1. 设置c运行库的静态编译,如图设置,将运行库设置为多线程/MT
    python

  2. 点击生成解决方案,将生成的exe上传至Any.run去分析
    如图,便可经过在线分析平台去分析shellcode。简单快捷
    git

槽点主要有以下几方面:github

  1. 必定要选择静态编译c运行库,由于Any.run 的运行库可能会不全。以防万一
  2. shellcode不能够是\xFF 这类形式,必须是0xFF。由于前者属于字符串,后者属于数组。待分析的shellcode较大,超过65535字节后,vs在编译时会报错 fatal error C1091: compiler limit: string exceeds 65535 bytes in length

scdbg

windows shellcode运行模拟器,模拟运行shellcode
对于简单的shellcode 推荐使用此方法,模拟运行找到c2地址shell

使用文章以及介绍windows

https://isc.sans.edu/forums/diary/Analyzing+Encoded+Shellcode+with+scdbg/24134api

优势数组

  1. 支持debug shellcode
  2. dum内存
  3. 重定向tcp请求到其余机器,可是不支持urlopen等函数

缺点:sass

  1. 功能较为单一,模拟运行不是很全。有时候可能执行不到某些流程。而且没有实现部分dll的导出函数

图片
数据结构

下载连接
http://sandsprite.com/CodeStuff/scdbg.zip

miasm

miasm是一个python llvm写的逆向工程框架。

可是官方中提供了不少例子,咱们能够直接利用官方提供的脚本去完成不少任务

miasm不单单支持pe文件,还支持elf等,支持x86,arm,mips等架构

miasm功能不单单局限于这些,还有不少好玩的功能,例如自动化脱壳等。参考

  1. https://miasm.re/blog/index.html
  2. https://github.com/cea-sec/miasm/

miasm 反编译shellcode

使用graphviz 加载got文件,得到以下

同理 arm的选择arm,mips选择mips处理器类型

若是不像使用官方自带,能够本身写

沙箱中运行shellcode

记录每步运行的各类寄存器的值

沙箱中运行可执行系统文件

在知道系统架构的状况下 能够选择相应系统架构的sandbox,运行shellcode,从而得到更多信息

能够支持自写dll,方便hook,如图,可是我没写

支持的系统架构以下

其余功能

  1. 添加断点
# A breakpoint callback takes the jitter as first parameterdef dump(jitter):
        # Dump data ad address run_addr with a length of len(data)
        new_data = jitter.vm.get_mem(run_addr, len(data))
        # Save to disk
        open('/tmp/dump.bin', 'wb').write(new_data)
        # Stop execution
        return False

    # Register a callback to the breakpointmyjit.add_breakpoint(0x4000004b, dump)...myjit.cpu.EAX = 0x40000000myjit.init_run(run_addr)myjit.continue_run()
  1. hook沙箱中系统函数和peb等和数据结构
    例如hook urlmon_URLDownloadToCacheFileW
def urlmon_URLDownloadToCacheFileW(jitter):
        ret_ad, args = jitter.func_args_stdcall(["lpunkcaller",
                                                 "szurl",
                                                 "szfilename",
                                                 "ccfilename",
                                                 "reserved",
                                                 "pbsc"])
        url = jitter.get_str_unic(args.szurl)
        print "URL:", url
        jitter.set_str_unic(args.szfilename, "toto")
        jitter.func_ret_stdcall(ret_ad, 0)

注意 有时候程序调用沙箱没有实现的api,则须要经过上述该方法本身实现一个
sandbox 默认只实现了如下几个dll的导出函数 ntdll.dll", "kernel32.dll", "user32.dll",
"ole32.dll", "urlmon.dll",
"ws2_32.dll", 'advapi32.dll', "psapi.dll"

  1. 读写并修改系统可执行文件
    例如pe文件的修改,添加.text区段,修改pe文件结构等。固然,也支持elf,mach-o文件的修改等
import sys
from elfesteem import pe_init

# Get the shellcode
data = open(sys.argv[1]).read()
# Generate a PE
pe = pe_init.PE(wsize=32)
# Add a ".text" section containing the shellcode to the PE
s_text = pe.SHList.add_section(name=".text", addr=0x1000, data=data)
# Set the entrypoint to the shellcode's address
pe.Opthdr.AddressOfEntryPoint = s_text.addr
# Write the PE to "sc_pe.py"
open('sc_pe.exe', 'w').write(str(pe))
思惟扩展
  1. sandbox加载一个pe文件
  2. 在pe文件中申请一段内存,存放shellcode
  3. 修改eip到shellcode处
  4. 运行

好处,能够结合pe文件自动分析,分析处该shellcode的具体行为

OD加载shellcode

方法一

须要安装Olly Advanced 插件

  1. 随便load一个应用程序
  2. Alt+m 打开内存页面,添加内存,如图
  3. 将shellcode复制进去
  4. 设置新的eip

方法二

该方法灵活应用

如图咱们能够看出,加载shellcode的方式有如下几个步骤

  1. 调用virtualloc申请内存,属性为可写可执行。用来存放shellcode
  2. 调用createprocess 执行shellcode

    注意,并非必定经过createprocess去执行shellcode。也能够经过内联汇编jmp,setThreadContext等方式去执行shellcode。理论上,只要能够修改eip,就能够执行shellcode

od中输入命令 bp createprocess

等运行shellcode的时候,od会自动停在createprocess处,也就是shellcode开始执行的位置。如图

相关文章
相关标签/搜索