1.调试前第一部曲 使用frida打开webview调试
- d*版本 5.31.1
根据历来活动界面经验,各大app使用webview进行活动的展开
使用frida hookd*app开启webview调试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | console.log("脚本加载成功");function main(){ Java.perform(function(){ var WebView = Java.use('android.webkit.WebView'); WebView.$init.overload('android.content.Context').implementation = function(a){ var result = this.$init(a); this.setWebContentsDebuggingEnabled(true); return result; } WebView.$init.overload('android.content.Context', 'android.util.AttributeSet').implementation = function(a,b){ var result = this.$init(a,b); this.setWebContentsDebuggingEnabled(true); return result; } WebView.$init.overload('android.content.Context', 'android.util.AttributeSet', 'int').implementation = function(a,b,c){ var result = this.$init(a,b,c); this.setWebContentsDebuggingEnabled(true); return result; } WebView.$init.overload('android.content.Context', 'android.util.AttributeSet', 'int', 'int').implementation = function(a,b,c,d){ var result = this.$init(a,b,c,d); this.setWebContentsDebuggingEnabled(true); return result; } WebView.$init.overload('android.content.Context', 'android.util.AttributeSet', 'int', 'boolean').implementation = function(a,b,c,d){ var result = this.$init(a,b,c,d); this.setWebContentsDebuggingEnabled(true); return result; } WebView.$init.overload('android.content.Context', 'android.util.AttributeSet', 'int', 'java.util.Map', 'boolean').implementation = function(a,b,c,d,e){ var result = this.$init(a,b,c,d,e); this.setWebContentsDebuggingEnabled(true); return result; } WebView.$init.overload('android.content.Context', 'android.util.AttributeSet', 'int', 'int', 'java.util.Map', 'boolean').implementation = function(a,b,c,d,e,f){ var result = this.$init(a,b,c,d,e,f); this.setWebContentsDebuggingEnabled(true); return result; } });}setImmediate(main); |
- 浏览器输入chrome://inspect/#devices 发现已经有目标调试网页出现


[!NOTE]
在逆向之前要确定好百分百加密的接口
首先我们要考虑接口的可触发次数,以及触发是否有其他杂乱接口干扰
以喂鱼接口为例子,我们只能触发有限次数
但是以任务菜单为例子,我们能触发多次,并且没有其他杂包
2.调试前第二部曲,过掉ob内自带无限debugger

点击后触发了无限debugger逻辑,考虑过掉该逻辑
可以考虑做抓包工具做远程替换,将'debu', 'gger'改为'',''即可
['constructor'](_0x2f614e['uzRAM']('debu', 'gger'))['call']('action');这里我们选择手动过掉

[!TIP]
OB混淆总是给人一种此地无银三百两的感觉,往下翻文件轻松的发现了加密逻辑位置,基本到这里就定位结束了。每次看到OB一些混淆,就知道接下来的任务简单了,攻破这个混淆就可以了
3. 开始确定调试目标
目标分析: data内加密字段
首先猜测是否为RSA、AES、DES

- 发送内容
1 | data: vyOviR13Aj2v2YfHwBzt9AZALCv7Tb7GGgbFy3bwIVlp/p1z8bInxbuAhqQlw3tuopM5OBzVnD0oyAX6CttfpA?59E9F16BA7DA911473B34942199E63906BB47BF669E930A449417783275F7A24F49E5456B23BE2C78286D67D85DB552D |
- 返回内容
1 | 0 DBBB668BAE191E448D975EC8321C631029ACCCEFF60F02B75B45731272A242E1500984E8A3794AF305613918247A9DCBAA62BC3A91B343D953B4E0574724B90F139F78CF3EBA716FA3B408FA0F25770285461FBA3481769948BD67F36A8584E9657B6111143A4F38AC89AB6975E61776964986E9A2D72F2365B9D6F0CF1A1BBC368CC632290B352DA22E8D412F11692F3FB683BBC03C650910E3373E74FA1C92D5881C594E9F32E259742E4F55AC4B06CE0A33054A9EEFC2AA6781F0CB0B7549007CC71053E3C042CEA2BE34ABDB228D3817067CEC998328EAA5E05C043D193D80A04F1CEC7E22BD396A4.........省略n多 |
- 由于发送以及返回都为加密内容,猜测为对称加密
4. 确定加密位置
- 观察启动器调用堆栈,发现调用堆栈极其复杂

- 所以我们开始使用一种技巧 观察文件名来确定业务逻辑主要的位置,

首先观测第一个js文件,我们可以将其标记为大环境框架js,内部有多种反射调用,疑似为异步调用框架。

由于这一层调用再fetch上面,所以有很大疑点,我们打断点进行观察


在上面发现是content-type等头部设置,我们在这里打上断点,观察这里的数据是否进行了加密。
[!TIP]
我认为JS逆向大部分跟参的过程都是在逐渐缩短自己的范围,如果我能确定这里已经生成了加密参数,那么在我接下来的逆向中,将会减少很多的工作量

由于ob混淆内部分逻辑在调试时会崩溃,所以采取去混淆行为。
[!tip]
新发现,在浏览器使用本地替换也可在远程调试webview的js中生效

确定接口名称和目标接口名称一致
在这时发现data并没有被加密,所以打在下一行,并且观察是否有网络请求发出

