最近收到粉丝私信,想多学习下js逆向相关的知识和事例,应大多数粉丝要求:今天份js逆向操练,36氪登录模拟
方针地址:36kr.com/
初步探测
- 点击登录按钮,切换到账户暗码登录
- 随便输入一个手机号码和6位数以上的暗码,点击登录
能够看到XHR请求现已发出来了
byMobilePassword
- 查看
byMobilePassword
相关的request header和payload request header中并未发现特别加密的参数 很明显payload中mobileNo和password是经过加密的
牛刀小试
- 先来榜首枪,依据关键字查找
mobileNo
only一个,点击文件进去试一下 - 格式化下代码
- 打上断点,点击登录按钮
- 断点成功断住,从chrome控制台能够看到
o.a.get(t, "mobileNo")
便是咱们的明文手机号码,Object(i.b)()
便是加密明文的办法,因而咱们的要点使命便是破解Object(i.b)()
这个办法
要点打破
- 鼠标光标放到
Object(i.b)()
上,点击弹出来的浮窗进入文件 - 文件定位到这段代码 简略剖析下这段代码:
arr=n(14)
,o=n(4)
,
i="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCeiLxP4ZavN8qhI+x+whAiFpGWpY9y1AHSQC86qEMBVnmqC8vdZAfxxuQWeQaeMWG07lXhXegTjZ5wn9pHnjg15wbjRGSTfwuZxSFW6sS3GYlrg40ckqAagzIjkE+5OLPsdjVYQyhLfKxj/79oOfjl/lV3rQnk/SSczHW0PEyUbQIDAQAB"
,a=function(){
vare=arguments.length>0&&void0!==arguments[0]?arguments[0]:"";
if(!Object(o.isNodeEnv)()){
vart=n(769)
,r=newt.JSEncrypt;
r.setPublicKey(i);
vara=r.encrypt(e);
returna
}
}
- 当咱们看到
r = new t.JSEncrypt;
这行代码的时分,有经验的一看就应该明白这可能是标准的RSA加密;r.setPublicKey(i);
是设置公钥,这里的i的值在上面也很明晰的写死了
i = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCeiLxP4ZavN8qhI+x+whAiFpGWpY9y1AHSQC86qEMBVnmqC8vdZAfxxuQWeQaeMWG07lXhXegTjZ5wn9pHnjg15wbjRGSTfwuZxSFW6sS3GYlrg40ckqAagzIjkE+5OLPsdjVYQyhLfKxj/79oOfjl/lV3rQnk/SSczHW0PEyUbQIDAQAB"
三种办法来破解登录
JSEncrypt库
这种办法最直接,也最简略,不过需求对相关加密库比较熟悉 在node.js环境中运用jsEncrypt库 首要, Node.js 环境中运用 JSEncrypt 需求先装置该库,能够经过 npm 装置: npm install jsencrypt
补一个window环境就能够直接运用了
代码如下:
window=global
functionget_encrypt(message){
constJSEncrypt=require('jsencrypt');
constencrypt=newJSEncrypt();
p_k='MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCeiLxP4ZavN8qhI+x+whAiFpGWpY9y1AHSQC86qEMBVnmqC8vdZAfxxuQWeQaeMWG07lXhXegTjZ5wn9pHnjg15wbjRGSTfwuZxSFW6sS3GYlrg40ckqAagzIjkE+5OLPsdjVYQyhLfKxj/79oOfjl/lV3rQnk/SSczHW0PEyUbQIDAQAB'
encrypt.setPublicKey(p_k)
//运用公钥加密数据
returnencrypt.encrypt(message);
}
console.log(get_encrypt('1'));
经过python调用,看到这个成果,就现已阐明咱们模拟的加密现现已过了36kr服务器的验证,仅仅输入的账户不对,换成你们正确的账户就行
硬扣
如果不知道是RSA加密,也没有联系,咱们用其他的办法,那就硬扣呗;
- 这几行代码n(**)差不多能够知道是webpack加载器n来的,在几个n处打上断点,刷新页面
- 断点成功进入,点击浮窗进入代码文件 成功定位到加载器
- 把runtime.****.js文件内容都拷贝下来
补环境
- 代码拷贝下来后,直接运转js文件
提示
ReferenceError: window is not defined
- 补一个
window = global
再次运转,代码ok - 格式化代码,缩近代码,能够看到是一个[]空数组 加密函数的文件看到这里的代码都是在[]数组中,
- 这里是webpack的数组办法,因而把这些function都拷贝到[]数组中
ReferenceError: navigator is not defined
- 导出加载器函数,加载器函数是
n
,_ps = n
后面就能够运用_ps
大局目标来调用对应的函数了 - 因为加载器中是数组目标,查找下
r = new t.JSEncrypt
咱们所需求的办法是在哪个functuion 数组跟python中一样,也是从0开始的,所以咱们需求的是第7个_ps(7)
打印出来的成果便是三个办法
{a:[Getter],b:[Getter],c:[Getter]}
b办法回来的便是a目标,而a目标便是咱们所需求的加密办法
7. 因而_ps(7).b('123345')
就能够得到加密成果 结构一个函数回来加密成果给python程序调用
functionget_encrypt(message){
return_ps(7).b(message)
}
- 接下来便是咱们经过python程序来进行登录,看到这个成果,就现已阐明咱们模拟的加密现现已过了36kr服务器的验证,仅仅输入的账户不对,换成你们正确的账户就行; 附上相关的python代码,js代码因而太长了,就不附上了,有需求学习的朋友能够私信我。
importrequests
importjson
importtime
importexecjs
headers={
"authority":"gateway.36kr.com",
"accept":"*/*",
"accept-language":"zh-CN,zh;q=0.9",
"cache-control":"no-cache",
"content-type":"application/json",
"origin":"https://www.36kr.com",
"pragma":"no-cache",
"referer":"https://www.36kr.com/",
"sec-ch-ua":""Chromium";v="110","NotA(Brand";v="24","GoogleChrome";v="110"",
"sec-ch-ua-mobile":"?0",
"sec-ch-ua-platform":""macOS"",
"sec-fetch-dest":"empty",
"sec-fetch-mode":"cors",
"sec-fetch-site":"same-site",
"user-agent":"Mozilla/5.0(Macintosh;IntelMacOSX10_15_7)AppleWebKit/537.36(KHTML,likeGecko)Chrome/110.0.0.0Safari/537.36"
}
url="https://gateway.36kr.com/api/mus/login/byMobilePassword"
round(time.time()*1000)
mobileNo='18814378681'
password='123456'
exjs=execjs.compile(open('36ke.js',encoding='utf-8').read())
mobileNo=exjs.call('get_encrypt',mobileNo)
password=exjs.call('get_encrypt',password)
data={
"krtoken":"",
"partner_id":"web",
"timestamp":round(time.time()*1000),
"param":{
"countryCode":"86",
"mobileNo":mobileNo,
"password":password
}
}
data=json.dumps(data,separators=(',',':'))
response=requests.post(url,headers=headers,data=data)
print(response.text)
Websocket办法
- 导出加密函数
- 发动咱们的sekiro工具
能够看到发动日志是正常的,我这里是sekiro3,默许发动的netty端口是5612
- 在浏览器控制台注入sekiro_web_client.js和咱们自己的脚本文件
functionguid(){
functionS4(){
return(((1+Math.random())*0x10000)|0).toString(16).substring(1);
}
return(S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
}
varclient=newSekiroClient("ws://127.0.0.1:5612/business/register?group=ws-group&clientId="+guid());
client.registerAction("sss",function(request,resolve,reject){
const{param1}=request.params;
resolve(sss(param1));
})
控制台提示现已和服务端建立了websocket衔接
- 接下来咱们就能够经过python发送咱们的请求获取加密的手机号和暗码了
然后能够经过加密后的数据请求登录接口了。。 这种办法的缺点便是刷新浏览器的时分注入的脚本就消失了,需求重新注入,当然咱们也能够经过Tampermonkey注入,不过这个小小的登录用这些,感觉就有点大炮轰蚊子了
总结:
js逆向依据实际情况,能够有多种办法破解办法,能够依照自己熟悉的来,条件要了解各种破解套路,才干找到对应最合适的。
更多资源信息可关注大众号:python君