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

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 7143|回复: 75
收起左侧

[Web逆向] 某居客滑块逆向分析

  [复制链接]
wangguang 发表于 2023-6-12 12:59
本帖最后由 wangguang 于 2023-6-12 12:59 编辑

某居客滑块逆向分析

1.前言

我是菜鸟,不会ast,只能硬扣啦。

参考了K哥爬虫的文章【验证码逆向专栏】安某客滑块逆向 - 『脱壳破解区』 - 吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn=

自己也是做了一个总结更了这个贴。

2.网址

aHR0cHM6Ly9hcGkuYW5qdWtlLmNvbS93ZWIvZ2VuZXJhbC9jYXB0Y2hhTmV3Lmh0bWw/

3.正言

拉动滑块抓包,有个checkInfo,返回包里面有个校验失败。这个包就是滑块校验的包。

1

1

2

2

参数分析:

checkInfo里面总共需要五个参数sessionId,responseId,dInfo,language,data五个参数。

sessionId

全局搜索sessionId,在captchaNew.html里面,请求这个页面用正则就能提取到啦

3

3

responseId

responseId在getInfoTp这个数据包里面

4

4

getInfoTp只有两个加密参数,sessionId和dInfo,sessionId已经有了,主要分析dInfo的生成。

5

5

dInfo

进入发包的地方

6

6

在发包的地方下断点。

7

7

回溯找到dInfo生成的地方,在572行下断点

8

8

打印_fSL[_0x90o[2]][_0x90o[67]]((0,_taN)(), _Lnn),可以确定这个地方就是代码生成的地方。

9

9

对代码手动解个混淆_0x90o[2]—>"Z",_0x90o[67]—>"AESEncrypt"

_fSL["Z"]["AESEncrypt"](_taN(), _Lnn)

_fSL["Z"]["AESEncrypt"]函数总共有两个参数,_Lnn就是sessionId。还有一个参数是_taN()函数。

10

10

进入_taN()函数,分析这段代码。

11

11

函数里面有个逻辑判断,我们打印undefined - (8 * 564 << 5 > 0),他是NaN。这个js的逻辑判断我自己其实也搞的不是很清楚。也懒的去记了,懒人自有懒人的用法,就是我有歪门诀窍。

12

12

就是把他这个判断重写,如果是true的话他就会弹出,是false就不会弹出。在浏览器运行并没有弹出。这段代码不执行!

13

13

那么_taN()函数的作用就是返回那些参数!经过多次复现,这些参数是写死的值!

return { sdkv: "3.0.1", busurl: "https://api.anjuke.com/web/general/captchaNew.html", useragent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64)     AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75     Safari/537.36", cid: undefined, devicefg: undefined, clienttype:"1" };

_fSL["Z"]["AESEncrypt"]函数的两个参数都已经解决了!那我们便来慢慢扣这个函数。这个函数我不是改写的,我是用扣代码的方法硬扣的。虽然方法笨,但是好用就好好方法!!!

在控制台打印_fSL["Z"]["AESEncrypt"]函数双击进入函数内部。

14

14

1161行到1181行就是这段代码啦!扣下来,然后手动解个混淆!!!

15

15
_0x90o[115]—>"split"
_0x90o[17]—>""
_0x90o[164]—>"reduce"
_0x90o[54]—>"parse"
_0x90o[53]—>"string"
_0x90o[108]—>"stringify"
_0x90o[165]—>"encrypt"
_0x90o[166]—>"mode"
_0x90o[167]—>"CBC"
_0x90o[108]—>"stringify"
_0x90o[168]—>"ciphertext"

解完混淆的代码:

