在一个偶然的机会下,一位美女黑客向我询问有关php验证码的问题,我才知道一个叫三叶草的安全组织正在举行信息安全技术大赛。
于是我看了一下题目,难度还是挺高的,由于比赛期间不能泄漏答案,于是等到今天才写出一些题目的攻略。
打开http://code1.myclover.org/Default.aspx
,可以看到以下界面:
这道题要求在60秒内提交60次验证码,我看了一下,发现还是有点难度的,最后用了一个比较特殊的方法完成。
打开firebug,点击go按钮,跳转到提交验证码的页面:
这时看一下firebug捕获的请求:
可以看到点击按钮后向Default.aspx
提交(POST)了一次数据,还有获取(GET)了Match.aspx和Code.aspx页面的数据。
1、首先看一下Default.aspx提交的参数。
提交的参数用php可以写成:
1 | $post = array( |
其中'Button1'
的值是固定的'Go!'
,那么'__EVENTVALIDATION'
和'__VIEWSTATE'
是从哪里获取的呢? 查看Default.aspx
的网页源码,可以发现源码里有两个隐藏域:
1 | <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEWAgLyjPLGBgKM54rGBmPDqObMucxXxtsHOLHUVmjnku17WnTdivWFADL9ShD4" /> |
所以提交数据之前要先获取Default.aspx
的源码,匹配出这两个隐藏域,再提交数据。
2、查看Default.aspx
提交数据后服务器的响应头信息:
我们感兴趣的是Set-Cookie信息:
1 | Set-Cookie |
其中ASP.NET_SessionId
值是用户与页面会话的标识。Star
值相当于标识了用户点击Go!按钮的时间。
用户点击了Go!按钮,服务器会记录点击的时间,正确提交60个验证码后,服务器会判断开始时间和最后提交的时间差,如果时间差小于60秒,就会显示过关的key。
3、获取Match.aspx页面的源码。
网页源码中也有同样的隐藏域,提交验证码时要用到:
1 | <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJMjYxMjUwMDUwZGS8D8v8uuSQ6rLtNG29gJP//sHvMScyfWHzWAIAiuZDlQ==" /> |
4、获取Code.aspx的信息。
可以看到页面返回一张验证码图片,而且响应头信息中有Set-Cookie
,"CheckCode"
字段是该验证码图片的唯一标识:
1 | Set-Cookie |
5、填写验证码后点击SUBMIT按钮,发现是向Match.aspx提交数据,查看提交的参数:
提交的参数用php可以写成:
1 | $post = array( |
其中’Button1’的值是固定的’SUBMIT’,’TextBox1’是验证码,隐藏域的值是在第3步中获取的。
综上所述,要完成验证码提交,需要完成以下步骤:
1、获取首页Default.aspx的源码,匹配出隐藏域的值。
2、模拟点击Go!按钮提交数据。
3、获取Match.aspx网页源码的隐藏域的值。
4、访问Code.aspx,获得验证码图片,自动识别成验证码数字。
识别验证码可以参考这篇文章:《php实现验证码的识别(初级篇)》。
5、模拟点击SUBMIT按钮提交验证码。
6、重复步骤456,一共重复60次。
7、注意每次请求都要发送和保存cookie。
但是由于我的网速和代码执行速度比较慢,所以每次都要执行60秒以上:
由于代码是php写的,但php又没有多线程,所以时间总是超过60秒,最后用了一种方法来模拟多线程。方法就是开两个页面来跑php代码,把代码分成3个文件:
submit.php
: 用来模拟提交验证码,验证码图片保存到valid.gif,cookie保存到cookie.txt。submit2.php
: 和submit.php差不多,验证码图片保存到valid2.gif,cookie保存到cookie2.txt。go.php
: 用来模拟点击Go!按钮,然后把cookie保存到cookie.txt,然后复制一份为cookie2.txt。
这样执行go.php
后,cookie.txt
和cookie2.txt
有相同的ASP.NET_SessionId
值和star值。
再同时执行submit.php
和submit2.php
,这两个脚本获取的验证码图片和验证码cookie都会保存在不同的文件里,所以不会互相干扰。
每个页面执行了40多秒,于是成功地获取了过关的key:
活动结束后,出题者的话:
我的code.aspx在OnLoad时间里面会生成验证码并md5存cookie。
只要你们通过发包的形式。只请求一次code.aspx。后面都同样的验证码即可。
看来以后做题前还是要多分析思考。