Linux上X86-64精靈二進制的包裝工/保護器。 Kiteshield用多層加密包裝Elf Binaries,並向它們注入加載,地圖並完全在用戶空間中執行包裝的二進製文件。基於PTRACE的運行時引擎可確保在任何給定時間中僅解密當前呼叫堆棧中的功能,並還實現了各種反欺騙技術,以使包裝的二進製文件盡可能難以反向工程。支持單讀和多線程二進製文件。
有關Kiteshield的工作方式,請參見下面的架構和代碼庫佈局部分。
Kiteshield旨在在二元混淆中進行有趣的學術練習,而不是在源代碼中可以在現實世界中使用的東西,因此是公開的。
以諾曼人在11世紀首選的盾牌命名(另外:在舊派符號中如此普遍的基特島)。
Kiteshield要求BitDefender拆卸器庫在包裝器中解碼說明。它作為packer/bddisasm的子模塊包含在內。要從新鮮的克隆構建它,請運行以下(請注意,您需要安裝CMAKE):
git submodule update --init
cd packer/bddisasm
mkdir build
cd build
cmake ..
make
現在,您可以通過從頂級目錄運行make來構建釋放模式的Kiteshield。另外,您可以使用make debug創建調試構建。 Kiteshield的調試構建禁用所有反欺騙功能,並打開裝載機的非常詳細的調試記錄。
為了調試實際的反欺騙功能,您可以在調試模式下構建Kiteshield,使用反欺騙功能打開使用make debug-antidebug 。
要打包一個名為program的二進製文件並輸出包裝的二進製文件packed.ks ,運行:
./packer/kiteshield program packed.ks
現在可以運行packed.ks ,並且應該在功能上等同於program ,但已加密且難以反向工程師。請注意,對於要應用的第2層加密,當Kiteshield依賴於存在的符號表時,不得將輸入二進制剝離。在大多數Linux發行版中,標準系統實用程序(例如/bin/ls )通常被剝離。
但是,您仍然可以使用-n標誌包裝剝離的二進製文件,而無需第2層加密:
./packer/kiteshield -n program packed.ks
這將產生僅使用第1層加密和運行時引擎的輸出二進制填充。
Kiteshield由兩個單獨的部分組成。包裝器是一個常規的C應用程序,可讀取,儀器和加密輸入二進製文件。加載程序是負責動態功能解密和反欺騙功能的獨立c應用程序,該功能被包裝器注入輸入二進製文件。它從內核接收初始控件,將二進制的所有適當段映射到內存中(包括適用的動態鏈接器),然後將控制權移交給應用程序。加載程序還包含運行時引擎,該引擎在輸入並在運行時退出時動態解密和加密功能。
由於加載程序從內核接收初始控件(即。
包裝器和加載程序代碼分別可以在packer/和loader/ Directories中找到。兩者共有的代碼可以在common/目錄中找到。代碼庫重要部分的高級概述如下:
kiteshield
├── common # Code common to packer/loader
│ ├── include
│ │ ├── defs.h
│ │ ├── obfuscation.h
│ │ └── rc4.h
│ ├── obfuscation.c # Obfuscation utilities
│ └── rc4.c # RC4 stream cipher implementation
├── LICENSE
├── loader # Loader code
│ ├── anti_debug.c # Anti-debugging functionality
│ ├── bin_to_header.py # Script to "headerize" a compiled loader
│ ├── entry.S # Loader entry point code
│ ├── include
│ │ ├── anti_debug.h
│ │ ├── debug.h
│ │ ├── elf_auxv.h
│ │ ├── errno.h
│ │ ├── malloc.h
│ │ ├── obfuscated_strings.h # Generated file produced by string_obfuscation.py
│ │ ├── signal.h
│ │ ├── string.h
│ │ ├── syscalls.h
│ │ └── types.h
│ ├── link.lds # Custom linker script for building loader
│ ├── loader.c # Binary loading/mapping code (userspace exec)
│ ├── Makefile
│ ├── malloc.c # Freestanding malloc/free implementation
│ ├── runtime.c # Main body of runtime engine code
│ ├── string.c # String processing utilities (eg. strncat)
│ ├── string_obfuscation.py # String obfuscation helper script
│ ├── syscalls.c # System call implementations in inline assembly
│ └── test # Loader unit tests
│ ├── attounit.h
│ ├── Makefile
│ ├── test_main.c
│ ├── test_malloc.c
│ └── test_rc4.c
├── Makefile
├── packer # Packer code
│ ├── bddisasm # Bitdefender x86-64 disassembler library (submodule)
│ ├── elfutils.c # ELF binary reading/writing utilities
│ ├── include
│ │ └── elfutils.h
│ ├── kiteshield.c # Main body of packer code
│ └── Makefile
├── README.md
└── testing # Integration tests (see testing/README.md)
Kiteshield將RC4加密的兩個(如果使用-n標誌)層將輸入Elf二進製文件包裝在兩個(或一個,如果使用-n標誌)層,以使磁盤上的二進制二進制相當混淆。這些層在運行時被裝載機剝離。
加密的第一層(在代碼庫中稱為“外層”)由單個RC4通過整個輸入二進制組成。這主要是為了對抗靜態分析。由於鑰匙的方式被去除(取決於加載器代碼),因此加密的第一層在執行包裝的二進制之前還有效地檢查了加載程序代碼,從而使Kiteshield抗代碼修補。
加密的第二層(在代碼庫中稱為“內層”)由單個對輸入二進制中幾乎每個函數的加密組成(通過包裝時的符號表識別)。每個功能條目都會觸發基於PTRACE的運行時引擎,並通過更換每個功能的輸入說明及其所有返回指令退出int3指令(執行時會提供SIGTRAP )。收到陷阱後,運行時引擎查找當前功能,並根據需要對其進行加密或解密,以便在當前呼叫堆棧中的功能在任何時間點都被解密。
剝離第1層後,機式避難所有效地重新插入了用戶空間中的exec (請參閱loader/loader.c 。在文獻中通常稱為“用戶空間exec”或“ userland exec”。以通過一系列mmap / MMAP / mprotect CORTINE CORTINE CORTINE CORTINE CORTINE CORTINE CORTINE CORTINE CORTINE CORTINE CORTINE CORTINE CORTINE BRIANDER(the Chord of Croun)映射到包裝的二進制中。使用ptrace的孩子)。
除了加密外,Kiteshield的加載程序代碼還包含許多抗干吊銷功能,旨在使分析運行的包裝二進制的功能盡可能困難(請參閱loader/anti_debug.c和loader/include/anti_debug.h )。
為了給基特島的具體示例,請考慮以下Hello World程序,我們將在調試模式下與Kiteshield打包。
#include <stdio.h>
int main ()
{
puts ( "Hello World!" );
return 0 ;
}在調試模式下包裝時,包裝二進製文件中的加載器代碼將記錄非常詳細的調試信息。以下是與上述程序相對應的包裝二進制的日誌。它已被註釋(並為清晰而添加了其他新線),以提供基特島的具體示例:
$ ./packed.ks
# Runtime startup
[kiteshield] starting ptrace runtime
[kiteshield] number of trap points: 5
[kiteshield] number of encrypted functions: 3
# List of points in memory that have been instrumented with an int3 instruction
[kiteshield] list of trap points:
[kiteshield] 8000011ac value: c3, type: ret, function: __libc_csu_init (#0)
[kiteshield] 800001150 value: 41, type: ent, function: __libc_csu_init (#0)
[kiteshield] 800001050 value: 31, type: ent, function: _start (#1)
[kiteshield] 80000114b value: c3, type: ret, function: main (#2)
[kiteshield] 800001135 value: 55, type: ent, function: main (#2)
# Runtime has started and is waiting on the packed app, begin mapping binary
# Stripping layer one encryption
[kiteshield] RC4 decrypting binary with key 85e19ad41fb8cc13e87e3cd1589a45fb
[kiteshield] decrypted 12336 bytes
# Mapping segments from packed binary program header table
[kiteshield] mapping LOAD section from packed binary at 800000000
[kiteshield] mapping LOAD section from packed binary at 800001000
[kiteshield] mapping LOAD section from packed binary at 800002000
[kiteshield] mapping LOAD section from packed binary at 800003000
# Mapping dynamic linker specified in INTERP header of packed binary
[kiteshield] mapping INTERP ELF at path /lib64/ld-linux-x86-64.so.2
[kiteshield] mapped LOAD section from fd at b00000000
[kiteshield] interpreter base address is b00000000
[kiteshield] mapped LOAD section from fd at b00001000
[kiteshield] mapped LOAD section from fd at b0001f000
[kiteshield] mapped extra space for static data (.bss) at b00029000 len 400
[kiteshield] mapped LOAD section from fd at b00027000
[kiteshield] binary base address is 800000000
# Modifying ELF auxiliary vector as needed for program execution
[kiteshield] taking 7ffff2997c60 as auxv start
[kiteshield] replaced auxv entry 9 with value 34359742544 (0x800001050)
[kiteshield] replaced auxv entry 3 with value 34359738432 (0x800000040)
[kiteshield] replaced auxv entry 7 with value 47244640256 (0xb00000000)
[kiteshield] replaced auxv entry 5 with value 11 (0xb)
[kiteshield] finished mapping binary into memory
[kiteshield] control will be passed to packed app at b00001090
# Mapping done
# Runtime attaches to the packed application with ptrace
[kiteshield] child is traced, handing control to packed binary
# Program is executing, functions are logged on entry/exit
[kiteshield] tid 13508: entering encrypted function _start decrypting with key 74c974f9d097e5a8c60049c3842c6110
[kiteshield] tid 13508: entering encrypted function __libc_csu_init decrypting with key 9124511baa87daa76c09b2426355dfca
[kiteshield] tid 13508: leaving function __libc_csu_init for address 7fa9a821d02a (no function record) via ret at 8000011ac
[kiteshield] tid 13508: entering encrypted function main decrypting with key 2f1c20e77ff3617b0b89a579669aba48
# Actual program output
Hello World!
# Packed application returns from main() and exits
[kiteshield] tid 13508: leaving function main for address 7fa9a821d09b (no function record) via ret at 80000114b
[kiteshield] tid 13508: exited with status 0
[kiteshield] all threads exited, exiting
Kiteshield有一系列廣泛的集成測試,可以驗證幾個不同平台的正確性。有關詳細信息,請參見testing/README.md 。
Kiteshield的寫作是構想的,而不是速度。在每個功能入口處捕獲Kiteshield運行時,並且出口非常昂貴。包裝有第2層加密的程序應期望遭受嚴重的性能。
MIT©Rhys Rustad-Elliott