1. 程式人生 > >薅羊毛系列之蜘蛛網電影搶票分析

薅羊毛系列之蜘蛛網電影搶票分析

說明:以下內容從我的個人部落格 blog.zhouzhipeng.com 複製過來,兩邊同步釋出。

首先宣告一下,這裡並不是給蜘蛛網打廣告。自己平時也比較喜歡看電影,剛好蜘蛛網電影app上有一個週六建行5元搶票活動,由於活動很火爆,幾乎很少能搶到! 所以想借用程式手段,自動提交搶票介面,來試圖能搶到5元電影票。

雖然沒有技術含量的東西,主要是想記錄一下,方便自己日後來回憶一下,同時也是一個思路的整理。
好了,廢話不多說,下面開始hack之旅!

前言

和所有電影app一樣,在經過選電影-> 選場次-> 選桌位 之後,來到了確認提交頁面,如下:

可以看到上圖中活動優惠有很多,我想”破”的就是龍卡星期六 5元看電影

這個 (因為活動時間已過,可以看到它顯示的是灰色,我是上午完成的抓包分析以及寫程式碼,圖片現在補上的)

理想情況是,你選好要看的電影只有進來這個頁面,剛好上午10點整的時候,5元這個活動就可以開始搶了! 現實情況是到了9:59 分快到10點差不多的時候,進來這個頁面你會發現被
告知已經”搶完了”!

現實很殘酷,考驗網速和手速以及運氣! 但是身為一名小碼農,怎能像一般人一樣也在哪裡拼手氣呢!(?)

第一步:抓包分析

不出意外的話,它的這個訂單提交頁面應該是http(s) 請求的,既然如此,當時就是先來抓包分析下http請求咯!

因為我的用的是mac電腦,所以用的Charles來抓包,略過配置步驟,直接貼一下抓包的請求:

經過初步的分析和體驗(我自己選了一個其他可用的活動提交了一個真實訂單), 發現最終提交訂單的介面的是

https://film.spider.com.cn/huayins/lockSeatList.html?insBirthday=&insId=&token=455FBE5EF0A0ED9545231547BB3050C6&userId=5da71497b4160d20c806c0568e535e07&hallId=17&feePrice=2.0%257C2.0&cinemaId=31070901&currentVersion=4.9.0&channelId=sfVivo&appVersion=460
&version=410&activityId=101511&showId=0170100000000000060598689&userName=xxxxxxxxxxx&partnerPrice=59.00&sign=e3277328f9fa9434efcec30e8259ad23&filetype=json&mobile=13080669828&insName=&filmId=201709909870&fpCount=&parorderId=610024803&seatId=6%253A9%257C6%253A8&key=huayins&fpId=

其中真實的userName 已被我和諧掉了。

postman 工具把引數展開看一下:

憑藉這多年的web開發經驗(? 裝下b), 會發現破案的難點在於上圖紅框中的兩個引數token sign, 一般而已token是登陸用的,而sign則為請求合法性的校驗值 (一般sign是多個引數值按照一定順序拼接之後再用md5加密得來. ? 對的,一般是)

簡化問題

上面的lockSeatList 連結中,有很多引數都是相對固定的,像什麼活動優惠5元看電影 這個activityId很容從其他抓包得到的查詢介面中獲取,在此不一一追溯.
而關鍵引數token通過我刷了幾次介面會發現,它在一段時間內也是不會變的,暫時不考慮其生成方式。

那麼剩下的最後一個難點問題在於我們怎麼能知道sign的生成演算法呢?!

對的,靠猜! (☺️) 開玩笑啦,當時是通過反編譯看程式碼!!

第二步:反編譯apk

沒錯,我們先假設蜘蛛網電影安卓app沒有很變態的加固、混淆之類的。 (如果有的話,就直接放棄得了,太花時間了。。。)

先到蜘蛛網官網弄一個apk檔案(這個很容易!) 這裡我不會貼任何下載連結,需要的實踐的朋友請自己去找。

拿到apk之後,不要慌張,善於利用一些大牛弄的反編譯工具,這裡給大家介紹一個 ,真的挺不錯的 javadecompilers.com (國外的網站,開啟可能有點慢)

進去之後,基本上傻瓜式的操作,直接上傳apk檔案,點一下Upload and Decompile 按鈕,剩下的就是等待了幾分鐘了。直接可以下載反編譯之後的原始碼檔案!

得到原始碼之後,剩下的事情就是分析程式碼,找出sign的生成演算法了!!

第三步:分析程式碼

用你熟悉的工具代開原始碼資料夾,這裡我用的是Intellij IDEA ,開啟之後如下所示:

有沒有。。。。 很懵逼的感覺!!! 特麼這麼多的檔案,從哪找起啊!!!

尋找入口很重要

在做任何事情都不能太盲目,我們要淡定、從容(? )。 先回憶下第一步:抓包分析 中發現的url https://film.spider.com.cn/huayins/lockSeatList.html?xxxx
是的,它就是入口!

找到發起該url請求的地方必定是我們要的,而這裡的關鍵字串lockSeatList.html 如果不出意外的話肯定是在程式碼中某個地方寫死的!

好的,我們先搜尋一下lockSeatList.html在哪裡出現:

如上圖所示,一共有三處地方,我們一個個的試一下。 先接著搜尋第一處 aeC4767f.ae 靜態欄位出現的地方:

出現了很多處,但是經過簡單的分析判斷,它並不是我們要的, “第一處” 排除.

接著,看下”第二處”:

恩,很高階的樣子,android界出了很多類似這種retrofit的框架,把http呼叫弄得用註解搞一下就完成了。。 鑑於有點複雜,可以先放一放這個,後面如果”第三處”也不是我們
要的,再回頭來分析下這個方法的呼叫方。

是的 ,直接突擊”第三處”疑似點:

接著再搜尋f7910W 出現的地方:

剛好只有一處地方出現(第二個是它自己本身,不算),注意看上圖紅框的地方,是不是有點像! 估計就是它了!!

水落石出

好的,我們進去看一看:

注意我標的紅箭頭的地方,這些並不是直接字串,還得一個個的去搜索這些變數的字串是個啥!
為了節省點大家的閱讀時間,這裡就不一一上搜索的截圖了,搜尋變數的方法與上面類似,直接晒一下我們最終要找的sign欄位的面貌:

不難發現,正如我們一開始猜想的,sign就是多個引數值拼接起來再加密的! 重點是下面的stringBuffer2

StringBuffer stringBuffer2 = new StringBuffer();
stringBuffer2.append(str).append(str2).append(str3).append(str4).append(k).append(m).append(str5).append(str6).append(stringBuffer).append(str7).append(q).append(str8).append(str9).append(str10).append(str11).append(str13).append(str14).append(str15).append("huayins").append("0779257096").append(v);

好的,接下來的事情就很簡單了,按照上面append的順序,它其實是每個url上的引數的值。 最終sign的拼接順序為:

showId cinemaId hallId filmId userName userId mobile urldecode(seatId) urldecode(feePrice) parorderId channelId partnerPrice activityId insName insBirthday insId fpId fpCount "huayins" "0779257096" token

模擬請求

有了以上過程後,我們只需要在原來的url引數上,對需要變更的activityId活動編號等做以下更新,動態算出對應的sign值介面。 我自己用
python實現了一版,在此可能不方便直接公開貼出,需要的小夥伴可以 fork 一份:https://git.io/vNbMh