SQL注入①
一道简单的SQL注入题,由蓝鲸安全平台提供
题目:后台好黑….什么都看不到啊……,答题地址:http://ctf.whaledu.com:10801/47g256f48gff/
目录
背景知识
Union盲注
当有时候网站对参数过滤的非常严格,例如以下规则:$filterlist = "/\(|\)|username|password|where|case|when|like|regexp|into|limit|=|for|;/";
大致总结如下:
- 没有了括号,标志着没有办法用mysql里的函数
没有了password,但是它却是字段名,所以sql语句中不能出现password这个列名。
也就是说,当我们不能使用mysql的函数和对指定的列表进行查询怎么办?
利用自己是mysql数据库进行实验:

发现mysql的字符串排序操作是从前往后依次用ascii码对比的,所以我们可以利用这个特性注入。
我们可以控制我们要查询的字段(例子中是第三列,所以根据第三列一一order by 3 ),让其从ascii码中可打印字符开始变化(48~127)然后不断去排序,当我们的猜测刚好比真正的数据大1时,我们的数据就会被排列到最上方,那么如果该语句接入的用户验证或者数据显示等地方,页面就会发生变化,我们以这个变化为临界点就能构造盲注了。
注意的是数据库的系统和函数使用,当然可以在调试脚本时候发现。如果我们要从小到大的查询,那么desc的降序排列是必须的,但是如果网页过滤了desc可以使用吗?其实也可以,只需要更改查询顺序,从大到小就可以了(127,48),而且如果使用desc那么临界点的地方我们猜测的数据应该比数据库中的大一。如果是升序,那么临界点就刚好是真是数据。
题目解析
使用源码泄露工具dirsearch-master,扫描该网址是否存在源码泄露,指令如下:
1 | python3 dirsearch.py -u http://ctf.whaledu.com:10801/47g256f48gff/ -e php |

发现三个可疑的url,逐个查看发现,index.php~后缀的url存在源码泄露,找到备份文件,查看源代码:
1 | <?php |
找到关键的说明,用户名的密码就是flag,所以应该需要注入。

我们看到php源码中函数filter过滤的很严格,这些字符都不能出现。

限制的比较坑的有如下两条:
- 没有了括号,标志着没有办法用mysql里的函数
- 没有了password,但是它却是字段名,所以sql语句中不能出现password这个列名。
- 现在只能想办法利用union盲注测试
- 根据sql语句我们构造如下(注意自己测试列数):
1 | select * from admin where username='admin' union distinct select 1,2,0x38 order by 3 desc; |
- 我们可以控制后面的那个查询的第三个字段,让他从最小开始变化,当查询结果第一条返回的username字段是2的时候,就可以知道这个字符的ascii码减一就是跟数据库中的相等,所以就可以一位一位的猜出来password字段了。
- 我们得先知道username是什么,所以需要一个不在过滤范围内的万能密钥。想到一个互斥运算符^(异或),那么任何空字符串与0异或都能得1,我们就能得到恒真式了。
- 提交
username='^0#&password=1,得到用户名为whaleadmin

接着使用爆破脚本就能够得到每个密码了
1 | #!/usr/bin/python |
最终cmd5查询密码或者md5本地爆破都能知道密码:

总结
要想完全理解本题,需要大家先了解SQL注入相关原理,并且自己通过搭建mysql数据库,进行实际测试,在网站过滤了大部分的参数后,union联合注入是CTF比赛中常见的类型,SQL注入攻击的核心之一就是找到可控的临界点。