superlib某咨询联盟登录之我知道你很急,但你先别急
#声明本文仅作为技术探讨,如不妥可联系,将第一时间删除本文
本贴为新手向,写的非常详细
#分析过程
即某某图书馆参考咨询联盟
点击登录,弹出一个简陋的滑块。
看看逻辑是什么
第一个接口,获取图片地址和TOKEN
关键参数
>captchaId:
captchaKey:
token:
全局搜索captchaId的value,captchaId来自于login.action
正则匹配即可
```python
captchaId = re.search(r"captchaId: '(.*?)',", html).group(1)
```
其余几个value未搜索到,那么搜key
captchaKey、token都有,进入下个断点,可以看到
captchaKey生成方法
```javascript
_0x4471c4 = _0x1b4779(_0x353d93 + (function() {
var _0x4887fd = _0x1dda;
for (var _0xa5adc8 = [], _0x5cdcca = '0123456789abcdef', _0xccd6e7 = 0x0; _0xccd6e7 < 0x24; _0xccd6e7++)
_0xa5adc8 = _0x5cdcca(Math(0x10 * Math()), 0x1);
return _0xa5adc8 = '4',
_0xa5adc8 = _0x5cdcca(0x3 & _0xa5adc8 | 0x8, 0x1),
_0xa5adc8 = _0xa5adc8 = _0xa5adc8 = _0xa5adc8 = '-',
_0xa5adc8('');
}()))
```
后面一部分是个nonce,还原一下算法(虽然可能没有必要)
里面有一些简单的混淆,解一下,也不会ast,所以苯方法,主要是_0x4887fd这个函数的问题,也就是_0x1dda,进入它
在这儿打个断点,然后copy(_0xd6aec5),复制到js里,相当于获取到了解密函数
解混淆后
```javascript
(function() {
for (var eList = [], ostring = '0123456789abcdef', index = 0; index < 36; index++)
eList = ostring.substr(Math.floor(16 * Math.random()), 1);
return eList = '4',
eList = ostring.substr(3 & eList | 8, 1),
eList = eList = eList = eList = '-',
eList.join('');
}())
```
eList、eList可能是检测位置
还原成python代码
```python
def getNonce():
eList = []
ostring = '0123456789abcdef'
for i in range(36):
eList.append(ostring)
eList = '4'
eList = ostring[(int(eList, 16) & 3) | 8]
eList = eList = eList = eList = '-'
return "".join(eList)
```
接下来是token,稍微要复杂一些
关键在于_0x1b4779这个函数,和_0x353d93 + _0x15764b + _0x32b96e + _0x4471c4中其他几个参数,往前打两个断点可以看到就是一个13位时间戳
_0x1b4779看到调用了好几回函数啊,不过看着这32位的返回值
怎么那么像md5呢
我们可以验证一下
那么一句话就结束了
```python
def getMd5(n:str):
return hashlib.md5(n.encode()).hexdigest()
timestap = '1703058076634'
nonce = getNonce()
captchaKey = getMd5(timestap + nonce)
```
token就是
时间戳+captchaId+'slide'+captchaKey取md5然后+':'+时间戳+过期时间(300000)
```python
token = getMd5(timestap + captchaId + 'slide' + captchaKey) + f':{int(timestap)+300000}'
```
构造获取请求所有参数,并且这个滑块也无需生成轨迹,ddddocr秒了,成功获得validate
```python
def getVerification(self):
callback = "jQuery19008360078251283902_"+self.timestap
_ = int(time.time()*1000) + 3000
url = "http://脱敏/captcha/get/verification/image"
nonce = getNonce()
captchaKey = getMd5(self.timestap + nonce)
token = getMd5(self.timestap + self.captchaId + 'slide' + captchaKey) + f':{int(self.timestap)+300000}'
params = {
"callback": callback,
"captchaId": self.captchaId,
"type": "slide",
"version": "1.1.14",
"captchaKey": captchaKey,
"token": token,
"referer": "http://脱敏/login/login.action",
"_": str(_+1),
}
response = self.s.get(
url,
headers=self.headers,
params=params
).text
response = json.loads(response.replace(callback+'(', '')[:-1])
token = response['token']
cutoutImage = response['imageVerificationVo']['cutoutImage']
shadeImage = response['imageVerificationVo']['shadeImage']
target_bytes = self.s.get(cutoutImage, headers=self.headers).content
background_bytes = self.s.get(shadeImage, headers=self.headers).content
textClickArr = "[{\"x\":"+ str(generate_distance(target_bytes, background_bytes))+"}]"
url = "http://脱敏/captcha/check/verification/result"
params = {
"callback": callback,
"captchaId": self.captchaId,
"type": "slide",
"token": token,
"textClickArr": textClickArr,
"coordinate": "[]",
"runEnv": "10",
"version": "1.1.14",
"_": str(_+2),
}
self.headers['Referer'] = 'http://脱敏/'
response = json.loads(requests.get(url, headers=self.headers, params=params).text.replace(callback+'(', '')[:-1])
print(response)
ifresponse['result']:
return response['extraData'].replace('{"validate":"', '').replace('"}', '')
else:
return self.getVerification()
def generate_distance(target_bytes, background_bytes):
det = ddddocr.DdddOcr(det=False, ocr=False, show_ad=False)
res = det.slide_match(target_bytes, background_bytes)
return res.get('target')
```
#大无语时刻(虚晃一枪)
哦天啊,你们知道它的验证密码是否正确的请求不仅仅是明文,而且还不带验证码,(怪不得xxxxxxxx,只能说某些事情发生也不是没有原因的)天啊我前面为什么要分析那么多,这验证码就是个摆设啊,登陆的时候(无cookie,无headers,无validate)完全不用管,白写这么多字。(也就是这个验证码既不起防止机器人登陆的功能,也不起防止密码爆破的作用)
此帖终结
#总结
这个故事告诉我们,先盘流程再逆向!不然最后会很急。 一整个惊住,最后的一刻,如此赤裸裸吗/捂脸。
题外话,请教下大佬:弹窗提示长时间未修改密码,需要修改验证,可有其他办法跳过验证吗?(因为原注册号码已经注销,而修改密码又需要原手机号的验证码。对于这样的情况,该怎么办,求解惑!感谢!!) carnelian 发表于 2023-12-21 00:00
一整个惊住,最后的一刻,如此赤裸裸吗/捂脸。
题外话,请教下大佬:弹窗提示长时间未修改密码,需要修改 ...
这个要具体情况具体分析,如果他只是一个验证,那你可以修改response,类似于我主页的那个mitmproxy,就过去了,如果它是和cookie啥相关的,那基本不可能过去 T4DNA 发表于 2023-12-21 00:03
这个要具体情况具体分析,如果他只是一个验证,那你可以修改response,类似于我主页的那个mitmproxy,就 ...
感谢楼主大大回复解答{:1_919:} 感谢楼主大大 感谢楼主大大 感谢分享。以后用到时再仔细看 感谢楼主 从头到尾全部看完,深有启发,膜拜大佬,谢谢分享!{:1_893:} 感谢楼主大大