本文章中所有內容僅供學習交流,抓包內容、敏感網址、數據接口均已做脫敏處理,嚴禁用于商業用途和非法用途,否則由此產生的一切后果均與作者無關,若有侵權,請聯系我立即刪除!
本次逆向目標來源于某位粉絲的求助:
隨便輸入賬號密碼點擊登陸,抓包發現接口的 Request Headers 有個加密參數 token,Form Data 里 loginNo、loginPwd、code、requestUUID 都是經過加密處理了的,loginNo 和 loginPwd 應該就是用戶名密碼了,由于登錄前需要過一下滑動驗證碼,因此可以猜測另外兩個參數與驗證碼有關,不過僅從抓包來看,另外兩個參數類似于 uuid 的格式,不太像驗證碼的參數。
另外可以注意到登陸前,有兩次 csrfSave 和一次 verCode 的請求,正常請求成功就會返回一個 JSON,里面有個 data 參數,后面應該是會用到的。
先看 Form Data,搜索任意一個參數,比如 loginNo,很容易在 login.js 里找到加密的地方,用戶名和密碼都經過了 encrypt 這個函數進行加密,backUrl 這個值,是利用 localStorage 屬性,從瀏覽器儲存的鍵值對的數據里取的,為空也不影響。
跟進 encrypt,可以看到用到了 JSEncrypt,標準的 RSA 加密:
再看看 loginCode,直接搜索這個值,可以看到是 verCode 這個請求返回的:
然后再看看 requestUUID,其值就是個 UUID,直接在當前文件(login.js)里搜索,可以看到定義的地方,有個 uploadUUID() 方法,就是在設置 UUID 的值,方法里面是向一個 uploadIdentifier 的接口發送了 post 請求:
這里注意,如果你直接全局搜索 UUID 的話,還可以在 common.js 里搜索到一個方法,經過測試,直接使用這個方法生成一個 uuid 也是可以請求通過的,這網站可能不嚴謹,不會嚴格檢測這個值。
Form Data 解決了,再來看看 Request Headers 里的 token 參數,由于它存在于請求頭里,所以我們可以通過 Hook 的方式來查找其生成的地方:
(function () {
var org=window.XMLHttpRequest.prototype.setRequestHeader;
window.XMLHttpRequest.prototype.setRequestHeader=function (key, value) {
if (key=='token') {
debugger;
}
return org.apply(this, arguments);
};
})();
這里我們也可以直接搜索 token、setRequestHeader 之類的關鍵字,很容易在 common.js 里找到,當我們點擊登陸,會有一個 csrfSave 的請求,返回的 data 值,經過 encrypt 方法加密后就是登陸請求頭的 token 了。
這個 token 參數在很多請求中都會用到,生成方法是一樣的,都是拿 csrfSave 請求返回的 data 經過 RSA 加密后得到的:
另外注意一點的就是,以上所有涉及到網絡請求的,Cookie 都需要一個 SESSION 值,這個可以在首次訪問頁面獲取到:
這里我們理一下登陸的流程:
這里第2步,也可以直接用 Python 或者 JS 生成一個 uuid,網站校驗不嚴格,也可以通過,另外可以看出這個滑塊是假的,通過代碼可以無視滑塊進行登錄。
GitHub 關注 K 哥爬蟲,持續分享爬蟲相關代碼!歡迎 star !https://github.com/kgepachong/
以下只演示部分關鍵代碼,不能直接運行! 完整代碼倉庫地址:https://github.com/kgepachong/crawler/
/*==================================# @Time : 2022-01-11
# @Author : 微信公眾號:K哥爬蟲
# @FileName: encrypt.js
# @Software: PyCharm
#==================================*/
JSEncrypt=require("jsencrypt")
function encrypt(pwd){
var key="MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsgDq4OqxuEisnk2F0EJFmw4xKa5IrcqEYHvqxPs2CHEg2kolhfWA2SjNuGAHxyDDE5MLtOvzuXjBx/5YJtc9zj2xR/0moesS+Vi/xtG1tkVaTCba+TV+Y5C61iyr3FGqr+KOD4/XECu0Xky1W9ZmmaFADmZi7+6gO9wjgVpU9aLcBcw/loHOeJrCqjp7pA98hRJRY+MML8MK15mnC4ebooOva+mJlstW6t/1lghR8WNV8cocxgcHHuXBxgns2MlACQbSdJ8c6Z3RQeRZBzyjfey6JCCfbEKouVrWIUuPphBL3OANfgp0B+QG31bapvePTfXU48TYK0M5kE+8LgbbWQIDAQAB";
var encrypt=new JSEncrypt();
encrypt.setPublicKey(key);
var encrypted=encrypt.encrypt(pwd);
return encrypted;
}
// 測試樣例
// console.log(encrypt("15555555555"))
個登錄界面可能有一點點。。。[黑線]
源碼放著了,要自己拿去吧[奸笑]
<!DOCTYPE html>
<html>
<head>
<title>Login Page</title>
<style>
body {
background-color: #000;
color: #fff;
text-align: center;
padding-top: 100px;
font-family: 'Courier New', Courier, monospace;
}
h1 {
font-size: 50px;
margin-bottom: 30px;
color: #ff0000;
text-shadow: 0 0 10px #ff0000;
}
table {
margin: 0 auto;
width: 400px;
}
th,
td {
padding: 10px;
}
input[type="text"],
input[type="date"] {
width: 300px;
padding: 5px;
border-radius: 5px;
border: 1px solid #ff0000;
background-color: #000;
color: #ff0000;
}
input[type="submit"] {
margin-top: 20px;
padding: 10px;
background-color: #ff0000;
color: #fff;
border: none;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s ease;
animation: pulseEffect 1s infinite;
}
input[type="submit"]:hover {
background-color: #ff6666;
animation: none;
}
.success-message {
margin-top: 30px;
display: none;
animation: fadeInEffect 2s;
}
.checkbox-option {
margin-top: 20px;
animation: slideInEffect 2s;
}
.contact-info {
margin-top: 40px;
animation: bounceEffect 1.5s infinite;
}
/* Animations */
@keyframes pulseEffect {
0% {
transform: scale(1);
}
50% {
transform: scale(1.2);
}
100% {
transform: scale(1);
}
}
@keyframes fadeInEffect {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes slideInEffect {
from {
transform: translateX(-100%);
}
to {
transform: translateX(0);
}
}
@keyframes bounceEffect {
0%,
100% {
transform: scale(1);
}
50% {
transform: scale(1.2);
}
}
</style>
<script>
window.onload=function () {
document.querySelector('form').addEventListener('submit', function (event) {
event.preventDefault();
var successMessage=document.getElementById('successMessage');
successMessage.style.display='block';
successMessage.style.animation='fadeInEffect 2s forwards';
var submitButton=document.getElementById('submitButton');
submitButton.disabled=true;
});
document.getElementById('closeButton').addEventListener('click', function () {
var successMessage=document.getElementById('successMessage');
successMessage.style.display='none';
});
}
</script>
</head>
<body>
<h1>死亡協議</h1>
<form>
<table>
<tr>
<th>受害者姓名</th>
<td><input type="text"></td>
</tr>
<tr>
<th>身份證號碼</th>
<td><input type="text"></td>
</tr>
<tr>
<th>iphone</th>
<td><input type="text"></td>
</tr>
<tr>
<th>郵箱</th>
<td><input type="text"></td>
</tr>
<tr>
<th>預定日期</th>
<td><input type="date"></td>
</tr>
</table>
<input id="submitButton" type="submit" value="簽署協議">
</form>
<div id="successMessage" class="success-message">
<p>最近自殺人數較多,可能會延期</p>
<button id="closeButton">關閉</button>
</div>
<div class="checkbox-option">
<input type="checkbox" id="agreementCheckbox">
<label for="agreementCheckbox">我同意所有要求</label>
</div>
<div class="contact-info">
<p>客服:LHTZ173@163.com</p>
</div>
</body>
家好,今天分享的是仿京東登錄頁面的簡單實現方法(結構與樣式),首先我們依舊是先看下效果圖
下面是HTML結構
下面是CSS樣式
PS:本人也是小白一枚,自學沒幾天,疏漏之處在所難免,請多擔待!
*請認真填寫需求信息,我們會在24小時內與您取得聯系。