Iscc 2017 ctf web Simple sqli 详细分析
概述
这道题目的解法并不唯一,但我个人感觉这种方法感觉是最触及核心的,也是见多识广的人应该了解的方法。
开始实践,细细琢磨
首先看到的就是这个验证码,
substr(md5(captcha), 0, 3)=9ef
关键在于他真的很’智能’真的是每次都变,不是闹着玩的
大概的意思是他会把captcha这个数据md5,然后取前3位,和等于号后面的值比较,相等就行了,然后好奇capcha到底怎么获得,看了一下元素,发现他是真的有这个参数的
不管那么多只能写一个脚本爆破md5的值,毕竟不能逆推只能比对,脚本如下:
1 |
|
开始注入:
首先我们尝试最一般的 username=admin&password=admin&captcha=8029
报 password error
说明似乎用户名被蒙对了
换一个随便的用户名 username=a&password=admin&captcha=9612
报 username error
说明登录验证是分两步进行的,首先是检验用户名是否正确,如果用户名正确那么验证密码正确与否,密码正确那么登陆成功,密码错误登录失败。但是用户名不正确,就不会检验密码,直接登录失败。
补充1
php常见的登录验证方式就是两种
1.select * from foobar where username=’’ and password=’’
查寻语句为真就登陆成功否则登录失败
2.select password from foobar where username=’’(这个username就是我们输
入的值)
如果找不到那么用户名错误
否则
如果查到的密码和输入的password/或者是输入的经过md5加密后的值相等那么登陆成功
否则输出密码错误
我们可以去验证一下是不是属于第二种情况(依据是他是否只select password还是select*)
这里面会报两个password error 因为union select @@version 也在查询到的数据中,他是对查询到的数据一条一条和密码去匹配,结果发现我们的两条数据和输入的密码都不一样,所以会报两个password error
我们来本机测试一下
两条数据清晰可见,union select 很多时候就是用来填充或者引入别的数据到同一个表里
那么我们只要用union select 去构造一个数据在存放查询得到的password 的那个表中,也就是上图的5.6.17的位置,再输入我们设定好的password,那样依赖他循环遍历对比的特点,就可以绕过密码登陆成功,我们试一下:
咦,怎么回事呢,因为他验证用的是我上面说的另一种方法,把我们输入的值得md5的结果和数据库中的对比,也就是说数据库中存储的全都是md5的值,因此我们修改一下我们的payload
完全符合我们的猜想,第一个用户名admin的真实密码无法和我们构造的假密码去匹配,所以第一个是错的,然后第二个恰恰使我们构造的假密码,绕过成功!!
补充2
登录验证类似于这样
1 |
|
总结
这种类型的绕过应该算是比较常见的绕过方式的一种,平时应该多积累,这样才能有所突破,运用起来也会游刃有余。