js之逆向调试

在平时的渗透测试中难免遇到那种加密的请求包 比如登录的时候 然后这个时候我们平常普通的爆破就不起作用了 就需要把需要爆破的数据加密后才能进行爆破

这种加密 一般都是前端加密的 可以通过调试js然后找到加密的函数 然后写脚本把我们的payload进行加密 然后在进行爆破 这种情况不仅仅可以用来登录爆破 注入也是一样的 把注入的payload加密 因为在后端拿到前端的加密数据后是会先进行解密的

这次举例调试是某音乐的评论请求

js调试分析

首先先打开F12找到我们需要的请求包

image-20220915164724434

image-20220915164741290

然后查看这个请求需要的参数

image-20220915165051973

有两个参数params和encSecKey

可以发现这俩都是加密的

然后点击Initiator

image-20220915165211380

这里相当于这个请求的整个过程中所调用到的js的执行栈 重下往上 最先执行的在最下面

然后我们点击最上面的的一个 因为这是最后发出请求时所调用的

image-20220915165926192

image-20220915170109267

进来之后点击花括号整理代码

image-20220915170031177

然后会发现这里高亮 这里就是最后发出请求的地方 看代码send也可以看出 然后在3552打上断点

image-20220915170210671

然后我们刷新页面

image-20220915170603343

然后打开Scope里面的local 查看request里面的url 找到我们之前F12找到的那个URL

明显这个不是 我们放包 点击这个蓝色的案例

image-20220915170707111

然后一直放到这个包 我们之前F12看到的

image-20220915170835525

然后我们打开callback

image-20220915171521356

这里看到的其实跟上面看到的一样

然后点击第二个

image-20220915171551632

image-20220915171632775

可以看到这里的data也是加密的

然后继续往下点

当点到第五个的时候 可以看到data是没有加密的

image-20220915171818979

然后我们在来到第四个

image-20220915172144271

在这个包里面可以看到是已经加密了 相当于运行到13430这一行的时候 参数被加密完了 所以加密过程就相当于在t2x.be3x这个函数内部

然后在这里打上断点 把上一步的断点取消

image-20220915181814125

然后刷新

image-20220915181839086

/api/cdn 不是我们需要的 继续放

image-20220915181904150

然后放到我们想要的

image-20220915182117413

然后这个时候一步一步的往下放

image-20220915191322819

点这个一步一步的放

然后放到这里的时候 发现已经加密了

image-20220915191519986

然后我们往上看

到了这里我们可以看到一个encSecKey

image-20220915191727959

这个不是我们最开始数据包里面看见的吗

所以我们可以断定 这里是加密的地方

image-20220915212308715

image-20220915212429766

在window.asrsea这一步进行加密 然后赋值给下面的params

然后通过对比 发现用到的参数就是这一些

image-20220915212902141

加密过程

相当于加密就用到了window.asrsea这个函数 ,然后全局搜索这个函数

image-20220915213700396

找到这个d 相当于这里window.asrsea(xx)就等于d(xxx)

然后d在这上面

image-20220915213752433

通过分析发现这个e这个函数用不到 就不管它

只看abcd

然后分析d

function d(d, e, f, g) {
var h = {}
, i = a(16);
return h.encText = b(d, g),
h.encText = b(h.encText, i),
h.encSecKey = c(i, e, f),
h
}

发现需要4个参数

然后回到window.asrsea 看传进去的是什么

var bKB4F = window.asrsea(JSON.stringify(i2x), buV2x([“流泪”, “强”]), buV2x(Rg7Z.md), buV2x([“爱心”, “女孩”, “惊恐”, “大笑”]));

d是解析的json数据 i2x

image-20220915214342144

第二个参数 是调用了一个函数 但是这个函数的参数是写死的 我们直接就不用看函数了 直接把这个函数丢到控制台执行

image-20220915214446733

发现是定值 010001

然后看第三个参数

image-20220915214820208

00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7

第四个参数

image-20220915214906409

分析下来 发现除了第一个参数是改变的 其他3个参数都是定值

现在参数搞定了 然后继续跟进d函数

image-20220915215110779

进来创建了一个空对象 以及给i赋值是往调用a函数的返回值给a传入16

然后分析a函数

image-20220915215222332

相当于a返回的就是一串随机字符串

然后继续往下看

image-20220915215417738

因为我们之前在这里可以看到params拼接的就是encText 以及encSecKey拼接的encSecKey

刚好就是这俩

image-20220915215531258

然后这里看

image-20220915220435274

因为c里面是加密 并且不产生随机数 所以如果这里把i写成定值 那么encSecKey 就是定值

然后通过打断点

image-20220915221128023

获取到i的值然后放开

image-20220915221246161

这里获取到的encSecKey现在就是定值

be7b9e882f081e2cccf4d0c19cd433d57eda561f928255e700edcbb023a5cc02427c9dde79ac4ec856e31a93d190434b35564be8dcabe5a1bafc29ef219d56d9e50cd6257c76823547410d2255b5cc71561299a63227a20c7b564e1746472d969e3ad1648d42a32468bf9a33104f0f8928d6893abdca81a37b4370c889f68b10

然后跟进b函数

image-20220915215624070

看这代码就明显看出了 这里是加密的

image-20220915221606542

image-20220915221700158

相当于现在除了d是变量 其他的全是定值

然后现在基本上就调试完了 知道了加密的来源

最后就只需要还原params 也就是这两步

image-20220915222039508

也就是b函数

function b(a, b) {
var c = CryptoJS.enc.Utf8.parse(b)
, d = CryptoJS.enc.Utf8.parse(“0102030405060708”)
, e = CryptoJS.enc.Utf8.parse(a)
, f = CryptoJS.AES.encrypt(e, c, {
iv: d,
mode: CryptoJS.mode.CBC
});
return f.toString()
}

最后还原函数的部分就不细讲了 就涉及加解密的东西了

还原代码

这是最后还原的代码

image-20220915222419532

image-20220915222458960

image-20220915222515879

image-20220915222539766

最后就能成功返回数据

然后渗透中的利用就继续写脚本 获取这些加密数据 来进行爆破请求等等


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!