declaresthatallcontentinthisarticleisforlearningandcommunicationonly,andthecontentofcapturedpackets,sensitiveURLs,anddatainterfaceshavebeendesensitized,andarestrictlyprohibitedforuseinCommercialuseandillegaluse,otherwiseallconsequencesarisingtherefromhavenothingtodowiththeauthor,ifthereisanyinfringement,pleasecontactmetodeleteimmediately!逆向目标目标:X米账号登录主页:aHR0cHM6Ly9hY2NvdW50LnhpYW9taS5jb20v接口:aHR0cHM6Ly9hY2NvdW50LnhpYW9taS5jb20vcGFzcy9zZXJ2aWNlTG9naW5BdXRoMg==逆向参数:FormData:hash:FCEA920F7412B5DA7BE0CF42B8C93759逆向过程抓包分析来到小米的登录页面,随便输入一个账号密码登陆,抓包定位到登录接口ForaHR0cHM6Ly9hY2NvdW50LnhpYW9taS5jb20vcGFzcy9zZXJ2aWNlTG9naW5BdXRoMg==POSTrequest,therearemanyparametersinFormData,let’sanalyzethemainparameters:serviceParam:{"checkSafePhone":false,"checkSafeAddress":false,"lsrp.0}fromtheliteralmeaning,parameter0":Itseemstobecheckingwhetherthemobilephoneandaddressaresafe.Asforthespecificmeaning,itistemporarilyunknown,anditisnotknownwhereitisset.callback:http://order.xxx.com/login/callback?followup=https%3A%2F%2Fwww.xx......,thecallbacklinkisgenerallyfixed,followedbyfollowupandsidparameter.qs:%3Fcallback%3Dhttp%253A%252F%252Forder.xxx.com%252Flogin%252Fcallback%2......,formatthevalueofqsandyoucanfindthatitisactuallycallback,sign,sid,_qrsizefourThevalueisassembledaccordingtoURLencoding._sign:w1RBM6cG8q2xj5JzBPPa65QKs9w=,thisstringseemstobeobtainedaftersomekindofencryption,oritmaybethevalueinthesourcecodeofthewebpage.user:15555555555,usernameincleartext.hash:FCEA920F7412B5DA7BE0CF42B8C93759,加密后的密码。参数逆向基本参数我们先来看serviceParam等基本参数。大意是直接搜索,看能不能直接找到这个值。搜索发现serviceParam关键字在一个302重定向请求中:我们注意到当只进入登录首页aHR0cHM6Ly9hY2NvdW50LnhpYW9taS5jb20v时,会连续出现两次302重定向,下面重点分析这两个重定向。对于第一次重定向,新的URL中有followup、callback、sign、sid参数,我们将在后续的登录请求中使用这些参数。第二次重定向,新的URL还有followup、callback、sign、sid参数,以及serviceParam、qs参数,后续登录请求也需要这些参数。找到参数的来源,直接从第二次重定向的链接中提取参数。这里使用response.history[1].headers['Location']提取页面Address第二次重定向返回的header中的target,urllib.parse.urlparse解析重定向链接urllib的URL结构。parse.parse_qs提取参数返回字典,代码示例:importrequestsimporturllib.parseheaders={'Host':'脱敏处理,全代码关注GitHub:https://github.com/kgepachong/crawler','User-Agent':'Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/91.0.4472.124Safari/537.36'}index_url='脱敏处理,完整代码关注GitHub:https:///github.com/kgepachong/crawler'response=requests.get(url=index_url,headers=headers)location_url=response.history[1]。headers['Location']urlparse=urllib.parse.urlparse(location_url)query_dict=urllib.parse.parse_qs(urlparse.query)print(query_dict)need_theme=query_dict['needTheme'][0]show_active_x=query_dict['showActiveX'][0]service_param=query_dict['serviceParam'][0]callback=query_dict['callback'][0]qs=query_dict['qs'][0]sid=query_dict['sid'][0]_sign=query_dict['_sign'][0]print(need_theme,show_active_x,service_param,callback,qs,sid,_sign)hash等参数齐全,现在还有一个加密的密码hash,一般来说,这个是用JS加密的,老方法,全局搜索hash或者hash:,在78.4da22c55.chunk.js文件中可以看到一句话:hash:S()(r.password).toUpperCase(),很明显明文密码加密后全部转为大写:的关键点是这个S()。当你移动鼠标时,你会发现它实际上调用了78.4da22c55.chunk.js的一个匿名函数。我们在匿名函数的返回位置打断点调试:e.exports=function(e,n){if(void0===e||null===e)thrownewError("Illegalargument"+e);varr=t.wordsToBytes(u(e,n));返回n&&n.asBytes?r:n&&n.asString?s.bytesToString(r):t.bytesToHex(r)}可以看到传入的e是明文密码,最后一个return语句是三元运算符,因为n没有定义,所以最后一个return其实是t。bytesToHex(r),它的值就是加密后的密码,但是所有的字母都是小写的。按照正常的思路,我们要开始扣JS了,这里传入参数r指定,varr=t.wordsToBytes(u(e,n));,先跟进u函数看:可以看到u函数其实用到了567的对象方法,在这个对象方法中,还用到了129、211、22等很多方法。如果一一扣除,到猴年才扣除,而且容易出错。代码太多,不容易定位错误的地方,所以这里需要换个思路。我们先看看t.bytesToHex(r)是什么,接着这个函数:bytesToHex:function(e){for(vart=[],n=0;n
