$30 off During Our Annual Pro Sale. View Details »

Source Code Protection Techniques in PHP

Source Code Protection Techniques in PHP

LaravelVueConf Taiwan 2023

Albert Chen

August 19, 2023
Tweet

More Decks by Albert Chen

Other Decks in Technology

Transcript

  1. Securing Your PHP
    Source Code Protection Techniques
    @LaravelVueConf 2023
    Albert Chen

    View Slide

  2. 02 Source Code Encoding
    Outline
    01 Protection Types in PHP
    03 Source Code Obfuscation
    04 OpCode and OpCache in PHP
    05 PHP Extension
    07 Q&A
    06 Existing Solutions

    View Slide

  3. Slido
    #1421565
    https://sli.do

    View Slide

  4. Commercial Software
    Outsourced Software without Source Code
    Non-Open-Source Software
    Hackers
    Who Needs Code Protection?

    View Slide

  5. Cloud Based Services
    Self-Hosted Solutions
    Source Code
    Binary File
    Software Delivery

    View Slide

  6. Compilation
    Source code can't be executed directly
    Need to compile to binary code
    Can't cross platforms
    eg. C, Rust, Golang
    Interpretation
    Need an interpreter for code execution
    Source code is needed for interpreter
    Cross platforms
    eg. Python, PHP, Ruby
    Compilation vs Interpretation

    View Slide

  7. Source Code
    Encoding
    Obfuscation
    Encryption
    Opcode
    Opcache
    Encryption
    Obfuscation
    VM Customization
    VM in PHP
    PHP Extension
    FFI in PHP
    Protection Types in PHP
    with/without extension
    in Zend VM

    View Slide

  8. eval
    Eval a string as PHP code
    Source Code Encoding

    View Slide

  9. eval
    used with multiple encoding functions
    Source Code Encoding

    View Slide

  10. Encoding functions
    base64_encode
    gzinflate
    str_rot13
    gzcompress
    gzencode
    pack
    Source Code Encoding

    View Slide

  11. Execution functions
    eval
    assert
    call_user_func
    call_user_func_array
    create_function
    Source Code Encoding

    View Slide

  12. PHPFuck
    Source Code Encoding

    View Slide

  13. PHPFuck
    Uses only seven different characters
    It's limited to PHP 7
    Published by splitline @SITCON 2021
    Source Code Encoding
    (https://github.com/splitline/PHPFuck)

    View Slide

  14. PHPFuck
    Variable Function
    Weak Type Conversion
    Source Code Encoding

    View Slide

  15. PHPFuck
    Convert any string with: ([+.^ ]) characters
    Source Code Encoding

    View Slide

  16. PHPFuck
    Numbers
    [ ] ^ [ ] => 0
    [ ] ^ [ [ ] ] => 1
    [ ] ^ [ [ ] ] + [ ] ^ [ [ ] ] => 2
    ......
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    Source Code Encoding

    View Slide

  17. PHPFuck
    Alphabets
    (string) [ ] => 'Array'
    [ ] . [ ] => 'ArrayArray'
    ( [ ] . [ ] ) [0] => 'A'
    Stringed Numbers
    (string) 1 => '1'
    1 . NULL => '1'
    1 . [ ] [ [ ] ] => '1'
    Source Code Encoding

    View Slide

  18. PHPFuck
    ASCII Codes
    'A' ^ '0' => 'q'
    'A' ^ '1' => 'p'
    'A' ^ '2' => 's'
    ......
    Create Function
    eval cannot be called using variable functions
    Source Code Encoding
    'create_function'(
    ... 'str_getcsv' (', code')
    );

    View Slide

  19. encoded
    string
    replaced
    encoded
    string
    strtr
    Dictionary Obfuscation
    Replace specific characters with dictionary mapping
    Source Code Encoding

    View Slide

  20. Dictionary Obfuscation
    Replace specific characters with dictionary mapping
    Source Code Encoding

    View Slide

  21. Hook zend_compile_string function
    eval() will call this function in ZendVM
    Dump Encoded Source Code
    Hook zend_compile_string
    in RINT stage

    View Slide

  22. Hook zend_compile_string function
    eval() will call this function in ZendVM
    Dump Encoded Source Code

    View Slide

  23. Hook zend_compile_string function
    eval() will call this function in ZendVM
    Dump Encoded Source Code

    View Slide

  24. Obfuscate with AST
    Analyze code in PHP files
    Visit all the Nodes in built AST
    Apply obfuscation strategies based on Node Types
    Source Code Obfuscation
    PHP Files
    PHP
    Parser
    AST

    View Slide

  25. PHP Parser by Nikic (without extension)
    Parsing PHP code into an Abstract Syntax Tree (AST)
    Dumping the AST in human-readable form
    Converting an AST back to PHP code
    Infrastructure to traverse and modify ASTs
    Resolution of namespaced names
    Evaluation of constant expressions
    Builders to simplify AST construction for code generation
    Converting an AST into JSON and back
    Source Code Obfuscation

    View Slide

  26. Obfuscate from AST
    Source Code Obfuscation

    View Slide

  27. Removal of Comment Info
    Source Code Obfuscation
    Annotation will not function
    (PHP
    代码加密技术_
    郭新华_PHPCON2018)

    View Slide

  28. Dynamic Variables
    Included Files
    Compact, Extract Functions
    Scrambling Scoped Variables
    Source Code Obfuscation
    (Example Reference: PHP
    代码加密技术 of
    郭新华 in PHPCON2018 China)

    View Slide

  29. Constant Propogation and Folding
    Source Code Obfuscation
    (Example Reference: PHP
    代码加密技术 of
    郭新华 in PHPCON2018 China)

    View Slide

  30. Inline Functions
    Insert functions to caller functions
    Source Code Obfuscation
    (Example Reference: PHP
    代码加密技术 of
    郭新华 in PHPCON2018 China)
    It will enlarge code size

    View Slide

  31. Can't add too much garbage
    Garbage Code
    Source Code Obfuscation
    (Example Reference: PHP
    代码加密技术 of
    郭新华 in PHPCON2018 China)

    View Slide

  32. Control Flow Confusion
    Source Code Obfuscation

    View Slide

  33. Control Flow Confusion (goto)
    Source Code Obfuscation

    View Slide

  34. Polymorphic Variation
    Source Code Obfuscation

    View Slide

  35. Source Code Encryption (with extension)
    Source Code Encryption
    encrypted
    code
    hook
    zend_compile_file
    execute
    decode

    View Slide

  36. Strings Encryption (with extension)
    Source Code Encryption
    Encrypted strings
    Decrypt before echo
    echo

    View Slide

  37. md5 _8dec4f04
    json_encode _a834509b
    Built-in Function Names Obfuscation (with extension)
    Source Code Encryption
    Function names in error message
    will become unreadable

    View Slide

  38. OpCode in PHP
    PHP's lifecycle
    OpCode doesn't contain source code

    View Slide

  39. OpCode in PHP
    OPCode
    OPCode are stored in opcode arrays by different
    compiled units (eg. file, function, method, closure)
    Each OPCode contains:
    handler
    operand 1 and its type
    operand 2 and its type
    result

    View Slide

  40. OpCode in PHP
    OPCode Definitions

    View Slide

  41. OpCode in PHP
    OPCode
    Can be dumped via phpdbg or VLD extension

    View Slide

  42. OpCode in PHP
    Dump OPCodes

    View Slide

  43. OpCache in PHP
    OPCache
    Compiling to OPCodes takes time
    Used to cache OPCodes without recompiling again
    Compilation artifacts will be cached in shared memory
    Checksum (Adler-32) validation before using cache
    Optimizations will be applied at this stage as well

    View Slide

  44. OpCache in PHP
    Compile PHP files to opcache files

    View Slide

  45. OpCache in PHP
    Compile PHP files to opcache files

    View Slide

  46. OpCache in PHP
    Metainfo of OPCache

    View Slide

  47. disassemble
    OpCache in PHP
    Disassemble OpCodes
    (https://github.com/GoSecure/php7-opcache-override)

    View Slide

  48. OpCache in PHP
    Facts about OpCache and OpCode
    OpCache is designed for speeding up the parsing
    process in PHP's lifecycle
    OpCode has no fixed standard like Java
    It may differ in different PHP versions (event minor
    versions)
    OpCodes are impossible to be converted back to
    original source code, but can still be disassembled
    Modern commercial protection solutions are almost
    based on OpCodes

    View Slide

  49. OpCache in PHP
    JIT with OpCache
    JIT is built on the base of OpCache
    (https://php.watch/articles/jit-in-depth)

    View Slide

  50. OpCache in PHP
    JIT with OpCache
    Jited code can't be dumped to opcache files
    (https://github.com/php/php-src/blob/bb092ab4c6fa36b56c89216f3a127fa763940bf0/ext/opcache/zend_file_cache.c#L1071)

    View Slide

  51. OpCache in PHP
    Obfuscation in modern solutions
    PHP Files OpCodes
    Scramble variables
    Inline functions
    Garbage code
    Control flow confusion
    Encrypt strings
    Scramble OpCodes
    Replace function names
    Add customized OpCodes
    Add anti-traced technique
    Encrypt OpCodes
    compile
    output
    obfuscate

    View Slide

  52. Zend VM Customization
    Limit PHP to specific version for OpCache's execution
    More advanced protection techniques can be applied in VM
    Disable other customized extensions
    Limit for executing obfuscated code only
    Apply more obfuscations on this PHP binary
    Pre-built environment can only be run at specific operating
    system and CPU architecture
    Built based on existing open-source projects like:
    dixyes/phpmicro

    View Slide

  53. Anti-Tracing
    Detect tracing extensions (xdebug)
    Check execution time between functions
    Detect if obfuscated code has been modified
    Checksum validation
    Verification before execution
    Authorized serial number
    MAC address binding
    Expiration date with license
    Detect if pointers in Zend VM are swapped
    Anti-Traced Techniques

    View Slide

  54. VM in PHP
    Zend VM
    PHP VM
    Bytecode
    VM implementation in PHP
    Minimal VM written in PHP
    PHP script will be compiled to customized bytecode
    No extensions are required
    Poor execution performance and limited feature

    View Slide

  55. PHP Extension
    Native PHP Extensions
    There's no AOT solution for PHP yet
    Protect your core logic in extension
    Core logic (eg. algorithms) can be written in PHP
    extension
    Native PHP extensions are developed in C language
    Not friendly to PHP developers
    Extensions are hard to maintain
    You may need to update your extensions by different
    PHP versions

    View Slide

  56. PHP Extension
    Zephir
    Zephir stands for Ze(nd Engine) Ph(p) I(nt)r(mediate)
    Maintained by Phalcon team
    High-level/domain specific language for PHP extensions
    Designed to ease the creation and maintainability of
    extensions for PHP
    Similar syntax to PHP language
    It's both dynamically and statically typed
    Memory safety, pointers or direct memory
    management are not allowed

    View Slide

  57. PHP Extension
    Compilation Scheme of Zephir
    Zephir offers native code generation (currently via
    compilation to C)
    A compiler like gcc/clang/vc++ optimizes and compiles
    the code down to machine code
    (https://docs.zephir-lang.com/0.12/en/motivation)

    View Slide

  58. PHP Extension
    Demo of Zephir

    View Slide

  59. FFI in PHP
    FFI (Foreign Function Interface)
    Was introduced in PHP 7.4
    Allows the loading of shared libraries (.so), calling of C
    functions and accessing of C data structures in PHP

    View Slide

  60. Existing Solutions
    Non-Extension Obfuscators
    Encoders are just toys, they don't provide any
    protections for your code
    Obfuscators which are not based on extensions provide
    limited protection
    There are lots of open-sourced obfuscators on GitHub.
    You can get them easily, so can crackers
    Security:
    ★☆☆☆☆
    Cost:
    ★★★★★ (most of them are free)
    Performance:
    ★★☆☆☆

    View Slide

  61. Existing Solutions
    Zend Guard
    It's maintained by Zend Technology since 2021
    No active maintenance by the team
    Doesn't support PHP7, only PHP 4.2~PHP 5.6
    Security:
    ★★☆☆☆ (It's been cracked)
    Cost:
    ★★☆☆☆ (600 annually)
    Performance:
    ★★★★☆
    (https://github.com/tools2/zend-decoder)

    View Slide

  62. Existing Solutions
    Source Guardian
    Since 2002
    Active maintenance by the team
    Support for PHP5, PHP7 and PHP PHP8
    Obfuscations based on OpCodes
    Security:
    ★★★★☆ (Lower versions got cracked)
    Cost:
    ★★★★☆ (249 for fixed version)
    Performance:
    ★★★★☆
    (https://medium.com/tenable-techblog/dumping-php-opcodes-protected-by-sourceguardian-a0acd8058038)
    (https://github.com/clouds-flight/php7-vld-sg11-patch)

    View Slide

  63. Existing Solutions
    ionCube
    Since 2002
    Active maintenance by the team
    Support for PHP7.4, PHP8.1, and other legacy versions
    Obfuscations based on OpCodes
    Security:
    ★★★★☆ (Lower versions got cracked)
    Cost:
    ★★★★☆ (119~449 for fixed version)
    Performance:
    ★★★★☆
    (https://easytoyou.eu/decoder/demophp72)

    View Slide

  64. Existing Solutions
    Swoole Compiler
    Since 2019
    Active maintenance by the team
    Support for PHP 5.4^, PHP7.x, PHP8.x
    Obfuscations based on OpCodes
    Security:
    ★★★★★
    Cost:
    ★★★☆☆ (420 annually or 1365~7000 lifetime)
    Performance:
    ★★★★★

    View Slide

  65. There's no 100% secure protection
    AI
    搭把手,推倒 PHP
    加密源碼的高牆
    本次的演講將深入探討 PHP Zend Engine
    的執行流
    程,以及一種加密殼的運作方式。我們將分享我們
    如何解開這種加密殼,並訓練 AI
    進行反編譯工作,
    讓我們更有效地理解和分析惡意軟體的行為。
    李樸/
    官澔
    HITCON2023

    View Slide

  66. Q&A

    View Slide