JS逆向|使用express框架开启服务并替换加密字符串

在阅读本文之前请确保电脑已安装好Node.js.

express,根据其Github上的描述,是一个:
Fast, unopinionated, minimalist web framework for node.
其Github地址:https://github.com/expressjs/express
根据其Readme文档,安装:
npm install express
保存演示code:

const express = require('express')
const app = express()
 
 
app.get('/', function (req, res) {
  res.send('Hello World')
})
 
 
app.listen(3000)

然后运行(控制台下输入node xxx.js),并打开浏览器,输入:

http://127.0.0.1:3000/

并回车,得到浏览器上的结果:


image.png

当然,这仅仅是个简单的例子,还需要了解function (req, res)的用途,上面的代码稍微改一下:

app.get('/', function (req, res) {
console.log(req.query); //只增加这一行,看看打印结果
res.send('Hello World')
})
在浏览器上输入如下URL,并回车:

http://127.0.0.1:3000/?sign=123456

查看命令行下的结果:


image.png

这样就清楚了,直接构造参数,然后用res.send返回结果。

继续沿用上一篇文章的代码,将 大数组 + 位移函数 + 解密函数的代码添加进来,并构造参数,如下

const express = require('express')
const app = express()
 
 
var _0x2075 = ['wrw3EMKc', 'BBdBHWk=', 'wplgd8O5dHbDtFfDucK9CsOS', 'f8KvAcKewoDClg==', 'XcKowo9uOyfChw==', 'XcKowpRzOzDCgMKuw5vCtH8=', 'HmQkw5vDt8OIBDbCpMKdw6Aaw7HDmcKb', 'wpxzdMO4', 'R8KHF1k1w5A=', 'w4LDgcOowrjDhg==', 'w6RKw6PCmVDDpw==', 'w6DDgsKrCsK5wqAwKsOMTkPDilwgB241RVBIw6rCvwpWw5fCo8OSw59pBcK7UlrCucOZHy7DgsO5wpx5J8K5wqbCtMOMwqvCsiUFw5s4JGfDmwQPw7Fawq3CgXlkJyE=', 'VcObYsOHKcKpwpI=', 'KkZfcE52w77ChsKgUQ==', 'CmQsw57DvA==', 'YV7CscOYZg==', 'w5jDt8OUwr46w5c6LsKEPsO0', 'F8OUMQhRw78Q', 'YMKzeTvCpMKzHcKKGSjCj2dJwq3Cj3/ChsKSFVpMw4sZwrg9H8OLw4/DqUlhYlpaa8KYJsO5AcK2wqnCmGhEwqkbdMKKLsO/wpBFMcKlC8OvKUkXZ8KpBsOxw4XDk8K5w4Y6w7VZO8K/wojCqcO2wqQow5Z+w6dew7I3TMObw6Ykw7I=', 'Mk8Bw6QawqU=', 'wo5zw4vCkxvDuSBqwoENw7rCrF3DksKewoPDqMKHNSzCgcK2fcKxPMKbGcKwCW5GZWRpw6fDmgHCjXrCnXE3w4zDqlt3w64lw7JiworDi8Knw5YoW1LDlUbDpkEtGQPDnw==', 'w6lvdMKW', 'w7JFdsOhwrBqwrlMYcKVJRjCuMKQwpLDtMONwprCsMORw4BtRV0oeEQPCgAmMgx2'];
(function(_0xf486e7, _0x2075d7) {
    var _0x5c3a18 = function(_0x5b65b1) {
        while (--_0x5b65b1) {
            _0xf486e7['push'](_0xf486e7['shift']());
        }
    };
    _0x5c3a18(++_0x2075d7);
}(_0x2075, 0xa4));
var _0x5c3a = function(_0xf486e7, _0x2075d7) {
    _0xf486e7 = _0xf486e7 - 0x0;
    var _0x5c3a18 = _0x2075[_0xf486e7];
    if (_0x5c3a['vEVEZj'] === undefined) {
        (function() {
            var _0x2e1ca4;
            try {
                var _0x28e173 = Function('return\x20(function()\x20' + '{}.constructor(\x22return\x20this\x22)(\x20)' + ');');
                _0x2e1ca4 = _0x28e173();
            } catch (_0x16acc9) {
                _0x2e1ca4 = window;
            }
            var _0x16f958 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
            _0x2e1ca4['atob'] || (_0x2e1ca4['atob'] = function(_0x5a7812) {
                var _0x3c7e74 = String(_0x5a7812)['replace'](/=+$/, '');
                var _0x5e030c = '';
                for (var _0x4eaee2 = 0x0, _0x5954ef, _0x29200e, _0x5a128b = 0x0; _0x29200e = _0x3c7e74['charAt'](_0x5a128b++); ~_0x29200e && (_0x5954ef = _0x4eaee2 % 0x4 ? _0x5954ef * 0x40 + _0x29200e : _0x29200e,
                _0x4eaee2++ % 0x4) ? _0x5e030c += String['fromCharCode'](0xff & _0x5954ef >> (-0x2 * _0x4eaee2 & 0x6)) : 0x0) {
                    _0x29200e = _0x16f958['indexOf'](_0x29200e);
                }
                return _0x5e030c;
            }
            );
        }());
        var _0x3acf89 = function(_0x593a19, _0xfee22e) {
            var _0x1b5349 = [], _0x4ddb21 = 0x0, _0x28ed27, _0x4b4996 = '', _0xbdd0c6 = '';
            _0x593a19 = atob(_0x593a19);
            for (var _0x1d6343 = 0x0, _0x3f947e = _0x593a19['length']; _0x1d6343 < _0x3f947e; _0x1d6343++) {
                _0xbdd0c6 += '%' + ('00' + _0x593a19['charCodeAt'](_0x1d6343)['toString'](0x10))['slice'](-0x2);
            }
            _0x593a19 = decodeURIComponent(_0xbdd0c6);
            var _0x1a120c;
            for (_0x1a120c = 0x0; _0x1a120c < 0x100; _0x1a120c++) {
                _0x1b5349[_0x1a120c] = _0x1a120c;
            }
            for (_0x1a120c = 0x0; _0x1a120c < 0x100; _0x1a120c++) {
                _0x4ddb21 = (_0x4ddb21 + _0x1b5349[_0x1a120c] + _0xfee22e['charCodeAt'](_0x1a120c % _0xfee22e['length'])) % 0x100;
                _0x28ed27 = _0x1b5349[_0x1a120c];
                _0x1b5349[_0x1a120c] = _0x1b5349[_0x4ddb21];
                _0x1b5349[_0x4ddb21] = _0x28ed27;
            }
            _0x1a120c = 0x0;
            _0x4ddb21 = 0x0;
            for (var _0x585b7f = 0x0; _0x585b7f < _0x593a19['length']; _0x585b7f++) {
                _0x1a120c = (_0x1a120c + 0x1) % 0x100;
                _0x4ddb21 = (_0x4ddb21 + _0x1b5349[_0x1a120c]) % 0x100;
                _0x28ed27 = _0x1b5349[_0x1a120c];
                _0x1b5349[_0x1a120c] = _0x1b5349[_0x4ddb21];
                _0x1b5349[_0x4ddb21] = _0x28ed27;
                _0x4b4996 += String['fromCharCode'](_0x593a19['charCodeAt'](_0x585b7f) ^ _0x1b5349[(_0x1b5349[_0x1a120c] + _0x1b5349[_0x4ddb21]) % 0x100]);
            }
            return _0x4b4996;
        };
        _0x5c3a['HKkhxp'] = _0x3acf89;
        _0x5c3a['eabUGz'] = {};
        _0x5c3a['vEVEZj'] = !![];
    }
    var _0x5b65b1 = _0x5c3a['eabUGz'][_0xf486e7];
    if (_0x5b65b1 === undefined) {
        if (_0x5c3a['vszZjY'] === undefined) {
            _0x5c3a['vszZjY'] = !![];
        }
        _0x5c3a18 = _0x5c3a['HKkhxp'](_0x5c3a18, _0x2075d7);
        _0x5c3a['eabUGz'][_0xf486e7] = _0x5c3a18;
    } else {
        _0x5c3a18 = _0x5b65b1;
    }
    return _0x5c3a18;
};
 
 
app.get('/', function (req, res) {
  //req.query = {callback:"_0x5c3a('0x8', 'CwZq')"}
  let callback = req.query.callback;
  let value = eval(callback); //直接eval计算传递进来的解密函数及参数
  console.log(callback,value);
  res.send(value)  //结果
})
 
app.listen(3000)

在node下运行后,在浏览器上进行简单的测试:

http://127.0.0.1:3000/?callback=_0x5c3a('0x8', 'CwZq')

回车后的结果:


image.png

这样,我们就可以用requests库进行请求,代码如下:

reg = re.compile(r"_0x5c3a\([\s\S]{12,14}'\)")
results = reg.findall(code) # code是所有混淆代码
 
 
for result in results:
    params = {"callback":result} #构造参数
    r = requests.get("http://127.0.0.1:3000/",params = params) #请求
    print (result,r.text) #打印结果
    code = code.replace(result,"'" + r.text + "'") #全局替换

结果如下:


image.png

和上一篇文章的结果一致,但效果明显要好很多,特别是在处理多个这样的调用时,其性能不是一个量级,因此在这里建议,卸载掉电脑上的pyexecjs在这个库吧,反正也没再更新了。

不过这里在使用get时,遇到了一个坑,就是当提交的参数里面包含特殊字符时(比如'&'),可能会解析错误,因此建议使用post方式,可自行百度相关教程。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容