Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

Slido #1421565 https://sli.do

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

eval Eval a string as PHP code Source Code Encoding

Slide 9

Slide 9 text

eval used with multiple encoding functions Source Code Encoding

Slide 10

Slide 10 text

Encoding functions base64_encode gzinflate str_rot13 gzcompress gzencode pack Source Code Encoding

Slide 11

Slide 11 text

Execution functions eval assert call_user_func call_user_func_array create_function Source Code Encoding

Slide 12

Slide 12 text

PHPFuck Source Code Encoding

Slide 13

Slide 13 text

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)

Slide 14

Slide 14 text

PHPFuck Variable Function Weak Type Conversion Source Code Encoding

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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') );

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

Dictionary Obfuscation Replace specific characters with dictionary mapping Source Code Encoding

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

Obfuscate from AST Source Code Obfuscation

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

Control Flow Confusion Source Code Obfuscation

Slide 33

Slide 33 text

Control Flow Confusion (goto) Source Code Obfuscation

Slide 34

Slide 34 text

Polymorphic Variation Source Code Obfuscation

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

OpCode in PHP OPCode Definitions

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

OpCode in PHP Dump OPCodes

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

OpCache in PHP Compile PHP files to opcache files

Slide 45

Slide 45 text

OpCache in PHP Compile PHP files to opcache files

Slide 46

Slide 46 text

OpCache in PHP Metainfo of OPCache

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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)

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

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

Slide 57

Slide 57 text

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)

Slide 58

Slide 58 text

PHP Extension Demo of Zephir

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

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: ★★☆☆☆

Slide 61

Slide 61 text

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)

Slide 62

Slide 62 text

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)

Slide 63

Slide 63 text

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)

Slide 64

Slide 64 text

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: ★★★★★

Slide 65

Slide 65 text

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

Slide 66

Slide 66 text

Q&A