hm maybe this makes some things more clearly. you are right that it has to do with the table (and version, since its not working on MySQL 5.1 anymore) so it does not work everywhere. but thats what we both said before. so here is an example how you can reproduce it:
mysql> select @@version;
+-------------------------+
| @@version |
+-------------------------+
| 5.0.27-community-nt-log |
+-------------------------+
1 row in set (0.00 sec)
/// also testet with
mysql> select @@version;
+----------------+
| @@VERSION |
+----------------+
| 4.1.12a-nt-log |
+----------------+
1 row in set (0.00 sec)
/// seems fixed in MySQL 5.1 as stated in the blogpost
mysql> CREATE TABLE `test` (
-> `id` int(1) NOT NULL auto_increment,
-> `name` varchar(255) default NULL,
-> `password` varchar(255) default NULL,
-> PRIMARY KEY (`id`)
-> ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
Query OK, 0 rows affected (0.03 sec)
mysql> select * from test;
Empty set (0.00 sec)
mysql> select * from test where id = '1'%'0';
Empty set (0.00 sec)
mysql> insert into test values('', 'Reiners', 'Reinerspw');
Query OK, 1 row affected, 1 warning (0.00 sec)
/// OR
mysql> insert into test set name = 'Reiners', password = 'Reinerspw';
Query OK, 1 row affected (0.00 sec)
mysql> select * from test where id = '1'%'0';
Empty set (0.00 sec)
mysql> select * from test;
+----+---------+-----------+
| id | name | password |
+----+---------+-----------+
| 1 | Reiners | Reinerspw |
+----+---------+-----------+
1 row in set (0.00 sec)
mysql> insert into test values('', 'rvdh', 'rvdhpw');
Query OK, 1 row affected, 1 warning (0.00 sec)
/// OR
mysql> insert into test set name = 'rvdh', password = 'rvdhpw';
Query OK, 1 row affected (0.00 sec)
mysql> select * from test;
+----+---------+-----------+
| id | name | password |
+----+---------+-----------+
| 1 | Reiners | Reinerspw |
| 2 | rvdh | rvdhpw |
+----+---------+-----------+
2 rows in set (0.00 sec)
mysql> select * from test where id = '1'%'0';
ERROR 1048 (23000): Column 'id' cannot be null
mysql> select * from test where id = null;
Empty set (0.00 sec)
mysql> select * from test where id = \N;
Empty set (0.01 sec)
mysql> select * from test where id = 1/0;
Empty set (0.00 sec)
mysql> select * from test where id = '';
Empty set (0.00 sec)
as you can see it does only work with the modulo operator so its not producing the same with other "NULL"s. dont ask me why ;) but thats the "trick" we talk about. and yes, again, it depends on the table. I need to test more on it later ... I'm not sure yet if the auto_increment is neccessary and why I need at least 2 entries. or do you see at first glance anything I missed? anyway, as Paic showed I'm not the only one with a crippled table, so it may help if you are a lucky attacker/pentester and if you cant access information_schema and procedure analyse() doesn't work for you.
now I go for some beers ;) cheers.
Edited 1 time(s). Last edit at 11/27/2009 01:42PM by Reiners.