本文章中所有内容仅供学习交流,抓包内容、敏感网址、数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除!
目标:实现账号登录,滑块验证,python纯算。
网站:aHR0cHM6Ly91cGFzcy4xMGpxa2EuY29tLmNuL2xvZ2luP3JlZGlyPUhUVFBfUkVGRVJFUg==
1.老样子先分析登录过程中需要的所有请求,账号密码登录,触发滑块,先是寻找获得图片的接口,分上下两部分分析整个过程,该网站会禁用f12,所以在请求之前就先打开控制台。
我们根据验证码图片的url可以找到在getprehandle请求中有我们想要的参数,后面在分析。
2.验证码触发前,主要有两次请求,getGS和dologinreturnjson2,在getGS的请求参数中可以看到是验证账号,得到dsk dsv ssv ,这些后面都会用到。
2.2在dologinreturnjson2请求中可以看到参数有点多,结果触发验证码。需要分析的参数就是uname passwd passwdsalt dsk crnd。
3.先是定位到参数生成的地方,那我直接根据参数名直接搜索,passwdsalt,这个结果会少很多,可以快速定位。跳转过来之后,在其之上就是所有参数的生成啦,太好了,源码中还有注释,直接都打上断点逐步分析、
4.登录账号先定到uname,先看uname和passwd这两个参数,加密方式还备注上了,真好,可以看到 ,传入账号-密码,经过thsencrypt中encode方法加密,密码的参数多做了一步处理,经过hex_md5,看名字应该是md5编码,在控制台打印测试一下,找个网站测试一下是标准的md5,这就可以不用分析js源码了,主要进thsencrypt的encode方法里面看看。单步跳进去
5.在encode中是传入三个参数直接返回函数encryptencode的结果,其中b是账号,a是密钥,c是公钥指数,返回base64格式字符串。转换成python代码。
[Python] 纯文本查看 复制代码 def encrypt_encode(plaintext: str) -> str:
modulus_hex = "" # 这里填入十六进制模数字符串
exponent_hex = "10001" # 一般是 65537 的十六进制表示
if not modulus_hex or not exponent_hex:
raise ValueError("modulus and publicExponent could not be null")
modulus = int(modulus_hex, 16)
exponent = int(exponent_hex, 16)
key = RSA.construct((modulus, exponent))
cipher = PKCS1_v1_5.new(key)
plaintext_bytes = plaintext.encode('utf-8')
encrypted_bytes = cipher.encrypt(plaintext_bytes)
if not encrypted_bytes:
raise ValueError("encrypt failed")
return b64encode(encrypted_bytes).decode('utf-8')
6.先验证代码是否能用,测试是不是标准rsa,因为加密结果每次都不一样,直接测试请求,在getGS中请求参数是uname rsa_version 和crnd ,现在看一下crnd怎么生成,继续往下走,进入getSaltGs中。
7.可以看到随机数转36进制取后八位,重复两边,生成的16位只包含数字和字母的字符串,那我直接从0到9和小写字母中随机取十六位,一样的效果。
8。用生成的uname和crnd测试getGS,若是uname参数为空,返回参数错误,若加密不对,返回的dsk ssv 等都是空。
测试完接着往下分析,相对dologinreturnjson2里面还有passwdsalt 和 dsk这两个参数没有分析,dsk是getGS中里面返回。
继续往下走, postData.passwdSalt = encodeDataSaltOnce(passwdVal,unameVal);,进入encodeDataSaltOnce中,分析生成过程。
9.先到第一生成n的地方,可以看到是拿crnd + dsk,传给r.hex,r在上面定义的有,可以看到是hash 256,往下走是先把ssv进行base64解码,在传入hash后的n,函数getStrXOR中转换。
可以看到是实现两个字符串的字符逐位异或操作(XOR 操作)。转化成python代码。
[Python] 纯文本查看 复制代码 def get_str_xor(e: str, t: str) -> str:
s = len(e)
r = len(t)
o = []
for d in range(s):
n = d % r
xor_char = chr(ord(e[d]) ^ ord(t[n]))
o.append(xor_char)
return ''.join(o)
10.继续往下走,转换后的结果取等号后面作为n,作为HmacSHA256的key,r.hex_hmac是HmacSHA256,e是密码。
11.测试了一下r.hex_hmac,e先md5后在HmacSHA256,结果作为getStrXOR第一个参数,对dsv进行sha256作为第二个参数。经过getStrXOR后n的值在base64编码一下,就到了rsa加密的最终n了,函数encodeDataSaltOnce返回rsa加密的n,python慢慢一步步的还原,这样就的到了passwdSalt。
12.到现在参数都分析完啦,可以测试了,验证一下,接下来开始分析滑块的验证。
13.滑块验证的请求参数主要查看一下两个,signature是请求图片是返回的sign,可以发现,那phrase这个参数就是主要检验的了,直接搜索。
14.跳转进去可以看到url的生成规则 后半部分是 (x) + ";" + inity + ";" + opt.width + ";" + opt.height;,其中opt的宽高都是定值,x是动的距离,需要看一下inity的生成,在当前js文件中搜索inity,不多很好定位。
15.可以看到inity的赋值 data.data.inity / 195 * opt.height的结果,data是getPreHandle的相应结果,opt.height写死。
16.图片的url在getPreHandle请求结果,其中请求参数都可以写死,来获得验证的图片和滑块,滑动距离的识别使用的是ddddocr,以下是python代码。
[Python] 纯文本查看 复制代码 def get_distance(bg, tp, save_path=None):
det = DdddOcr(det=False, ocr=False, show_ad=False)
res = det.slide_match(tp, bg, simple_target=True)
if save_path is not None:
# 将背景图片的二进制数据加载为Pillow Image对象
left, top, right, bottom = res['target'][0], res['target'][1], res['target'][2], res['target'][3]
bg_image = Image.open(io.BytesIO(bg))
draw = ImageDraw.Draw(bg_image)
draw.rectangle([left, top, right, bottom], outline="red", width=2)
bg_image.save(save_path)
logger.info(f"已保存标注后的图片到: {save_path}")
return res
return res
17.测试滑块验证结果,识别坐标标注的左上角和右下角,当取滑动距离时和浏览器需要的距离有一点偏差,测试一下减去个固定值就行,验证成功就可以拿到ticket了。
18.接下来就是最后一步了,来看下半部分,在验证的时候多了一些滑块验证成功后的一些参数,带上这些参数,再去验证登录,就可以啦。
验证了以下,至此结束啦,感谢观看哦,祝大家端午节快乐!!(选择甜粽子还是肉粽子呢,犒劳自己)
|