发现加密消失了(蜜罐),我们再次进行尝试,并观察密文生成位置
1 | "https://app.dewu.com/hacking-fish/v1/task/list?data=i4aGW0KBO1Rn6MBDfu%2FthRGTH4WL26tsRG5epeKND4xFVZdsJvwMJt9xJbAMY4hi09HOCqxTRQCRrEWqcsKt1w%E2%80%8BC74F514DAA73D51BBB723CC4B8FDEA29168327DD99B4BA5C1A0CA918F74375F359D3E405D4BBAFEE29E9CB872CA6CA14" |
发现在 const v = yield c(g, p) 这里的时候 我们的加密逻辑已经完成了,需要往上继续跟踪

我们跨过工具代码部分逻辑,继续分析。

发现这里已经生成了

由于堆栈跟踪断层,我们发现在请求函数的上层作用域有疑似参数处理过程 打好断点重新触发

发现了生成前的param对象

观察本作用域触发后的上一层,发现正在疑似拼接函数,跳出函数进行单步跟踪

定位方式1 硬跟异步,善用工具框架公用逻辑部分
时刻留意data动向进行继续单步跟踪(对付异步的比较不错的方法)


切记一定要用这个跟,其他的不要用

在yield这里狂按f9

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | return new (n || (n = Promise))((function(o, i) { function a(t) { try { f(r.next(t)) } catch (t) { i(t) } } function c(t) { try { f(r.throw(t)) } catch (t) { i(t) } } |
在这里发现异步实现框架,进行参数过滤

当t为关键参数时候,需要使用上面的f9跟进关键函数

在这里就可以使用条件断点,来过滤想要跟入的异步函数

我们发现,我们已经成功跟入了一个新的业务逻辑js(从名字观看)

从谷歌自带的提示中发现,貌似在循环执行五个函数
貌似是在对请求的数据进行处理,这也是我们需要的

(这里没法看到函数列表 一个一个去打断点,只能回到

继续单步跟入查看,查看位置都是一样的

直到跟入核心函数,对数据处理的部分

S.Fun110就是我们的目标函数
到此刻我们定位成功
定位方式2 巧用代理,定位加密参数生成位置(推荐)

首先我们先找到一个时机点,这个时机点应该是加密参数生成前,在请求基本生成完成后
请求基本生成完成后是指什么时刻?给出大家一个例子

在这里创建了基本请求后,然后有未加密的数据。
当然在要代理的地方我们不用过于担心设置的是否正确,我们可以正确的拿到承接关系
比如我们代理
1 2 3 4 5 | { path: this.listPath, method: "get", params: t } |
这个对象,但是对象赋值给了多个对象,我们对赋值的对象均进行跟踪
对每个值的以及每个值的拷贝进行跟踪
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | new Proxy(obj, {set: function(obj, prop, value) { console.log("set--->",obj, prop, value); debugger return Reflect.set(...arguments);}, get: function(obj, prop) { console.log("get--->",obj, prop); debugger return Reflect.get(...arguments); } } ) |
所以在此处我们设置

来观察e.data属性的获取情况,重点关注param的情况


这里出现了我们说的拷贝情况,把o.data一起代理上

观察获取到的属性,有param我们就观察上层堆栈


在这里发现v.data也需要设置

发现在获取param时候也成功定位到了加密函数
两种定位方式都需要一定调试技巧,在跟异步的时候都可以对流程的理清有一定帮助
5.进行算法还原
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 | 'value': function(_0x29b3a1, _0x105de1, _0x46790f, _0x5db7e4) { var _0x495033 = { 'jnDMy': function(_0x399cc7, _0x21f72e) { return _0x399cc7 - _0x21f72e; }, 'kREPA': function(_0x27b72a, _0x456f3a) { return _0x27b72a >> _0x456f3a; }, 'jbiNJ': function(_0x1694e5, _0x37a70c) { return _0x1694e5 + _0x37a70c; }, 'pgDxk': function(_0x1f7057, _0x573714) { return _0x35594c['aMZtC'](_0x1f7057, _0x573714); }, "\u0077\u0056\u0065\u004b\u004e": function(_0x2beba4) { return _0x35594c['Hwkfd'](_0x2beba4); }, 'FtodS': function(_0x18aecc, _0x493efd) { return _0x18aecc - _0x493efd; }, 'dNODL': function(_0x1aabb7, _0xce4941) { return _0x1aabb7 < _0xce4941; }, 'eovOE': function(_0x20e70a, _0x57ec84) { return _0x35594c['XTSbV'](_0x20e70a, _0x57ec84); }, 'JGYXo': function(_0x4a600c, _0x471cfd) { return _0x35594c['HwQGE'](_0x4a600c, _0x471cfd); }, 'DKWdp': function(_0x34df49, _0x1efc82) { return _0x35594c['cqNxF'](_0x34df49, _0x1efc82); }, 'uLcaf': function(_0x896ecd, _0x3cdc64) { return _0x35594c['Haher'](_0x896ecd, _0x3cdc64); }, 'fFTKY': function(_0x37b5b4, _0x373c04) { return _0x37b5b4 >= _0x373c04; }, 'NAEpD': function(_0x68aa83, _0x460689) { return _0x35594c['aLSFO'](_0x68aa83, _0x460689); }, 'NCrAQ': function(_0x1fe228, _0x57c621) { return _0x1fe228 % _0x57c621; }, 'Rbmel': function(_0x34d831, _0x4e6a74) { return _0x34d831 / _0x4e6a74; }, 'siLbZ': function(_0x104496, _0x5bdbaf) { return _0x104496 & _0x5bdbaf; }, 'Uzghn': function(_0x4454e1, _0x2f9444) { return _0x4454e1 - _0x2f9444; }, 'iImdx': function(_0x11bc2f, _0x4039cb) { return _0x11bc2f + _0x4039cb; }, 'bboWb': function(_0x2a5bac, _0x982394) { return _0x2a5bac != _0x982394; }, 'Cmwqf': function(_0x557ece, _0x3778c7) { return _0x557ece - _0x3778c7; }, 'RWuoe': function(_0x3d5eaa, _0x5dad97) { return _0x3d5eaa * _0x5dad97; }, 'YqrBL': function(_0x2a7355) { return _0x2a7355(); }, 'IDltp': function(_0x21a13a) { return _0x21a13a(); }, 'fklWl': function(_0x166bac, _0x98d225) { return _0x166bac(_0x98d225); }, 'ZhTHm': function(_0x24cc52) { return _0x24cc52(); }, 'tbWeE': function(_0x5a1e1d, _0x52bb9e) { return _0x5a1e1d >= _0x52bb9e; }, 'nUvFD': function(_0x4ee77b, _0x436c41) { return _0x4ee77b == _0x436c41; }, 'COxtG': function(_0x1433c5, _0x3b08e8) { return _0x1433c5 == _0x3b08e8; }, 'maQEK': function(_0x2600f8, _0x5a5b55) { return _0x2600f8 > _0x5a5b55; }, 'Pteet': function(_0xf9798b, _0x132e77) { return _0xf9798b >> _0x132e77; }, 'mxZIe': function(_0xf2e1e4, _0xd1632a) { return _0xf2e1e4 >= _0xd1632a; }, 'bcKuF': function(_0x870c5e, _0x1a7bf3) { return _0x870c5e < _0x1a7bf3; }, "\u0059\u0050\u0064\u0073\u006c": function(_0x1dc8d0, _0x271b0b) { return _0x35594c['gUBLr'](_0x1dc8d0, _0x271b0b); }, 'uniSO': function(_0x280a53, _0x2843ba) { return _0x280a53 & _0x2843ba; }, 'hhxpV': function(_0x43fda3, _0x3ef904) { return _0x43fda3 < _0x3ef904; }, 'nUORC': function(_0x49652d, _0x303afc) { return _0x49652d < _0x303afc; }, 'blZcG': function(_0x34a5e5, _0x47dfc3) { return _0x34a5e5 + _0x47dfc3; }, 'nDhum': function(_0x20cee7, _0x3c40c1) { return _0x20cee7(_0x3c40c1); }, 'PRHhW': function(_0x4ca3a6, _0x2fd0b0) { return _0x4ca3a6 >> _0x2fd0b0; }, 'YMZWA': function(_0x1b56d9, _0x4e7143) { return _0x1b56d9 | _0x4e7143; }, 'xmGMu': function(_0x3668cf, _0x24817e) { return _0x3668cf > _0x24817e; }, 'wkVpc': function(_0x46a0e7, _0x41ee8a) { return _0x35594c['ohatu'](_0x46a0e7, _0x41ee8a); }, 'IUSwf': 'unsupported\x20PKCS#8\x20public\x20key\x20hex', 'Glggr': function(_0x2d00ef, _0x4f6fe4) { return _0x2d00ef !== _0x4f6fe4; } }; var _0x4879b7, _0x4a8f01, _0x1a0eab, _0x5da258, _0x2bd525, _0xe412e2, _0x345581, _0x4dfef5, _0x483389, _0x3bf831, _0x1c4a22, _0x4595dc, _0x3291c5, _0x10fab7 = _0x42a8e8(0x30, 0x10), _0x3b1c65 = '', _0x4a9b51 = '0', _0x11dd4c = _0x29b3a1; if ("teg".split("").reverse().join("") === (_0x105de1 || 'post')['toLocaleLowerCase']()) try { var _0x1e5a73 = [] , _0x3e45e7 = JSON['parse'](_0x29b3a1); Object['keys'](_0x3e45e7)['map'](function(_0x9b096) { return _0x1e5a73['push'](''['concat'](_0x9b096, '=')['concat'](encodeURIComponent(_0x3e45e7[_0x9b096]))), _0x9b096; }), _0x11dd4c = _0x1e5a73['join']('&'); } catch (_0x4997f8) { console['log'](_0x35594c['MSvQu']); } if (!_0x5db7e4 && '0' === String(_0x257145)) return { 'a': _0x10fab7, 'b': _0x42a8e8(0x30, 0x10), 'c': ''['concat'](_0x4a9b51, ',')['concat'](_0x128360), 'd': _0x29b3a1, 'e': _0x42a8e8(0x30, 0x10) }; try { var _0x173191, _0x59ca79 = function(_0x1cabba, _0x15b456, _0x4acfca) { _0x337f99['dnHfa'](null, _0x1cabba) && (_0x337f99['FOejE'](_0x337f99['upliq'], typeof _0x1cabba) ? this['fromNumber'](_0x1cabba, _0x15b456, _0x4acfca) : null == _0x15b456 && _0x337f99['TVpeu']('string', typeof _0x1cabba) ? this['fromString'](_0x1cabba, 0x100) : this['fromString'](_0x1cabba, _0x15b456)); }, _0x400e8f = function() { return new _0x59ca79(null); }, _0x316e10 = function(_0x2569d6) { var _0x528ed4, _0x5217de, _0x1de34f, _0x20f23b = '', _0x191816 = 0x0; for (_0x528ed4 = 0x0; _0x528ed4 < _0x2569d6['length'] && _0x2569d6['charAt'](_0x528ed4) != _0xe72856; ++_0x528ed4) _0x337f99['IOuwo'](_0x1de34f = _0x16d26a['indexOf'](_0x2569d6['charAt'](_0x528ed4)), 0x0) || (0x0 == _0x191816 ? (_0x20f23b += _0x4d7989(_0x1de34f >> 0x2), _0x5217de = _0x337f99['SjWnk'](0x3, _0x1de34f), _0x191816 = 0x1) : 0x1 == _0x191816 ? (_0x20f23b += _0x4d7989(_0x337f99['iVTra'](_0x5217de, 0x2) | _0x1de34f >> 0x4), _0x5217de = _0x337f99['SjWnk'](0xf, _0x1de34f), _0x191816 = 0x2) : 0x2 == _0x191816 ? (_0x20f23b += _0x337f99['qEDXs'](_0x4d7989, _0x5217de), _0x20f23b += _0x4d7989(_0x1de34f >> 0x2), _0x5217de = _0x337f99['OJQhi'](0x3, _0x1de34f), _0x191816 = 0x3) : (_0x20f23b += _0x4d7989(_0x5217de << 0x2 | _0x1de34f >> 0x4), _0x20f23b += _0x4d7989(_0x337f99['KuSZA'](0xf, _0x1de34f)), _0x191816 = 0x0)); return 0x1 == _0x191816 && (_0x20f23b += _0x4d7989(_0x337f99['iVTra'](_0x5217de, 0x2))), _0x20f23b; }, _0x4d7989 = function(_0x579c8f) { return _0x5ca101['charAt'](_0x579c8f); }, _0x10aeb0 = function(_0x428ff9, _0x276953) { var _0x1d865e = _0x12330c[_0x428ff9['charCodeAt'](_0x276953)]; return null == _0x1d865e ? -0x1 : _0x1d865e; }, _0x271122 = function(_0x244e5b) { var _0x1792c6, _0x250c55 = 0x1; return _0x337f99['dnHfa'](0x0, _0x1792c6 = _0x337f99['PlLEe'](_0x244e5b, 0x10)) && (_0x244e5b = _0x1792c6, _0x250c55 += 0x10), 0x0 != (_0x1792c6 = _0x244e5b >> 0x8) && (_0x244e5b = _0x1792c6, _0x250c55 += 0x8), _0x337f99['PnfLG'](0x0, _0x1792c6 = _0x244e5b >> 0x4) && (_0x244e5b = _0x1792c6, _0x250c55 += 0x4), 0x0 != (_0x1792c6 = _0x244e5b >> 0x2) && (_0x244e5b = _0x1792c6, _0x250c55 += 0x2), 0x0 != (_0x1792c6 = _0x244e5b >> 0x1) && (_0x244e5b = _0x1792c6, _0x250c55 += 0x1), _0x250c55; }, _0x1de423 = function(_0x470164) { this['m'] = _0x470164; }, _0x5033d5 = function(_0x1c3314) { this['m'] = _0x1c3314, this['mp'] = _0x1c3314['invDigit'](), this['mpl'] = 0x7fff & this['mp'], this['mph'] = this['mp'] >> 0xf, this['um'] = _0x495033['jnDMy'](0x1 << _0x1c3314['DB'] - 0xf, 0x1), this['mt2'] = 0x2 * _0x1c3314['t']; }, _0xa66064 = function() { this['i'] = 0x0, this['j'] = 0x0, this['S'] = new Array(); }, _0x4f62c5 = function() { !function(_0x39abac) { _0x171384[_0x5c9259++] ^= 0xff & _0x39abac, _0x171384[_0x5c9259++] ^= _0x39abac >> 0x8 & 0xff, _0x171384[_0x5c9259++] ^= _0x39abac >> 0x10 & 0xff, _0x171384[_0x5c9259++] ^= _0x495033['kREPA'](_0x39abac, 0x18) & 0xff, _0x5c9259 >= _0x446f14 && (_0x5c9259 -= _0x446f14); }(new Date()['getTime']()); }, _0x27cf6d = function() { if (null == _0x42b025) { for (_0x4f62c5(), (_0x42b025 = new _0xa66064())['init'](_0x171384), _0x5c9259 = 0x0; _0x5c9259 < _0x171384['length']; ++_0x5c9259) _0x171384[_0x5c9259] = 0x0; _0x5c9259 = 0x0; } return _0x42b025['next'](); }, _0x13d83e = function() {}, _0x47f03c = function() { this['n'] = null, this['e'] = 0x0, this['d'] = null, this['p'] = null, this['q'] = null, this['dmp1'] = null, this['dmq1'] = null, this['coeff'] = null; }; 'Microsoft\x20Internet\x20Explorer' == navigator['appName'] ? (_0x59ca79['prototype']['am'] = function(_0x997169, _0x13e72e, _0x30fb98, _0x4d34cb, _0x51786c, _0x452448) { for (var _0x1345c7 = 0x7fff & _0x13e72e, _0x4c73ab = _0x13e72e >> 0xf; --_0x452448 >= 0x0; ) { var _0x547e23 = 0x7fff & this[_0x997169] , _0x190547 = _0x337f99['CkSfX'](this[_0x997169++], 0xf) , _0x3aefc8 = _0x4c73ab * _0x547e23 + _0x190547 * _0x1345c7; _0x51786c = _0x337f99['CwSBC'](_0x337f99['PlLEe'](_0x547e23 = _0x337f99['cccOp'](_0x1345c7 * _0x547e23 + ((0x7fff & _0x3aefc8) << 0xf), _0x30fb98[_0x4d34cb]) + (0x3fffffff & _0x51786c), 0x1e) + _0x337f99['PlLEe'](_0x3aefc8, 0xf), _0x337f99['UBVQR'](_0x4c73ab, _0x190547)) + (_0x51786c >>> 0x1e), _0x30fb98[_0x4d34cb++] = _0x337f99['OJQhi'](0x3fffffff, _0x547e23); } return _0x51786c; } , _0x173191 = 0x1e) : _0x35594c['VTQiX']("epacsteN".split("").reverse().join(""), navigator['appName']) ? (_0x59ca79['prototype']['am'] = function(_0x53ad28, _0x5b1d73, _0xe60088, _0x574d0d, _0x40bb42, _0xb27fd2) { for (; --_0xb27fd2 >= 0x0; ) { var _0x54c12e = _0x495033['jbiNJ'](_0x5b1d73 * this[_0x53ad28++], _0xe60088[_0x574d0d]) + _0x40bb42; _0x40bb42 = Math['floor'](_0x54c12e / 0x4000000), _0xe60088[_0x574d0d++] = _0x495033['pgDxk'](0x3ffffff, _0x54c12e); } return _0x40bb42; } , _0x173191 = 0x1a) : (_0x59ca79['prototype']['am'] = function(_0xa394d3, _0x1ac0ad, _0x5a4adf, _0x2727f7, _0x25ef30, _0xb77c06) { for (var _0x3f16d3 = 0x3fff & _0x1ac0ad, _0x4b2a4f = _0x1ac0ad >> 0xe; --_0xb77c06 >= 0x0; ) { var _0x2096ad = _0x337f99['YirMV'](0x3fff, this[_0xa394d3]) , _0x383759 = this[_0xa394d3++] >> 0xe , _0x1d1f92 = _0x337f99['CwSBC'](_0x4b2a4f * _0x2096ad, _0x383759 * _0x3f16d3); _0x25ef30 = ((_0x2096ad = _0x3f16d3 * _0x2096ad + (_0x337f99['XFjfj'](0x3fff, _0x1d1f92) << 0xe) + _0x5a4adf[_0x2727f7] + _0x25ef30) >> 0x1c) + (_0x1d1f92 >> 0xe) + _0x4b2a4f * _0x383759, _0x5a4adf[_0x2727f7++] = 0xfffffff & _0x2096ad; } return _0x25ef30; } , _0x173191 = 0x1c); var _0x16d26a = "/+9876543210zyxwvutsrqponmlkjihgfedcbaZYXWVUTSRQPONMLKJIHGFEDCBA".split("").reverse().join("") , _0xe72856 = '='; _0x59ca79['prototype']['DB'] = _0x173191, _0x59ca79['prototype']['DM'] = _0x35594c['Haher'](0x1, _0x173191) - 0x1, _0x59ca79['prototype']['DV'] = 0x1 << _0x173191, _0x59ca79['prototype']['FV'] = Math['pow'](0x2, 0x34), _0x59ca79['prototype']['F1'] = 0x34 - _0x173191, _0x59ca79['prototype']['F2'] = _0x35594c['qQlTX'](0x2, _0x173191) - 0x34; var _0x278663, _0x31bca6, _0x5ca101 = '0123456789abcdefghijklmnopqrstuvwxyz', _0x12330c = new Array(); for (_0x278663 = '0'['charCodeAt'](0x0), _0x31bca6 = 0x0; _0x31bca6 <= 0x9; ++_0x31bca6) _0x12330c[_0x278663++] = _0x31bca6; for (_0x278663 = 'a'['charCodeAt'](0x0), _0x31bca6 = 0xa; _0x35594c['gUBLr'](_0x31bca6, 0x24); ++_0x31bca6) _0x12330c[_0x278663++] = _0x31bca6; for (_0x278663 = 'A'['charCodeAt'](0x0), _0x31bca6 = 0xa; _0x31bca6 < 0x24; ++_0x31bca6) _0x12330c[_0x278663++] = _0x31bca6; _0x1de423['prototype']['convert'] = function(_0x1d9733) { return _0x1d9733['s'] < 0x0 || _0x1d9733['compareTo'](this['m']) >= 0x0 ? _0x1d9733['mod'](this['m']) : _0x1d9733; } , _0x1de423['prototype']['revert'] = function(_0x1a46be) { return _0x1a46be; } , _0x1de423['prototype']['reduce'] = function(_0x143f01) { _0x143f01['divRemTo'](this['m'], null, _0x143f01); } , _0x1de423['prototype']['mulTo'] = function(_0x12a399, _0x5b95c6, _0x12a816) { _0x12a399['multiplyTo'](_0x5b95c6, _0x12a816), this['reduce'](_0x12a816); } , _0x1de423['prototype']['sqrTo'] = function(_0x35a5b5, _0x3a2efe) { _0x35a5b5['squareTo'](_0x3a2efe), this['reduce'](_0x3a2efe); } , _0x5033d5['prototype']['convert'] = function(_0x36c1f1) { var _0x4ef797 = _0x400e8f(); return _0x36c1f1['abs']()['dlShiftTo'](this['m']['t'], _0x4ef797), _0x4ef797['divRemTo'](this['m'], null, _0x4ef797), _0x36c1f1['s'] < 0x0 && _0x4ef797['compareTo'](_0x59ca79['ZERO']) > 0x0 && this['m']['subTo'](_0x4ef797, _0x4ef797), _0x4ef797; } , _0x5033d5['prototype']['revert'] = function(_0x10be0c) { var _0x32d8cc = _0x495033['wVeKN'](_0x400e8f); return _0x10be0c['copyTo'](_0x32d8cc), this['reduce'](_0x32d8cc), _0x32d8cc; } , _0x5033d5['prototype']['reduce'] = function(_0x5e09a8) { for (; _0x5e09a8['t'] <= this['mt2']; ) _0x5e09a8[_0x5e09a8['t']++] = 0x0; for (var _0x8bb497 = 0x0; _0x8bb497 < this['m']['t']; ++_0x8bb497) { var _0x3934d6 = 0x7fff & _0x5e09a8[_0x8bb497] , _0x245588 = _0x337f99['VUyyp'](_0x3934d6 * this['mpl'], (_0x337f99['UBVQR'](_0x3934d6, this['mph']) + (_0x5e09a8[_0x8bb497] >> 0xf) * this['mpl'] & this['um']) << 0xf) & _0x5e09a8['DM']; for (_0x5e09a8[_0x3934d6 = _0x337f99['NScfM'](_0x8bb497, this['m']['t'])] += this['m']['am'](0x0, _0x245588, _0x5e09a8, _0x8bb497, 0x0, this['m']['t']); _0x337f99['OKtob'](_0x5e09a8[_0x3934d6], _0x5e09a8['DV']); ) _0x5e09a8[_0x3934d6] -= _0x5e09a8['DV'], _0x5e09a8[++_0x3934d6]++; } _0x5e09a8['clamp'](), _0x5e09a8['drShiftTo'](this['m']['t'], _0x5e09a8), _0x337f99['pAsGx'](_0x5e09a8['compareTo'](this['m']), 0x0) && _0x5e09a8['subTo'](this['m'], _0x5e09a8); } , _0x5033d5['prototype']['mulTo'] = function(_0x455b2f, _0x54e3f6, _0x366c2a) { _0x455b2f['multiplyTo'](_0x54e3f6, _0x366c2a), this['reduce'](_0x366c2a); } , _0x5033d5['prototype']['sqrTo'] = function(_0x2f5649, _0x4ca1d4) { _0x2f5649['squareTo'](_0x4ca1d4), this['reduce'](_0x4ca1d4); } , _0x59ca79['prototype']['copyTo'] = function(_0x246d98) { for (var _0x670209 = _0x495033['FtodS'](this['t'], 0x1); _0x670209 >= 0x0; --_0x670209) _0x246d98[_0x670209] = this[_0x670209]; _0x246d98['t'] = this['t'], _0x246d98['s'] = this['s']; } , _0x59ca79['prototype']['fromInt'] = function(_0x592524) { this['t'] = 0x1, this['s'] = _0x495033['dNODL'](_0x592524, 0x0) ? -0x1 : 0x0, _0x495033['eovOE'](_0x592524, 0x0) ? this[0x0] = _0x592524 : _0x592524 < -0x1 ? this[0x0] = _0x495033['jbiNJ'](_0x592524, this['DV']) : this['t'] = 0x0; } , _0x59ca79['prototype']['fromString'] = function(_0x4ec61a, _0x54fd36) { var _0x4e4aa4; if (_0x495033['JGYXo'](0x10, _0x54fd36)) _0x4e4aa4 = 0x4; else if (_0x495033['JGYXo'](0x8, _0x54fd36)) _0x4e4aa4 = 0x3; else if (0x100 == _0x54fd36) _0x4e4aa4 = 0x8; else if (0x2 == _0x54fd36) _0x4e4aa4 = 0x1; else if (0x20 == _0x54fd36) _0x4e4aa4 = 0x5; else { if (0x4 != _0x54fd36) return void this['fromRadix'](_0x4ec61a, _0x54fd36); _0x4e4aa4 = 0x2; } this['t'] = 0x0, this['s'] = 0x0; for (var _0x3feedf = _0x4ec61a['length'], _0x26405f = !0x1, _0x60ba00 = 0x0; --_0x3feedf >= 0x0; ) { var _0x256069 = 0x8 == _0x4e4aa4 ? 0xff & _0x4ec61a[_0x3feedf] : _0x10aeb0(_0x4ec61a, _0x3feedf); _0x256069 < 0x0 ? _0x495033['DKWdp']('-', _0x4ec61a['charAt'](_0x3feedf)) && (_0x26405f = !0x0) : (_0x26405f = !0x1, 0x0 == _0x60ba00 ? this[this['t']++] = _0x256069 : _0x495033['jbiNJ'](_0x60ba00, _0x4e4aa4) > this['DB'] ? (this[this['t'] - 0x1] |= (_0x256069 & (0x1 << this['DB'] - _0x60ba00) - 0x1) << _0x60ba00, this[this['t']++] = _0x256069 >> this['DB'] - _0x60ba00) : this[this['t'] - 0x1] |= _0x495033['uLcaf'](_0x256069, _0x60ba00), _0x495033['fFTKY'](_0x60ba00 += _0x4e4aa4, this['DB']) && (_0x60ba00 -= this['DB'])); } 0x8 == _0x4e4aa4 && 0x0 != _0x495033['pgDxk'](0x80, _0x4ec61a[0x0]) && (this['s'] = -0x1, _0x60ba00 > 0x0 && (this[this['t'] - 0x1] |= _0x495033['uLcaf']((0x1 << _0x495033['jnDMy'](this['DB'], _0x60ba00)) - 0x1, _0x60ba00))), this['clamp'](), _0x26405f && _0x59ca79['ZERO']['subTo'](this, this); } , _0x59ca79['prototype']['clamp'] = function() { for (var _0x524ab4 = this['s'] & this['DM']; this['t'] > 0x0 && this[_0x337f99['DYHQZ'](this['t'], 0x1)] == _0x524ab4; ) --this['t']; } , _0x59ca79['prototype']['dlShiftTo'] = function(_0x127b5a, _0x5a3f5d) { var _0x3ae35a; for (_0x3ae35a = _0x495033['jnDMy'](this['t'], 0x1); _0x3ae35a >= 0x0; --_0x3ae35a) _0x5a3f5d[_0x3ae35a + _0x127b5a] = this[_0x3ae35a]; for (_0x3ae35a = _0x495033['FtodS'](_0x127b5a, 0x1); _0x3ae35a >= 0x0; --_0x3ae35a) _0x5a3f5d[_0x3ae35a] = 0x0; _0x5a3f5d['t'] = _0x495033['NAEpD'](this['t'], _0x127b5a), _0x5a3f5d['s'] = this['s']; } , _0x59ca79['prototype']['drShiftTo'] = function(_0x491999, _0x11a0b1) { for (var _0x34467b = _0x491999; _0x34467b < this['t']; ++_0x34467b) _0x11a0b1[_0x34467b - _0x491999] = this[_0x34467b]; _0x11a0b1['t'] = Math['max'](_0x495033['FtodS'](this['t'], _0x491999), 0x0), _0x11a0b1['s'] = this['s']; } , _0x59ca79['prototype']['lShiftTo'] = function(_0x4a74ad, _0x396269) { var _0x5b8409, _0x3b0ced = _0x495033["\u004e\u0043\u0072\u0041\u0051"](_0x4a74ad, this['DB']), _0x10ba0f = this['DB'] - _0x3b0ced, _0x41ca43 = _0x495033['jnDMy'](0x1 << _0x10ba0f, 0x1), _0x3ce424 = Math['floor'](_0x495033['Rbmel'](_0x4a74ad, this['DB'])), _0x3d2ed7 = _0x495033['siLbZ'](this['s'] << _0x3b0ced, this['DM']); for (_0x5b8409 = this['t'] - 0x1; _0x5b8409 >= 0x0; --_0x5b8409) _0x396269[_0x5b8409 + _0x3ce424 + 0x1] = this[_0x5b8409] >> _0x10ba0f | _0x3d2ed7, _0x3d2ed7 = (this[_0x5b8409] & _0x41ca43) << _0x3b0ced; for (_0x5b8409 = _0x495033['Uzghn'](_0x3ce424, 0x1); _0x5b8409 >= 0x0; --_0x5b8409) _0x396269[_0x5b8409] = 0x0; _0x396269[_0x3ce424] = _0x3d2ed7, _0x396269['t'] = _0x495033['NAEpD'](this['t'], _0x3ce424) + 0x1, _0x396269['s'] = this['s'], _0x396269['clamp'](); } , _0x59ca79['prototype']['rShiftTo'] = function(_0x196e06, _0x618c6c) { _0x618c6c['s'] = this['s']; var _0x2625e7 = Math['floor'](_0x196e06 / this['DB']); if (_0x2625e7 >= this['t']) _0x618c6c['t'] = 0x0; else { var _0x18d979 = _0x337f99['deNGZ'](_0x196e06, this['DB']) , _0x195461 = _0x337f99['DYHQZ'](this['DB'], _0x18d979) , _0x4ef2d5 = _0x337f99['DYHQZ'](0x1 << _0x18d979, 0x1); _0x618c6c[0x0] = this[_0x2625e7] >> _0x18d979; for (var _0x17d5a2 = _0x2625e7 + 0x1; _0x17d5a2 < this['t']; ++_0x17d5a2) _0x618c6c[_0x337f99['DYHQZ'](_0x17d5a2, _0x2625e7) - 0x1] |= (this[_0x17d5a2] & _0x4ef2d5) << _0x195461, _0x618c6c[_0x17d5a2 - _0x2625e7] = _0x337f99['KbFOT'](this[_0x17d5a2], _0x18d979); _0x18d979 > 0x0 && (_0x618c6c[_0x337f99['DYHQZ'](_0x337f99['DYHQZ'](this['t'], _0x2625e7), 0x1)] |= _0x337f99['FTCXD'](this['s'] & _0x4ef2d5, _0x195461)), _0x618c6c['t'] = this['t'] - _0x2625e7, _0x618c6c['clamp'](); } } , _0x59ca79['prototype']['subTo'] = function(_0x4dbc12, _0x20a2d1) { for (var _0x189c46 = 0x0, _0x30233b = 0x0, _0x4252e4 = Math['min'](_0x4dbc12['t'], this['t']); _0x337f99['kiEVa'](_0x189c46, _0x4252e4); ) _0x30233b += _0x337f99['DYHQZ'](this[_0x189c46], _0x4dbc12[_0x189c46]), _0x20a2d1[_0x189c46++] = _0x337f99['Vdwnb'](_0x30233b, this['DM']), _0x30233b >>= this['DB']; if (_0x4dbc12['t'] < this['t']) { for (_0x30233b -= _0x4dbc12['s']; _0x189c46 < this['t']; ) _0x30233b += this[_0x189c46], _0x20a2d1[_0x189c46++] = _0x30233b & this['DM'], _0x30233b >>= this['DB']; _0x30233b += this['s']; } else { for (_0x30233b += this['s']; _0x189c46 < _0x4dbc12['t']; ) _0x30233b -= _0x4dbc12[_0x189c46], _0x20a2d1[_0x189c46++] = _0x337f99['peDge'](_0x30233b, this['DM']), _0x30233b >>= this['DB']; _0x30233b -= _0x4dbc12['s']; } _0x20a2d1['s'] = _0x30233b < 0x0 ? -0x1 : 0x0, _0x30233b < -0x1 ? _0x20a2d1[_0x189c46++] = this['DV'] + _0x30233b : _0x337f99['RShhk'](_0x30233b, 0x0) && (_0x20a2d1[_0x189c46++] = _0x30233b), _0x20a2d1['t'] = _0x189c46, _0x20a2d1['clamp'](); } |
映入眼帘的是一个简单的ob混淆,简单的ob混淆和看源码一样
[!tip]
这里有一个小技巧,打return语句的断点,看从哪里返回,再次出发,反向跟踪

将这个函数里的return语句都打上断点
建议拖到可以折叠的ide里面,搞清函数作用域再下手


发现在尾部的对象比较可疑,并且发现了一定的浏览器检测函数

和我们猜想的一样,数据最终在此处生成,我们首先先跟踪_0x10fab7的生成方式

用搜索功能发现这个是随机生成的哈希值
遗憾的发现 abcde中 abce都是随机值
分析一下data数据的来源

发现数据来源一个aes
1 | 'data': ''['concat'](_0x4879b7, '?')['concat'](''['concat'](_0x4a8f01)['concat'](_0x3bf831)['concat'](_0x1c4a22)['concat'](_0x2bd525)['concat'](_0xe412e2)['concat'](_0x345581)['concat'](_0x4dfef5)['concat'](_0x483389)['concat'](_0x1a0eab)['concat'](_0x5da258)['concat'](_0x3291c5)['concat'](_0x4595dc)['length'] > 0x5 ? ''['concat'](_0x4a8f01)['concat'](_0x3bf831)['concat'](_0x1c4a22)['concat'](_0x2bd525)['concat'](_0xe412e2)['concat'](_0x345581)['concat'](_0x4dfef5)['concat'](_0x5b3ed3)['concat'](_0x1a0eab)['concat'](_0x5da258)['concat'](_0x3291c5)['concat'](_0x4595dc) : '')['concat'](_0x3d369) |
在这里发现一顿concat ,只有_0x4879b7 _0x3d369有值
在上面发现aes加密逻辑

key和iv都很明显
9AB3F04305F7C09AA29B48B729461DD2F5437976EDF4806D
key:
_0x24bbfa['enc']['Utf8']['parse'](_0x10fab7['substr'](0xa, 0x10))
'F7C09AA29B48B729'
iv:
_0x24bbfa['enc']['Utf8']['parse'](_0x10fab7['substr'](0x14, 0x10)
'48B729461DD2F543'
加密结果(为第二个参数的值)
'7369676e3d6665323662656663343934343464333632633866313734363336333062646261'
1 2 | var _0x3d369 = _0x3b1c65 ? _0x3b1c65['ciphertext'] ? _0x3b1c65['ciphertext']['toString']()['toUpperCase']() : _0x3b1c65 : '', _0x43a85d = _0x10fab7['split'](""), _0xc7af72 = Number(_0x35594c['qNJuC'](new Date()['valueOf'](), 0x3e8)['toFixed'](0x0))['toString'](0x10)['toUpperCase']()['split'](''); |
接下来发现对密文进行处理
var _0x3d369 = _0x3b1c65 ? _0x3b1c65['ciphertext'] ? _0x3b1c65['ciphertext']['toString']()['toUpperCase']() : _0x3b1c65 : ''
碰巧拿到了上面拼接的第二个参数
接下来继续研究第一参数的生成

发现其参数生成和日期有关系

这个是在生成时间戳
1 | var _0x16af4, _0x2551e2, _0x30a9c6 = _0x109447['getKey'](_0x35594c['atlzK'])['encrypt'](_0x43a85d['join']('')), _0x365b44 = "".split("").reverse().join(""); |
在这里发现了对aes的密钥的进一步加密 从getkey可以大致推断出他是rsa加密
'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANMGZPlLobHYWoZyMvHD0a6emIjEmtf5Z6Q++VIBRulxsUfYvcczjB0fMVvAnd1douKmOX4G690q9NZ6Q7z/TV8CAwEAAQ=='从返回值中拿到密钥

看到了npq 以及e 即可确定这是一个标准的rsa加密,我们接下来只需要得到加密前的明文即可完成分析

在encrypt后打断点观察明文

发现明文就是92B3F04305F7C09AA29B48B729461DD2F5437976662B4ED4
49714c457c58d6734ad87bda0ec38b1bad41d89ceecea1eb4d9cdcfaccf654ec48e0ec2c0cee3722a48aa1b56b8a14a5fbb003e80d5b920e33dad3072408af3d
加密的结果长度和第一个差不多,我推测就是一个编码的转换问题
"SXFMRXxY1nNK2HvaDsOLG61B2JzuzqHrTZzc+sz2VOxI4OwsDO43IqSKobVrihSl+7AD6A1bkg4z2tMHJAivPQ"

发现我们推断的结果正确,到此加密分析全部结束
总结

在分析过程中,发现大量明文对浏览器环境的监测,防止大家放到node里面一把梭,总的来说是做算法更容易一些。
[!tip]
对d*的防护建议:
对关键字符串进行加密,此文件中多次出现encrypt关键字,并且AES加密也没有进行隐藏,很容易搜索定位到。
建议取消无限debugger的防护,这样给人一种此地无银三百两的感觉,直接定位到了关键加密的函数