78模板网分享cms建站教程,提供网站模板、网站插件、办公模板等模板教程免费学习,找模板教程就上78模板网!

phpjm php加密的解密过程,phpjmphp加密解密

phpjm php加密的解密过程,phpjmphp加密解密

前言

最近接手一套系统,安装后发现不能运行,被告知必须修改hosts绑定域名才能执行,怒,这怎么可以?暴力开心它。

准备篇

看了一下用的是phpjm.net的加密。

其实还是挺简单的,主要是利用了php变量名和数组索引名支持特殊字符,准确的来说是:

$[a-zA-Z_x7f-xff][a-zA-Z0-9_x7f-xff]*

phpjm就是把里面的变量名弄成乱码,然后再使用base64和gzcompress经过数次加密。

手动分析

先把乱码都替换成稍微正常一点的东西,至少能让人明白是啥玩意。

<?

/**

 *Author: 塞北的雪

 *Website:http://blog.csdn.net/sbdx

*/

$filename='文件名';

$str = file_get_contents("$filename.php");

function tolog($str)

{

    file_put_contents("replace_log.txt", $str . "n", FILE_APPEND);

}

preg_match_all('|$[a-zA-Z_x7f-xff][wx7f-xff]*|', $str, $params) or die('err 1.');

$params = array_unique($params[0]); // 去重复

$replace = array();

$i = 1;

foreach ($params as $k=>$v)

{

    if(preg_match('/$[a-zA-Z_]+/',$v,$re))//过滤掉正常的英文变量名

    {

        unset($params[$k]); continue;

    }

    $replace[] = '$p'.$i;

    tolog($v . ' => $p' . $i); // 记录到日志

    $i++;

}

$str = str_replace($params, $replace, $str);

// 第二步 替换所有函数名

// 正则 function ([a-zA-Z_x7f-xff][wx7f-xff]*)

preg_match_all('|function ([a-zA-Z_x7f-xff][wx7f-xff]*)|', $str, $params) or die('err 2.');

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

// 第三步 替换所有不可显示字符,可选,如果转义后则不能用decode函数解码了

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-x08x0e-x1fx7f-xff]|s', "tohex", $str);

*/

// 写到文件

$str=str_replace(';',";rn",$str);

$filename++;

file_put_contents($filename."_2.php", $str);

echo 'Done.';

解密变量名的函数:

<?php

/**

 *Author: 塞北的雪

 *Website:http://blog.csdn.net/sbdx

*/

function fun1($p2, $p3 = "")

{

    $p2 = base64_decode($p2);

    if (empty($p2)) return "";

    if ($p3 == "")

    {

        return ~$p2;

    }

    else

    {

        $p4 = base64_decode($p2);

        $p3 = str_pad($p3, 1000, $p3);

        return $p2 ^ $p3;

    }

}

代码的最后会有一串eval执行的一串很长的代码,这个就是下一次要分析的字符串了,如此重复数次就能得到源码了。

自动分析篇

auto_decode v1.1

<?php

/**

 *Author: 塞北的雪

 *Website:http://blog.csdn.net/sbdx

*/

    $filename='sssssssssssssssssss.php';

    $counter=0; 

    function fun1($p2, $p3 = "")

    {

        $p2 = base64_decode($p2);

        if (empty($p2)) return "";

        if ($p3 == "")

        {

            return ~$p2;

        }

        else

        {

            $p3 = str_pad($p3, 1000, $p3);

            return $p2 ^ $p3;

        }

    }

    function decode($str)

    {

        global $counter;

        $debase=base64_decode($str);

        if($debase{0}=='$' or $debase{0}==';')

        {

            echo '使用 base64_decode()<br>';

            return $debase;

        }

        $source=@gzuncompress($debase);

        if($source!==false)

        {

            echo '使用 gzuncompress(base64_decode())<br>';

            return $source;

        }

        $source=@fun1($debase);

        if($source!='')

        {

            echo '使用 fun1(base64_decode())<br>';

            return $source;

        }

        die('第 '.$counter.' 次解密失败!');

    }

    $str=file_get_contents($filename);

    for($i=1;$i<=8;$i++)

    {

        if(stripos($str,'Access Denied')!==FALSE){die("解密完成,请查看 auto_$counter.php");}

        $counter++;

        echo '第 '.$counter.' 次解密开始!<br>'; 

        //echo '原始字串:'.$str;

        preg_match_all("#(?<='](').+?(?=')#",$str,$re);

        $code=$re[0][count($re[0])-1];

        //echo '提取字串:'.$code.'<br>';

        $str=decode($code);

        //echo '解密字串:'.$str.'<hr>';

        $str=str_replace(';',";rn",$str);

        file_put_contents("auto_$counter.php",$str);

    }

auto_decode v2

发现上个版本有的文件解不了,又重写了一个版本,这次

<?php

$source=file_get_contents('weixin.templatemessage.php');

$level=1;

function decode($p1, $p2 = "")

{

    $p1 = base64_decode($p1);

    if (empty($p1))  return "";

    if ($p2 == "")

    {

        return ~$p1;

    }

    else

    {

        $p4 = strlen($p1);

        $p2 = str_pad($p2, $p4, $p2);

        return $p1 ^ $p2;

    }

}

function crack($source)

{

    global $level;

    preg_match_all("#eval.*('(.+?)'#i",$source,$re);

    $str=$re[1][0];

    $s=@base64_decode($str);

    if(false===$s)

    {

        $s=decode($str);

    }

    if(@gzuncompress($s)!==false)

    {

        $s=gzuncompress($s);

    }

    if(stripos($s,'$')===false)

    {

        if(@gzuncompress($s)!==false)

        {

            $s=gzuncompress($s);

        }

        elseif(preg_match('#[^a-zA-Z+-=]#i',$s))

        {

            $s=decode($s);

        }

        else

        {

            $s=base64_decode(s);

        }

    }

    //file_put_contents($level.'.txt',$s);

    $level++;

    return $s;

}

//5轮循环,如果不够再增加次数,最后一次关键字unset

for($i=1;$i<=5;$i++)

{

    $source=crack($source);

}

echo $source.'<br>';

解密完后里面还是会有点垃圾代码,大家清理掉就可以了。我懒得再用正则写了。

总结

正则是个好东西。

本文链接:http://78moban.cn/post/10346.html

版权声明:站内所有文章皆来自网络转载,只供模板演示使用,并无任何其它意义!

联系技术
文章删除 友链合作 技术交流群
1050177837
公众号
公众号
公众号
返回顶部