<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>

          某麥最新 analysis 算法逆向分析(多種語言實(shí)現(xiàn))

          共 15196字,需瀏覽 31分鐘

           ·

          2022-10-24 11:42

          這是「進(jìn)擊的Coder」的第 737 ?篇技術(shù)分享 作者:TheWeiJun 來源:逆向與爬蟲的故事

          閱讀本文大概需要 13 分鐘。




          ? ? ??特別聲明:本公眾號文章只作為學(xué)術(shù)研究,不作為其它不法用途;如有侵權(quán)請聯(lián)系作者刪除。

          15deba4685c5e331224f48499469004b.webp


          ?目錄


          一、前言介紹 二、 參數(shù)分析 三、斷點(diǎn)調(diào)試 四、算法分析 五、思路總結(jié)




          趣味模塊


          ? ? ??小明是一名工程師,最近小明遇到了一個棘手的問題:小明發(fā)現(xiàn)自己曾經(jīng)熬了幾個通宵搞定的某麥算法居然升級了。小明惆悵進(jìn)行中....,按照之前的套路進(jìn)行加密定位和還原,發(fā)現(xiàn)都不好使了。這篇文章中,將解決小明遇到的困境,讓我們一起去看小明遇到的問題并通過多種語言去實(shí)現(xiàn)算法還原吧!




          一、前言介紹


          前言:? 想必 大家都了解什么是JS逆向吧?我們在以往的文章中涉及到JS逆向的網(wǎng)站,采用的方式都是去還原JS代碼,然后使用Python去調(diào)用JS源碼傳遞參數(shù)返回結(jié)果。這個過程雖然沒有問題,但是對于爬取效率的提升、代碼的性能都會受到影響。雖然爬蟲的職責(zé)是首先確保能不能拿到數(shù)據(jù),但是我覺得還有一個問題,那就是爬取效率。如果這兩者都具備了,那將是最完美的!對于一些加密邏輯不是太復(fù)雜的網(wǎng)站,我們完全可以進(jìn)行源碼跨語言還原。耐心看完本文,你會受益匪淺的!




          二、參數(shù)分析


          備注 :如果想看舊版文章的,可以點(diǎn)擊此鏈接:某麥analysis參數(shù)算法分析


          1、首先打開我們今天要模擬的網(wǎng)站,刷新當(dāng)前頁面,首頁截圖如下:

          bd8fec9e85fba1d9a59ab1da796f715d.webp

          2、然后打開開發(fā)者工具,查找指定的XHR請求數(shù)據(jù)包,截圖如下所示:

          49f873e4178a92b192ba14dfb18fa7c5.webp

          3、接下來,我們對該接口參數(shù)進(jìn)行初判斷及整理分析:

          2ef336967a6af4fc65f32aa857ccd986.webp

          params參數(shù)分析:

          • analysis? ? ? ? ? ? ? 初步懷疑是base64加密

          • country? ? ? ? ? ? ? ?固定值

          • version? ? ? ? ? ? ? ? 搜索版本

          • search、advise? 搜索關(guān)鍵字


          headers參數(shù)分析:

          說明: 由于headers參數(shù)沒有重要參數(shù)影響,故不作說明。




          三、斷點(diǎn)調(diào)試


          1、使用最簡單的方式,查詢指定關(guān)鍵字、加密方法,定位加密參數(shù)具體坐標(biāo)文件,截圖如下:

          4f5782a0e15f6f1e3ae4c9c08f8aee1f.webp

          說明: 經(jīng)過查詢,我們可以肯定的是代碼中沒有用到這個變量名,然后我們?nèi)ニ阉骷用芊椒?,發(fā)現(xiàn)能搜到結(jié)果,但是和我們的加密參數(shù)關(guān)聯(lián)不大,截圖如下:

          ee76f8972167b27c99092c46f32711f7.webp


          3、接下來,我們還是使用XHR打斷點(diǎn),回溯堆棧的方式查找吧,截圖如下:

          7381ae4124041e651572a81b9ca09f5c.webp

          說明:查看斷點(diǎn)發(fā)包的請求函數(shù),我們發(fā)現(xiàn)標(biāo)紅的地方已經(jīng)計算出了加密參數(shù),顯然我們的斷點(diǎn)是置后的,不過沒有關(guān)系,我們查看函數(shù)執(zhí)行堆棧進(jìn)行回溯查找。


          4、由于需要堆棧調(diào)試,過濾掉一些沒用的流程,我們直接定位到加密地方,截圖如下:

          84142fc48649b1bb5c72a8642eb727fb.webp

          總結(jié):此時上圖中參數(shù)e即為我們想要還原的加密參數(shù),整個流程貫通后,我們只需要對js算法進(jìn)行還原即可。




          四、算法還原


          1、JS版本算法還原

                
                  var n = {};
                
                
                  
                    
          function i(e) { var t, a = (t = "", ????????["66",?"52",?"6d",?"6d",?"43",?"68",?"61",?"72",?"43",?"6f",?"64",?"65"].forEach((function?(e)?{ t += unescape("%u00" + e) } )), t); return String[a](e) }
          function h(e) { return function (e) { try { return btoa(e) } catch (t) { return Buffer.from(e).toString("base64") } }(encodeURIComponent(e).replace(/%([0-9A-F]{2})/g, (function (e, t) { return i("0x" + t) } ))) }
          function g(e, t) { t || (t = s()); for (var a = (e = e.split("")).length, n = t.length, o = "charCodeAt", r = 0; r < a; r++) e[r] = i(e[r][o](0) ^ t[(r + 10) % n][o](0)); return e.join("") }
          n.cv = h; n.oZ = g;
          function get_enCdata(keyword, path) { var l = "xyz517cda96abcd"; var d = "@#"; var s = 687; var o = +new Date - (s || 0) - 1661224081041; var r = ["cn", "ios14", keyword, keyword]; r = r.sort().join(""); r = n.cv(r); r += d + path + d + o + d + 3; a = (0, n.cv)((0, n.oZ)(r, l)); console.log(a); return a } get_enCdata("王者榮耀", "/search/index")

          console打印結(jié)果如下:

          ec01b241907eb1aa7d2af15faff6a7e9.webp

          Python執(zhí)行JS代碼編寫如下:

                
                  
                    def js_load():
                  
                
                
                      with open('encrypt.js', 'r', encoding='UTF-8') as f:
                
                
                          lines = f.read()
                
                
                          ctx = execjs.compile(lines)
                
                
                      return ctx
                
                
                  
                    
          headers = { 'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="96", "Google Chrome";v="96"', 'accept': 'application/json, text/plain, */*', 'sec-ch-ua-mobile': '?0', 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36', 'sec-ch-ua-platform': '"macOS"', 'sec-fetch-site': 'same-site', 'sec-fetch-mode': 'cors', 'sec-fetch-dest': 'empty', 'accept-language': 'zh-CN,zh;q=0.9', } ctx = js_load() keyword = "王者榮耀" url = "https://xxxxxx/search/index" analysis?=?ctx.call("get_enCdata",?keyword,?urlparse(url).path) params = ( # ('analysis', ), ('country', 'cn'), ('search', keyword), ('advise', keyword), ('version', 'ios14'), ) # analysis?=?get_analysis(params,?urlparse(url).path) params = dict(params) params.update({ "analysis":analysis, })
          response = requests.get(url, headers=headers, params=params) print(response.text)

          打印結(jié)果如下:

          9c8059d141101f3625ce247ac8166b52.webp

          2、Python版本算法還原完整代碼:

                
                  
                    # -*- coding: utf-8 -*-
                  
                
                
                  
                    # --------------------------------------
                  
                
                
                  
                    # @author : 逆向與爬蟲故事公眾號
                  
                
                
                  
                    # --------------------------------------
                  
                
                
                  import time
                
                
                  
                    
          import requests import base64 from urllib.parse import urlparse

          def get_analysis(params, path): salt = "xyz517cda96abcd" data = list(dict(params).values()) data.sort() first_ba64 = base64.b64encode("".join(data).encode()).decode() first_ba64 += f"@#{path}@#{int(time.time()) * 1000 - 687 - 1661224081041}@#3" base_chr = ''.join(chr(ord(v) ^ ord(salt[(r + 10) % len(salt)])) for r, v in enumerate(first_ba64)) analysis = base64.b64encode(base_chr.encode()).decode() return analysis
          def start_requests(keyword):
          headers = { 'authority': 'api.qimai.cn', 'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="96", "Google Chrome";v="96"', 'accept': 'application/json, text/plain, */*', 'sec-ch-ua-mobile': '?0', 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36', ????????'sec-ch-ua-platform':?'"macOS"', 'sec-fetch-site': 'same-site', 'sec-fetch-mode': 'cors', ????????'sec-fetch-dest':?'empty', 'accept-language': 'zh-CN,zh;q=0.9', } url = "https://xxxxx/search/index" params = ( # ('analysis', ), ('country', 'cn'), ('search', keyword), ('advise', keyword), ('version', 'ios14'), ) analysis = get_analysis(params, urlparse(url).path) params = dict(params) params.update({ "analysis": analysis, })
          response = requests.get(url, headers=headers, params=params) print(response.text)
          if __name__ == '__main__': start_requests("王者榮耀")


          Pycharm打印結(jié)果如下:

          9c8059d141101f3625ce247ac8166b52.webp


          3、GoLang版本算法還原完整代碼:

                
                  
                    // Package main ------------------
                  
                
                
                  
                    // @author    : 逆向與爬蟲故事公眾號
                  
                
                
                  
                    // -------------------------------
                  
                
                
                  package main
                
                
                  
                    
          import ( "encoding/base64" "fmt" "io/ioutil" "log" "net/http" "time" )
          func getAnalysis(keyword, path string) string { salt := "xyz517cda96abcd" baseStr := fmt.Sprintf("cnios14%s%s", keyword, keyword) baseBase64 := base64.StdEncoding.EncodeToString([]byte(baseStr)) baseBase64 += fmt.Sprintf("@#%s@#%d@#3", path, time.Now().Unix()*1000-687-1661224081041) dataStr := "" for i := 0; i < len(baseBase64); i++ { dataStr += string(baseBase64[i] ^ salt[(i+10)%len(salt)]) } analysis := base64.StdEncoding.EncodeToString([]byte(dataStr)) return analysis }
          func main() { client := &http.Client{} keyword := "王者榮耀" path := "/search/index" analysis := getAnalysis(keyword, path) fmt.Println(analysis) req, err := http.NewRequest("GET", "https://xxxx/search/index?analysis="+analysis+"&country=cn&version=ios14&search="+keyword+"&advise="+keyword+"", nil) if err != nil { log.Fatal(err) } req.Header.Set("accept", "application/json, text/plain, */*") req.Header.Set("accept-language", "zh-CN,zh;q=0.9") req.Header.Set("cache-control", "no-cache") req.Header.Set("cookie", "gr_user_id=6326ec0c-e4bb-40f4-80fa-f136f53ec138; qm_check=A1sdRUIQChtxen8tJ0NMOQkKWVIeEHhARFQEQi5VVFk1RVJcd3UQABZQS0FIWhoSUFRZEgMSBBRRTlNISFVKF0o%3D; Hm_lvt_ff3eefaf44c797b33945945d0de0e370=1665841750,1665843752,1665999455,1666149354; tgw_l7_route=d09474674af82c17375cfcdd775c0c28; PHPSESSID=c8sbl02kml6qbdktrgkf2l7iia; ada35577182650f1_gr_session_id=25228f5f-bbba-4660-86f5-d45ebd688bb6; ada35577182650f1_gr_session_id_25228f5f-bbba-4660-86f5-d45ebd688bb6=true; synct=1666149373.597; Hm_lpvt_ff3eefaf44c797b33945945d0de0e370=1666149374; syncd=-1222") req.Header.Set("pragma", "no-cache") req.Header.Set("sec-ch-ua", `"Chromium";v="106", "Google Chrome";v="106", "Not;A=Brand";v="99"`) req.Header.Set("sec-ch-ua-mobile", "?0") req.Header.Set("sec-ch-ua-platform", `"macOS"`) req.Header.Set("sec-fetch-dest", "empty") //req.Header.Set("sec-fetch-mode", "cors") req.Header.Set("sec-fetch-site", "same-site") req.Header.Set("user-agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36") resp, err := client.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close() bodyText, err := ioutil.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Printf("%s\n", bodyText) }


          GoLand打印結(jié)果如下:

          0210001525617c00215bb0314f5e8eab.webp



          五、思路總結(jié)


          回顧整個分析流程,本次難點(diǎn)主要概括為以下幾點(diǎn):


          • 如何快速定位加密參數(shù)的位置
          • 堆?;厮萑绾芜^濾無用代碼
          • 如何扣JS代碼并能run起來
          • Python還原加密算法實(shí)現(xiàn)
          • GoLang還原加密算法實(shí)現(xiàn)
          • 熟練掌握數(shù)據(jù)類型及邏輯運(yùn)算
          06a23b341dcd62bec73a3c36e3d4b1cc.webp

          End

          崔慶才的新書《Python3網(wǎng)絡(luò)爬蟲開發(fā)實(shí)戰(zhàn)(第二版)》已經(jīng)正式上市了!書中詳細(xì)介紹了零基礎(chǔ)用 Python 開發(fā)爬蟲的各方面知識,同時相比第一版新增了 JavaScript 逆向、Android 逆向、異步爬蟲、深度學(xué)習(xí)、Kubernetes 相關(guān)內(nèi)容,?同時本書已經(jīng)獲得 Python 之父 Guido 的推薦,目前本書正在七折促銷中!

          內(nèi)容介紹:《Python3網(wǎng)絡(luò)爬蟲開發(fā)實(shí)戰(zhàn)(第二版)》內(nèi)容介紹


          5db7cdf7875af232f5158c7f5ede9239.webp


          掃碼購買



          d1761100a09042dad5282ac10663a94d.webp

          點(diǎn)個在看你最好看

          037fb23c42d91fc261b58e8c630dcd9b.webp
          瀏覽 77
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <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>
                  超碰在线看不卡了 | 小泽玛利亚在线视频 | 女人十八毛片一级A片蜜臀 | 青青草原视频精品在线免费观看 | 91人妻人人澡人人爽人人精品 |