shellcode 反匯編,模擬運行以及調試方法


onlinedisassembler

https://onlinedisassembler.com 在線反匯編工具,類似於lda。功能比較單一。

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
    ![](https://potatso-1253210846.cos.ap-beijing.myqcloud.com//imgImage [2].png)

  2. 點擊生成解決方案,將生成的exe上傳至Any.run去分析
    如圖,即可通過在線分析平台去分析shellcode。簡單快捷
    ![](https://potatso-1253210846.cos.ap-beijing.myqcloud.com//imgImage [3].png)

槽點主要有如下幾方面:

  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地址

使用文章以及介紹

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

優點

  1. 支持debug shellcode
  2. dum內存
  3. 重定向tcp請求到其他機器,但是不支持urlopen等函數

缺點:

  1. 功能較為單一,模擬運行不是很全。有時候可能執行不到某些流程。並且沒有實現部分dll的導出函數

圖片
![](https://potatso-1253210846.cos.ap-beijing.myqcloud.com//imgImage [4].png)

下載鏈接
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

![](https://potatso-1253210846.cos.ap-beijing.myqcloud.com//imgImage [6].png)

使用graphviz 加載got文件,獲得如下
![](https://potatso-1253210846.cos.ap-beijing.myqcloud.com//imgImage [5].png)

![](https://potatso-1253210846.cos.ap-beijing.myqcloud.com//imgImage [7].png)

同理 arm的選擇arm,mips選擇mips處理器類型

如果不像使用官方自帶,可以自己寫

沙箱中運行shellcode

![](https://potatso-1253210846.cos.ap-beijing.myqcloud.com//imgImage [8].png)

記錄每步運行的各種寄存器的值

沙箱中運行可執行系統文件

在知道系統架構的情況下 可以選擇相應系統架構的sandbox,運行shellcode,從而獲得更多信息
![](https://potatso-1253210846.cos.ap-beijing.myqcloud.com//imgImage [9].png)

可以支持自寫dll,方便hook,如圖,但是我沒寫
![](https://potatso-1253210846.cos.ap-beijing.myqcloud.com//imgImage [10].png)

支持的系統架構如下
![](https://potatso-1253210846.cos.ap-beijing.myqcloud.com//imgImage [11].png)

其他功能

  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的具體行為
![](https://potatso-1253210846.cos.ap-beijing.myqcloud.com//imgImage [12].png)

OD加載shellcode

方法一

需要安裝Olly Advanced 插件

  1. 隨便load一個應用程序
  2. Alt+m 打開內存頁面,添加內存,如圖
    ![](https://potatso-1253210846.cos.ap-beijing.myqcloud.com//imgImage [13].png)
  3. 將shellcode復制進去
  4. 設置新的eip

方法二

該方法靈活應用
![](https://potatso-1253210846.cos.ap-beijing.myqcloud.com//imgImage [14].png)

如圖我們可以看出,加載shellcode的方式有以下幾個步驟

  1. 調用virtualloc申請內存,屬性為可寫可執行。用來存放shellcode
  2. 調用createprocess 執行shellcode

注意,並不是一定通過createprocess去執行shellcode。也可以通過內聯匯編jmp,setThreadContext等方式去執行shellcode。理論上,只要可以修改eip,就可以執行shellcode

od中輸入命令 bp createprocess

等運行shellcode的時候,od會自動停在createprocess處,也就是shellcode開始執行的位置。如圖
![](https://potatso-1253210846.cos.ap-beijing.myqcloud.com//imgImage [15].png)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM