第四题:geek番外篇(sql注入中引号过滤)
我们打开题目,发现和上一道题一模一样,所以还是sql注入的问题,我们还是先试一下万能密码 ‘or ’1‘=‘1
既然万能密码不行我们就随机打几个用户名和密码看看能发现什么
这时候我们发现调用语句,select*from users where username=' xxx ' and password=' xxx '
我们看一下万能密码是如何工作的: select*from users where username=' admin ' and password=
' ' or '1'='1' 当sql语句在数据库中搜找用户名和密码的时候 =优先于and and优先于or 。因为1=1是恒成立的,我们都知道or只要有一者成立,返回的值就为1,也就是用户名和密码等同于正确的用户名和密码。
我们在换一个有点特别的用户名aaa''' 看看能得到什么
我们发现我们在用户名中输入的引号被过滤了。
那我们的核心思想还是要构造一个恒等式。
这时候我们先到转义符号\ 类似于c语言当我们想在printf输出时候输出%时,我们就需要打%%。类似的,当我们想要输出引号时,我们就需要一个转义符号,\’ 这样我们就可以把username后面的一个引号注,此时我们构想一个这样的语句:select * from users where username='aaa\' and password='1=1\'; 也就是说该语句中\后面的引号,不再能和前面的引号闭合而和password后面的引号闭合 但是这并不是一个恒等式。然而这时的查询语句:...where username = 'aaa ‘ and password = ' 1=1 我们可以肯定的是,数据库不可能存在一个用户名为:aaa ‘ and password = 所以整个where语句还是不成立的。
那我们应该如何使where语句成立呢?
让 username=0 综合弱类型转换,当字符串和数字进行比较的时候,字符串会转换成数字。 此时 0=0 显然 ,where语句成立。
那么如何构造出username=0呢?
这时候我们想到使用sql语句中的位异或。如:0^0=0 而且在mysql中 'aaa\' and password=' ^0=0是成立的,最重要的是位异或的优先级高于等于号,当我们把数据提交给服务器的时候,系统会先运算位异或。
最后我们构造一个payload:
select * from users where username='aaa\' and password='^0#';
提交后我们发现了我们想要的flag