某志願網js逆向

来源:https://www.cnblogs.com/wandaren/archive/2023/08/09/17619116.html
-Advertisement-
Play Games

逆向過程分析與js代碼扣取 請求頭U-Sign數據 通過瀏覽器開發者工具可以看到返回數據的介面/youzy.dms.basiclib.api.college.query 添加XHR斷點刷新瀏覽器會自動進入斷點 查看具體請求數據,將斷點定位到r = r.then(t.shift(), t.shift( ...


逆向過程分析與js代碼扣取

請求頭U-Sign數據

image.png

通過瀏覽器開發者工具可以看到返回數據的介面/youzy.dms.basiclib.api.college.query

image.png

添加XHR斷點刷新瀏覽器會自動進入斷點

image.png

查看具體請求數據,將斷點定位到r = r.then(t.shift(), t.shift());

image.png

F8跳轉到改斷點位置,可以看到有5個方法

image.png

點擊[[FunctionLocation]]:後的js查看方法,發現第一個方法裡面有u-sign

image.png

將斷點定位到u-sign,並將上一步的斷點放開,F8定位到u-sign

image.png

  • 發現u-sign由o方法生成

image.png

  • 複製出url和data的值,data可以直接右鍵複製對象

image.png

data = {
   "keyword": "",
   "provinceNames": [],
   "natureTypes": [],
   "eduLevel": "",
   "categories": [],
   "features": [],
   "pageIndex": 1,
   "pageSize": 20,
   "sort": 11
}

進入o方法,斷點並執行

image.png 觀察發現該方法,發現參數o只是做了一個拼接,數據加密由n(o)完成,i值為固定值,a值為請求參數

var i = "9SASji5OWnG41iRKiSvTJHlXHmRySRp1"
o = Object.keys(a).length > 0 ? "".concat(JSON.stringify(a), "&").concat(i) : "&".concat(i);
o = o.toLowerCase()
n(o)

image.png

進入n方法並斷點

image.png 複製出方法並改成正常方法

// 防止重名改為exports123
exports123 = function(e, r) {
 if (null == e)
   throw new Error("Illegal argument " + e);
 var n = t.wordsToBytes(a(e, r));
 return r && r.asBytes ? n : r && r.asString ? o.bytesToString(n) : t.bytesToHex(n)
}

我們現在可以得到js

var i = "9SASji5OWnG41iRKiSvTJHlXHmRySRp1",
data = {
       "keyword": "",
       "provinceNames": [],
       "natureTypes": [],
       "eduLevel": "",
       "categories": [],
       "features": [],
       "pageIndex": 1,
       "pageSize": 20,
       "sort": 11
},
uri = '/youzy.dms.basiclib.api.college.query'


exports123 = function(e, r) {
   if (null == e)
       throw new Error("Illegal argument " + e);
   var n = t.wordsToBytes(a(e, r));
   return r && r.asBytes ? n : r && r.asString ? o.bytesToString(n) : t.bytesToHex(n)
}

// 將a改為data
o = Object.keys(data).length > 0 ? "".concat(JSON.stringify(data), "&").concat(i) : "&".concat(i);
o = o.toLowerCase()

console.log(exports123(o))

執行發現t未定義,進入t image.png image.png 跳轉到到wordsToBytes在r中,即t為r,將r複製出來並改名r123,並將t.wordsToBytes改為r123.wordsToBytes

r123 = {
 rotl: function(e, t) {
   return e << t | e >>> 32 - t
},
 rotr: function(e, t) {
   return e << 32 - t | e >>> t
},
 endian: function(e) {
   if (e.constructor == Number)
     return 16711935 & r123.rotl(e, 8) | 4278255360 & r123.rotl(e, 24);
   for (var t = 0; t < e.length; t++)
     e[t] = r123.endian(e[t]);
   return e
},
 randomBytes: function(e) {
   for (var t = []; e > 0; e--)
     t.push(Math.floor(256 * Math.random()));
   return t
},
 bytesToWords: function(e) {
   for (var t = [], r = 0, n = 0; r < e.length; r++,
        n += 8)
     t[n >>> 5] |= e[r] << 24 - n % 32;
   return t
},
 wordsToBytes: function(e) {
   for (var t = [], r = 0; r < 32 * e.length; r += 8)
     t.push(e[r >>> 5] >>> 24 - r % 32 & 255);
   return t
},
 bytesToHex: function(e) {
   for (var t = [], r = 0; r < e.length; r++)
     t.push((e[r] >>> 4).toString(16)),
       t.push((15 & e[r]).toString(16));
   return t.join("")
},
 hexToBytes: function(e) {
   for (var t = [], r = 0; r < e.length; r += 2)
     t.push(parseInt(e.substr(r, 2), 16));
   return t
},
 bytesToBase64: function(e) {
   for (var r = [], n = 0; n < e.length; n += 3)
     for (var i = e[n] << 16 | e[n + 1] << 8 | e[n + 2], o = 0; o < 4; o++)
       8 * n + 6 * o <= 8 * e.length ? r.push(t.charAt(i >>> 6 * (3 - o) & 63)) : r.push("=");
   return r.join("")
},
 base64ToBytes: function(e) {
   e = e.replace(/[^A-Z0-9+\/]/gi, "");
   for (var r = [], n = 0, i = 0; n < e.length; i = ++n % 4)
     0 != i && r.push((t.indexOf(e.charAt(n - 1)) & Math.pow(2, -2 * i + 8) - 1) << 2 * i | t.indexOf(e.charAt(n)) >>> 6 - 2 * i);
   return r
}
}

此時我們的js文件為

var i = "9SASji5OWnG41iRKiSvTJHlXHmRySRp1",
data = {
   "keyword": "",
   "provinceNames": [],
   "natureTypes": [],
   "eduLevel": "",
   "categories": [],
   "features": [],
   "pageIndex": 1,
   "pageSize": 20,
   "sort": 11
}, uri = '/youzy.dms.basiclib.api.college.query'
exports123 = function(e, r) {
   if (null == e)
       throw new Error("Illegal argument " + e);
   var n = r123.wordsToBytes(a(e, r));
   return r && r.asBytes ? n : r && r.asString ? o.bytesToString(n) : t.bytesToHex(n)
}

//t
r123 = {
   rotl: function(e, t) {
       return e << t | e >>> 32 - t
  },
   rotr: function(e, t) {
       return e << 32 - t | e >>> t
  },
   endian: function(e) {
       if (e.constructor == Number)
           return 16711935 & r123.rotl(e, 8) | 4278255360 & r123.rotl(e, 24);
       for (var t = 0; t < e.length; t++)
           e[t] = r123.endian(e[t]);
       return e
  },
   randomBytes: function(e) {
       for (var t = []; e > 0; e--)
           t.push(Math.floor(256 * Math.random()));
       return t
  },
   bytesToWords: function(e) {
       for (var t = [], r = 0, n = 0; r < e.length; r++,
           n += 8)
           t[n >>> 5] |= e[r] << 24 - n % 32;
       return t
  },
   wordsToBytes: function(e) {
       for (var t = [], r = 0; r < 32 * e.length; r += 8)
           t.push(e[r >>> 5] >>> 24 - r % 32 & 255);
       return t
  },
   bytesToHex: function(e) {
       for (var t = [], r = 0; r < e.length; r++)
           t.push((e[r] >>> 4).toString(16)),
               t.push((15 & e[r]).toString(16));
       return t.join("")
  },
   hexToBytes: function(e) {
       for (var t = [], r = 0; r < e.length; r += 2)
           t.push(parseInt(e.substr(r, 2), 16));
       return t
  },
   bytesToBase64: function(e) {
       for (var r = [], n = 0; n < e.length; n += 3)
           for (var i = e[n] << 16 | e[n + 1] << 8 | e[n + 2], o = 0; o < 4; o++)
               8 * n + 6 * o <= 8 * e.length ? r.push(t.charAt(i >>> 6 * (3 - o) & 63)) : r.push("=");
       return r.join("")
  },
   base64ToBytes: function(e) {
       e = e.replace(/[^A-Z0-9+\/]/gi, "");
       for (var r = [], n = 0, i = 0; n < e.length; i = ++n % 4)
           0 != i && r.push((t.indexOf(e.charAt(n - 1)) & Math.pow(2, -2 * i + 8) - 1) << 2 * i | t.indexOf(e.charAt(n)) >>> 6 - 2 * i);
       return r
  }
}

o = Object.keys(data).length > 0 ? "".concat(JSON.stringify(data), "&").concat(i) : "&".concat(i);
o = o.toLowerCase()

console.log(exports123(o))

執行提示a未定義

image.png

進入a並將a複製出來,改名123,替換其中的t.bytesToWords為r123.bytesToWords,t.endianr為123.endian

a123 = function(e, r) {
   e.constructor == String ? e = r && "binary" === r.encoding ? o.stringToBytes(e) : n.stringToBytes(e) : i(e) ? e = Array.prototype.slice.call(e, 0) : Array.isArray(e) || e.constructor === Uint8Array || (e = e.toString());
   for (var s = r123.bytesToWords(e), u = 8 * e.length, c = 1732584193, f = -271733879, d = -1732584194, l = 271733878, h = 0; h < s.length; h++)
       s[h] =
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 思路分析 在開始動手之前,分析一下整個功能的實現過程: 根據圖片大小創建 canvas1 畫布,並將原圖片直接定位在 canvas1 上; 在畫布上添加一個蒙層,以區分當前 canvas 圖像是被裁剪的原圖像; 在蒙層上方,對裁剪區域(鼠 ...
  • Avue 是一個基於Element-plus低代碼前端框架,它使用JSON 配置來生成頁面,可以減少頁面開發工作量,極大提升效率; 雖然Avue官網上面都有這些配置說明,但是如果剛開始接觸不熟悉框架的話需要很久才找到自己需要的參數配置,為了方便自己今後查找使用,現將一些開發中常用的配置梳理在下 一、 ...
  • 這幾天在學vue3, 用Element-plus 加 vue3 搭了個框架,在這裡記錄一下項目搭建中遇到的問題。 1、使用 Element-plus 的 icon 圖標,顯示不出來 首先,用命令行中安裝 Element-plus 的圖標: npm install @element-plus/icon ...
  • >我們是[袋鼠雲數棧 UED 團隊](http://ued.dtstack.cn/),致力於打造優秀的一站式數據中台產品。我們始終保持工匠精神,探索前端道路,為社區積累並傳播經驗價值。 >本文作者:景明 ## 升級背景 目前公司產品有關 react 的工具版本普遍較低,其中 react router ...
  • 在現代的 Web 應用程式中,頁面訪問攔截是非常重要的一個方面。它可以用於確保用戶只能訪問他們有許可權的頁面,提高應用程式的安全性和用戶體驗。本篇博文將介紹如何使用 Vue 框架來實現頁面訪問攔截的功能。 ...
  • 本文主要做推薦系統淺析,主要介紹推薦系統的定義,推薦系統的基礎框架,簡單介紹設計推薦的相關方法以及架構。適用於部分對推薦系統感興趣的同學以及有相關基礎的同學,本人水平有限,歡迎大家指正。 ...
  • 不知道大家在開發的時候,有沒有想過(遇到)這些問題: 1、大家都是按需要開發,都是一個職級的同事,為什麼有些人的思路就很清晰,代碼也很整潔、易懂;而自己開發,往往不知道怎麼下手設計,寫完了也是bug一堆,codeReview的時候更是頻頻被懟... 2、感覺每天都是CURD,寫重覆的代碼,做類似的需... ...
  • ## 10.1、概念 - AOP(Aspect Oriented Programming)是一種設計思想,是軟體設計領域中的面向切麵編程 - AOP是面向對象編程(OOP)的一種補充和完善,OOP是縱向繼承機制,AOP是橫向抽取機制 - AOP能通過預編譯方式和運行期動態代理方式,實現在不修改源代碼 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...