吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

搜索
查看: 4065|回复: 55
上一主题 下一主题
收起左侧

[Web逆向] 某壁纸网站js逆向,涉及ob混淆,滑块

  [复制链接]
跳转到指定楼层
楼主
Esword 发表于 2021-7-17 12:49 回帖奖励
本帖最后由 Esword 于 2021-7-21 15:13 编辑

  首先在此声明,本文章仅仅用于研究学习,不可用于任何商业活动,否则后果自负。

今天的npy
aHR0cHM6Ly9iei56enptaC5jbi9pbmRleA==
npy这三个字自己脑补吧,哈哈哈哈。


解决无限debugger


法一

右击debugger行数位置,点击add conditional breakpoint..,添加false,然后按回撤, 刷新网页,发现成功跳过无限debugger



法二

1、在js文件右击, 然后点击save as ..., 把js文件保存到本地。



2、修改保存到本地的js文件,将debugger成false保存js文件




3、在浏览器Soures获取需要替换的js文件url




4、使用fiddler等工具动态拦截替换js,刷新网页即可



法三
       注入代码到js文件

[JavaScript] 纯文本查看 复制代码
//去除无限debugger
Function.prototype.__constructor_back = Function.prototype.constructor;
Function.prototype.constructor = function() {
    if(arguments && typeof arguments[0]==='string'){
        //alert("new function: "+ arguments[0]);
        if("debugger" === arguments[0]){
            //arguments[0]="console.log(\"anti debugger\");";
            //arguments[0]=";";
            return
        }
    }
   return Function.prototype.__constructor_back.apply(this,arguments);
}


加密分析与定位
        其实看到上面这个过无限debugger的大家都可以大致猜出我们今天的网站有这个一项,这里我才用的法三,注入js。其实一开始我用的法一,但是效果不理想,不是不理想,是很不好,卡死人。里面的验证码滑动都特别卡,我后来尝试法三后,特别的丝滑,跟正常一样。        先说说这个网站吧,它开始是一打开网页就有滑动验证码,后来改了,一打开第一页没有了,下面请求就会有。
首先我们看一下它的代码(下图),很明显,被混淆了。这里我们可以用下面这个网站进行混淆还原,让它至少可以看了。
http://tool.yuanrenxue.com/decode_obfuscator猿人学ob混淆还原工具



        把这些混淆还原一下后,我们看下一页,首先遇到的是滑动验证码,这里滑动验证码的获取就不多赘述,抓包就好了,在 XHR 里面就可以看到请求。我们看一下滑动验证码检验是否成功参数。




可以看到有三个参数,其中 captchaType 是固定不变的,而 token 是跟滑动验证码的 bs64编码 一起返回的,就是下图,jigsawImageBase64 originalImageBase64 分别对应滑块图片与背景图片。



        正如上图看到的,secretKey token 也被一起返回回来,它们两个下面要被用到。那就剩下一个参数 pointJson ,我们搜索一下它,会发现就只有一个js文件,再在文件里面找它,发现有好几个(也就2个,哈哈哈哈哈),这里就是打断点确定是哪个了。



最后确定下来是这个,在这里你会发现,这个根本没有轨迹的验证什么的,就是单纯验证一下缺口的左边到图片左边缘的像素距离。这里我们看一下还原后的代码。

[JavaScript] 纯文本查看 复制代码
function pointJson(moveBlockLeft,secretKey) {
    _0x4b1647 = moveBlockLeft
    pointJson =  secretKey ? _0x43f1b9(JSON['stringify']({
            'x': _0x4b1647,
            'y': 0x5
        }), secretKey) : JSON['stringify']({
            'x': _0x4b1647,
            'y': 0x5
        });
    return pointJson

}


这个是我改的,看里面的,没有什么的大的改变,说明这里没有怎么混淆,看一下上面两个参数 moveBlockLeft secretKey secretKey 就不多说,就是上面说的,而 moveBlockLeft 就是像素距离。但是这里还有一个函数_0x43f1b9,我们看一下它的代码。



