吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2825|回复: 32
收起左侧

[Web逆向] 某试读解密

[复制链接]
scz 发表于 2024-9-1 15:02

创建: 2024-09-01 14:26

纯粹是好奇心,无其他意图,如有侵权,删之即可。

逆向目标

RC4密文: 54f7d1b1123e55cd0b4347a7e6c696d57d531c818c891f930cbb5f3bbdc1bc7b999a9cfbbbae76eaeb5628e1230cba
RC4KEY:  V0hBVCBUSEUgRlVDSw==

访问目标,有18页试读。F12注意到chunk-6699a887.e1b613e3.js,Babel反混淆。有几个函数太扎眼:

//
// _0x57ce6e即
// https://path/some.xxxx
//
// 从此函数看出,有种情况会出现some.zip,而非some.xxxx
//
async 'openURL'(_0x57ce6e) {
    const _0x3f7d43 = _0x377d3e;
    this.lazyAble ? this.loadDecrypt(this.lazyUrl + '0.xxxx') : _0x57ce6e.endsWith(".zip") ? this.loadHash(_0x57ce6e) : _0x57ce6e.endsWith(".xxxx") ? this.loadDecrypt(_0x57ce6e) : this._openURL(_0x57ce6e);
},

//
// _0x21407d即some.xxxx
//
// _0x2815a9对象有两个属性
// "password": "9YsNbnJtxoeFu1MbGnH8cP7qWUHwEsNg",
// "spassword": "xSeZw1dY2HKAj3yk",
//
// Object(_0x4710a0.a)即function _0x3f2c74
//
async 'loadDecrypt'(_0x21407d) {
    const _0x1ff5be = _0x377d3e;
    let _0x415c9c = await fetch(_0x21407d);
    if (_0x415c9c.ok) {
        //
        // AES-CBC解密,得到PDF数据,放在_0x1c4379中
        //
        const _0x1c4379 = await Object(_0x4710a0.a)(_0x415c9c, _0x2815a9.spassword);
        try {
            await this.initDocument(_0x1c4379.buffer, 'aaa.pdf'),
            this.loading = false,
            this.updateView();
        } catch (_0x7c47b4) {
            console.log(_0x7c47b4);
        }
    }
},

//
// loadDecrypt会调用此函数
//
// _0x1f65fe对应some.xxxx
// _0x3c635f是"xSeZw1dY2HKAj3yk"
//
async function _0x3f2c74(_0x1f65fe, _0x3c635f) {
    const _0x5241fb = _0x49a261,
    //
    // _0x178a1b即some.xxxx的数据
    //
    _0x178a1b = await _0x1f65fe.arrayBuffer(),
    //
    // salt
    //
    _0x1633f3 = _0x178a1b.slice(0x0, 0x8),
    //
    // iv
    //
    _0x26ccd9 = _0x178a1b.slice(0x8, 0x18),
    _0x24e12e = _0x178a1b.slice(0x18),
    //
    // Derive PBKDF2 key
    // password="xSeZw1dY2HKAj3yk"
    // salt
    //
    _0x1404e3 = await _0x4b76a1(_0x3c635f, _0x1633f3),
    _0x1a9ab4 = await window.crypto.subtle.decrypt({
        'name': "AES-CBC",
        'iv': _0x26ccd9
    }, _0x1404e3, _0x24e12e);
    return new Uint8Array(_0x1a9ab4);
}

