1.难点
3.分析
分析参数1
定位代码
调试菜单栏下,选择Elements
通过ctrl+f
输入username
或password
定位加密参数
代码
一般表单提交的代码在form
内部,不在的话可能有JS加密。
再分析代码,发现这里有个点击时间触发了doLogin()函数
继续跟进,在调试菜单栏Network
下通过ctrl+f
输入doLogin
定位函数,发现两处doLogin
貌似是混淆代码
通过JS解密工具
function doLogin() {
var password_old = $("#MemberPassword").val();
var encrypt = new JSEncrypt();
var public_key = $("#pk").val();
encrypt.setPublicKey(public_key);
var pass_new = encrypt.encrypt(password_old);
$("#MemberPassword").val(pass_new);
$("#login_button").submit()
}
能解密出来,说明是基础的混淆。
核心代码
分析doLogin函数
function doLogin() {
var password_old = $("#MemberPassword").val(); // 获取html中id为MemberPassword的内容
var encrypt = new JSEncrypt();
var public_key = $("#pk").val(); // 获取中html获取id为pk的值,作为公钥
encrypt.setPublicKey(public_key);
var pass_new = encrypt.encrypt(password_old); // 加密
$("#MemberPassword").val(pass_new); // 设置id为MemberPassword的标签内容为pass_new
$("#login_button").submit() // 提交表单
}
可以看到,这里password_old
变成了pass_new
。password_old
应该是未加密的原始密码,pass_new
应该是加密了的密码。
解决方案
有公钥私钥的加密,是RSA
加密,一般这种不回去解密,而是去进行加密得到加密后的密文。
分析参数2
定位代码
调试菜单栏下,选择Elements
对比发现,这两处的csrfmiddlewaretoken
值不一样,说明这个参数是动态的。
一般token是服务器动态返回的,而不是加密的。
分析参数3
4.编码实现
# 辅助函数,用于处理html
# parseHtml.py
from lxml import etree
def getEle(rule: str, htmlStr: str):
html = etree.HTML(htmlStr)
res = html.xpath(rule)
return res
# run.py
# 获取值:pk和csrfmiddlewaretoken
import requests
import parseHtml
url = 'http://shanzhi.spbeen.com/login/'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.101 Safari/537.36',
}
resp = requests.get(url, headers=headers)
resp.encoding = 'utf-8'
res__pk = parseHtml.getEle('//*[@id="pk"]/@value', resp.text)
res__token = parseHtml.getEle('//input[@name="csrfmiddlewaretoken"]/@value', resp.text)
pk = res__pk[0].strip()
token = res__token[0].strip()
print(pk)
print(token)