<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          玩轉(zhuǎn) JS 逆向:RPC 加持,爬蟲效率飆升

          共 10370字,需瀏覽 21分鐘

           ·

          2023-08-18 21:48

          大家好,我是安果!

          一些復(fù)雜的網(wǎng)站針對(duì)參數(shù)是層層加密,如果選擇硬剛,去扣代碼、補(bǔ)環(huán)境,耗時(shí)耗力的同時(shí),不一定能獲取完整的加密邏輯

          在 JS 逆向中,我們可以通過(guò) RPC 通信,直接調(diào)用瀏覽器的方法生成加密參數(shù),這樣可以省去扣代碼的時(shí)間

          本篇文章將介紹 Sekiro RPC 進(jìn)行 JS 逆向的完整流程

          目標(biāo)網(wǎng)站:

          aHR0cHM6Ly93d3cueGluZ3R1LmNuL3N1cC9jcmVhdG9yL2hvdA==

          具體操作步驟如下:

          1、Sekiro RPC

          Sekiro 是一個(gè)多語(yǔ)言的、分布式網(wǎng)絡(luò)拓?fù)錈o(wú)關(guān)的服務(wù)發(fā)布平臺(tái)

          它能基于長(zhǎng)連接和代碼注入 API 服務(wù)暴露的框架,可用于逆向(包含 JS 逆向和 App 逆向)

          官網(wǎng):

          https://sekiro.iinti.cn/sekiro-doc/

          2、分析網(wǎng)站

          打開目標(biāo)網(wǎng)站,發(fā)現(xiàn)接口 /h/api/gateway/handler_get 中的查詢參數(shù) sign 是加密的

          在 Sources - Page 面板下,通過(guò)關(guān)鍵字 sign: 全局查詢

          發(fā)現(xiàn)加密參數(shù)生成的具體邏輯如下:

          PS:通過(guò)方法 generatePayload 生成 sign,其中 c、l 為參數(shù)

          文件位置:

          https://*/obj/goofy/star/idou_fe/assets/vendor-a1b40867.js

          然后,在方法 generatePayload 方法內(nèi)添加條件斷點(diǎn)

          這樣,通過(guò)多次 Debugger 分析,可以得出參數(shù)的生成規(guī)則(即:參數(shù)固定值、參數(shù)生成邏輯)

          //條件監(jiān)聽
          //條件:c.service_name==='author.AdStarAuthorService'

          這樣,在調(diào)試模式下,我們可以在瀏覽器控制臺(tái)進(jìn)行測(cè)試了

          如下,直接調(diào)用方法可以拿到加密后的參數(shù)

          3、加密文件重寫 Overrides

          在本地新建一個(gè)文件夾,Sources - Overrides 關(guān)聯(lián)該本地目錄

          PS:開啟 Overrides 并授予權(quán)限

          在 Sources - Page 面板下,選擇 vendor-a1b40867.js 文件右鍵,選擇 Save for overrides 將文件保存到 Overrides 中

          4、Sekiro 定義

          修改 Overrides 中 vendor-a1b40867.js 文件

          定義 SekiroClient 方法對(duì)象并實(shí)例化,注冊(cè)一個(gè)方法進(jìn)行監(jiān)聽處理

          SekiroClient 源碼如下:

          https://raw.githubusercontent.com/yint-tech/sekiro-samples/main/demo-web/sekiroWeb.js

          通過(guò)關(guān)鍵字 generatePayload 找到對(duì)應(yīng)方法,回車換行,輸入如下邏輯

          PS:修改源碼后,需要重新開啟、關(guān)閉 Overrides 開關(guān)一次( Enable Local Overrides )

          ...
          function SekiroClient(e){if(this.wsURL=e,this.handlers={},this.socket={},!e)throw new Error("wsURL can not be empty!!");this.webSocketFactory=this.resolveWebSocketFactory(),this.connect()}SekiroClient.prototype.resolveWebSocketFactory=function(){if("object"==typeof window){var e=window.WebSocket?window.WebSocket:window.MozWebSocket;return function(o){function t(o){this.mSocket=new e(o)}return t.prototype.close=function(){this.mSocket.close()},t.prototype.onmessage=function(e){this.mSocket.onmessage=e},t.prototype.onopen=function(e){this.mSocket.onopen=e},t.prototype.onclose=function(e){this.mSocket.onclose=e},t.prototype.send=function(e){this.mSocket.send(e)},new t(o)}}if("object"==typeof weex)try{console.log("test webSocket for weex");var o=weex.requireModule("webSocket");return console.log("find webSocket for weex:"+o),function(e){try{o.close()}catch(e){}return o.WebSocket(e,""),o}}catch(e){console.log(e)}if("object"==typeof WebSocket)return function(o){return new e(o)};throw new Error("the js environment do not support websocket")},SekiroClient.prototype.connect=function(){console.log("sekiro: begin of connect to wsURL: "+this.wsURL);var e=this;try{this.socket=this.webSocketFactory(this.wsURL)}catch(o){return console.log("sekiro: create connection failed,reconnect after 2s:"+o),void setTimeout(function(){e.connect()},2e3)}this.socket.onmessage(function(o){e.handleSekiroRequest(o.data)}),this.socket.onopen(function(e){console.log("sekiro: open a sekiro client connection")}),this.socket.onclose(function(o){console.log("sekiro: disconnected ,reconnection after 2s"),setTimeout(function(){e.connect()},2e3)})},SekiroClient.prototype.handleSekiroRequest=function(e){console.log("receive sekiro request: "+e);var o=JSON.parse(e),t=o.__sekiro_seq__;if(o.action){var n=o.action;if(this.handlers[n]){var s=this.handlers[n],i=this;try{s(o,function(e){try{i.sendSuccess(t,e)}catch(e){i.sendFailed(t,"e:"+e)}},function(e){i.sendFailed(t,e)})}catch(e){console.log("error: "+e),i.sendFailed(t,":"+e)}}else this.sendFailed(t,"no action handler: "+n+" defined")}else this.sendFailed(t,"need request param {action}")},SekiroClient.prototype.sendSuccess=function(e,o){var t;if("string"==typeof o)try{t=JSON.parse(o)}catch(e){(t={}).data=o}else"object"==typeof o?t=o:(t={}).data=o;(Array.isArray(t)||"string"==typeof t)&&(t={data:t,code:0}),t.code?t.code=0:(t.status,t.status=0),t.__sekiro_seq__=e;var n=JSON.stringify(t);console.log("response :"+n),this.socket.send(n)},SekiroClient.prototype.sendFailed=function(e,o){"string"!=typeof o&&(o=JSON.stringify(o));var t={};t.message=o,t.status=-1,t.__sekiro_seq__=e;var n=JSON.stringify(t);console.log("sekiro: response :"+n),this.socket.send(n)},SekiroClient.prototype.registerAction=function(e,o){if("string"!=typeof e)throw new Error("an action must be string");if("function"!=typeof o)throw new Error("a handler must be function");return console.log("sekiro: register action: "+e),this.handlers[e]=o,this};

          //實(shí)例化一個(gè)客戶端連接對(duì)象
          //group:業(yè)務(wù)類型
          //clientId:設(shè)備id
          var client = new SekiroClient("wss://sekiro.iinti.cn:5612/business/register?group=test_web&clientId=" + Math.random());

          //注冊(cè)
           client.registerAction("xingtu"function (request, resolve, reject{
               // var enc_data = request['data']
               // var res = enc_data;
               // resolve(v()(res));
               let c={
                   "hot_list_id""0",
                   "tag""61e541324fe6649d1b8a2ee3",
                   "service_name""author.AdStarAuthorService",
                   "service_method""GetHotListData"
               };

               let l={
                   "strict"true,
                   "serializing"true,
                   "rule": {
                       "include": [
                           "hot_list_id",
                           "tag",
                           "download",
                           "image_download",
                           "province",
                           "city",
                           "rlid"
                       ]
                   }
               };
          resolve(generatePayload(c,l));
           });
          ...

          重新訪問(wèn)下面地址,查看控制臺(tái),發(fā)現(xiàn) Sekiro 已經(jīng)準(zhǔn)備完畢

          5、Python 調(diào)用

          通過(guò) Websocket 調(diào)用,借助瀏覽器調(diào)用 generatePayload() 方法,獲取加密后的值 sign

          最后,組成完整的 URL 獲取數(shù)據(jù)

          import requests

          # Websocket通訊,獲取sign(Sekiro)
          def get_signature():
              data = {"group""test_web",
                      "action""xingtu"
                      }
              resp = requests.get("http://sekiro.iinti.cn:5612/business/invoke", params=data).json()
              return resp['sign']

          # 獲取數(shù)據(jù)
          def get_data(sign):
              url = f"https://*host/h/api/gateway/handler_get/?hot_list_id=0&tag=*tag&service_name=author.AdStarAuthorService&service_method=GetHotListData&sign_strict=1&sign={sign}"

              payload = {}
              headers = {
                  'authority''*host',
                  'agw-js-conv''str',
                  'pragma''no-cache',
                  'x-login-source''1',
                  'x-star-service-method''GetHotListData',
                  'x-star-service-name''author.AdStarAuthorService',
                  'Cookie''cookie',
                  'User-Agent''Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36'
              }
              response = requests.request("GET", url, headers=headers, data=payload)

              print(response.text)

          if __name__ == '__main__':
              sign = get_signature()
              print("sign:",sign)

              get_data(sign)

          6、補(bǔ)充一下

          除了 Overrides 覆蓋文件外,還可以使用油猴腳本或?yàn)g覽器插件進(jìn)行腳本注入,完成 Sekiro 的初始化及事件注冊(cè)

          相比傳統(tǒng)的 JS 逆向,利用 Sekiro 直接調(diào)用方法獲取加密參數(shù)更加方便快捷然后;但是它有一個(gè)缺點(diǎn),即:需要通過(guò)瀏覽器打開目標(biāo)網(wǎng)站

          如果你覺得文章還不錯(cuò),請(qǐng)大家 點(diǎn)贊、分享、留言 下,因?yàn)檫@將是我持續(xù)輸出更多優(yōu)質(zhì)文章的最強(qiáng)動(dòng)力!


          推薦閱讀

          5 分鐘,教你從零快速編寫一個(gè)油猴腳本!

          Python 絕招:解鎖小紅書信息流的無(wú)限潛力!

          反爬篇 | 手把手教你處理 JS 逆向之字體反爬(下)

          休閑時(shí)光:最近上映的電影與爬蟲世界,帶您徹底放松!


          END


          好文和朋友一起看~

          瀏覽 1638
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  三级午夜在线无码 | 日本免费特一级 | 中文字幕日韩高清 | 无码视频在线免费观看 | 丁香五月婷操 |