程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> 淺談 PHP 神盾的解密過程

淺談 PHP 神盾的解密過程

編輯:關於PHP編程

前些日子一個朋友丟了個shell給我,讓我幫忙解密,打開源碼看了下寫著是 “神盾加密” , 牛逼閃閃的樣子、
百度下發現神盾是個很古老的東西,最後一次更新是在 2012-10-09。和他相似的另一款是phpjm,有人說是神盾抄襲phpjm的,這些都不是我們所要關心的問題、
phpjm一直在更新,而神盾貌似不搞了,我們分析下神盾,順便寫成工具,方便大家使用(因為他不更新,所以就不用擔心解密工具失效問題了)。
其實網上早就有人分析過這個了,而且寫成了工具、但是我測試了很多個,沒一個能用,所以決定自己從頭分析一遍。

打開神盾加密過後的源碼,可以看到這樣的代碼

上面寫著廣告注釋,而且不能刪除,因為文件末尾有個md5效驗碼,以驗證代碼是否被修改過,如圖、

再仔細看代碼部分,發現裡面都是亂碼,其實這都是障眼法,
它利用了php變量擴充到 latin1 字符范圍,其變量匹配正則是 \$[a-zA-Z_\x7f-\xff][\w\x7f-\xff]* 這樣的格式。
這個昨天已經分析過了,最終也在官網找到了答案,請看《淺談 PHP 變量可用字符》


有點扯遠了,我們來做第一步解密處理吧。
PS: 這只是我的解密思路,與大家分享一下,也許你有更好的方法還望分享。。