这里的代码很明显,这里我们改下一下,用 nodejs crypto-js 库,改一下就好了。可以参考我下面这个代码。

[JavaScript] 纯文本查看 复制代码
var CryptoJS = require("crypto-js");
function _0x43f1b9(_0x393fb6) {
    var _0x4d513d = arguments["length"] > 1 && undefined !== arguments[1] ? arguments[1] : "XwKsGlMcdPMEhR1B",
        _0x4b1647 =  CryptoJS.enc.Utf8.parse(_0x4d513d),
        _0x2e1dac =  CryptoJS.enc.Utf8.parse(_0x393fb6),
        _0x84666d = CryptoJS.AES.encrypt(_0x2e1dac, _0x4b1647, {
            "mode": CryptoJS.mode.ECB,
            "padding": CryptoJS.pad.Pkcs7
        });
    return _0x84666d.toString();
}


这样这个参数 pointJson 就解决了。
这样这个网的滑块就过了。
滑块过后你点击的页面才会加载,但是看请求头会发现有一个参数 captcha



这里再次搜索这个 captcha ,会定位到下图这样的代码



这个会发现 _0x4dd66d ,这个参数可以根据调用栈找到加密办法。也就是下面这个。



我们看一下还原后以及被我改的代码。

[JavaScript] 纯文本查看 复制代码
function captcha(moveBlockLeft,token,secretKey) {
    var captcha = secretKey ? _0x43f1b9(token + '---' + JSON['stringify']({
        'x': moveBlockLeft,
        'y': 0x5
    }), secretKey) : token + '---' + JSON["stringify"]({
        'x': moveBlockLeft,
        'y': 0x5
    });
    return captcha
}


_0x43f1b9 这个是不是很熟悉,每次,他就是上面nodejs crypto-js 库改加密的函数。
好了这个就是 captcha 的加密。
下面是 auth_key 的加密,当我们点击一个图片时,它会发出请求,其实有两个,一个是缩小版,一个是原版,这个 auth_key 的加密其实很好找的也是与上面一样,搜索就好了,这里就不咋赘述,我就放一个网站加密代码。



还原后以及改写代码:

[JavaScript] 纯文本查看 复制代码
function url(_0x29df17, _0xea945) {
    var _0x537ece = "YQTJLVCqattV1T0fhuhJTW1vyH7ZdyE3",
        _0x5998d = "https://doge.zzzmh.cn",
        _0x5c5042 = _0x50ecce(32),
        _0x56d562 = parseInt((_0xea945 || Date["now"]()) / 1000) + 1800,
        _0x25aa83 = _0x29df17["substring"](_0x5998d["length"], -1 == _0x29df17["lastIndexOf"]("?") ? _0x29df17["length"] : _0x29df17["lastIndexOf"]("?")),
        _0x41d299 = _0x56d562 + "-" + _0x5c5042 + "-0-" + md5(_0x25aa83 + "-" + _0x56d562 + "-" + _0x5c5042 + "-0-" + _0x537ece);

    return _0x29df17 + (_0x29df17["indexOf"]("?") < 0 ? "?" : "&") + "auth_key=" + _0x41d299;
}


这样这个网站的加密就算完成了,但是呢,人家返回的数据也是解密的,还得解密,哈哈哈哈哈,靓男无语了,没办法,只能解密了。
我们先看一下它返回的加密数据。



看是看不出什么的,直接动手搞它。这里我看的是调用栈,然后找到它的。是下图这个。



然后我们打开,设置断点,翻页,刚好停在那里。



其实我们就要下面代码就好了。

[JavaScript] 纯文本查看 复制代码
_0x417d7d['data']['result'] = JSON['parse'](_0x6247d3['a'][_0x3de3('0x5e', 'D6$F')](_0x417d7d['data']['result']))


这里我们就看下还原后代码。

[JavaScript] 纯文本查看 复制代码
_0x417d7d["data"]["result"] = JSON["parse"](_0x6247d3["a"]["decipher"](_0x417d7d["data"]["result"]))


我的代码。

[JavaScript] 纯文本查看 复制代码
function _0x41d299(_0x29df17) {
    for (var _0xea945 = [-111, 52, 91, 65, -65, 116, 119, 106, -121, -82, -5, 80, 51, 97, 68, -83, -112, -51, 23, -46, -34, -114, -55, -11, -127, 90, 33, 22, -31, 50, -17, 20, -44, 15, -94, -123, 118, -23, -61, 114, 71, -104, -126, -117, -81, -54, -18, -110, -4, -95, -91, 94, -80, -14, 120, 105, 85, 104, -86, -108, 67, 25, 101, 108, 16, -105, 111, -10, 117, -73, 77, 89, -29, -98, -68, 112, 107, -1, 86, 121, 88, -101, -124, 69, -30, -8, -113, -74, -118, 57, -25, 12, -115, -106, 95, 127, 84, 124, -102, -28, 73, 43, -60, 28, 46, 115, 30, 122, -75, 125, -67, -77, 3, -7, -53, -13, 53, 78, -72, 1, 11, -71, -39, -79, -3, 19, 41, 126, -43, -125, -27, 34, 63, 8, 72, -35, -41, -63, 60, -24, 102, 47, -119, -103, -22, 45, 59, 64, -96, 49, 83, -107, -120, -57, -70, 0, -38, -84, -40, 24, 14, 48, 29, 44, -36, -47, 56, -92, 38, 37, 4, -50, 103, 10, -89, 55, 113, -26, 110, 54, 36, -20, -78, -12, -116, 70, -37, 5, -62, -76, -48, -64, 79, 100, 40, 6, -58, -90, -19, -9, 39, 93, -99, 21, 7, 26, -2, 27, -45, 81, 58, -122, 76, -66, 2, 92, -42, 98, -16, 9, 61, 62, -15, 99, -21, 31, -56, 87, 17, -52, -69, -33, -59, -85, 66, 74, 18, -93, -128, -87, -32, 42, 32, -88, 109, 96, 13, -6, 75, -100, -49, 35, -97, 82, -109, 123], _0x537ece = 0, _0x5c5042 = 0, _0x56d562 = 0, _0x25aa83 = new Array(), _0x5998d = 0; _0x5998d < _0x29df17["length"]; _0x5998d++) {
        _0x537ece = _0x537ece + 1 & 255, _0x5c5042 = (255 & _0xea945[_0x537ece]) + _0x5c5042 & 255;
        var _0x41d299 = _0xea945[_0x537ece];
        _0xea945[_0x537ece] = _0xea945[_0x5c5042], _0xea945[_0x5c5042] = _0x41d299, _0x56d562 = (255 & _0xea945[_0x537ece]) + (255 & _0xea945[_0x5c5042]) & 255, _0x25aa83["push"](_0x29df17[_0x5998d] ^ _0xea945[_0x56d562]);
    }

    return _0x25aa83;
}

function _0x438891(_0x29df17) {
    for (var _0xea945, _0x537ece, _0x5c5042 = "", _0x56d562 = 0; _0x56d562 < _0x29df17["length"];) _0xea945 = _0x29df17[_0x56d562], _0x537ece = 0, _0xea945 >>> 7 === 0 ? (_0x5c5042 += String["fromCharCode"](_0x29df17[_0x56d562]), _0x56d562 += 1) : 252 === (252 & _0xea945) ? (_0x537ece = (3 & _0x29df17[_0x56d562]) << 30, _0x537ece |= (63 & _0x29df17[_0x56d562 + 1]) << 24, _0x537ece |= (63 & _0x29df17[_0x56d562 + 2]) << 18, _0x537ece |= (63 & _0x29df17[_0x56d562 + 3]) << 12, _0x537ece |= (63 & _0x29df17[_0x56d562 + 4]) << 6, _0x537ece |= 63 & _0x29df17[_0x56d562 + 5], _0x5c5042 += String["fromCharCode"](_0x537ece), _0x56d562 += 6) : 248 === (248 & _0xea945) ? (_0x537ece = (7 & _0x29df17[_0x56d562]) << 24, _0x537ece |= (63 & _0x29df17[_0x56d562 + 1]) << 18, _0x537ece |= (63 & _0x29df17[_0x56d562 + 2]) << 12, _0x537ece |= (63 & _0x29df17[_0x56d562 + 3]) << 6, _0x537ece |= 63 & _0x29df17[_0x56d562 + 4], _0x5c5042 += String["fromCharCode"](_0x537ece), _0x56d562 += 5) : 240 === (240 & _0xea945) ? (_0x537ece = (15 & _0x29df17[_0x56d562]) << 18, _0x537ece |= (63 & _0x29df17[_0x56d562 + 1]) << 12, _0x537ece |= (63 & _0x29df17[_0x56d562 + 2]) << 6, _0x537ece |= 63 & _0x29df17[_0x56d562 + 3], _0x5c5042 += String["fromCharCode"](_0x537ece), _0x56d562 += 4) : 224 === (224 & _0xea945) ? (_0x537ece = (31 & _0x29df17[_0x56d562]) << 12, _0x537ece |= (63 & _0x29df17[_0x56d562 + 1]) << 6, _0x537ece |= 63 & _0x29df17[_0x56d562 + 2], _0x5c5042 += String["fromCharCode"](_0x537ece), _0x56d562 += 3) : 192 === (192 & _0xea945) ? (_0x537ece = (63 & _0x29df17[_0x56d562]) << 6, _0x537ece |= 63 & _0x29df17[_0x56d562 + 1], _0x5c5042 += String["fromCharCode"](_0x537ece), _0x56d562 += 2) : (_0x5c5042 += String["fromCharCode"](_0x29df17[_0x56d562]), _0x56d562 += 1);

    return _0x5c5042;
}

function _0x21a6fa(_0x29df17) {
    for (var _0xea945 = atob(_0x29df17), _0x537ece = new Int8Array(_0xea945["length"]), _0x5c5042 = 0; _0x5c5042 < _0xea945["length"]; _0x5c5042++) _0x537ece[_0x5c5042] = _0xea945["charCodeAt"](_0x5c5042);

    return _0x537ece;
}

function _0xbe7c1c(_0x29df17) {
    return _0x438891(_0x41d299(_0x21a6fa(_0x29df17)));
}

function decode(str) {
    var info = _0xbe7c1c(str)
    info_dict = JSON.parse(info)
    // console.log(info_dict)
    return info_dict
}


其实本质上就是个解码的过程。decode 就是主函数。

我们试一个看一看。
[Asm] 纯文本查看 复制代码
{
  currPage: 1,
  list: [
    { t: 2, w: 6500, h: 3300, i: 'c8bfcd9f880411ebb6edd017c2d2eca2' },
    { t: 2, w: 3840, h: 2233, i: 'c6ac1e46880411ebb6edd017c2d2eca2' },
    { t: 2, w: 1920, h: 1080, i: 'c5398839880411ebb6edd017c2d2eca2' },
    { t: 2, w: 4149, h: 2480, i: '01217514880511ebb6edd017c2d2eca2' },
    { t: 1, w: 2560, h: 1440, i: 'cec99a46880411ebb6edd017c2d2eca2' },
    { t: 2, w: 1920, h: 1200, i: '27524ac7880511ebb6edd017c2d2eca2' },
    { t: 1, w: 1920, h: 1080, i: '865885b0881611ebb6edd017c2d2eca2' },
    { t: 2, w: 3840, h: 2160, i: '0bbd039fb5a54de2b240ab0fcd3af8ed' },
    { t: 2, w: 3840, h: 2160, i: '3f30472a880511ebb6edd017c2d2eca2' },
    { t: 2, w: 3840, h: 2160, i: 'a9982f7441bd4e07a3b1a26af43457d9' },
    { t: 2, w: 4500, h: 2800, i: '0c0f3f16880511ebb6edd017c2d2eca2' },
    { t: 2, w: 3840, h: 2400, i: '4921c7d7eae046c7a4d8575b02a6ae2b' },
    { t: 2, w: 1920, h: 1080, i: 'c5340e3e880811ebb6edd017c2d2eca2' },
    { t: 2, w: 7680, h: 4320, i: '21142970880911ebb6edd017c2d2eca2' },
    { t: 2, w: 4000, h: 2433, i: '156a17e6880511ebb6edd017c2d2eca2' },
    { t: 2, w: 3859, h: 2594, i: '070dfddb880511ebb6edd017c2d2eca2' },
    { t: 2, w: 3840, h: 2160, i: 'bbc58c3d998d4f389fdae649334873f7' },
    { t: 2, w: 7680, h: 4320, i: '4dd06e4787714b08a2d56b5528569a67' },
    { t: 2, w: 2560, h: 1440, i: 'ce329083a43b4526ac6129f8c651bae5' },
    { t: 2, w: 2800, h: 1350, i: '1e8d7c5e880511ebb6edd017c2d2eca2' },
    { t: 2, w: 3840, h: 2160, i: 'cae57fea880411ebb6edd017c2d2eca2' },
    { t: 2, w: 4096, h: 2404, i: '56ac935951ab4af78bf31af55b600d95' },
    { t: 2, w: 7680, h: 4320, i: '4678e4f731874d668ec21a2d2608878c' }
  ],
  pageSize: 23,
  totalCount: 34339,
  totalPage: 1493
}


很好,解决了,只有这些是什么,就自己搞吧,这里提示一下,跟获取原图链接有关,跟上面 auth_key 获取有关。


图片展示


这就是我搞定其中一部分的图片,很不错,高清的。



这里就放一张。



如果jio的我写的不错就点个关注。

image.png (371.22 KB, 下载次数: 3)

image.png

image.png (163.17 KB, 下载次数: 2)

image.png

免费评分

参与人数 16吾爱币 +15 热心值 +15 收起 理由
TonyKing + 1 用心讨论,共获提升!
bluesky20210721 + 1 + 1 我很赞同!
cssos15 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
232621597 + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
lin32111 + 1 + 1 很赞
SHASHA2021 + 1 + 1 热心回复!
onlyclxy + 1 热心回复!
chngchun + 1 + 1 我很赞同!
gaosld + 1 + 1 谢谢@Thanks!
victos + 1 + 1 谢谢@Thanks!
三滑稽甲苯 + 2 + 1 用心讨论,共获提升!
天空宫阙 + 2 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
HumorsMrLin + 1 我很赞同!
HOOK_XYS + 1 + 1 谢谢@Thanks!
Maise + 1 我很赞同!
hj170520 + 2 + 1 热心回复!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

来自 2#
 楼主| Esword 发表于 2021-7-22 10:08 |楼主
现在可以看了,xdm
推荐
yufd1986 发表于 2021-7-22 15:53
这个网站目前已经更新了,每个js都加上了debugger,['constructor']('debu' + 'gger')['call']('action')); 还混淆了一下。。。
5#
QingYi. 发表于 2021-7-19 09:04
6#
lych2005a 发表于 2021-7-19 09:25
还以为能下载,怎么没有了。
7#
axy 发表于 2021-7-19 09:58
怎么没有了?还想学习学习的
8#
zsxbla 发表于 2021-7-19 09:59
咋没了 还想看看的
9#
三滑稽甲苯 发表于 2021-7-19 10:06
本帖最后由 三滑稽甲苯 于 2021-7-19 10:14 编辑

刚刚看到,点进来怎么就没了
PS. 到lz个人主页的广播可以看到一部分
10#
tangyi606 发表于 2021-7-19 10:12
怎么了,满心期待  点进来来没了~~
11#
dllrose 发表于 2021-7-19 15:24
是不是不能发这种的呢,技术文章?点进来就没了
12#
哆啦A梦 发表于 2021-7-19 16:08
现在这种都直接挂····
13#
cooleephone 发表于 2021-7-19 16:11
可惜来晚了,感觉应该能进步的
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2021-9-20 08:13

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表