百度知道提问参数“utdata”加密算法彻底剖析,百度知道防机器人策略

提示:

本文不会写出详细分析过程,只是会大略的提一下,这方面的东西比较敏感,我本人也很痛恨伸手党,相关内容点到为止,具体的自己看一下就知道了,如果肯你花时间自己研究半个小时,你会理解的比我还透彻!

(PS:以前也可能有人写过此类文章吧 ,内行看门道,外行看热闹吧……)

因某些业务需要,需要开发一套与百度知道相关的软件(功能你懂的),其中某个环节需要分析百度知道提问数据格式及算法,以下是分析过程……

首先通过某些方法得到百度知道提问时网页提交的数据,以及对应的加密方法,其实就是一个js脚本,流程如下(部分分析日志):

<!--

--------------------------------------------------------------
重要代码:
--------------------------------------------------------------

1、页面底部载入了关键 js 脚本:
<script src="http://iknow.bdimg.com/new/js/new.js?@=1dbeamp" type="text/javascript"></script>

2、http://iknow.bdimg.com/new/js/new.js 载入了关键提问算法:
document.write('<script type="text/javascript" src="http://iknow.bdimg.com/base/js/ut.js"><\/script>');

3、base/js/ut.js 为关键参数“utdata”的加密算法。

…… 省略 ……

--------------------------------------------------------------
ut.js 算法核心代码:
--------------------------------------------------------------

1、行数:2,代码:var START=new Date().getTime()
   时间戳,当前时间距1970年1月1日午夜(GMT时间)之间的毫秒数。
   功能:记录页面运行的起始时间,并加入最后提交的参数之中,在函数 N() 中:(new Date()).getTime()-START
   用来判断用户在页面停留了多久,区分****************,这是影响***及***的关键参数!!!!

2、行数:11,代码:var J=(new Date()).getTime();
   时间戳,当前时间距1970年1月1日午夜(GMT时间)之间的毫秒数。
   功能:用来做校验值,并用于最后参数加密操作,此值为关键数值。

3、关键运算函数:N()、D(Z)

…… 省略 ……

-->

加密算法函数为“D(Z)”,其实是很简单的一个加密算法:

function D(Z){
    //最终加密函数
    var U=[];
    var X={};
    var Y=J%100;  //时间戳除以100,取余数
    for(var W=0,V=Z.length; W<V; W++){
        var a=Z.charCodeAt(W)^Y;
        U.push(a);
        if(!X[a]){
            X[a]=[]
        }
        X[a].push(W)
    }
    return U
}

核心算法代码只有一行,重点不在这里,在对其原始明文数据分析之后,得出了一个很狗血的结论……

提交的原始数据包:

------------------------------------------------------------------------------------
提交数据:
------------------------------------------------------------------------------------

POST /submit/ajax?jasmine=1 HTTP/1.1
Host: zhidao.baidu.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:9.0) Gecko/20100101 Firefox/9.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.5
Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer: http://zhidao.baidu.com/new?word=
Content-Length: 【425】
Cookie: **************************
Pragma: no-cache
Cache-Control: no-cache

cm=100001&query=&title=【问题内容,长度50字节】&detail=<p><br%20%2F><%2Fp>&cid=【问题分类ID】&pid=&wealth=【财富悬赏】&team=&teamid=&anoy=0&fix=&utdata=101,106,106,126,103,106,107,91,96,126,96,126,96,126,96,126,96,126,96,126,97,126,102,126,102,126,102,91,102,96,97,99,97,91,99,102,102,98,126,107,98,98,13439812833821&fr=&querytype=&psquery=&rich=1&testcase=1&usnsqflag=


------------------------------------------------------------------------------------
返回数据:
------------------------------------------------------------------------------------

HTTP/1.1 200 OK
Content-type: text/html;charset=GBK
Content-Length: 249
Connection: Keep-Alive
Date: Fri, 03 Aug 2012 08:08:46 GMT
Server: apache


{"errorNo" : "0"
		,"data" : {
			"cm" : "100001"
,"qid" : "*********"
			,"cid" : "440"
			,"check" : ""
			,"image" : ""
,"title" : "********************"
}}

都是一些很简单的参数,文中有部分说明……

重要的参数是:utdata,收集了一组测试数据之后,进行了解密(见上图),然后狗血了……

