The previous article Practical Restoration of PHP Encrypted Files mentioned that I discovered the shortcomings of the PHP encryption method, so I wrote this article.
Background analysis
As we all know, PHP is a scripting language. Scripting languages mainly use interpretation instead of compilation. So compared to compiled languages (C, C#, C++), it does not have the ability to directly generate exedll. Therefore, the traditional encryption method cannot be used.
So there are generally two encryption methods in PHP: obfuscation and encryption.
Obfuscation is not encryption in the strict sense. This kind of code is like the code that uses pinyin abbreviations to name variables, but it looks like you have worked harder. This is beyond the scope of our discussion.
Encryption is performed in two ways: one is with extension (Loader). The other is no extension.
First, let’s talk about the encryption method without expansion. This encryption method is very brainless, because its decryption process is public and requires the use of known PHP functions. The encrypted code is generally similar to the following:
<?phpeval(base64_decode("cGhwaW5mbygpOw=="));
Even the one that looks very complicated:
is just a variation of the above. This decryption form is very easy to crack if it is exposed. Just find eval and change it to echo.
The other extension method is more complicated. The function of the extension here is mainly to decrypt and execute the code. Compared with the non-extension form, it hides the decryption and execution code in the extension, so the cracking is more complicated.
The extensions here are generally divided into two types: 1. Those that provide decryption execution functions. 2. Directly overwrite zend_compile_file to implement the function of parsing custom php files.
The first and most typical example is the zoeeyguard mentioned in my last article, which mainly uses the zend_eval_string function to execute PHP code.
The second representative includes: Zend Guard and Song Ge’s php-beast.
It can be said that the two cracking ideas are similar. You can give priority to trying the ideas in my previous article.
Of course, what if I didn’t solve the problem in my previous article?
At this time, you need to use a big killer weapon.
You will find that I have been talking about the two functions zend_compile_file and zend_eval_string in the previous article. Some smart phpers have already thought of it, yes! The idea is still to find eval and change it to echo.
Practical examples
We can’t just talk without doing anything. Let’s take an example:
This time we’ll start with Brother Song’s php-beast. Brother Song's code is very beautifully written. Knowing that AES DES decryption takes time, he wrote a Cache.
1. Download the php source code package for Linux (it is best to choose one between 5.6 and 5.5. 7 is not supported. BTW: 7 has a lot of changes. Many things are not compatible. Zend Guard does not support 7 either. I took a detour here.)
2. Find the function in the file Zendzend_language_scanner.c: zend_op_array *compile_file(zend_file_handle *file_handle, int type TSRMLS_DC) which is about 500 lines long. Add the following code in front of it (the code is written It sucks, don’t complain):
ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type TSRMLS_DC) { zend_lex_state original_lex_state; zend_op_array *op_array = (zend_op_array *) emalloc(sizeof(zend_op_array)); zend_op_array *original_active_op_array = CG(active_op_array); zend_op_array *retval=NULL; int compiler_result; zend_bool compilation_successful=0; znode retval_znode; zend_bool original_in_compilation = CG(in_compilation); /** BEGIN **/ //加在这里的含义就是每次php编译php源码的时候都把这份源码打印一份 char *buf; size_t size; zend_stream_fixup(file_handle, &buf, &size); printf("\n#######\nFILE TYPE: %d FILE NAME: %s CONTENT: %s\n#######\n", (*file_handle).type, (*file_handle).filename, buf); /** END **/
Execute in the php folder:
//节省点时间 ./configure --disable-ipv6 --disable-all make make install
4. If everything goes well, PHP has been installed successfully.
5. We write two test files: the function is: test.php executes it to encrypt before.php to generate after.php.
//test.php <?php $path = __DIR__ . '/before.php'; $newPath = __DIR__ . '/after.php'; $result = beast_encode_file($path, $newPath, 0, BEAST_ENCRYPT_TYPE_DES); var_dump($result);
//before.php <?php print 'http://wx-app.com.cn/' . PHP_EOL;
7. Execute the following php test.php and then execute php after.php.
Look at the screenshots below:
Summary
1. There is no password that cannot be broken. All we can do is increase the cracking time. If the cracking time is greater than a person's lifespan, then this encryption method is definitely successful.
2. For encrypted programs, just as the cracker needs to understand and guess the writer's thinking, the writer also needs to understand the cracker's methods and means. Only in this way can we write programs that are more difficult to crack.
3. Compared with encryption, I think obfuscation is more suitable for "encryption" of PHP source code.
4. If you want to encrypt your PHP code and publish it, the best way is to increase the fee and provide the source code directly.