看到一个网站的登录环节做了密码的加密,尝试着做了破解,权当对js破解的一个练习。
开始破解
登录url下面看到data如下:
其中password和sso_token明显是加密后的数据。
搜索sso_token可以定位到js文件:
看到这里的sso_token 其实是网页 上id 为sso_token的一个值,定位到这个页面的url为:
http://login.haodou.com/
下面就可以追踪password的加密了,如图一所示打断点后可以看到:
最后密码的获得是通过这个表达式完成:
post_data.password = hd.secure.encrypt($('#timestamp').val() + '|' + post_data.password);
这里的$('#timestamp').val() 是个十位数的时间戳,在js中的实现是:new Date().getTime().toString().substr(0,10)
这里的 post_data.password 就是我们的原始密码。
最后只需要考虑hd.secure.encrypt 这个方法即可。
通过刚才的断点可以定位到这个函数所在位置:
这个函数是包含在一个对象当中:
复制这个对象中的所有js代码,放到js文件中,运行js文件后会显示缺少window对象和navigator对象,构造这两个对象即可:
var window = window ||{};
var navigator = navigator ||{};
另外,把这个对象的函数名和最后没有用到的return都删除掉,让我们的js代码看起来更简洁。
最后把生成密码的函数单独拿出来构造一个函数,用来我们每次调用的时候进行密码返回。
function encrypt(plain){
var n= 'yevTQ5C8exDUo/c0y0Lrxp+quYD9vxjkKFAgdqV0PtLefJ4FEB4VeTTGDfqaWVgQXeQeyCp0yjCd8EGVUd/77z+Z/HlBpaavHwsE77Rjf3r9AC+aSN+ZZC4uoZL0bYDiDgYcG32CPLdVPP8zbKxa/BSbUb1PhxEot/fMTo+rLrU=';
var e='AQAB';
var n = pidCryptUtil.decodeBase64(n)
, e = pidCryptUtil.decodeBase64(e)
, rsa = new pidCrypt.RSA();
rsa.setPublic(pidCryptUtil.convertToHex(n), pidCryptUtil.convertToHex(e));
return pidCryptUtil.encodeBase64(pidCryptUtil.convertFromHex(rsa.encrypt(plain)))
}
function get_pwd(pwd) {
timestamp = new Date().getTime().toString().substr(0,10)
new_pwd = encrypt(timestamp + '|' + pwd);
return new_pwd
}
每次调用get_pwd函数,传入密码,就可以获得加密后的password。
加密环节完成后,就可以编写py脚本。都是基础操作,代码如下:
import execjs
import requests
from pyquery import PyQuery as pq
def get_pwd():
with open('haodou_js.js', 'r', encoding='UTF-8') as f:
js2 = f.read()
ctx2 = execjs.compile(js2)
pwd = ctx2.call("get_pwd", '123456') #这里放密码
return pwd
def get_sso_token():
url = 'http://login.haodou.com/'
headers = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8', 'Connection': 'keep-alive',
'Cookie': 'PHPSESSID=cg1sinvvc3lejkv3uvv3o61jj0; HDid=1561778611245; product=1; _uab_collina=156179025038866839820592; _wtip=0%7C%2B5; UM_distinctid=16ba1f63de6a2a-0fc5697c844879-e343166-1fa400-16ba1f63de7bae; _ga=GA1.2.626879575.1561790398; _gid=GA1.2.2045726504.1561790398; Hm_lvt_fbb4fdac678166fd7a6f7e50d6e5040c=1561790398; Hm_lpvt_fbb4fdac678166fd7a6f7e50d6e5040c=1561791766; _gat=1',
'Host': 'login.haodou.com', 'Referer': 'http://www.haodou.com/', 'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'}
res = requests.get(url, headers=headers)
doc = pq(res.text)
sso_token = doc('#sso_token').attr('value')
print(sso_token)
return sso_token
def login():
url = 'http://login.haodou.com/index.php?do=check'
headers = {'Accept': 'application/json, text/javascript, */*; q=0.01', 'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8', 'Connection': 'keep-alive', 'Content-Length': '340',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Cookie': 'PHPSESSID=cg1sinvvc3lejkv3uvv3o61jj0; HDid=1561778611245; product=1',
'Host': 'login.haodou.com', 'Origin': 'http://login.haodou.com', 'Referer': 'http://login.haodou.com/',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36',
'X-Requested-With': 'XMLHttpRequest'}
password = get_pwd()
sso_token = get_sso_token()
data = {
'account': '18811111111',
'type': '2',
'password': password,
'referer': 'http://www.haodou.com',
'auto_login': '0',
'valicode': '',
'sso_token': sso_token,
}
res = requests.post(url, headers=headers, data=data)
print(res.status_code)
print(res.text)
print(res.cookies.get_dict())
if __name__ == '__main__':
login()
以上,就完成了整个登录的破解过程。
完整代码传送----------如果对你有所帮助,欢迎点击star:点击查看GitHub