强智教务JAVA/PHP模拟登录 密码JavaScript脚本encodeInp()加密算法破解

一:背景

强智教务系统

  • 在模拟登录强智教务系统时,遇到了用户名和密码被JS进行加密提交的问题,加密JavaScript代码如下:

function submitForm1() {
    try {
        var xh = document.getElementById("userAccount").value;
        var pwd = document.getElementById("userPassword").value;
        if (xh == "") {
            alert("用户名不能为空!");
            return false;
        }
        if (pwd == "") {
            alert("密码不能为空!");
            return false;
        }
        var account = encodeInp(xh);
        var passwd = encodeInp(pwd);
        var encoded = account + "%%%" + passwd;
        document.getElementById("encoded").value = encoded;
        var jzmmid = document.getElementById("Form1").jzmmid;
        return true;
    } catch (e) {
        alert(e.Message);
        return false;
    }
}

二:Javascript加密分析

  • 我们首先需要获得该JS加密函数,强智教务的加密算法在 conwork.js里,代码如下:
eval(function (p, a, c, k, e, d) {
    e = function (c) {
        return (c < a ? "" : e(parseInt(c / a))) + ((c = c % a) > 35 ? String.fromCharCode(c + 29) : c.toString(36))
    };
    if (!''.replace(/^/, String)) {
        while (c--)d[e(c)] = k[c] || e(c);
        k = [function (e) {
            return d[e]
        }];
        e = function () {
            return '\\w+'
        };
        c = 1;
    }
    ;
    while (c--)if (k[c]) p = p.replace(new RegExp('\\b' + e(c) + '\\b', 'g'), k[c]);
    return p;
}('b 9="o+/=";p q(a){b e="";b 8,5,7="";b f,g,c,1="";b i=0;m{8=a.h(i++);5=a.h(i++);7=a.h(i++);f=8>>2;g=((8&3)<<4)|(5>>4);c=((5&s)<<2)|(7>>6);1=7&t;k(j(5)){c=1=l}v k(j(7)){1=l}e=e+9.d(f)+9.d(g)+9.d(c)+9.d(1);8=5=7="";f=g=c=1=""}u(i<a.n);r e}', 32, 32, '|enc4||||chr2||chr3|chr1|keyStr|input|var|enc3|charAt|output|enc1|enc2|charCodeAt||isNaN|if|64|do|length|ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789|function|encodeInp|return|15|63|while|else'.split('|'), 0, {}))
  • 可能对js不是很熟的人,看这个也很难看明白,下面我整理成了通用写法,代码如下:
var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

function encodeInp(input) {
    var output = "";
    var chr1, chr2, chr3 = "";
    var enc1, enc2, enc3, enc4 = "";
    var i = 0;
    do {
        chr1 = input.charCodeAt(i++);
        chr2 = input.charCodeAt(i++);
        chr3 = input.charCodeAt(i++);
        enc1 = chr1 >> 2;
        enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
        enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
        enc4 = chr3 & 63;
        if (isNaN(chr2)) {
            enc3 = enc4 = 64
        } else if (isNaN(chr3)) {
            enc4 = 64
        }
        output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) + keyStr.charAt(enc3) + keyStr.charAt(enc4);
        chr1 = chr2 = chr3 = "";
        enc1 = enc2 = enc3 = enc4 = ""
    } while (i < input.length);
    return output
}

三:JAVA实现(Java执行JavaScript脚本方法)

  • 新建一个接口,内部实现和JS函数名相同的抽象方法:
  • Methods.java
public interface Methods {
    public String encodeInp(String input);
}
  • Java执行JavaScript函数破解加密算法 ;
    /**
     *  Java执行JavaScript脚本破解加密算法
     * @param str
     * @return 加密后的字符串
     */
    public String playJs(String str) {
        // 创建一个脚本引擎管理器
        ScriptEngineManager manager = new ScriptEngineManager();
        // 获取一个指定的名称的脚本引擎
        ScriptEngine engine = manager.getEngineByName("js");
        try {
            // 获取当前类的所在目录的路径(%20是处理空格)
            String path = JsoupCookie.class.getResource("/").getPath().replaceAll("%20", " ");
            // FileReader的参数为所要执行的js文件的路径(对空格进行处理)
            engine.eval(new FileReader(path + "conwork.js"));
            if (engine instanceof Invocable) {
                Invocable invocable = (Invocable) engine;
                // 从脚本引擎中返回一个给定接口的实现
                Methods executeMethod = invocable.getInterface(Methods.class);
                // 执行指定的js方法
                return executeMethod.encodeInp(str);
            }
        } catch (Exception e) {
            // e.printStackTrace();
        }
        return null;
    }

四:PHP实现(根据Javascript的encodeInp()算法原理编写)

// 模拟js的charCodeAt()方法
function charCodeAt($str, $index)
{
    $char = mb_substr($str, $index, 1, 'UTF-8');
    if ($char!=='' && mb_check_encoding($char, 'UTF-8'))
    {
        $ret = mb_convert_encoding($char, 'UTF-32BE', 'UTF-8');
        return hexdec(bin2hex($ret));
    } else {
        return null;
    }
}

// 加密方法
function encodeInp($input)
{
    $keyStr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
    $output = '';
    $i = 0;
    do {
        $chr1 = charCodeAt($input, $i++);
        var_dump($chr1);
        $chr2 = charCodeAt($input, $i++);
        $chr3 = charCodeAt($input, $i++);
        $enc1 = $chr1 >> 2;
        $enc2 = (($chr1 & 3) << 4) | ($chr2 >> 4);
        $enc3 = (($chr2 & 15) << 2) | ($chr3 >> 6);
        $enc4 = $chr3 & 63;
        if ($chr2 === null) {
            $enc3 = $enc4 = 64;
        } else if ($chr3 == null) {
            $enc4 = 64;
        }
        $output = $output . $keyStr[$enc1] . $keyStr[$enc2] . $keyStr[$enc3] . $keyStr[$enc4];
    } while ($i < strlen($input));
    return $output;
}

echo encodeInp('a123456');

最后: encoded = encodeInp($account) .'%%%' .encodeInp($passwd);

发布了284 篇原创文章 · 获赞 258 · 访问量 121万+

猜你喜欢

转载自blog.csdn.net/meimeieee/article/details/91352214
今日推荐