本次js逆向没有存在代码混淆,所以还是比较简单的,重要的就是js逆向的思路,目标网站https://notice.qb.com/detail?noticeId=215让我们开始吧
进入网站后按F12,查看DOC中的,可以看出该网页一部分内容是异步加载而成继续在XHR中寻找,发现了第一个common中就有我们需要的内容然后点到Headers看看它具体是有哪些请求参数,大概知道哪几个是固定值,哪几个是变化的,接下来多刷新几次(如果碰到debug疯狂按F8),比较验证一下,最后得出结论,sig是动态变化的,ts是10位的时间戳,其他都是固定值(id是每篇文章唯一的,可视为固定)
我一般先是通过search来找找sig这个关键词,如果碰到代码混淆的话,就要用其他方法来寻找了,然而这个网站是真的简单…一找就找到了,就在第一个js中
进入js后,按ctrl+F,再次搜索sig,顺利找到了一串代码 g.sig = (0, o.encrypt)(“sha256”, (0, o.encrypt)(“md5”, (0, o.encrypt)(“md5”, m))).toLowerCase() 以我敏锐的洞察力,我已经肯定这个就是我们要的sig了 ,但是还是需要验证一下先在这几个地方打上断点,然后对参数g,f,m添加监听,这几个参数都与sig有关
回到Network下的XHR按F5刷新,稍等一会后按一下F8,看到右侧展开参数g后,里面的内容跟我们需要请求的参数,只差一个sig的差别,而接下来这个g.sig=大串加密,很明显是对sig赋值,那么究竟是怎么加密的呢
继续按F11,我们看到它跳转到一个方法中,该方法传过来两个参数,一个是字符串md5,一个是一串字符串,再来看一下这个方法(0,o.encrypt)(“md5”, m),是它没错了,我内心几乎已经肯定是md5加密,那么sig的赋值方式应该就是 ,对m的两次md5加密之后,再一次sha256加密,到此js逆向基本结束
如果不确定是不是md5加密,那就验证一下,继续按F8,一旦m显示了数值,就切到console,输入以下代码
随便找个md5在线加密的网站,例如
https://www.sojson.com/md5/,把m的字符串复制黏贴,你看,是不是一样的
最后就是改写成python代码了,还是简单的,不会就百度,精辟,值得注意的就是,response.text中,是一大串base64加密后的字符串,解码一下即可
# -*- coding: utf-8 -*-
import json
import re
import time
import hashlib
import requests
import base64
header={
'Content-Type': 'text/plain;charset=UTF-8',
'Origin': 'https://notice.qb.com',
'Referer': 'https://notice.qb.com/detail?noticeId=215',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36'
}
def main():
# post链接
path = 'https://api.qb.com/v1/common/'
#获取sig和ts
sig,ts = getSig()
#伪造参数
data = {'a': 'at', 'appId': 0, 'd': {'id': 215, 'ty': 0, 'con': 1, 'p': 0, 'ps': 10, 'la': 1}, 'ts': ts, 'reqLang': 0, 'sig': sig}
response = requests.post(url=path, data=json.dumps(data), headers=header, timeout=5)
response.encoding = 'utf-8'
print(response.text)
#正则提取内容
justsoso= re.search(r"base64,(.*?)ggg==", response.text).group(1)
just = justsoso+'ggg=='
print(just)
#base64解码
finally_data = base64.b64decode(just)
print(finally_data)
file = open('1.jpg', 'wb')
file.write(finally_data)
def getSig():
#时间戳
ts = int(time.time())
#构造m参数
m = 'a=at&appId=0&con=1&id=215&la=1&p=0&ps=10&reqLang=0&ts='+str(ts)+'&ty=070f239020d3a28b8d24ba1706f2dd7c03dcaa2fa5e7a077f1f517e5f2d3a68a1'
#二次md5加密之后,再一次sga256加密
sig = get_sha256(get_md5(get_md5(m)))
return sig,ts
def get_md5(value):
#MD5加密
return hashlib.md5(value.encode("utf8")).hexdigest()
def get_sha256(value):
#sha256加密
return hashlib.sha256(value.encode("utf-8")).hexdigest()
if __name__ == '__main__':
main()
最后…居然是一张图片,当时我就懵逼了,还没右键另存为来得快,不过js逆向基本就是这样