携程testab补环境/纯算分析

  • 声明
  • 本文以学习交流为目的、不得用于任何商业用途和违法违规场景。
一 , 正片开始

网址:aHR0cHM6Ly9ob3RlbHMuY3RyaXAuY29tL2hvdGVscy8xNTAxODQ5Mi5odG1s

需要分析的参数:testab

然后直接搜索会发现 testab 会发现这两个地方

在这个地方打断点你会惊奇的发现打不上 

所以只能第一个搜索出来的地方上了断点 准备的差不多 然后刷新一下界面 然后等待一会 会发现成功的断住了

这里生成了一个随机数 返回把它加载到window的全局方里面 

点击下一步

然后让他跳进去 我们这是已经知道了一个方法加载到window全局方法里面

所以在在里面打了一个断点  然后执行到了这里 看一下e()执行了什么 

发现这个e()生成的就是我们需要的testab参数

通过浏览器发包会发现 这个生成的随机数会去请求一个js文件 这里大概就是可以猜测这是个动态js加密参数

解决这个有几种办法 :

  1. rpc
  2. 补环境
  3. 还原算法

这里交流2和3

1. 补环境:

先整体看一下

因为js是动态的 所以要保存一份作为替换以便调试 SekishikiMeikaiHa会传入一个window和一个打对象 是先调用的方法 然后返回了一个方法 然后再传入的 _bot_1417为window。  _bot_3bd0a这个是传入的对象 看下在哪使用到了这个对象 (可以了解一下vmp的执行过程 这里就不多说了)

会发现他把对象的b值传入到了decode解码。尝试把代码扣下来放在本地执行 查看decode返回的结果 发现是一个二维数组(vmp里面是指令集 不过多的介绍了)

然后看一下把返回的数组 然后入到这个里面使用 所有这个就是开始执行这些指令的循环

在这个地方打印调试输出。 看一下结果 呢么有人会说为什么在这个地方下个打印呢 因为我也不知道 哈哈哈哈哈 开下玩笑 字符的拼接无非就是join + 这是这几种 最多的就是运算符+

一顿打印会发现拼接了下面这些值(简化了的 全部输出有几万行)

通过日志分析 需要补充的环境还是还是挺多的 可以考虑使用jvtool插件之类的进。补环境 发现里面还检测了node一些api 使用node来执行得先解决一些node的api以防止检测。推荐在vm或v8里面执行 具体不说了 可以尝试学习补环境 

