極驗反爬蟲防護分析之交互流程分析
極驗(//www.geetest.com/
),是中國比較有名的身份驗證,反爬蟲的產品。其反爬蟲的手段較多,大概分為: pencil、beeline、click、slide、voice 等多種驗證方式,尤其Slide方式是基於大數據的智慧行為驗證,用戶體驗較好很得客戶青睞,比如我要搶鞋的官網就是基於它來做用戶登錄的身份驗證。
通過極驗官網的文檔,我們可以得知Geetest的大致交互流程如下圖:
本帖最後由 besterChen 於 2020-4-22 18:19 編輯一些廢話在論壇混了多年,跟著各位大神學到了許多有用的知識,當然也用了好多前輩們分享的軟體。索取至此奈何自己能力平平沒啥可拿出來分享的東西,又礙於面子怕分享的內容拾人牙慧惹人恥笑。 眼看著我的CB越來越少,總不能一直坐吃山空,所以拿出以前的一點筆記分享出來,試試運氣看能否騙個精華,混點CB。如果分享的內容已經有人寫過,或者沒啥技術含量,還望各位壇友多多包涵~ 本文要分享的內容是去年為了搶鞋而分析 極驗(GeeTest)反爬蟲防護的筆記,由於篇幅較長(為了多混點CB)我會按照我的分析順序,分成如下四個主題與大家分享: 本篇是第一篇,下面進入正文~ 極驗( 通過極驗官網的文檔,我們可以得知Geetest的大致交互流程如下圖: 結合我搶鞋的介面,整理如下: 1. 獲取驗證ID及驗證流水號
{ "challenge": "decd09d6c9f1bb219f7550cea8e18c01", "gt": "2328764cdf162e8e60cc0b04383fef81", "success": 1 }
2. 獲取驗證素材資源
{ "status": "success", "data": { "maze": "/static/js/maze.1.0.1.js", "fullpage": "/static/js/fullpage.8.7.9.js", "geetest": "/static/js/geetest.6.0.9.js", "pencil": "/static/js/pencil.1.0.3.js", "click": "/static/js/click.2.8.1.js", "beeline": "/static/js/beeline.1.0.1.js", "type": "fullpage", "static_servers": ["static.geetest.com/", "dn-staticdown.qbox.me/"], "aspect_radio": { "beeline": 50, "voice": 128, "pencil": 128, "click": 128, "slide": 103 }, "voice": "/static/js/voice.1.2.0.js", "slide": "/static/js/slide.7.6.0.js" } }
3. 獲取驗證的基本參數
{ "status": "success", "data": { "i18n_labels": { "fullpage": "驗證進行中, 請耐心等候", "goto_homepage": "前往驗證服務 Geetest 官方網站", "goto_confirm": "前往", "success": "驗證成功", "error_content": "請輕觸重試", "copyright": "Geetest", "refresh_page": "頁面出現錯誤!要繼續操作,請重新整理此頁面", "loading_content": "智慧驗證中", "next_ready": "請完成驗證", "error_title": "網路逾時", "next": "載入中", "error": "網路不佳", "reset": "重試", "goto_cancel": "取消", "ready": "按此進行驗證 ", "success_title": "驗證通過" }, "s": "326b4e30", "theme": "wind", "static_servers": ["static.geetest.com", "dn-staticdown.qbox.me"], "feedback": "", "c": [12, 58, 98, 36, 43, 95, 62, 15, 12], "theme_version": "1.5.5", "api_server": "api.geetest.com", "logo": false } } 4. 獲取驗證方式
{ "status": "success", "data": { "result": "slide" } } 5. 獲取驗證素材資訊
{ "benchmark": false, "xpos": 0, "slice": "pictures/gt/0191efce3/slice/8eba80808.png", "gt": "2328764cdf162e8e60cc0b04383fef81", "ypos": 27, "api_server": "//api.geetest.com/", "theme": "ant", "link": "", "template": "", "id": "adecd09d6c9f1bb219f7550cea8e18c01", "version": "6.0.9", "product": "embed", "mobile": true, "width": "100%", "hide_delay": 800, "static_servers": ["static.geetest.com/", "dn-staticdown.qbox.me/"], "so": 0, "bg": "pictures/gt/0191efce3/bg/8eba80808.jpg", "type": "multilink", "height": 160, "https": true, "theme_version": "1.2.3", "challenge": "decd09d6c9f1bb219f7550cea8e18c01eb", "fullbg": "pictures/gt/0191efce3/0191efce3.jpg", "clean": false, "i18n_labels": { "error": "出現錯誤,請關閉驗證重試", "tip": "", "voice": "視覺障礙", "success": "sec 秒.超過 score% 的使用者", "slide": "拉動左邊標示完成上方拼圖", "forbidden": "哇~怪物吃了拼圖,請 3 秒後重試", "close": "關閉驗證", "fail": "拼圖位置不正確", "cancel": "取消", "feedback": "說明和反饋", "loading": "載入中...", "logo": "Geetest", "refresh": "重新載入" }, "s": "6e4d352f", "c": [12, 58, 98, 36, 43, 95, 62, 15, 12], "feedback": "", "fullpage": false, "logo": false, "show_delay": 250 }
6. 提交驗證請求
{ "valIDAte": "545a86f1a2af6f09afc4d1abbb166679", "success": 1, "score": "5", "message": "success" } 7. 提交登錄認證
{ "email": "[email protected]", "firstName": "大頭", "loginRedirectPath": "/", "memberCommand": { "addEmail": null, "address": null, "behaviorScore": null, "birthday": null, "birthdayStr": null, "businessPartnerName": null, "captcha": null, "cardNo": null, "certNo": null, "certType": null, "childrenNum": null, "city": null, "copExt1": null, "corpDepartment": null, "corpPosition": null, "corporation": null, "corporationCode": null, "corporationName": null, "country": null, "countryCode": "", "createTime": null, "createType": null, "currPoint": null, "district": null, "educationLvl": null, "email": null, "familyNum": null, "firstName": null, "gender": null, "height": null, "homePage": null, "id": null, "invitecode": null, "invitor": null, "isBookEmail": null, "isBookMobileMessage": null, "isCorpSeed": null, "isDefault": null, "isFacebook": false, "isInviteSeed": null, "isMobileValidated": null, "isPrivacyPolicy": null, "isRecEmail": null, "keyPassword": null, "lastName": null, "lifeCycleStatus": null, "lifeCycleStatusDesc": null, "loginName": "[email protected]", "marriage": null, "memberAttention": null, "memberCode": null, "memberRank": null, "memberType": null, "mobile": null, "msn": null, "nickname": null, "onboardDate": null, "password": "A046803714a", "passwordAgain": "EJ2JjA3Rw32DrDMHI1Biu7+YKevYJhvU2EyllSQCmm5fp+QRaVvlz8AfztnM2u0r8Etx3LoBnverg1myEh5lq9HNCEA5aMeHSNX6bR7oJfkkMRqR3XSZdM+0ineNUnHnVuSNnHLbCIxAoecRjDkUSC/umq8+QE9a3X0DOB6SUm8=", "pet": null, "province": null, "pwdAnswer": null, "pwdQuestion": null, "qq": null, "rankId": null, "rankName": null, "realName": null, "regSource": null, "registerIp": null, "remark": null, "salary": null, "secondLang": null, "securityCode": null, "sendemail": null, "smsCode": null, "supervisor": null, "sysUser": null, "telephone": null, "token": null, "totalPoint": null, "usedPoint": null, "version": null, "weight": null, "yearsOfWork": null, "zipcode": null }, "mobileNumber": "+86 18660278523", "omnitureProp31": 3443350, "org.springframework.validation.BindingResult.memberCommand": { "errorCount": 0, "fieldError": null, "fieldErrorCount": 0, "globalError": null, "globalErrorCount": 0, "nestedPath": "", "objectName": "memberCommand" } } 8. 驗證流程整理經測試不需要所有介面都模擬,比如直接指定驗證方式為滑塊驗證,依次調用介面: 1 –> 3 –> 5 –> 6 –> 7 即可。 至此,整個交互流程分析完畢,產生的問題如下:
|
極驗(//www.geetest.com/
),是中國比較有名的身份驗證,反爬蟲的產品。其反爬蟲的手段較多,大概分為: pencil、beeline、click、slide、voice 等多種驗證方式,尤其Slide方式是基於大數據的智慧行為驗證,用戶體驗較好很得客戶青睞,比如我要搶鞋的官網就是基於它來做用戶登錄的身份驗證。
通過極驗官網的文檔,我們可以得知Geetest的大致交互流程如下圖:
結合我搶鞋的介面,整理如下:
1. 獲取驗證ID及驗證流水號
-
請求地址: //www.nike.com.hk/geetest/doget.json?t=1563879949387&type=MEMBER_LOGIN
-
請求方式: POST
-
請求參數說明:
- t: 當前時間戳(毫秒)
-
響應內容:
{ "challenge": "decd09d6c9f1bb219f7550cea8e18c01", "gt": "2328764cdf162e8e60cc0b04383fef81", "success": 1 }
-
返回參數說明:
- gt: 驗證id
- challenge: 驗證流水號
2. 獲取驗證素材資源
-
請求地址: //api.geetest.com/gettype.php?gt=2328764cdf162e8e60cc0b04383fef81&callback=geetest_1563879954116
-
請求方式: GET
-
請求參數說明:
- gt: 之前介面返回的驗證ID
-
響應內容:
{ "status": "success", "data": { "maze": "/static/js/maze.1.0.1.js", "fullpage": "/static/js/fullpage.8.7.9.js", "geetest": "/static/js/geetest.6.0.9.js", "pencil": "/static/js/pencil.1.0.3.js", "click": "/static/js/click.2.8.1.js", "beeline": "/static/js/beeline.1.0.1.js", "type": "fullpage", "static_servers": ["static.geetest.com/", "dn-staticdown.qbox.me/"], "aspect_radio": { "beeline": 50, "voice": 128, "pencil": 128, "click": 128, "slide": 103 }, "voice": "/static/js/voice.1.2.0.js", "slide": "/static/js/slide.7.6.0.js" } }
-
示例:
3. 獲取驗證的基本參數
-
請求地址: //api.geetest.com/get.php?gt=2328764cdf162e8e60cc0b0438…
-
請求方式: GET
-
請求參數說明:
- gt: 之前介面返回的驗證ID
- challenge: 之前介面返回的驗證流水號
- lang=zh-hk
- pt=0
- w=4A8S6ZFe9GO43hbI3exYdbebCvxWVtD38od3qc7tqtxxARm4HCI… (待分析)
- callback=回調函數的方法名
-
響應內容:
{ "status": "success", "data": { "i18n_labels": { "fullpage": "驗證進行中, 請耐心等候", "goto_homepage": "前往驗證服務 Geetest 官方網站", "goto_confirm": "前往", "success": "驗證成功", "error_content": "請輕觸重試", "copyright": "Geetest", "refresh_page": "頁面出現錯誤!要繼續操作,請重新整理此頁面", "loading_content": "智慧驗證中", "next_ready": "請完成驗證", "error_title": "網路逾時", "next": "載入中", "error": "網路不佳", "reset": "重試", "goto_cancel": "取消", "ready": "按此進行驗證 ", "success_title": "驗證通過" }, "s": "326b4e30", "theme": "wind", "static_servers": ["static.geetest.com", "dn-staticdown.qbox.me"], "feedback": "", "c": [12, 58, 98, 36, 43, 95, 62, 15, 12], "theme_version": "1.5.5", "api_server": "api.geetest.com", "logo": false } }
4. 獲取驗證方式
-
請求地址: //api.geetest.com/ajax.php?gt=2328764cdf162e8e60cc0b0438…
-
請求方式: GET
-
請求參數說明:
- gt: 之前介面返回的驗證ID
- challenge: 之前介面返回的驗證流水號
- lang=zh-hk
- pt=0
- w=pxIvtqzNcdSbk0QJHeRBsozbYtm8519UAKjSyuCMk01J21VwEEWOlV… (待分析)
- callback=回調函數的方法名
-
響應內容:
{ "status": "success", "data": { "result": "slide" } }
5. 獲取驗證素材資訊
-
請求地址: //api.geetest.com/get.php?is_next=true&type=slide3>=2328764…
-
請求方式: GET
-
請求參數說明:
- gt: 之前介面返回的驗證ID
- challenge: 之前介面返回的驗證流水號
- lang=zh-hk
- is_next=true
- type=slide3
- https=false
- protocol=//
- offline=false
- product=embed
- api_server=api.geetest.com
- isPC=true
- width=100%
- callback=回調函數的方法名
-
響應內容:
{ "benchmark": false, "xpos": 0, "slice": "pictures/gt/0191efce3/slice/8eba80808.png", "gt": "2328764cdf162e8e60cc0b04383fef81", "ypos": 27, "api_server": "//api.geetest.com/", "theme": "ant", "link": "", "template": "", "id": "adecd09d6c9f1bb219f7550cea8e18c01", "version": "6.0.9", "product": "embed", "mobile": true, "width": "100%", "hide_delay": 800, "static_servers": ["static.geetest.com/", "dn-staticdown.qbox.me/"], "so": 0, "bg": "pictures/gt/0191efce3/bg/8eba80808.jpg", "type": "multilink", "height": 160, "https": true, "theme_version": "1.2.3", "challenge": "decd09d6c9f1bb219f7550cea8e18c01eb", "fullbg": "pictures/gt/0191efce3/0191efce3.jpg", "clean": false, "i18n_labels": { "error": "出現錯誤,請關閉驗證重試", "tip": "", "voice": "視覺障礙", "success": "sec 秒.超過 score% 的使用者", "slide": "拉動左邊標示完成上方拼圖", "forbidden": "哇~怪物吃了拼圖,請 3 秒後重試", "close": "關閉驗證", "fail": "拼圖位置不正確", "cancel": "取消", "feedback": "說明和反饋", "loading": "載入中...", "logo": "Geetest", "refresh": "重新載入" }, "s": "6e4d352f", "c": [12, 58, 98, 36, 43, 95, 62, 15, 12], "feedback": "", "fullpage": false, "logo": false, "show_delay": 250 }
-
響應參數說明:
6. 提交驗證請求
-
請求方式: GET
-
請求參數說明:
- gt: 之前介面返回的驗證ID
- challenge: 第六步返回的驗證流水號
- lang=zh-hk
- pt=0
- w=cY71fua4Cuvs8Cyrf3rW(VzZHB)oSpARQMV65Dtg… (待分析)
-
響應內容:
{ "valIDAte": "545a86f1a2af6f09afc4d1abbb166679", "success": 1, "score": "5", "message": "success" }
7. 提交登錄認證
-
請求地址: //www.nike.com.hk/member/login.json?loxiaflag=1563879969519
-
請求方式: POST
-
請求參數說明:
- loginName: [email protected]
- countryCode:
- password=EJ2JjA3Rw32DrDMHI1Biu7+YKevYJhvU2EyllSQ… (加密後的密碼待分析)
- passwordAgain=EJ2JjA3Rw32DrDMHI1Biu7+YKevYJhvU2EyllSQ… (加密後的密碼待分析)
- rememberLoginName=checked
- type
- geetest_challenge=decd09d6c9f1bb219f7550cea8e18c01eb (第六步返回的驗證流水號)
- geetest_validate=545a86f1a2af6f09afc4d1abbb166679 (第七步返回的validate)
- geetest_seccode=545a86f1a2af6f09afc4d1abbb166679|jordan (第七步返回的validate|jordan)
-
響應內容:
{ "email": "[email protected]", "firstName": "大頭", "loginRedirectPath": "/", "memberCommand": { "addEmail": null, "address": null, "behaviorScore": null, "birthday": null, "birthdayStr": null, "businessPartnerName": null, "captcha": null, "cardNo": null, "certNo": null, "certType": null, "childrenNum": null, "city": null, "copExt1": null, "corpDepartment": null, "corpPosition": null, "corporation": null, "corporationCode": null, "corporationName": null, "country": null, "countryCode": "", "createTime": null, "createType": null, "currPoint": null, "district": null, "educationLvl": null, "email": null, "familyNum": null, "firstName": null, "gender": null, "height": null, "homePage": null, "id": null, "invitecode": null, "invitor": null, "isBookEmail": null, "isBookMobileMessage": null, "isCorpSeed": null, "isDefault": null, "isFacebook": false, "isInviteSeed": null, "isMobileValidated": null, "isPrivacyPolicy": null, "isRecEmail": null, "keyPassword": null, "lastName": null, "lifeCycleStatus": null, "lifeCycleStatusDesc": null, "loginName": "[email protected]", "marriage": null, "memberAttention": null, "memberCode": null, "memberRank": null, "memberType": null, "mobile": null, "msn": null, "nickname": null, "onboardDate": null, "password": "A046803714a", "passwordAgain": "EJ2JjA3Rw32DrDMHI1Biu7+YKevYJhvU2EyllSQCmm5fp+QRaVvlz8AfztnM2u0r8Etx3LoBnverg1myEh5lq9HNCEA5aMeHSNX6bR7oJfkkMRqR3XSZdM+0ineNUnHnVuSNnHLbCIxAoecRjDkUSC/umq8+QE9a3X0DOB6SUm8=", "pet": null, "province": null, "pwdAnswer": null, "pwdQuestion": null, "qq": null, "rankId": null, "rankName": null, "realName": null, "regSource": null, "registerIp": null, "remark": null, "salary": null, "secondLang": null, "securityCode": null, "sendemail": null, "smsCode": null, "supervisor": null, "sysUser": null, "telephone": null, "token": null, "totalPoint": null, "usedPoint": null, "version": null, "weight": null, "yearsOfWork": null, "zipcode": null }, "mobileNumber": "+86 18660278523", "omnitureProp31": 3443350, "org.springframework.validation.BindingResult.memberCommand": { "errorCount": 0, "fieldError": null, "fieldErrorCount": 0, "globalError": null, "globalErrorCount": 0, "nestedPath": "", "objectName": "memberCommand" } }
8. 驗證流程整理
經測試不需要所有介面都模擬,比如直接指定驗證方式為滑塊驗證,依次調用介面: 1 –> 3 –> 5 –> 6 –> 7 即可。
至此,整個交互流程分析完畢,產生的問題如下:
- 所有用於驗證的程式碼都是混淆之後的,如何進行程式碼還原或者調試分析。
- 請求與返回的關鍵數據都是加密的後的字元串如上述3、4、6等介面中的W參數,如何解密。