Friday, 10 December 2010

[转]Discuz论坛自动发帖机原理分析

1. 起因:某人在自己的空间搭了个discuz,设置了诸多必须灌水的邪恶规定。本人一向潜水员当惯了当然不爽,既然要灌,那就往死里灌吧^_^~~

2. 前提条件:

a. discuz论坛无任何图片验证码,包括登陆以及发帖的时候。

b. form中无随即校验码。

其实a里面如果只是登陆的时候需要验证码都好办,关键是post的时候没有就行,加上本来就是一个batch程序,不想也没必要加上ocr,反正大多数情况下也起不到多大作用,尤其是现在的验证码经常变态到人都不知道结果的时候。

至于form里面分析了一下其实只有一个formhash而已,虽然这个hash是随即,但它其实是和你的session相关联的,所以一切就好办了~~

3. 准备工作:

a. 使用命令行来实现,脚本都懒得写了,不求美观,够用就行~反正又不指着这玩意儿捞钱~~ 使用命令行工具的话能够模拟post操作的印象里只有curl(linux下移植过来的,简介自己解决吧)了,有知道其他工具的麻烦吼一声~

b. 为了sniffer传输的数据,我用的httpwatch。嵌入ie的挺方便,一来不用漫天找
里面的数据,二来也省的动用专门的sniffer。

c. 文本编辑器。地球人都知道~~~个人推荐Emeditor~

4. 实施:只写部分过程和原理了~~

a. 想发帖不登陆是不行的,所以先获得标示身份的cookie。

原理1:curl -D,简写就只给个参数,详细的去看curl --help。大概意思就是将received httpheader dump出来。cookie在http传输过程中是通过写入header来发送给服务器的(服务器也是通过header里面的SET-Header设定 cookie),所以把整个header dump出来绝对够的。虽然这个header只是received的,但是curl的下次使用的时候可以自动将其转换为send的数据,比方说把Set- Cookie字段自动作为Cookie字段发送出去。另外需要注意一点,ie的cookie不能直接拿来放到curl用,起码我在测试的时候是这样的,还 没想通为什么~~=_=###

原理2:上面说过了discuz所有的form其实都是有一个form hash的,而这个form hash正常情况下是不会变的。没看过代码,怀疑可能是本机客户端的一个标示决定的,因为初始情况下,IE的hash是一个,即使你重开n多次都是一样。 而curl获取到的又是另外一个。

原理3:curl -d,用curl来post数据。



步骤1:既然form hash本机的“同一种browser”是一样的,所以先用curl -D cookie.txt -o cache.htm http://xinr.cn/bbs/index.php来获取测试页面,然后从cache.htm里面得到formhash值。

curl -D cookie.txt -o cache.htm http://xinr.cn/bbs/login.php

步骤2:自己拿ie登陆一遍,用httpwatch看看post的数据大致有哪些,然后。这个是个人都会,不多说了。关键记得改写的都写全,否则 server get request发现有参数没写肯定给你返回来。二一个是反正用的post,里面包含中文也没关系,只要不是要求encoded的就行。

步骤3:curl -d 把数据全都post出去就行。注意一点就是原本form里面可能已经写了action="login.php?action=xxx"之类的东西别扔了~~ 运行完打开cache.htm确认一下登陆是否成功就行。

curl -d "action=login&key1=value1&......" -D cookie.txt -o cache.htm http://xinr.cn/bbs/login.php

b. 自动发帖

原理1:curl -b,重用指定的cookie(确切地说应该是header),指定到上面的cookie.txt就行。

原理2:curl -d和form hash,同上。

步骤1:获取新建帖子的页面,用httpwatch sniffer一下或者直接分析源代码就行。和上面一样。

步骤2:发送新建帖子数据。比a里面的步骤3多加了一个包含cookie的参数而已,没什么特别的。碰到的第一个问题是自己测试的时候发现post数据中有下面这么一行。

key: attach[] value: filename="" Content-Type: application/octet-stream

看名字是发送附件的,正常情况下是没什么问题,烦就烦在value里面有一个引号,而命令行里面引号又属于不能乱用滴~ 自己又忘了批处理里面的转义符是个啥了=_= ^和%貌似都不是,还好服务器对这一项要求不严,直接发送个空数据就是了。
第二个问题就是源代码里面指定的key(姑且就这么叫了)是带有一些html字符的,譬如action=newthread&fid=10,改成action=newthread&fid=10就是。

curl -d "action=newthead&key1=value1....." -b cookie.txt -o cache.htm http://xinr.cn/bbs/post.php

步骤3:正确发送完成后确认返回的页面即可。

5. Summary:

a. 没啥技术含量的,不少都是人肉操作。平时积累点批处理和脚本的知识有的时候是可以给自己省事滴^_^~~

b. 扩展:
需要更新cookie的操作的话,可以用curl -b -D同时指向同一个文件。
需要多代理的话加-x然后再用批处理写一个for循环从列表里面读就是了。或者adsl直接rasphone重新拨号~~
需要对付服务器的user-agent验证的话,用-A即可。(其实很多在线听歌的流媒体服务器就用到agent认证,NetTransport最早也是 用的类似方法来模拟realplayer的) 想起来某人之前听的wmserver也是有个wmplayer的认证,当时就是拿的这个搞定的。

c. 其实网上那些个投票机、爆吧机还有最早的短信轰炸之类的破玩意儿也都是这个原理,自己扩展一下再加一点自动化的东西就是了。唯一而且也最有效的办法就是用图片验证码了,自己曾经找过几个命令行的ocr软件,都不咋滴~如果自己编的话恐怕也只能针对个别验证码及其之简单到取几个点就能分析的网站了。

d. 灌水真的没啥意义~~某个管理员同学手动改下数据库帮我加点帖子吧^_^~~不然浪费生命啊~~~~~

e. 源码就不贴了,说白了其实就两行命令而已~~~~

No comments:

Post a Comment