{
  '0': 'QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm1234567890$_[]',
  '1': '__pluginBodyChildren',
  '4': 'default',
  '6': '__pluginElementAppend',
  '9': 'default',
  '11': '__pluginElementCreate',
  '14': 'default',
  '16': '__pluginElementRender',
  '19': 'default',
  '21': '__pluginElementTagname',
  '24': 'default',
  '26': '__pluginErrorStack',
  '29': 'default',
  '31': '__pluginImageCreate',
  '34': 'default',
  '36': '__pluginNavigatorPlatform',
  '39': 'default',
  '41': '__pluginNodeJs',
  '44': 'default',
  '46': '__pluginPlatform',
  '49': 'default',
  '51': '__pluginReadOnlyPlatform',
  '54': 'default',
  '56': '__pluginReadOnlyAppCodeName',
  '59': 'default',
  '61': '__pluginReadOnlyUserAgent',
  '64': 'default',
  '66': '__pluginWindowPrototype',
  '69': 'default',
  '71': '__pluginWebdriver',
  '74': 'default',
  '76': 'root',
  '78': '__pluginBodyChildren',
  '79': 'default',
  '81': '__pluginElementAppend',
  '82': 'default',
  '84': '__pluginElementCreate',
  '85': 'default',
  '87': '__pluginElementRender',
  '88': 'default',
  '90': '__pluginElementTagname',
  '91': 'default',
  '93': '__pluginErrorStack',
  '94': 'default',
  '96': '__pluginImageCreate',
  '97': 'default',
  '99': '__pluginNavigatorPlatform',
  '100': 'default',
  '102': '__pluginNodeJs',
  '103': 'default',
  '105': '__pluginPlatform',
  '106': 'default',
  '108': '__pluginReadOnlyPlatform',
  '109': 'default',
  '111': '__pluginReadOnlyAppCodeName',
  '112': 'default',
  '114': '__pluginReadOnlyUserAgent',
  '115': 'default',
  '117': '__pluginWindowPrototype',
  '118': 'default',
  '120': '__pluginWebdriver',
  '121': 'default',
  '132': 'Math',
  '133': 'require',
  '134': 'document',
  '135': 'navigator',
  '136': 'location',
  '137': 'Object',
  '138': 'Window',
  '139': 'window',
  '140': 'String',
  '141': 'escape',
  '142': 'Array',
  '143': 'Boolean',
  '144': 'Date',
  '145': 'RegExp',
  '146': 'JSON',
  '147': 'Function',
  '148': 'Location',
  '149': 'Navigator',
  '150': 'encodeURIComponent',
  '151': 'bind',
  '154': 'j9dJSRWGMezHLqyCu1pPQfs2XN0Ilhma7-UicAK6btroVxgZw5_nYOvE3TF48BDk',
  '155': 'call',
  '156': 'bind',
  '158': 'bind',
  '159': 'call',
  '161': 'toString',
  '164': 'map',
  '168': 'forEach',
  '172': 'push',
  '176': 'join',
  '180': 'indexOf',
  '184': 'charCodeAt',
  '188': 'replace',
  '192': 'toLowerCase',
  '196': 'indexOf',
  '199': 'fromCharCode',
  '202': 'toGMTString',
  '204': 'setMinutes',
  '206': 'getMinutes',
  '208': 'undefined',
  '209': 'OwAFMfVbLF',
  '212': '\\s+|\\s*\\/\\*.*?\\*\\/\\s*|\\s*\\/\\/.*\\s*',
  '215': 'hotelhst',
  '219': 'OwAFMfVbLF',
  '310': 'length',
  '330': 'div',
  '333': 'h1',
  '334': 'h2',
  '335': 'h3',
  '336': 'h4',
  '337': 'span',
  '339': 'ul',
  '340': 'li',
  '357': 'jsdom',
  '358': 'async_hooks',
  '359': 'cluster',
  '360': 'os',
  '361': 'repl',
  '389': 'floor',
  '395': 'floor',
  '396': 'WQ',
  '400': 'floor',
  '401': 'WQ',
  '404': 'floor',
  '405': 'WQ',
  '406': 'WQ',
  '418': 'length',
  '420': 'floor',
  '426': 'forEach',
  '429': 'call',
  '432': 'floor',
  '433': 'random',
  '438': 'setMinutes',
  '439': 'getMinutes',
  '443': 'cookie',
  '446': 'WQ',
  '447': ';expires=',
  '448': 'WQ',
  '449': 'toGMTString',
  '451': 'WQ',
  '452': ';path=/',
  '453': 'WQ',
  '455': 'push',
  '458': 'length',
  '463': 'Q1',
  '464': 'length',
  '470': 'charAt',
  '471': 'length',
  '474': 'length',
  '477': 'WQ',
  '479': 'Q4345',
  '481': 'charCodeAt',
  '496': 'window',
  '497': 'document',
  '499': 'body',
  '500': 'children',
  '502': 'length',
  '504': 'window',
  '505': 'parseInt',
  '519': 'window',
  '520': 'document',
  '522': 'createElement',
  '523': 'div',
  '525': 'createElement',
  '526': 'div',
  '528': 'appendChild',
  '530': 'appendChild',
  '541': 'window',
  '542': 'document',
  '544': 'createElement',
  '545': 'div',
  '547': 'div',
  '550': 'createElement',
  '564': 'window',
  '565': 'document',
  '567': 'createElement',
  '568': 'div',
  '570': 'style',
  '571': 'height',
  '573': '20px',
  '575': 'offsetHeight',
  '576': 'body',
  '577': 'appendChild',
  '580': 'offsetHeight',
  '582': 'remove',
  '593': 'window',
  '594': 'document',
  '596': 'div',
  '599': 'h1',
  '600': 'h2',
  '601': 'h3',
  '602': 'h4',
  '603': 'span',
  '605': 'ul',
  '606': 'li',
  '608': 'length',
  '610': 'createElement',
  '612': 'tagName',
  '633': 'fbejkbakrbadskfe',
  '635': 'stack',
  '637': 'vm|repl|bootstrapNodeJSCore|tryModuleLoad|evalmachine|runInContext',
  '640': 'test',
  '641': 'stack',
  '645': 'number',
  '656': 'window',
  '657': 'Image',
  '659': 'window',
  '660': 'Image',
  '663': 'keys',
  '664': '__proto__',
  '667': 'length',
  '669': 'indexOf',
  '682': 'window',
  '683': 'navigator',
  '685': 'platform',
  '688': 'length',
  '699': 'length',
  '707': 'constructor',
  '708': 'constructor',
  '710': 'return process.mainModule.constructor._load',
  '725': 'window',
  '726': 'navigator',
  '728': 'platform',
  '731': 'length',
  '746': 'ctrip.com',
  '747': 'window',
  '748': 'navigator',
  '750': 'platform',
  '751': 'platform',
  '753': 'platform',
  '756': 'platform',
  '767': 'ctrip.com',
  '768': 'window',
  '769': 'navigator',
  '771': 'appCodeName',
  '772': 'appCodeName',
  '774': 'appCodeName',
  '777': 'appCodeName',
  '788': 'ctrip.com',
  '789': 'window',
  '790': 'navigator',
  '792': 'userAgent',
  '793': 'userAgent',
  '795': 'userAgent',
  '798': 'userAgent',
  '809': 'window',
  '810': 'function',
  '815': 'native code',
  '820': 'stringify',
  '822': '{}',
  '833': 'window',
  '834': 'navigator',
  '836': 'window',
  '837': 'document',
  '839': 'window',
  '840': 'webdriver',
  '843': 'getOwnPropertyNames',
  '845': 'getOwnPropertyNames',
  '847': 'join',
  '851': 'indexOf',
  '852': 'webdriver',
  '854': '_phantom',
  '856': 'undefined',
  '859': '__nightmare',
  '861': 'undefined',
  '864': '_selenium',
  '866': 'undefined',
  '869': 'callPhantom',
  '871': 'undefined',
  '874': 'callSelenium',
  '876': 'undefined',
  '879': '_Selenium_IDE_Recorder',
  '881': 'undefined',
  '884': '__webdriver_evaluate',
  '886': 'undefined',
  '889': '__selenium_evaluate',
  '891': 'undefined',
  '894': '__webdriver_script_function',
  '896': 'undefined',
  '899': '__webdriver_script_func',
  '901': 'undefined',
  '904': '__webdriver_script_fn',
  '906': 'undefined',
  '909': '__fxdriver_evaluate',
  '911': 'undefined',
  '914': '__driver_unwrapped',
  '916': 'undefined',
  '919': '__webdriver_unwrapped',
  '921': 'undefined',
  '924': '__driver_evaluate',
  '926': 'undefined',
  '929': '__selenium_unwrapped',
  '931': 'undefined',
  '934': '__fxdriver_unwrapped',
  '936': 'undefined',
  '939': 'external',
  '940': 'external',
  '941': 'toString',
  '942': 'external',
  '943': 'toString',
  '945': 'external',
  '946': 'toString',
  '949': 'indexOf',
  '951': 'Sequentum',
  '956': 'documentElement',
  '957': 'getAttribute',
  '959': 'selenium',
  '962': 'documentElement',
  '963': 'getAttribute',
  '965': 'webdriver',
  '968': 'documentElement',
  '969': 'getAttribute',
  '971': 'driver',
  '974': '\\$[a-z]dc_',
  '980': 'concat',
  '981': 'keys',
  '984': '__proto__',
  '986': 'length',
  '988': 'match',
  '990': 'cache_',
  '994': 'userAgent',
  '997': 'userAgent',
  '998': 'toLowerCase',
  '1001': 'indexOf',
  '1002': 'headless',
  '1007': 'getOwnPropertyDescriptor',
  '1008': 'webdriver',
  '1009': 'getOwnPropertyDescriptor',
  '1010': 'webdriver',
  '1012': 'get'
}

下面是补环境运行的结果发现运行结果一直 环境补出来大概几千行 加油慢慢补 

2. 接下来分析算法还原。

然后我们在这些运算符号的位置打印输出日志

发现最后的结果是由这个64位数组拼接过来结果

看一下这个数组怎么来的

对应的是 发现这个f是转码过来  在vmp里面大部分都是由String.fromCharCode转码过来

初始化完会生成这个64位数组 然后对该数组进行运算

最后生成下面这个数组 

最后补一张纯算的运行结果

纯算分析就到这里 多观察打印日志 里面都在里面 主要还是靠自己

如有侵权 请联系我删除 有需要的断点调试信息的需备注

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值