百度网盘验证码

稍微研究了一下百度网盘验证码

出现验证码

经测试,当错误达到3次的时候会出现验证码

验证码有效期

一个验证码可以使用4次

验证码json错误代码

“errno”:-9 表示验证码正确但密码错误
“errno”:-62 表示验证码错误
其他错误id均返回”密码错误”

0X0A 验证码获取数据

1
2
3
4
5
GET
http://pan.baidu.com/api/getcaptcha?prod=shareverify&web=1&t=0.17692429808447097&bdstoken=xxxxxxxx&channel=chunlei&clienttype=0&web=1&app_id=250528&logid=MTUwMTE0MDcxODM4MzAuMzg4MTYwMjU4NTEwNDE4Nw==
Response
{"errno":0,"request_id":4815926209795371593,"vcode_str":"3332423865633234636166333465663732323763363637363764323966666433666231353934333132383237303030303030303030303030303031353031313430373233FDDD802E25E0CA338CA357758BFA0C2A","vcode_img":"http:\/\/pan.baidu.com\/genimage?3332423865633234636166333465663732323763363637363764323966666433666231353934333132383237303030303030303030303030303031353031313430373233FDDD802E25E0CA338CA357758BFA0C2A","raw_ans":"us29hx8tj"}

0X0B 获取验证码

1
2
3
http://pan.baidu.com/genimage?3332423865633234636166333465663732323763363637363764323966666433666231353934333132383237303030303030303030303030303031353031313430373233FDDD802E25E0CA338CA357758BFA0C2A
sux9

以上,7.27。
7.31 该验证码内容变成了W6VZ

0X0C 验证码/密码验证数据

1
2
3
4
POST
http://pan.baidu.com/share/verify?shareid=1418533617&uk=242193955&t=1501140718192&bdstoken=xxxxxxxx&channel=chunlei&clienttype=0&web=1&app_id=250528&logid=MTUwMTE0MDcxODIwMDAuNTMzMTIyODk3MTE2NTc4
pwd=1234&vcode=kbsc&vcode_str=333242386563323463616633346566373232376336363736376432396666643366623130323633373235363730303030303030303030303030303135303131343035383718A34A8B1A577A6148FF40B2A42C7325

0x0A 0X0B 分析

值得注意的是,0X0A数据返回中的raw_ans字段应该是验证码生成所使用的源数据,而vcode_str则是影响生成的验证码,有理由相信raw_ans和vcode_str有某种关联。
由于在使用同一vcode_str时,验证码内容不改变,且验证code的时候传递了这个值,有理由相信vcode_str本身是验证码的加密版本,验证时只是传递回去解密并判断,但是根据下面的测试,从vcode_str到验证码,并不是简单的编码转换,至少还有另外一个参数或说是key,该值可能与时间或其他随时间变动或其他会变动的参数有关。
也就是说,程序逻辑可能是这样:置随机数生成raw_ans,从raw_ans随机抽取字符加密生成vcode_str。
vcode_str有时长度为166,有时长度为168
前68为基本固定为33324238656332346361663334656637323237633636373637643239666664336662
69-88值在30-39之间变动,如31393932383034343233
89-114像是padding,基本固定30303030303030303030303030
115-136(168位vcode_str)
115-134(166位vcode_str)
固定在数值30-39之间变动

1
2
3031353031313433303537
31353031313432353135

最后32位像是hash
A4C7E4B8896D893EF0403CA97A53D057

实际上根据burp提供的随机率分析统计功能,在测试了3000+样本之后,发现vcode_str其实是在162-168位之间浮动。
样本下载
从样本中基本可以看出来,主要是padding部分的长度变动了,和手动分析的有点出入。
另外,padding后面的数字似乎和时间有关,或是说按照时间进行一定的递增。

由于burp的统计结果不支持在字符串中间部分进行padding,只能在开头和结尾部分,而百度的这个vcode_str是在中间部分进行padding的,所以统计图其实有点不准确。
附一张burp提供的光谱测试统计图
另外我还测试了raw_ans的随机情况,虽然有些统计方法并未达标,但看不懂,所以基本认为是随机了。其实就算不是随机,要以此攻击的话成功率也很低,成本偏高。

验证数据分析

http://pan.baidu.com/share/verify?shareid=1418533617&uk=242193955&t=时间戳+随机三位数&bdstoken=xxxxxxxx&channel=chunlei&clienttype=0&web=1&app_id=250528&logid=base64(时间戳+随机三位数+000.+随机15-20位数)

pwd=密码&vcode=验证码&vcode_str=vcode_str

替换vcode_str之后提交对应验证码,依然提示验证码错误,显然服务端不是单纯的解密vcode_str,还有别的判断机制,用以判别我们最后应该获取到的vcode_str是哪个。
删除了logid和t参数,验证码依然是四次验证限制。
目测没有对cookie进行改动的行为,那么只可能是对vcode_str本身进行了次数限制,比如getcaptcha函数产生一个vcode_str,然后在verify函数中进行验证code和次数,同时保存在session或其他机制中,一旦验证次数超过四次就unset掉这个vcode_str,而genimage函数则只是起到将vcode_str图像化的作用。
这种情况下,重放攻击很可能就不存在了,只能对genimage函数进行分析。

结论

根据已知的情况可知,genimage函数很可能并不是只受vcode_str参数的影响,还受到其他条件的约束(见0X0B的测试),因此没有源码的话黑盒逆向将十分困难,与此相比,验证码识别会简单的多。