例如:

//密文
109,111,110,118,108,104,98,83,105,118,105,118,105,118,105,118,104,118,104,118,104,118,104,118,104,118,110,83,105,105,108,107,110,83,107,110,110,106,118,99,106,106,13442338918901

M = 1  //某个防机器人参数,不解释
Key = 90  //加密密匙

//很有意思的明文
754,628 3,3,3,3,2,2,2,2,2,4     33614   1440,900

明文:754,628 3,3,3,3,2,2,2,2,2,4     33614   1440,900 

格式:鼠标运行轨迹坐标 chr(9) 网页某些元素排序 chr(9) 用户在页面停留的毫秒数 chr(9) 用户屏幕分辨率

呵呵,这其中隐藏着一个很“牛逼”的防机器人策略……

可以自己思考一下……

(第一回合:百度某工程师彻底败北)

留言评论(旧系统):

safe121 @ 2012-08-06 21:37:40

强大的JS啊。。鼠标运行轨迹..........据说某铸写了个JS记录键盘的....

本站回复:

JavaScript 获取鼠标坐标很简单的……

晴天小铸 @ 2012-08-07 18:19:53

强大的时间戳。。。。。。。

本站回复:

╮(╯_╰)╭

晴天小铸 @ 2012-08-07 18:30:34

文章的char(9)是啥不鸟姐其他的能理解。。。

本站回复:

chr(9) = 制表符,一个常用函数,返回指定 ASCII 值对应的字符。

晴天小铸 @ 2012-08-08 23:29:45

我昨天看头脑短路了chr(9)我以为是象征某个东西 现在又看了看才知道说的 char(9)是固定值 百度好牛逼。。。 求老大的fuzz 思路

本站回复:

chr(9) = 制表符,因为在网页中制表符和空格难以区分,所以直接用编程函数代替了(这是一个习惯,很多程序员在写文章的时候,都喜欢用chr函数表示一些不能直接显示的特殊字符,一目了然),这个制表符百度是作为分隔符用的。

beijin @ 2013-09-02 21:48:15

为什么程序中用空格代替char(9) 和浏览器使用char(9)运行出来的密文一样?不解

本站回复:

百度服务器端应该是两种字符通用(空格、制表符)。

佚名 @ 2013-09-02 22:02:24

算得了utdata,还是被他们发现说违反了规范

本站回复:

囧……

佚名 @ 2013-11-19 11:37:52

有源码吗?可以发一份给我吗?邮箱:971113420@qq.com,谢谢

本站回复:

暂不开源,谢谢!

小宇 @ 2013-11-20 16:10:12

站长接单子吗 想找你合作 做一个程序

本站回复:

非法程序不接,具体请加QQ:root@lcx.cc

佚名 @ 2013-11-21 17:52:31

这个还好吧...蛋疼的是代理问题 回答一次换一个。

本站回复:

是啊,所以你需要准备一大堆代理。 King Of The Proxy (代理之王) v1.0 发布、HTTP代理采集、验证工具: http://lcx.cc/?i=2844

佚名 @ 2013-12-03 11:37:37

有个问题要请教一下 时间j 更接近时间START 还是更接近生成utdata 的(new Date()).getTime()?

本站回复:

2、行数:11,代码:var J=(new Date()).getTime();

佚名 @ 2013-12-03 11:39:09

有个问题要请教一下 时间j 更接近时间START 还是更接近生成utdata 的(new Date()).getTime()?

本站回复:

2、行数:11,代码:var J=(new Date()).getTime();

佚名 @ 2013-12-03 16:17:53

留言内容: 有个问题要请教一下 时间j 更接近时间START 还是更接近生成utdata 的(new Date()).getTime()? 站长回复: 2、行数:11,代码:var J=(new Date()).getTime(); 谢谢你的回答。我的意思是 J 和 START 是不是相差1秒左右?

本站回复:

是的,是有时间差,具体差多少,看浏览器运行速度了,START只是记录页面运行的起始时间,用来判断用户在页面停留了多久。

呆逼自然萌 @ 2014-10-12 20:40:31

我发现百度贴吧的和这个很像

本站回复:

百度算法都差不多,都是一个部门写的。

呆逼自然萌 @ 2015-03-29 02:50:57

防机器人策略

本站回复: