preface

PHP is an interpreted scripting language. Unlike compiled languages, PHP source code is not translated directly into machine language. Instead, it is translated into intermediate code (OPCODE), which is then interpreted and run by the interpreter (ZEND engine).

The principles of PHP source code protection can be divided into three broad categories.

  • Source code confusion (encoding)
  • OPCODE confusion (encoding)
  • Description Engine (VM)

The deployment can be divided into two categories.

  • No extension
  • There are extensions

The following analysis of the implementation of various encryption schemes

PHP encryption scheme analysis

No extension scheme

Source code confusion

Unextended encryption is common among small developers. This source code protection method is less intrusive, does not need to do additional configuration to the server, and is highly compatible.

In this case, the source code restoration after obfuscation is very simple and can be completely restored. Sometimes even comments are retained (x I don’t think this confusion can be called encryption basic flow compression code -> confuse variable function class name -> Use simple functions and methods to encode encryption example: Base64 XOR

[Click to view information] or private reply to “information” to obtain

Manual decryption

See this PHP do not panic this decryption process after the processing of variables and function names using a large number of non-print characters according to the normal process can be CTRL + Alt + L shortcut formatting code (here use PhpStorm other IDE formatting encountered special symbols may have problems This is pre-coded.)

There is a PHP feature that will ignore characters in a table other than base64 in PHP without affecting decoding. PHP7 May throw an error when it encounters null characters and you can do this with PHP5.6 (there is a compatibility issue here). The easiest way to do this is to find the function that was executed last in the file and print it out. The last step in this method of encoding is always to use eval to execute the restored PHP code So printing the last function basically gives the PHP code all the way out (x). Note: Some protection schemes also use call_user_func or call_user_func_array to call eval indirectly

Successfully restored source code

Automated universal decryption

PHP provides powerful extensions to hook eval. Hook Zend engine zend_compile_string zend_include_or_eval can be used to fetch the source code This is the hook zend_compile_string function

/* $Id$ */ #include "php.h" #include "ext/standard/info.h" static zend_op_array * ( * old_compile_string )( zval * source_string , char * filename TSRMLS_DC ); static zend_op_array * evalhook_compile_string ( zval * source_string , char * filename TSRMLS_DC ) { if ( strstr ( filename , "eval()'d code" )) { printf ( "\n------eval-------\n%s\n------eval-------\n" , Z_STRVAL_P ( source_string )); } return old_compile_string ( source_string , filename TSRMLS_CC ); } PHP_MINIT_FUNCTION ( evalhook ) { return SUCCESS ; } PHP_MSHUTDOWN_FUNCTION ( evalhook ) { return SUCCESS ; } PHP_RINIT_FUNCTION ( evalhook ) { old_compile_string = zend_compile_string ; zend_compile_string = evalhook_compile_string ; return SUCCESS ; } PHP_RSHUTDOWN_FUNCTION ( evalhook ) { zend_compile_string = old_compile_string ; return SUCCESS ; } PHP_MINFO_FUNCTION ( evalhook ) { php_info_print_table_start (); php_info_print_table_row ( 2 , "eval hooking" , "enabled" ); php_info_print_table_end (); } zend_function_entry evalhook_functions [] = { ZEND_FE_END }; zend_module_entry evalhook_module_entry = { STANDARD_MODULE_HEADER , "evalhook" , evalhook_functions , PHP_MINIT ( evalhook ), PHP_MSHUTDOWN ( evalhook ), PHP_RINIT ( evalhook ), PHP_RSHUTDOWN ( evalhook ), PHP_MINFO (evalhook), "0.1-dev", STANDARD_MODULE_PROPERTIES}; ZEND_GET_MODULE ( evalhook )Copy the code

Successfully restored source code

PHP Extension

Source code confusion

Code obfuscation with PHP extensions is similar to code obfuscation without extensions, except that the code restoration process is shifted from PHP code to PHP extensions. Also, aes DES xor encryption is used to encrypt PHP code directly. HOOK translation PHP functions decrypt PHP files before translating them. This scheme can also fully restore the source code. Comments are even retained when there is no other obfuscation or compression.

Manual decryption

Take the Beast as an example. So the beast encryption scheme compiles the encryption key into the extension. All we need to do is look for the key to decrypt the Beast because it’s an open source project. There are already symbol tables and source code that make decompiling to find keys very easy. But that’s a little too easy. So here is a demonstration of using IDA analysis decryption without source code.

Zend_compile_file will translate PHP files into opcode, so most PHP encryption extensions need hook to intercept PHP file loads and replace PHP files

Following along, there are two functions that normally operate on this function twice in the design of this PHP encryption extension: one that hooks the function at startup and one that restores the function at stop. Continue following the launch hook

Obviously file processing logic is in cgi_compile_file

The argument to the decrypt_file function that tracks the file handle exists in the file handle so it should be a file decryption function

According to the code can be seen that the structure of the beast encrypted file | encrypt_file_header_sign file header tags (not fixed can modify) | reallen file length int 4 bytes | expire due time int 4 bytes | entype encryption Int 4 bytes | | encrypted files

After analyzing the file header, the encryption mode of the file is 02

With the beast_get_encrypt_algo

2 corresponds to AES_handler_OPS

AES 128 ECB encryption mode is used to directly extract the key parameter content length of just 16 bits

At this point, we’ve got the encryption key

Use the KEY to decrypt the PHP file

Automated universal decryption

Write the PHP extension HOOK zend_compile_file

Beast encryption does no extra work on the PHP file decrypting the file is exactly the same as the original file before encryption PHP comments and the original format are preserved note: Zendzend_language_scanner. C ZEND_API zend_op_array *compile_file

opcode

PHP translates the source code into a compile-like binary intermediate opcode that the Zend engine executes. The previous sections covered direct manipulation of the PHP source code before compilation. Here is the opcode operation, skip the translation process, directly to the Existing Opcode zend engine execution (opcode compiled by different versions of PHP engine may have compatibility issues). This PHP code protection method can only hook zend_execute to get opcode. It is impossible to get the original source directly, only through decompilation as much as possible to restore the source code. Zendguard (Zend) _SourceGuardian(SG) IonCube (IC) Swoole Compiler is the basis for most commercial PHP protection schemes. The translated Opcode can only be executed on the modified engine, further enhancing security.

VAT code

Mysql > hook zend_execute to get opcode and use the corresponding version of PHP opcode to push back the PHP code.

Private reply to “Information” for the following:

1. More than 200 e-books of network security series

2. Complete kit

3. 100 COPIES of SRC source code technical documents

4, network security basic introduction, Linux, Web security, attack and defense video

6, network security learning route

7. CTF flag capture contest analysis

The appendix

PHP Extension compilation

Docker run it --rm -v/MNT/HGFS/TMPSSD /php-eval-hook/:/ext/ PHP :5.6 /bin/bash apt-get update apt install libtoolCopy the code
phpize
Copy the code

Phpize generated Makefile

./configure --enable-evalhook
Copy the code

Configure compilation options to enable extensions

The compiled extension will be put into the./modules/ directory to use the extension

PHP -d extension= extension location -f fileCopy the code

You can load multiple extensions repeatedly using -d Extension

conclusion

When choosing PHP source protection options, choose either OpCode or virtual machine source obfuscations. Source obfuscations only add a bit of difficulty in obtaining and reading source code, and do not protect against encrypted extensions that can be accessed by attackers