function AES(_cRV, _2undefinedp) {  
    if (false) {  
        var _0xisab = 778 >> 124 % 940 >> 724 % 64;  
    } else  
        _2undefinedp = _2undefinedp["split"]("")["reduce"](function(_PUi, _JrX, _JP9) {  
            if (true + 1 + undefined) {  
                var _0xl8pp = 87 & 393 << 237;  
            } else  
                return _JP9 % 2 == 0 ? _PUi + "" : _PUi + _JrX;  
        }, ""),  
        _2undefinedp = _jWF["parse"](_2undefinedp),  
        _cRV = "string" == typeof _cRV ? _cRV : JSON["stringify"](_cRV),  
        _cRV = _WMx["encrypt"](_cRV, _2undefinedp, {  
            iv: _2undefinedp,  
            mode: _mjv["mode"]["CBC"],  
            padding: _GrF  
        }),  
        _2undefinedp = _9kJ["stringify"](_cRV["ciphertext"]);  
    return (0,  
    encodeURIComponent)(_2undefinedp);  
}

继续分析这段代码,映入眼帘就是一个逻辑判断,ifL里面是false那么便可以把if (false) { var _0xisab = 778 >> 124 % 940 >> 724 % 64; } else这段代码给删了。

function(_PUi, _JrX, _JP9)函数里面又有个逻辑判断

16

16

这段代码不执行

if (true + 1 + undefined) { var _0xl8pp = 87 & 393 << 237; } else

把这段代码删掉。

因为是加密算法,_jWF["parse"]用加密库的crypto.enc.Utf8.parse替换掉。

"string" == typeof _cRV ? _cRV : JSON["stringify"](_cRV)是一个三元运算符。在浏览器运行代码是false执行:后面的代码。

17

17

所以删除前面的代码"string" == typeof _cRV ? _cRV :

再下一行代码就是加密之后重新赋值给_cRV,调用加密库把_WMx["encrypt"]替换成crypto.AES.encrypt

18

18

mode是CBC,把_mjv["mode"]["CBC"]替换成mode: crypto.mode.CBC

19

19

进入_GrF函数查看他的padding,可以看到它的padding是PCKS7

20

20
将padding: _GrF替换成padding: Cry.pad.Pkcs7

下一行代码我搞了好久,看了好多文章都是改写的。都是把这段代码删掉直接将加密的值tostring,我没搞明白。也希望大佬指教一下。

我个人比较蠢,搞不明白怎么改写,于是我直接就硬扣。简单粗暴,就是浪费了一点点时间。

_2undefinedp = _9kJ["stringify"](_cRV["ciphertext"]);代码的意思就是

获取_cRV的ciphertext并将其丢进_9kJ["stringify"]然后赋值给_2undefinedp

在浏览器打印_cRV的ciphertext是一堆数组。

21

21

在浏览器的stringify跟我在node环境中运行的stringify是不一样的值。所以我打算直接把它浏览器的stringify扣下来

22

22

23

23

双击进入 _9kJ[_0x90o[108]]函数内部

24

24

9102到9128行就是stringify函数,还是一样,手动解一波混淆然后分析代码

25

25

_0x90o[495]—>"words"
_0x90o[496]—>"sigBytes"
_0x90o[578]—>"_map"
_0x90o[563]—>"clamp"
_0x90o[371]—>"push"
_0x90o[211]—>"charAt"
_0x90o[211]—>"charAt"
_0x90o[36]—>"length"
_0x90o[371]—>"push"
_0x90o[328]—>"join"
_0x90o[17]—>""

解完混淆后的代码:

