JS逆向 模拟抓取 八比特 网站数据(AES加密问题)

网上看到有人要抓这网站,刚有空所以研究下,写下过程,比较简单。

首先老三样,抓包,看参数,可以看到,header中有验证参数.

JS逆向 模拟抓取 八比特 网站数据(AES加密问题)_第1张图片

看了下就这一下验证参数,拿这个参数和body里的参数到postman中模拟发送下看看,成功,说明就这一个参数,解决这个就能正常抓取。

JS逆向 模拟抓取 八比特 网站数据(AES加密问题)_第2张图片

Authorization 肯定是在发送前在js生成的,F12 筛选js文件, 刷新页面,ctrl+f 搜索 js中搜索下 secretKeyVersion看看,明显是第一个,因为其他的都是请求里的,咱们要找js里的,然后 到对应 JS里面看看,点击Sources , 找到c73f210.js 这个JS。

JS逆向 模拟抓取 八比特 网站数据(AES加密问题)_第3张图片

将JS格式化一下,方便调试,然后 在这个JS中搜索secretKeyVersion ,定位到关键字位置。

JS逆向 模拟抓取 八比特 网站数据(AES加密问题)_第4张图片

可以看到,从这里加入到header的,sign也在,所以确定是这块,现在 就是看一下这个 sign是怎么生成的,有个写死字符串,

可能是key - - 好多人都在js 中写死- 然后给 e.headers.Authorization = JSON.stringify({ 这一行下断,页面翻页,让触发请求,会断到
这个地方,因为他拿数据会用到这个sign。

JS逆向 模拟抓取 八比特 网站数据(AES加密问题)_第5张图片

到断点后就可以看看这个Ct.c是个啥了, 直接把 Object(Ct.c) 粘贴到Console下打印看看,应该 是加密方法,那后台那个括号里面就应该是参数了。跟进去看看,
在打印出来的这个函数上点一下就能自动跟踪到对应 方法了。

到加密方法了,应该是用AES 的ECB模式加密的,咱们自己模拟请求的话得实现这个,先不管,看看他用的啥库,一般不会自己写的,都用的公共库。

在r.a.AES.encrypt 这一行下断,让代码执行到这一行,然后把这个方法拿到console执行一下,跟踪到对应加密方法里。

JS逆向 模拟抓取 八比特 网站数据(AES加密问题)_第6张图片

 

现在来猜猜他用的是不是公共 js库,翻一翻找找一些常量,不可变参数(因为js代码大部分都会混淆的),例如

JS逆向 模拟抓取 八比特 网站数据(AES加密问题)_第7张图片

然后去github搜索下代码试试,比较下就可以确认是用的cryptoJS(如果是自己实现的话就要自己动手了),这就好办,下载一份试试,测试下

JS逆向 模拟抓取 八比特 网站数据(AES加密问题)_第8张图片

我模拟加密了下效果一模一样。

JS逆向 模拟抓取 八比特 网站数据(AES加密问题)_第9张图片

OK,加密过程搞明白 ,现在开始模拟,我用的 python , 有二种方法,一种模拟执行js,一种自己根据他的加密方式实现一套,我在网上查了查,有人实现过,
拿过来改改就能用。没有这个包的同学Crypto , 用pip install pycrypto 安装。

from Crypto.Cipher import AES
import base64
import requests

class EncryptClass:
	def add_to_16(self, s):
	    while len(s) % 16 != 0:
	        s += (16 - len(s) % 16) * chr(16 - len(s) % 16)
	    return str.encode(s)  # 返回bytes

	def encry(self, text, key='WTAHAPPYACTIVITY'):
	    aes = AES.new(str.encode(key), AES.MODE_ECB)  # 初始化加密器,本例采用ECB加密模式
	    encrypted_text = str(base64.encodebytes(aes.encrypt(self.add_to_16(text))), encoding='utf8').replace('\n', '')  # 加密
	    encrypted_text = encrypted_text.replace('/', "_").replace('+', "-")  # ddd.replace(/\//g, "^")
	    return encrypted_text
 # -*- coding:utf-8 -*-

from encrypt import EncryptClass
import requests
import json
import time

word = '{"appId":"1","timestamp":' + str(int(time.time()))  +',"serverCode":"0"}'
key = 'WTAHAPPYACTIVITY'  # 此处问加密key值

encrypt = EncryptClass()
sign = encrypt.encry(word, key)
# print(sign)

headers = {
	"from": "web",
	"Host": "gate.8btc.com",
	'content-type': 'application/json',
	"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36",
	"Authorization": json.dumps({
		"secretKeyVersion": 1,
		"sign": str(sign)
	})
}
post_data = {
    "operationName": "listArticle",
    # offset 用来翻页的,改变这个就行,每次+20
    "variables":{"first":20,"offset":40,"informationFlow":True,"tag":6250},
    "query" : "query listArticle($first: Int = 20, $offset: Int, $category: Int, $tag: Int, $informationFlow: Boolean, $country: String) {  articleGraph {    list: listArticle(page: {first: $first, offset: $offset, pattern: OFFSET}, param: {categoryId: $category, tagId: $tag, country: $country, informationFlow: $informationFlow}) {      ...articleListFragment      __typename    }    __typename  }}fragment articleListFragment on BaseArticleConnection {  edges {    node {      id      template      post {        title        thumbnail        desc        postDate        isOriginal        __typename      }      extra {        tags {          name          termId          slug          taxonomy          __typename        }        authorInfo {          id          uid          base {            displayName            avatar            __typename          }          __typename        }        __typename      }      ... on Venture {        meta {          cat          amount          round          area          investors          date          project          __typename        }        __typename      }      ... on Weekly {        weeklyNum        __typename      }      ... on Special {        themeNum        __typename      }      ... on Policy {        country        __typename      }      __typename    }    __typename  }  pageInfo {    totalCount    __typename  }  __typename}"
}
url_api = "https://gate.8btc.com/one-graph-auth/graphql"
res = requests.post(url_api, headers = headers, json = post_data)
result_data = res.json()
for item in result_data['data']['articleGraph']['list']['edges']:
	# print(item['node']['extra']['post'])
	print(json.dumps(item['node']['post']['title'], sort_keys=True, indent=2, ensure_ascii=False))

看看效果,稍等改造下就能用啦。OK结束。

JS逆向 模拟抓取 八比特 网站数据(AES加密问题)_第10张图片

你可能感兴趣的:(python,爬虫,js逆向,post,java)