//
// loadDecrypt会间接调用此函数
// _0xb02836是"xSeZw1dY2HKAj3yk",_0x1d6150即0.xxxx前8字节,充作
// PBKDF2的salt
//
// CyberChef/Derive PBKDF2 key
// Passphrase="xSeZw1dY2HKAj3yk" (UTF8)
// Key size=128
// Iterations=65536
// Hashing functioin=SHA256
// Salt=d6 dc bf d0 0e c1 81 f1 (HEX)
// Output=1f67c8caec75e3069c52e43e29555904
//
async function _0x4b76a1(_0xb02836, _0x1d6150) {
    const _0x5a76ae = _0x49a261,
    _0x31b848 = {
        'name': 'PBKDF2',
        'salt': _0x1d6150,
        'iterations': 0x10000,
        'hash': 'SHA-256'
    },
    _0x42ed5e = await window.crypto.subtle.importKey("raw", new TextEncoder().encode(_0xb02836), {
        'name': "PBKDF2"
    }, false, ["deriveKey"]),
    _0x11cb7a = await window.crypto.subtle.deriveKey(_0x31b848, _0x42ed5e, {
        'name': "AES-CBC",
        'length': 0x80
    //
    // false改成true,表示extractable,方便查看结果
    // }, false, ["encrypt", "decrypt"]);
    //
    }, true, ["encrypt", "decrypt"]);
  return _0x11cb7a;
}

先反混淆,再Overrides,设断,单步几下,就是上面那堆注释,无需其他奇技淫巧。

整理一下框架流程:

let buf         = get_binary_from_file( ifile );
let salt        = buf.slice( 0, 8 );
let iv          = buf.slice( 0x8, 0x18 );
let ebuf        = buf.slice( 0x18 );

let keysize     = 128;
let password    = "xSeZw1dY2HKAj3yk";
let iterations  = 0x10000;
let hasher      = CryptoJS.algo.SHA256;
let key         = PrivateDeriveKey( keysize, password, salt, iterations, hasher );

let dbuf        = aes_decrypt( key, iv, ebuf );
save_binary( dbuf, ofile );

免费评分

参与人数 11吾爱币 +18 热心值 +10 收起 理由
一家之言 + 1 + 1 我很赞同!
涛之雨 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
hyeiz + 1 + 1 谢谢@Thanks!
lihuhu + 1 我很赞同!
刺心 + 2 + 1 谢谢@Thanks!
满不懂 + 1 + 1 谢谢@Thanks!
xlln + 1 + 1 我很赞同!
SVIP9大会员 + 1 + 1 牛逼
Eqwer + 3 + 1 我很赞同!
zghwelcome + 1 我很赞同!
huluwa123 + 1 用心讨论,共获提升!

查看全部评分

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

 楼主| scz 发表于 2024-9-1 16:58
Eqwer 发表于 2024-9-1 16:40
老哥,冒昧问一句,PrivateDeriveKey函数是在您自己实现的嘛?我昨天一开始想用python实现,最终就卡在了这 ...

那个只是CryptoJS.PBKDF2的参数封装,没自己实现。我看你已经用crypt-js了,应该也有这个函数。它这个就是标准的PBKDF2。此处,直接扣async function _0x4b76a1(_0xb02836, _0x1d6150)出来,也可以,没依赖其他乱七八糟的。我注释中有个CyberChef/Derive PBKDF2 key,那是一组测试集,就是确认是不是标准实现。

免费评分

参与人数 2吾爱币 +2 热心值 +1 收起 理由
lgc81034 + 1 谢谢@Thanks!
Eqwer + 1 + 1 谢谢@Thanks!

查看全部评分

Eqwer 发表于 2024-9-1 16:40
老哥,冒昧问一句,PrivateDeriveKey函数是在您自己实现的嘛?我昨天一开始想用python实现,最终就卡在了这里,最后用的nodejs,crypt-js里有importKey和deriveKey才实现。
3134433 发表于 2024-9-1 15:30
Eqwer 发表于 2024-9-1 16:03
我去,我昨晚也刚逆向完这个网站,这个网站还有跨权。
二零一八小王子 发表于 2024-9-1 16:16
大神原来在这也出没
sadffg 发表于 2024-9-1 16:30
不知道有没有小视频解密的
cbkxh 发表于 2024-9-1 17:14
来学习的,谢谢分享
01z8z0 发表于 2024-9-1 17:59
感谢分享,看看。。。。。
wy125 发表于 2024-9-1 18:18
感谢分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2024-11-22 16:30

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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