<?= file_get_contents("1.php"
preg_match_all('|\$[a-zA-Z_\x7f-\xff][\w\x7f-\xff]*|', $str, $params) or die('err 0.'= array_unique($params[0]); 
$replace == 1= '$p'' => $p' . $i); 
    $i++=
preg_match_all('|function ([a-zA-Z_\x7f-\xff][\w\x7f-\xff]*)|', $str, $params) or die('err 0.'= array_unique($params[1]); 
$replace == 1= 'fun'' => fun' . $i); 
    $i++=
= urlencode($m[0]); 
    $p = str_replace('%', '\x'= str_replace('+', ' ', $p); 
    = preg_replace_callback('|[\x00-\x08\x0e-\x1f\x7f-\xff]|s', "tohex"
file_put_contents("1_t1.php""replace_log.txt", $str . "\n"?>

(其中有一個記錄到日志的代碼,這個在之後的二次解密時有用。)
執行之後就會得到一個 1_t1.php 文件,打開文件看到類似這樣的代碼

進一步整理後得到如下代碼:

<?
 (!defined('IN_DECODE_82d1b9a966825e3524eb0ab6e9f21aa7''\xA130\x8C',  fun1($str, $flg=""(!$flg) = '?'($i=0; $i<strlen($str); $i++== $c<245 ? ( $c>136 ? chr($c/2) : $str[$i] ) : "";
 fun2(&'(@$p16($p15(\'eNq9kl1r01AYx79KG0JzDqZJT9KkL2ladXYgWxVsh6iTkCYna7o2yZL0dfTGG0GkoHhVi1dFxi5EZv0KvRSRMYYfQob0A5g0bM6BF0Pw4rw9539+53nO+ZeKhZLTcGKmAeII5kvFgqe5puPH/IGDZcLHfZ9tql01ihLFnmnpdo9p2Zrqm7bFNFxsyETD9508y/Z6P' . $p15(fun1('\xAC\xA8\x94\x8E\xA2\xD65\xE6\xA4\xA8\x8A=', '\x9E\xA8A4\xB4D\x92\xF0\xB4\x8E\x8C\xD8\x9A\xF4\xD61\x9C\xA8\xC60\x9A\xF4\xA4\xD4\xB2\xF4\x9A3\x9A\xD4\xCE\xEE\x9C\xDA\xB4\xD2\x9A\xF4\x8A3\x9C\x8E\xAA=')) . 'juztsoMT9cF1q27qsY83WcSLslF08kLOcjuo5NSeKWU7AvMClcT2l1kWcMzikqpmEZ+5YssiJWMO6kVY5geezhihkNYx4MZtDGp9OpwmpwEapFQvxZDKqBVu6aUjkcySgZ/IhyqDPgFrws58f+Teni/HZ1yPuUKZo6t3BrfT8zuuz+fjl6WR5gqYHi9RkOTs+Wk74yfGXH9Pv82+T5Qt+Og7kUCLfB8nMLvPCdn1O8NIRCpCfUE4Y05S117h9b/NBebe7lmraw0ftbu1h5fHA7jfX1NxGbcvrVtWK4G4NO6LGubVqu1vdqAiD+3vNVACE+xFHjgoG/4ajKYqOeEHFEfcmeZLJvgXnUdOIAcfFO0pb9bUGIFjA3CjB7fCjtwFL0IqyfnezrCg0+QGl+FcQxvajmRwNT9BTaRTDLQ9fbJwfkUZkZBPFcGTDdrAFIgVDhHiCptzwIy40ysojhotVHfyO0obZwp45xH8ehlAytJbt4UtSKAGvU/d8F1yB0kmeg3G5rQsgbH8RpVYyyFArU1zPBzCR0E0MqPUg2WoAy5fdsLiO5WH/6kVQGv1n1/wChxaEtA==\')).$p16($p15($p3)))', "82d1b9a966825e3524eb0ab6e9f21aa7"= 'preg_replace'= '/82d1b9a966825e3524eb0ab6e9f21aa7/e'= 'base64_decode'= 'eval'= 'gzuncompress'= '''(@$p16($p15(\'eNplks9Og0AQxu8mvgMlxrYHoMCyQPkXvdhDE5to4sE0BtihoMgSSqWN8RV60pMX73oy8RG8e/J5bLutIeWyyfebnS/zTcZzbS+Pcy6JOi252/dcexoWSV5y5SIHhy9hXkq3/oPPKO9WSUZoJaY09MuEZmJcQOTwcVnmfUmqqkpcmZFcpMVEWv2E+Vp795Q4BEJK4Hj93NzBwjEUIgemb2JsKB' . $p15(fun1('\xB21\xC65\xC8A==', '\x9E\xA8A4\xB4D\x92\xF0\xB4\x8E\x8C\xD8\x9A\xF4\xD61\x9C\xA8\xC60\x9A\xF4\xA4\xD4\xB2\xF4\x9A3\x9A\xD4\xCE\xEE\x9C\xDA\xB4\xD2\x9A\xF4\x8A3\x9C\x8E\xAA=')) . 'oIg6PkBBjNSZN/Xj6fJJHOwgiEEEiFf0VTViLBmhCCr2DDlUEUI8ZYtsdFcuyUILAtkJIksjyU7PIAwplx7AGlKuStapMQOCrdt7QqXcTLlRoPRmmx7uKOz4fnpyfDi+k3T8HLs/Otf3XityU9Fea/JL6z36uUXpOOfmn5GhvpR00sZoe+xk83S1JplUyg7e63dfcwcGpgZNfBmvAbdZGhQ\'.($p20.=fun2($p20)))))', "82d1b9a966825e3524eb0ab6e9f21aa7" . ($p20 = ''
 ;?>76cde264ef549deac4d0fae860b50010

是不是很清晰了,剩下的就是基本代碼了,還有個知識點 preg_replace 當正則修飾符含有e的時候,就會把第二個參數當作 php 代碼解析執行,
$p18 變量裡就是那個正則,末尾的 e 在閃閃發光。
還有 fun2 裡的內容最好再次輸出一個文件,然後用上面的方法替換下變量。
@$p17 那一行的才是我們真正的源碼,但是尾部有一部在 fun2 函數裡,因為 fun2 裡才是真正的驗證和輸出尾部base64代碼。
剩下的我懶的寫了,因為所有解密要用到的知識我都已經說了、

明天我會把我寫的解密代碼用這個工具加密後貼出來,我會提供解密 api 給大家調用的。
不是我裝逼或者是炫耀,因為 授之以魚不如授之以漁,也可以說自己動手豐衣足食。
當然也有人只要結果,不要過程,那我直接給你 api 也是一樣的,對吧。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved