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

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 10448|回复: 66
收起左侧

[Web逆向] 某数和某5秒-反混淆动态注入调试的一种方案

  [复制链接]
漁滒 发表于 2022-3-6 22:35

@TOC

本篇文章主要讲述使用mitmproxy进行代码注入的一种方案,可以解决动态js和加密js的情况,本篇主要使用两个案例来展示。js逆向分析相关的在本篇文章中不会详细说,因为关系不大。本篇文章参考以下内容

1.中国商标网JS调试 - 动态代码注入
2.js逆向案例-rus5逻辑学习
3.某5某秒分析笔记
4.【JS逆向系列】某空气质量监测平台无限 debugger 与 python算法还原

某数的动态js,每次访问返回的都是不同的js,使用无痕模式打开浏览器,打开f12里面,选中事件监听断点中的脚本

在这里插入图片描述
此时打开网页可以看到如下的类型的代码

在这里插入图片描述

按照前面的思路,那么就是先把代码拿到手,然后进行反混淆,再讲反混淆后的代码设置回响应。这次依然是使用mitmproxy进行拦截,使用ast进行反混淆并添加断点

在这里插入图片描述

此时调试代码就比较方便了,也不用再去设置事件监听断点。,下一步可以在eval.call前面找到已经组装好的第二层代码,接下来就是进入vm了。

在这里插入图片描述

如果要将这里面的代码进行反混淆,还是一样需要先把代码拿到手,也就是说需要主动执行第一层的代码,然后拿到第二层的代码,此时将代码反混淆后,在第一层代码合适的地方,用反混淆后的代码替换掉原来第二层的代码。

在这里插入图片描述

这样就可以反混淆vm里面的代码里面的任意地方加上断点来调试,整体代码如下

def response(flow: http.HTTPFlow):
    if 'new_house.html' in flow.request.url:
        # 拦截首层html
        print('数据拦截', flow.request.url)

        with open('new_house.html', 'wb') as f:
            f.write(flow.response.content)

        # 反混淆第一层,并注入代码,等待生成第二层
        os.system('node astfangdi_init')
        print('首次处理完成')
        # 主动执行生成第二层代码
        nodejs = os.popen('node fangdi_init')
        jscode = nodejs.read().replace('\n', '')
        nodejs.close()

        with open('fangdi_init.json', 'w', encoding='utf-8') as f:
            f.write(jscode)
        print('二层代码获取完成')
        # 反混淆第二层代码
        os.system('node astfangdi2')
        print('二层代码反混淆完成')
        # 反混淆第一层代码,并注入前面生成的第二层代码
        os.system('node astfangdi')

        with open('new_house_decrypt.html', 'rb') as f:
            htmlcon = f.read()
        flow.response.set_content(htmlcon)
        print('首层代码注入完成')

然后是某5秒的加密js,还是使用无痕模式打开浏览器以及选中事件监听断点中的脚本

在这里插入图片描述
会断在一个_cf_chl_opt的参数上面,然后会请求一个jsch/v1的接口

在这里插入图片描述

返回的是一段带有ob混淆的内容,脚本断点会在解密后执行时断下

在这里插入图片描述

这个的拦截就和之前是一样的了,直接可以替换掉。不是说有加密的js吗?那么继续往下看。

在这里插入图片描述
后面还会接着请求一个flow/ov1这样的接口,里面的请求体和响应体就是加密了的,当然,准确来说不是加密,后面会说到。

在这里插入图片描述
在这里插入图片描述

这里解密后会使用function的构造函数进行代码。

在这里插入图片描述
这里也是有ob混淆的代码,这里想要拦截反混淆就不是这么简单了,因为返回的是加密了的代码,如果想要反混淆,那么就必须先解密代码。而这里又衍生出一个问题,就算我解密反混淆后,还是不能直接把响应设置进去,因为原本代码是加密的,我直接设置没有加密的代码,那么网页肯定会报错的。

那么这里在原来的基础上,还要多两步,就是把js解密,和重新加密回去。如何找到解密的函数这里就不详细说了,逻辑比较简单,那么就可以直接改成python的代码来解密

 data64 = base64.b64decode(flow.response.content)
 x = reduce(lambda n, m: n ^ m, [32] + list((cRay + "_0").encode()))
 dedata = bytes([((data64[A] & 255) - x - A % 65535 + 65535) % 255 for A in range(len(data64))])

这里的dedata 就是得到的js明文,接下来就可以愉快的对代码进行反混淆了,那么怎么加密回去呢,这里其实就是一个反向运算。举个简单的例子就是解密是减去1,那么加密就是加上。如果解密是乘以x,那么加密就是除以x。加密的代码如下

endata = bytes([((dedata[A]) - 65535 + (A % 65535) + x) % 255 for A in range(len(dedata))])
flow.response.set_content(base64.b64encode(endata))

这样就可以把反混淆的代码设置回去了

在这里插入图片描述

这样就可以得到反混淆后的vm代码。调试起来就相对简单了一些,这个是响应体,那请求体也加密了。如果想看看请求的时候提交了什么,或者直接修改请求体的话,那是类似的逻辑,需要先解密,然后再加密才能设置回去。这里主要说一下加密的内容,其实说加密不太准备,应该说只是一个压缩方法。

在这里插入图片描述
这里的逻辑其实就是lzstring的压缩算法,python中也有lzstring这个库,但是不能直接使用,因为这里使用的是非标准的base64编码表,需要对源码进行部分修改

在这里插入图片描述

这样我们就可以随时对请求体和响应体拦截,不断的对比本地生成的数据和网页提交的数据的差别来生成我们的本地环境,mitmproxy的学习到此就结束啦。

免费评分

参与人数 26威望 +2 吾爱币 +124 热心值 +21 收起 理由
Ameliaaaz + 1 + 1 谢谢@Thanks!
成弟 + 1 破解一个验证。。可以加我一下吗?我没有你的联系方式。。这里每天限制发几.
HaHaWa + 1 我很赞同!
ContacNt + 1 我很赞同!
努力加载中 + 1 + 1 热心回复!
Passacaglia0 + 1 + 1 谢谢@Thanks!
KDG + 1 + 1 谢谢@Thanks!
matsutei + 1 + 1 感谢分享,楼主辛苦了!
weixin123 + 1 我很赞同!
huzhenliang123 + 1 + 1 感觉会很好用,渔歌nb
9987651234 + 1 + 1 谢谢@Thanks!
kflksj + 1 + 1 用心讨论,共获提升!
gaosld + 1 + 1 谢谢@Thanks!
yixi + 1 + 1 谢谢@Thanks!
涛之雨 + 2 + 100 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
Akihi6 + 1 谢谢@Thanks!
qcinnovative + 1 + 1 用心讨论,共获提升!
52PojieFen + 1 + 1 谢谢@Thanks!
jnez112358 + 1 + 1 谢谢@Thanks!
Moran110 + 1 + 1 用心讨论,共获提升!
kkavifo + 1 + 1 谢谢@Thanks!
夫子点灯 + 1 谢谢@Thanks!
fengxu + 1 + 1 热心回复!
为之奈何? + 1 + 1 我很赞同!
Panel + 1 + 1 我很赞同!
悦来客栈的老板 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

本帖被以下淘专辑推荐:

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

ghd19940802 发表于 2022-3-8 11:12
本帖最后由 ghd19940802 于 2022-3-8 11:14 编辑
shayu2021 发表于 2022-3-8 09:18
再次谢谢帮助,整好了。

不客气 PHP我不是很懂
备份下我的
[PHP] 纯文本查看 复制代码
<?php
function getMmsKey($e) {
    $t = 185025305;
    $n = rotateRight($e, $t % 17);
    return yihuo($n, $t);
}
function rotateRight($e, $t) {
    for ($r, $n = 0;$t > $n;$n++) {
        $r = 1 & $e;
        $e = rr($e, 1);
        $r = ll($r, 31);
        $e = $e + $r;
    }
    return $e;
}
function rr($v, $n) {
    $v = $v & 0x80000000 ? $v | 0xFFFFFFFF00000000 : $v & 0xFFFFFFFF;
    return $v >> ($n & 0x1F);
}
function ll($v, $n) {
    $t = ($v & 0xFFFFFFFF) << ($n & 0x1F);
    return $t & 0x80000000 ? $t | 0xFFFFFFFF00000000 : $t & 0xFFFFFFFF;
}
function yihuo($a, $b) {
    $c = ($a ^ $b) & 0xffffffff;
    if ($c & 0x80000000) $c-= 0x100000000;
    return $c;
}
echo getMmsKey(time());
?>
ghd19940802 发表于 2022-3-7 18:11
本帖最后由 ghd19940802 于 2022-3-7 18:14 编辑
shayu2021 发表于 2022-3-7 10:45
求大神解密一下这个视频,获取视频的地址加密的,解不了
http://www.le.com/ptv/vplay/31530669.html

获取视频页面ID http://www.le.com/ptv/vplay/31530669.html  31530669就是ID

请求视频信息 http://player-pc.le.com/mms/out/video/playJson.json?platid=1&splatid=103&tss=ios&id=31530669&domain=www.le.com&tkey={{tkey}}&source=1001&#174;ion=cn 关键参数tkey 需要配合JS加密时间戳生成

获取到各分辨率地址 拼接上http://play.g3proxy.lecloud.com{{r1080p}}&format=1&tzm={{tzm}}关键参数tzm 需要配合JS加密时间戳生成  发送请求获得播放地址,只适用于免费视频, 收费视频应该需要大佬来  我只会这些了 下面是加密算法

"1080p": [

                    "/vod/v2/Mjc4LzMxLzM0L2xldHYtdXRzLzE0L3Zlcl8wMF8yMi0xMTIyNTA0NTk0LWF2Yy0yOTkyMTc4LWFhYy0xMjgwMDAtNTcxNTU2MC0yMjM4MDk3MzEzLWM5ZDA1NjE0NWRkNjMyZDQzMjZjMDhmN2UxZmYxZDFiLTE1NDc5ODc1NzgyNDgubXA0?b=3132&mmsid=66909480&tm=1646647630&key=015af80874a1a468f55d8d23b875c839&platid=1&splatid=103&playid=0&tss=ios&vtype=52&cvid=996928022288&payff=0&pip=6c9d4734fbf9db5d668d8f59c592cbdf&xm=51386a1e98ff9e7872202c7b93526786",
                    "278/31/34/letv-uts/14/ver_00_22-1122504594-avc-2992178-aac-128000-5715560-2238097313-c9d056145dd632d4326c08f7e1ff1d1b-1547987578248.mp4"

                ],

[JavaScript] 纯文本查看 复制代码
function getMmsKey (e) {
    var t = 185025305
    n = rotateRight(e, t % 17);
    return n ^ t
}

function rotateRight (e, t) {
    for (var r, n = 0; t > n; n++) r = 1 & e, e >>= 1, r <<= 31, e += r;
    return e
}
// postman命令 主要是上面的两个方法 自己改下
pm.environment.set("tkey", getMmsKey (Date.now() / 1000));

免费评分

参与人数 2吾爱币 +8 热心值 +2 收起 理由
fengbolee + 2 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
涛之雨 + 6 + 1 用心讨论,共获提升!

查看全部评分

Mrian-hua 发表于 2022-3-6 22:53
Moran110 发表于 2022-3-7 09:15
感谢分享,楼主辛苦了!
wannabe 发表于 2022-3-7 09:15
渔哥开课吧
jnez112358 发表于 2022-3-7 09:41
开课啦,好好学习,天天向上,谢谢分享
ricky2196 发表于 2022-3-7 10:34
学习了,多谢大佬分享
头像被屏蔽
shayu2021 发表于 2022-3-7 10:45
提示: 作者被禁止或删除 内容自动屏蔽
骑骡子赶猪 发表于 2022-3-7 10:52
大佬牛逼
晓儿 发表于 2022-3-7 11:03
大神啊!求技术
xwencai 发表于 2022-3-7 11:26
大佬牛逼
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

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

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

GMT+8, 2024-10-9 08:27

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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