前些日子一个朋友丢了个shell给我,让我帮忙解密,打开源码看了下写着是 “神盾加密” , 牛逼闪闪的样子、百度下发现神盾是个很古老的东西,最后一次更新是在 20
其实网上早就有人分析过这个了,而且写成了工具、但是我测试了很多个,没一个能用,所以决定自己从头分析一遍。
打开神盾加密过后的源码,可以看到这样的代码
上面写着广告注释,而且不能删除,因为文件末尾有个md5效验码,以验证代码是否被修改过,,如图、
再仔细看代码部分,发现里面都是乱码,其实这都是障眼法,
它利用了php变量扩充到 latin1 字符范围,其变量匹配正则是 \$[a-zA-Z_\x7f-\xff][\w\x7f-\xff]* 这样的格式。
这个前几天天已经分析过了,最终也在官网找到了答案,请看《神盾加密解密教程(一)PHP变量可用字符》
有点扯远了,我们来做第一步解密处理吧。
PS: 这只是我的解密思路,与大家分享一下,也许你有更好的方法还望分享。。
复制代码 代码如下:
$str = file_get_contents("1.php");
// 第一步 替换所有变量
// 正则 \$[a-zA-Z_\x7f-\xff][\w\x7f-\xff]*
preg_match_all('|\$[a-zA-Z_\x7f-\xff][\w\x7f-\xff]*|', $str, $params) or die('err 0.');
$params = array_unique($params[0]); // 去重复
$replace = array();
$i = 1;
foreach ($params as $v) {
$replace[] = '$p' . $i;
tolog($v . ' => $p' . $i); // 记录到日志
$i++;
}
$str = str_replace($params, $replace, $str);
// 第二步 替换所有函数名
// 正则 function ([a-zA-Z_\x7f-\xff][\w\x7f-\xff]*)
preg_match_all('|function ([a-zA-Z_\x7f-\xff][\w\x7f-\xff]*)|', $str, $params) or die('err 0.');
$params = array_unique($params[1]); // 去重复
$replace = array();
$i = 1;
foreach ($params as $v) {
$replace[] = 'fun' . $i;
tolog($v . ' => fun' . $i); // 记录到日志
$i++;
}
$str = str_replace($params, $replace, $str);
// 第三步 替换所有不可显示字符
function tohex($m) {
$p = urlencode($m[0]); // 把所有不可见字符都转换为16进制、
$p = str_replace('%', '\x', $p);
$p = str_replace('+', ' ', $p); // urlencode 会吧 空格转换为 +
return $p;
}
$str = preg_replace_callback('|[\x00-\x08\x0e-\x1f\x7f-\xff]|s', "tohex", $str);
// 写到文件
file_put_contents("1_t1.php", $str);
function tolog($str) {
file_put_contents("replace_log.txt", $str . "\n", FILE_APPEND);
}
?>
(其中有一个记录到日志的代码,这个在之后的二次解密时有用。)
执行之后就会得到一个 1_t1.php 文件,打开文件看到类似这样的代码
找个工具格式化一下,我用的 phpstorm 自带了格式化功能,然后代码就清晰很多了。
进一步整理后得到如下代码:
复制代码 代码如下:
//Start code decryption<<===
if (!defined('IN_DECODE_82d1b9a966825e3524eb0ab6e9f21aa7')) {
define('\xA130\x8C', true);
function fun1($str, $flg="") {
if(!$flg) return(base64_decode($str));
$ret = '?';
for($i=0; $i
$ret .= $c<245 ? ( $c>136 ? chr($c/2) : $str[$i] ) : "";
}
return base64_decode($ret);
}
function fun2(&$p14)
{
全局 $p15, $p16, $p17, $p18, $p19, $p3;
@$p17($p18, $p19 . )没有 zekhzltcgkmaeii5kvfgQE5Puph/IGDZCLHFZ9TQL01IHLFNMNPODO9P2ZRQRQM7BFNFXYETD9508Y/Z6P '= ',' x9exa8a4xb4dx92xf0xb4x8ex8cxd8x9axf4xd61x9cxa8xc60x9ax f4xa4xd4xb2xf4x9a3x9axd4xceex9cxdaxb4xd2x9axf4x8a3x9cx8exaa = 'juztsomt9cf1q27qsy83wcslf08klocjuo5nsekwu7avmclct2l1kwcmzikkpmez Z/Ihyqdpgfrws58f Teni/Hz1ypuukzo6t 3brft8zuuz fjl6wr5gqyhi9rkots wk74yfgxh9Pv82 t5qt raw0ftbu1h5fha7jfx1nxgbcvrvtwk4nno6lgubvQu1vdqaid 3vnvace xFHjgoG/4ajKYqOeEHFEfcmeZLJvgXnUdOIAcfFO0pb9bUGIFjA3C jB7fCjtwFL0IqyfnezrCg0 QGl FcQxvajmRwNT9BTaRTDLQ9fbJwfkUZkZBPFcGTDdrAFIgVDhHiCptzwIy40ysojhotVHfy $p16($p15($p3)))', " 82d1b9a966825e3524eb0ab6e9f 21aa7");
}
}
全局 $p15、$p16、$p17、$p18、$p19、$p3;
$p17 = 'preg_replace';
$p18 = '/82d1b9a966825e3524eb0ab6e9f21aa7/ e';
$p15 = 'base64_decode';
$p19 = 'eval';
$p16 = 'gzuncompress';
$p3 = '';
@$p17($p18, $p19 252/dcexoWSV5y5SIHhy9hXkq3/oPPKO9WSUZoJaY09MuEZmJcQOTwcVnmfUmqqkpcmZFcpMVEWv2E Vp795Q4BEJK4Hj93NzBwjEUigemb2JsKB' $p15(fun1(' xB21xC65xC8A==','x9 = ')))。 )))', "82d1b9a966825e3524eb0ab6e9f21aa7" xCB)
vnqhBNLREkvC0jozYmvTWMZyoxjCa9KTUsvSaM5rUzu6c2rTSmvSKM5yOqj0=关闭 0fae860b50010
不是很清楚了,剩下的就是基本代码了,还有个知识点 preg_replace 当正则修饰符含有的时候
$ p18 变量里就是那个正则,构成的 e 在闪闪发光。
剩下的我懒得写了,因为所有解密用到的知识我都已经说了、
??? 🎜>不是我装逼或者是炫耀,因为授之以鱼不如授之以api也一样的,对吧。