function stringify(_oJg){  
if (null * !![] - true)  
    for (var _IRC = _oJg["words"], _onW = _oJg["sigBytes"], _0l0 = this["_map"], _0tH = (_oJg["clamp"](),  
    []), _3YV = 0; _3YV < _onW; _3YV += 3)  
        for (var _ESV = (_IRC[_3YV >>> 2] >>> 24 - _3YV % 4 * 8 & 255) << 16 | (_IRC[_3YV + 1 >>> 2] >>> 24 - (_3YV + 1) % 4 * 8 & 255) << 8 | _IRC[_3YV + 2 >>> 2] >>> 24 - (_3YV + 2) % 4 * 8 & 255, _Yqz = 0; _Yqz < 4 && _3YV + .75 * _Yqz < _onW; _Yqz++)  
            _0tH["push"](_0l0["charAt"](_ESV >>> 6 * (3 - _Yqz) & 63));  
else {f  
    var _0xa4go = 414 ^ 196 - 999;  
}  
var _Au9 = _0l0["charAt"](64);  
if (415 % 8 / 7 == 1) {  
    if (_Au9)  
        for (; _0tH["length"] % 4; )  
            _0tH["push"](_Au9);  
} else {  
    var _0xlpgisd = {  
        _0x5qpbhy: function(_0xmuozc2, _0xb2dmao) {  
            return _0xmuozc2 + _0xb2dmao;  
        }  
    };  
    var _0xx8i6 = _0xlpgisd._0x5qpbhy(528, 610);  
}  
if (8 * 454 >> 5 == 1) {  
    var _0xr7wa = 125 ^ 726 % 265 + 184;  
} else  
    return _0tH["join"]("");  
}

这段代码还是很好分析的,就几个逻辑判断走向

第一个逻辑判断null * !![] - true是-1

26

26

27

27

删除后面的代码else { var _0xa4go = 414 ^ 196 - 999; }

第二个逻辑判断415 % 8 / 7 == 1是true

28

28

29

29

删除后面的代码else { var _0xlpgisd = { _0x5qpbhy: function(_0xmuozc2, _0xb2dmao) { return _0xmuozc2 + _0xb2dmao; } }; var _0xx8i6 = _0xlpgisd._0x5qpbhy(528, 610); }

第三个逻辑判断8 * 454 >> 5 == 1是false

30

30
删除前面的代码if (8 * 454 >> 5 == 1) { var _0xr7wa = 125 ^ 726 % 265 + 184; } else

31

31
运行代码报错了,_0l0 = this["_map"]报错了,浏览器打印一下this["_map"]是一段字符串,直接写死。

32

32

把sessionId从浏览器上面复制下来传进去运行,代码运行成功了!!!

33

33

用py复现,成功拿到了reponseId

34

34

Data

进入发包的地方

35

35

36

36
异步跟栈到箭头标着的地方,可以看到data参数。把断点下到577行,然后把其他断点都放开。重新刷新进入到这个577断点处。

37

37

可以看到data是个参数,我们需要回溯找到它加密的地方。但是由于代码都是混淆的,我的解决办法是回溯到每一个堆栈都下个断点然后手动解混淆看看有什么关键词啥的。

38

38

回溯了几个堆栈,看到了关键词"AESEncrypt",不就是我们刚刚 dInfo加密的函数名字嘛!第一个参数是_Ug0,第二个参数是sessionId。第二个我们有了,那么第一个参数是什么?

同时打印了(_ctu[_0x9pl[7]][_0x9pl[247]](_Ug0, _mGq[_0x9pl[46]][_0x9pl[104]])),可以证明此处就是data生成的地方。

39

39

40

40
在此文件搜索_Ug0,一下子就跟到了_Ug0生成的地方。

41

41

x是缺口,track是轨迹,p是一个有两个0的数组。

42

42

把_Ug0跟sessionId通过AES加密之后看看是不是跟浏览器生成的一样。

43

43

44

44

哟西,是一模一样的。

结尾:

轨迹处理大家可以参考k哥这篇文章【验证码逆向专栏】安某客滑块逆向 - 『脱壳破解区』 - 吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

我写这篇文章主要是因为不会改写,所以就用硬扣的方法完成这个滑块的逆向分析。方法虽然笨,但是笨鸟先飞。只要能解决问题的方法就是好方法!!!

前面的dInfo不需要和浏览器一模一样,指纹不一样其生成的就不一样。只要能请求获取到responseId那么就绝对没有问题啦。

