整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          「JS 逆向百例」HN某服務網登錄逆向,驗證碼形同虛

          「JS 逆向百例」HN某服務網登錄逆向,驗證碼形同虛設

          本文章中所有內容僅供學習交流,抓包內容、敏感網址、數據接口均已做脫敏處理,嚴禁用于商業用途和非法用途,否則由此產生的一切后果均與作者無關,若有侵權,請聯系我立即刪除!

          逆向目標

          • 目標:某政務服務網登錄接口
          • 主頁:aHR0cHM6Ly9sb2dpbi5obnp3ZncuZ292LmNuL3RhY3MtdWMvbG9naW4vaW5kZXg=
          • 接口:aHR0cHM6Ly9sb2dpbi5obnp3ZncuZ292LmNuL3RhY3MtdWMvbmF0dXJhbE1hbi9sb2dpbk5v
          • 逆向參數:Form Data:loginNo、loginPwd、code、requestUUIDRequest Headers:token

          抓包分析

          本次逆向目標來源于某位粉絲的求助:

          隨便輸入賬號密碼點擊登陸,抓包發現接口的 Request Headers 有個加密參數 token,Form Data 里 loginNo、loginPwd、code、requestUUID 都是經過加密處理了的,loginNo 和 loginPwd 應該就是用戶名密碼了,由于登錄前需要過一下滑動驗證碼,因此可以猜測另外兩個參數與驗證碼有關,不過僅從抓包來看,另外兩個參數類似于 uuid 的格式,不太像驗證碼的參數。

          另外可以注意到登陸前,有兩次 csrfSave 和一次 verCode 的請求,正常請求成功就會返回一個 JSON,里面有個 data 參數,后面應該是會用到的。

          參數逆向

          Form 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 也是可以請求通過的,這網站可能不嚴謹,不會嚴格檢測這個值。

          Request Headers

          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 值,這個可以在首次訪問頁面獲取到:

          登陸流程

          這里我們理一下登陸的流程:

          1. 訪問首頁拿 Cookie 中的 SESSION 值;
          2. 訪問 csrfSave,拿到一個 data 值,經過 RSA 加密得到 token,攜帶 token 訪問 uploadIdentifier,拿到 uuid;
          3. 訪問 csrfSave,拿到一個 data 值,經過 RSA 加密得到 token,攜帶 token 訪問 verCode,拿到 code;
          4. 訪問 csrfSave,拿到一個 data 值,經過 RSA 加密得到 token,攜帶 token、uuid、code 和加密后的賬號密碼,訪問 loginNo 登錄。

          這里第2步,也可以直接用 Python 或者 JS 生成一個 uuid,網站校驗不嚴格,也可以通過,另外可以看出這個滑塊是假的,通過代碼可以無視滑塊進行登錄。

          完整代碼

          GitHub 關注 K 哥爬蟲,持續分享爬蟲相關代碼!歡迎 star !https://github.com/kgepachong/

          以下只演示部分關鍵代碼,不能直接運行! 完整代碼倉庫地址:https://github.com/kgepachong/crawler/

          JavaScript 加密代碼

          /*==================================# @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"))

          Python 登錄代碼

          個登錄界面可能有一點點。。。[黑線]

          源碼放著了,要自己拿去吧[奸笑]


          <!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:本人也是小白一枚,自學沒幾天,疏漏之處在所難免,請多擔待!


          主站蜘蛛池模板: 一区二区精品在线| 一区二区视频在线免费观看| 亚洲Av高清一区二区三区| 国产福利日本一区二区三区| 精品国产一区二区三区2021| 亚洲av无码片区一区二区三区 | 无码少妇丰满熟妇一区二区| 国产一区二区三区在线观看精品| 黑巨人与欧美精品一区| 国产AV午夜精品一区二区入口| 国产伦精品一区二区三区精品| 精品一区二区三区自拍图片区| 精品国产AⅤ一区二区三区4区 | 国产成人精品一区二三区在线观看| 中文无码一区二区不卡αv| 美女一区二区三区| 亚洲熟女乱综合一区二区| 国产成人一区二区三中文| 无码精品人妻一区二区三区免费看| 日韩av片无码一区二区三区不卡| 成人免费一区二区三区在线观看| 亚洲视频一区网站| 无码精品一区二区三区免费视频| 亚洲色大成网站www永久一区| 亚洲国产成人久久一区WWW | 四虎成人精品一区二区免费网站| 青青青国产精品一区二区| 精品视频一区二区三区在线观看 | 精品国产一区二区三区免费看 | 国产伦精品一区二区三区免费迷 | 日韩在线观看一区二区三区| AV鲁丝一区鲁丝二区鲁丝三区 | 中文字幕一区二区三区乱码| 亚洲国产一区明星换脸| 在线不卡一区二区三区日韩| 99偷拍视频精品一区二区| 日本精品无码一区二区三区久久久 | 久久青草精品一区二区三区| 国产精品高清一区二区三区| 国产av一区二区三区日韩| 无码人妻品一区二区三区精99|