颜亦解析分析-AST反混淆与nodejs调用

11 篇文章 7 订阅

一、抓包并进行简单的静态分析

打开Fiddler,然后打开目标网址https://jsap.attakids.com/?url=https://v.qq.com/x/cover/mzc0020002ka95z/k0036081njj.html
在这里插入图片描述
这里可以看到请求了https://jsap.attakids.com/Api.php这个接口,其中还需要10个请求的参数。

接着继续看看主页的内容
在这里插入图片描述
这里可以看到,除了Sign和Token两个参数是实际有加密的,其他的参数都是直接在源代码中给出,使用正则匹配等方式提取即可。

下面还有一段ob混淆的js代码,将其先进行反混淆(关于ast的详细内容可以查看之前的帖子,这里就不做过长的解析。地址:《JavaScript AST其实很简单》
反混淆的js过程,下面只展示部分内容

function ajax_api() {
  $["cookie"]("uuid", Vkey + '-' + Key + '-' + Sign + '-' + Token);
  AccessToken = Vkey + '-' + Key + '-' + Sign + '-' + Token;

  if (isios) {
    ios = '1';
  } else {
    ios = '0';
  }

  if (isiPad) {
    wap = '1';
  } else {
    wap = '0';
  }

  $["ajax"]({
    'type': "post",
    'url': Api + "/Api.php",
    'dataType': "json",
    'headers': {
      'Token': Vkey,
      'Access-Token': AccessToken,
      'Version': Version
    },
    'data': {
      'url': Vurl,
      'wap': wap,
      'ios': ios,
      'host': Host,
      'key': Key,
      'sign': Sign,
      'token': Token,
      'type': Type,
      'referer': Ref,
      'time': Time
    },
    'success': function (_0x3040ec) {
      if (_0x3040ec["code"] == "200") {
        
        var _0x4acba7 = decode_url(_0x3040ec["url"], $["md5"](Host + Token));
        _0x3040ec["url"] = decodeURIComponent(_0x4acba7);
        
      }
    }
  });
}

此时,请求的逻辑就非常清晰了,但是还需要加密参数Sign和Token的算法。

二、网页断点动态分析

如果有一些实际的参数,会更好的分析。打开f12,然后重新加载网页
在这里插入图片描述

直接出现反调试,无限debugger。从函数调用堆栈可以看出,是从jquery.md5.js中出来的。接着查看一下这个js
在这里插入图片描述

可以看到大数组,又是一段ob混淆,继续进行反混淆,然后使用浏览器的Overrides功能,加载本地的js文件。(详细的Overrides功能教程可以参考鹅大的文章,地址:基于Chrome Overrides和Initiator进行js分析

设置好以后再次刷新,此时就不会出现无限debugger,可以自己设置断点

在这里插入图片描述

这里一共套了三层函数,分别为

函数名
$.md5
lc
encode_url

$.md5函数是标准的md5函数,自己随便试一下就可以得知,接着跟进去lc函数

在这里插入图片描述

lc函数里面又套了4层函数,_0x2f6ff0是加盐,在传入的字符串前加上固定的"17325841932717338791732584194271733878",然后另外三个函数共同组成一个标准的md5。

前面两个函数都比较简单,接着看看encode_url

在这里插入图片描述
在这里插入图片描述

encode_url函数的函数实体就是_0x3c4b2e函数,里面主要是md5,字符串切分拼接,异或等运算。我这里就不做python的还原了,直接扣js出来用。那么三个函数搞定了,请求也应该顺理成章的搞定了。

三.扣取代码,使用python实现自动化请求

将_0x3c4b2e函数扣出来,然后使用node运行,提示缺什么函数没有定义,就继续扣出来。这里没有涉及环境检测等问题,所以一直复制粘贴到不报错就可以了

最后增加一段自定义的代码来实现加密还是解密

var do_type = process.argv[2];
if (do_type === 'ENCODE'){
    console.log(_0x3c4b2e(process.argv[3], "ENCODE", process.argv[4], 0));
}else {
    console.log(_0x3c4b2e(process.argv[3], "DECODE", process.argv[4]));
}

为什么还有解密呢?再回到第一次解混淆的js。
在这里插入图片描述
当请求成功时,返回的url是加密的,需要解密后才是真实地址。下面是完整python代码


import requests
import os
import re
import hashlib
from urllib import parse

def main():
    url = 'https://jsap.attakids.com/?url=https://v.qq.com/x/cover/mzc0020002ka95z/k0036081njj.html'
    response = requests.get(url)
    salt = '17325841932717338791732584194271733878'
    Domain = re.findall('(?<=var Domain = ").+?(?=")', response.text)[0]
    Vurl = re.findall('(?<=var Vurl = ").+?(?=")', response.text)[0]
    Vkey = re.findall('(?<=var Vkey = ").+?(?=")', response.text)[0]
    Key = re.findall('(?<=var Key = ").+?(?=")', response.text)[0]
    Version = re.findall('(?<=var Version = ").+?(?=")', response.text)[0]
    Time = re.findall('(?<=var Time = )\d+', response.text)[0]
    sign_v2 = re.findall('var Sign = encode_url.+', response.text)[0]
    sign_v2 = re.findall("(?<=').{32}(?=')", sign_v2)[0]
    Token_v2 = re.findall('var Token = encode_url.+', response.text)[0]
    Token_v2 = re.findall("(?<=').{32}(?=')", Token_v2)[0]
    url = response.url
    Host = parse.urlparse(url).netloc

    Sign = Host+Time+Vurl+Key
    Sign = salt + hashlib.md5(Sign.encode()).hexdigest()
    Sign = hashlib.md5(Sign.encode()).hexdigest()
    nodejs = os.popen('node attakids ENCODE ' + Sign + ' ' + sign_v2)
    Sign = nodejs.read().replace('\n', '').replace('+', '-').replace('/', '_').replace('=', '.')
    nodejs.close()

    Token = Domain+Time+Vurl+Sign
    Token = salt + hashlib.md5(Token.encode()).hexdigest()
    Token = hashlib.md5(Token.encode()).hexdigest()
    nodejs = os.popen('node attakids ENCODE ' + Token + ' ' + Time + Token_v2)
    Token = nodejs.read().replace('\n', '').replace('+', '-').replace('/', '_').replace('=', '.')
    nodejs.close()

    headers = {
        'Token': Vkey,
        'access-token': Vkey + '-' + Key + '-' + Sign + '-' + Token,
        'Version': Version,
        'cookie': 'uuid=' + Vkey + '-' + Key + '-' + Sign + '-' + Token,
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36',
    }

    data = {
        'url': Vurl,
        'wap': 0,
        'ios': 0,
        'host': Host,
        'key': Key,
        'sign': Sign,
        'token': Token,
        'type': '',
        'referer': '',
        'time': Time
    }

    url = 'https://jsap.attakids.com/Api.php'
    response = requests.post(url, headers=headers, data=data)
    if response.status_code == 200:
        response = response.json()
        print(response)
        title = response['title']
        print(title)
        enc_url = response['url'].replace('-', '+').replace('_', '/').replace('.', '=')
        nodejs = os.popen('node attakids DECODE ' + enc_url + ' ' + hashlib.md5((Host + Token).encode()).hexdigest())
        dec_url = nodejs.read().replace('\n', '')
        nodejs.close()
        dec_url = 'https://'+Host+parse.unquote(dec_url)
        print(dec_url)
        if response['type'] == 'hls':
            response = requests.get(dec_url)
            print(response.text)
    else:
        print(response.status_code)
        print(response.content)

if __name__ == '__main__':
    main()

js代码就不放出来了,有兴趣的可以自己尝试扣取js测试

最后结果图

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值