免费评分

参与人数 40威望 +2 吾爱币 +139 热心值 +36 收起 理由
fengrenzi + 1 + 1 我很赞同!
wangwenjia + 1 + 1 我很赞同!
zhaocz + 1 + 1 用心讨论,共获提升!
15343347719 + 1 我很赞同!
541 + 1 + 1 我很赞同!
笙若 + 1 + 1 谢谢@Thanks!
shiloh21 + 1 谢谢@Thanks!
mingyuetianya + 1 + 1 我很赞同!
Boly + 1 谢谢@Thanks!
b12312312 + 1 + 1 我很赞同!
开心的一逼 + 1 + 1 谢谢@Thanks!
allspark + 1 + 1 用心讨论,共获提升!
PYNZ + 1 + 1 热心回复!
alderaan + 1 + 1 热心回复!
Yangzaipython + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
D3M1 + 1 + 1 谢谢@Thanks!
1MajorTom1 + 1 热心回复!
Bob5230 + 1 热心回复!
pnine + 1 + 1 我很赞同!
外酥内嫩 + 1 + 1 我很赞同!
Spacecraft + 1 用心讨论,共获提升!
DSUPER + 1 + 1 热心回复!
zoc + 1 + 1 大佬牛逼!!
毛新航 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
timeni + 1 + 1 用心讨论,共获提升!
aabbcc123123 + 1 + 1 谢谢@Thanks!
HillBoom + 1 + 1 用心讨论,共获提升!
Akihi6 + 1 + 1 用心讨论,共获提升!
cevin666 + 1 + 1 锟斤拷谢锟斤拷锟斤拷原锟斤拷锟斤拷品锟斤拷锟结爱锟狡斤拷锟斤拷坛锟斤拷.
N1san + 1 + 1 热心回复!
Javajpa + 1 + 1 用心讨论,共获提升!
fengbolee + 2 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
VXORBY + 1 + 1 谢谢@Thanks!
涛之雨 + 2 + 100 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
HaiWang2019 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
kevinbinhe + 1 + 1 谢谢@Thanks!
pwp + 3 + 1 我很赞同!
Learn3days + 1 + 1 用心讨论,共获提升!
钟欣桐 + 1 + 1 用心讨论,共获提升!
悦来客栈的老板 + 1 + 1 用心讨论,共获提升!

查看全部评分

本帖被以下淘专辑推荐:

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

ccwuax 发表于 2023-6-12 16:05
高手呀,像这种滑块加混淆的,我直接无视了,搞2个月都可能搞不出来,直接GG
spygg 发表于 2023-7-6 18:36
能从算法上突破很厉害,以前遇到阿里的拉到头校验的,什么随机值啥的办法想尽了都不行后来耍无赖,手动拉动然后记录下轨迹,后面回放这个轨迹竟然可以了
goodwz 发表于 2023-6-12 14:34
1188 发表于 2023-6-12 16:12
轨迹也好搞,用程序多跑些轨迹样本,数据丰富些,每次缺口在相同位置的,稍微修改几个值可以重复使用。
Jack-lee 发表于 2023-6-12 16:47
这种滑块验证码怎么做的么
头像被屏蔽
kevinbinhe 发表于 2023-6-12 19:43
提示: 该帖被管理员或版主屏蔽
爱吃鱼的有点帅 发表于 2023-6-12 22:36
大佬真牛批,好复杂
头像被屏蔽
moruye 发表于 2023-6-12 23:15
提示: 该帖被管理员或版主屏蔽
头像被屏蔽
LZW1768857595 发表于 2023-6-13 07:26
提示: 该帖被管理员或版主屏蔽
wendao_lx 发表于 2023-6-13 08:42
想请问,咋个手动解个混淆
您需要登录后才可以回帖 登录 | 注册[Register]

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

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

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

GMT+8, 2024-4-28 12:17

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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