最近收到粉丝私信,想多学习下js逆向相关的知识和事例,应大多数粉丝要求:今天份js逆向操练,36氪登录模拟

方针地址:36kr.com/

初步探测

  1. 点击登录按钮,切换到账户暗码登录
    手把手带你模拟36氪登录
  2. 随便输入一个手机号码和6位数以上的暗码,点击登录
    手把手带你模拟36氪登录
    能够看到XHR请求现已发出来了byMobilePassword
  3. 查看byMobilePassword相关的request header和payload request header中并未发现特别加密的参数
    手把手带你模拟36氪登录
    很明显payload中mobileNo和password是经过加密的
    手把手带你模拟36氪登录

牛刀小试

  1. 先来榜首枪,依据关键字查找mobileNoonly一个,点击文件进去试一下
    手把手带你模拟36氪登录
  2. 格式化下代码
    手把手带你模拟36氪登录
  3. 打上断点,点击登录按钮
    手把手带你模拟36氪登录
  4. 断点成功断住,从chrome控制台能够看到o.a.get(t, "mobileNo")便是咱们的明文手机号码,Object(i.b)()便是加密明文的办法,因而咱们的要点使命便是破解Object(i.b)()这个办法
    手把手带你模拟36氪登录

要点打破

  1. 鼠标光标放到Object(i.b)()上,点击弹出来的浮窗进入文件
    手把手带你模拟36氪登录
  2. 文件定位到这段代码
    手把手带你模拟36氪登录
    简略剖析下这段代码:
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
}
}
  1. 当咱们看到r = new t.JSEncrypt;这行代码的时分,有经验的一看就应该明白这可能是标准的RSA加密; r.setPublicKey(i);是设置公钥,这里的i的值在上面也很明晰的写死了
    手把手带你模拟36氪登录

i = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCeiLxP4ZavN8qhI+x+whAiFpGWpY9y1AHSQC86qEMBVnmqC8vdZAfxxuQWeQaeMWG07lXhXegTjZ5wn9pHnjg15wbjRGSTfwuZxSFW6sS3GYlrg40ckqAagzIjkE+5OLPsdjVYQyhLfKxj/79oOfjl/lV3rQnk/SSczHW0PEyUbQIDAQAB"

三种办法来破解登录

JSEncrypt库

这种办法最直接,也最简略,不过需求对相关加密库比较熟悉 在node.js环境中运用jsEncrypt库 首要, Node.js 环境中运用 JSEncrypt 需求先装置该库,能够经过 npm 装置: npm install jsencrypt 补一个window环境就能够直接运用了

手把手带你模拟36氪登录
代码如下:

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服务器的验证,仅仅输入的账户不对,换成你们正确的账户就行

手把手带你模拟36氪登录

硬扣

如果不知道是RSA加密,也没有联系,咱们用其他的办法,那就硬扣呗;

  1. 这几行代码n(**)差不多能够知道是webpack加载器n来的,在几个n处打上断点,刷新页面

手把手带你模拟36氪登录

  1. 断点成功进入,点击浮窗进入代码文件
    手把手带你模拟36氪登录
    成功定位到加载器
    手把手带你模拟36氪登录
  2. 把runtime.****.js文件内容都拷贝下来

手把手带你模拟36氪登录

补环境

  1. 代码拷贝下来后,直接运转js文件
    手把手带你模拟36氪登录
    提示ReferenceError: window is not defined
  2. 补一个window = global再次运转,代码ok
    手把手带你模拟36氪登录
  3. 格式化代码,缩近代码,能够看到是一个[]空数组
    手把手带你模拟36氪登录
    加密函数的文件看到这里的代码都是在[]数组中,
    手把手带你模拟36氪登录
  4. 这里是webpack的数组办法,因而把这些function都拷贝到[]数组中
    手把手带你模拟36氪登录

ReferenceError: navigator is not defined

手把手带你模拟36氪登录

  1. 导出加载器函数,加载器函数是n,
    手把手带你模拟36氪登录
    _ps = n后面就能够运用_ps大局目标来调用对应的函数了
    手把手带你模拟36氪登录
  2. 因为加载器中是数组目标,查找下 r = new t.JSEncrypt 咱们所需求的办法是在哪个functuion
    手把手带你模拟36氪登录
    数组跟python中一样,也是从0开始的,所以咱们需求的是第7个 _ps(7)打印出来的成果便是三个办法
{a:[Getter],b:[Getter],c:[Getter]}

手把手带你模拟36氪登录

b办法回来的便是a目标,而a目标便是咱们所需求的加密办法

手把手带你模拟36氪登录
7. 因而_ps(7).b('123345')就能够得到加密成果 结构一个函数回来加密成果给python程序调用

functionget_encrypt(message){
return_ps(7).b(message)
}
  1. 接下来便是咱们经过python程序来进行登录,看到这个成果,就现已阐明咱们模拟的加密现现已过了36kr服务器的验证,仅仅输入的账户不对,换成你们正确的账户就行;
    手把手带你模拟36氪登录
    附上相关的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办法

  1. 导出加密函数

手把手带你模拟36氪登录

  1. 发动咱们的sekiro工具
    手把手带你模拟36氪登录

能够看到发动日志是正常的,我这里是sekiro3,默许发动的netty端口是5612

手把手带你模拟36氪登录

  1. 在浏览器控制台注入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衔接

手把手带你模拟36氪登录

  1. 接下来咱们就能够经过python发送咱们的请求获取加密的手机号和暗码了

手把手带你模拟36氪登录
然后能够经过加密后的数据请求登录接口了。。 这种办法的缺点便是刷新浏览器的时分注入的脚本就消失了,需求重新注入,当然咱们也能够经过Tampermonkey注入,不过这个小小的登录用这些,感觉就有点大炮轰蚊子了

总结:

js逆向依据实际情况,能够有多种办法破解办法,能够依照自己熟悉的来,条件要了解各种破解套路,才干找到对应最合适的。

手把手带你模拟36氪登录

更多资源信息可关注大众号:python君