Введение в практическую безопасность (2019)/HTTP, инструменты & SQL injection: различия между версиями

Материал из SecSem Wiki
Перейти к навигации Перейти к поиску
(SQL injection)
(HTTP)
(не показано 10 промежуточных версий этого же участника)
Строка 1: Строка 1:
 +
__NOTOC__
 
== HTTP ==
 
== HTTP ==
  
Клиенты (например, веб-браузеры) взаимодействуют с веб-приложениями по протоколу '''HTTP''' ([https://ru.wikipedia.org/wiki/HTTP википедия], стандарт HTTP 1.1: [https://tools.ietf.org/html/rfc2616 RFC 2616], [https://tools.ietf.org/html/rfc7230 RFC 7230], [https://tools.ietf.org/html/rfc7231 RFC 7231]). Он работает поверх [https://ru.wikipedia.org/wiki/Transmission_Control_Protocol TCP], стандартный TCP-порт для HTTP без SSL (шифрования) это порт '''80''', а для HTTPS (HTTP поверх SSL, т. е. с шифрованием) это порт '''443'''. Протокол состоит из запросов (которые клиент отправляет серверу) и ответов (которые сервер присылает в ответ). Протокол HTTP версии 1.1 (наиболее используемой в данный момент) и более ранних - текстовый, то есть сообщения этого протокола человекочитаемые. К примеру, вот запрос, который сделает браузер при переходе по URL http://sql1.stands.course.secsem.ru/users:<br>[[Файл:Http-req-annot.png]] <br>Ответ сервера на него:<br>[[Файл:Http-res-annot.png]]<br>Ещё пример, запрос, который сделает браузер при попытке (неудачной) залогиниться на сайте vk.com c почтой "admin@adminmail.ru" и паролем "adminpassword":<br>[[Файл:Http-req-post-annot.png]]<br>Ответ сервера на этот запрос<br>[[Файл:Http-res-post-annot.png]]
+
Клиенты (например, веб-браузеры) взаимодействуют с веб-приложениями по протоколу '''HTTP''' ([https://ru.wikipedia.org/wiki/HTTP википедия], стандарт HTTP 1.1: [https://tools.ietf.org/html/rfc2616 RFC 2616], [https://tools.ietf.org/html/rfc7230 RFC 7230], [https://tools.ietf.org/html/rfc7231 RFC 7231]). Он работает поверх [https://ru.wikipedia.org/wiki/Transmission_Control_Protocol TCP], стандартный TCP-порт для HTTP это порт '''80''', а для HTTPS (HTTP поверх SSL, т. е. с шифрованием) это порт '''443'''. Протокол состоит из запросов (которые клиент отправляет серверу) и ответов (которые сервер присылает в ответ). Протокол HTTP версии 1.1 (наиболее используемой в данный момент) и более ранних - текстовый, то есть сообщения этого протокола человекочитаемые. К примеру, вот запрос, который сделает браузер при переходе по URL http://sql1.stands.course.secsem.ru/users:<br>[[Файл:Http-req-annot.png]] <br>Ответ сервера на него:<br>[[Файл:Http-res-annot.png]]<br>Ещё пример, запрос, который сделает браузер при попытке (неудачной) залогиниться на сайте vk.com c почтой "admin@adminmail.ru" и паролем "adminpassword":<br>[[Файл:Http-req-post-annot.png]]<br>Ответ сервера на этот запрос<br>[[Файл:Http-res-post-annot.png]]
 +
 
 +
Еще информация: [http://old.secsem.ru/lections?action=AttachFile&do=get&target=infosec-network2013-4-%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D1%8B+%D0%B2%D0%B5%D0%B1-%D1%82%D0%B5%D1%85%D0%BD%D0%BE%D0%BB%D0%BE%D0%B3%D0%B8%D0%B9.pdf про основы веб-технологий в слайдах нашего спецкурса 2013 года].
  
 
== Инструменты ==
 
== Инструменты ==
  
# Для анализа HTTP-взаимодействия между клиентом и сервером, а также для вмешательства в него удобен '''Burp Suite'''. Он может работать как HTTP-proxy, то есть получать от клиента запрос и пересылать его серверу, получать ответ сервера и передавать его клиенту. При этом Burp может показывать запросы и ответы пользователю, задерживать и изменять их. Кроме этого, он может формировать и отправлять новые HTTP-запросы сам ("вручную"). [http://demo.secsem.ru/workshop/burp Здесь написано как его скачать и начать использовать].
+
=== Burp Suite ===
# Более простые инструменты, позволяющие отправлять HTTP-запросы веб-приложению и получать ответы - '''netcat''' и '''curl'''.
+
 
#* '''Netcat''' ([https://www.opennet.ru/man.shtml?topic=netcat man]) позволяет установить tcp-соединение, после чего отправляет на другой конец всё что подано ему на стандартный ввод и печатает на стандартный вывод всё, что получил. Он позволяет буквально "руками" набрать и отправить HTTP-запрос. Вот как можно отправить запрос, соответствующий переходу по URL http://mail.ru:<br>[[Файл:Nc-http.png|800px]]<br>То же самое, но с флагом "-v" (который говорит Netcat выдавать более подробную диагностику, в т. ч. написать об успешности установления TCP-соединения и парой дополнительных HTTP-заголовков (заголовок "Connection: close" говорит серверу что после этого запроса TCP-соединение будет закрыто, новых запросов в нём не будет): [[Файл:Nc-http2.png|800px]]<br>
+
Для анализа HTTP-взаимодействия между клиентом и сервером, а также для вмешательства в него удобен '''Burp Suite'''. Он может работать как HTTP-proxy, то есть получать от клиента запрос и пересылать его серверу, получать ответ сервера и передавать его клиенту. При этом Burp может показывать запросы и ответы пользователю, задерживать и изменять их. Кроме этого, он может формировать и отправлять новые HTTP-запросы сам ("вручную"). [http://demo.secsem.ru/workshop/burp Здесь написано как его скачать и начать использовать].
#* '''curl''' ([https://curl.haxx.se/docs/manpage.html man]) позволяет очень просто делать HTTP-запросы из консоли.<br>[[Файл:Curl example org.png|800px]]
+
 
 +
=== Netcat и curl ===
 +
 
 +
Более простые инструменты, позволяющие отправлять HTTP-запросы веб-приложению и получать ответы - '''netcat''' и '''curl'''.
 +
 
 +
'''Netcat''' ([https://www.opennet.ru/man.shtml?topic=netcat man]) позволяет установить tcp-соединение, после чего отправляет на другой конец всё что подано ему на стандартный ввод и печатает на стандартный вывод всё, что получил. Он позволяет буквально "руками" набрать и отправить HTTP-запрос. Вот как можно отправить запрос, соответствующий переходу по URL http://mail.ru:
 +
<pre>$ nc mail.ru 80
 +
GET / HTTP/1.1
 +
Host: mail.ru
 +
 
 +
HTTP/1.1 301 Moved Permanently
 +
Server: nginx/1.14.1
 +
Date: Sun, 24 Feb 2019 20:08:08 GMT
 +
Content-Type: text/html
 +
Content-Length: 185
 +
Connection: keep-alive
 +
Location: https://mail.ru
 +
X-XSS-Protection: 1; mode=block; report=https://cspreport.mail.ru/xxssprotection
 +
X-Content-Type-Options: nosniff
 +
 
 +
<html>
 +
<head><title>301 Moved Permanently</title></head>
 +
<body bgcolor="white">
 +
<center><h1>301 Moved Permanently</h1></center>
 +
<hr><center>nginx/1.14.1</center>
 +
</body>
 +
</html>
 +
^C</pre>
 +
То же самое, но с флагом "-v" (который говорит Netcat выдавать более подробную диагностику, в т. ч. написать об успешности установления TCP-соединения и парой дополнительных HTTP-заголовков (заголовок "Connection: close" говорит серверу что после этого запроса TCP-соединение будет закрыто, новых запросов в нём не будет):
 +
<pre>$ nc -v mail.ru 80
 +
Connection to mail.ru 80 port [tcp/http] succeeded!
 +
GET / HTTP/1.1
 +
Host: mail.ru
 +
Accept: */*
 +
Connection: close
 +
 
 +
HTTP/1.1 301 Moved Permanently
 +
Server: nginx/1.14.1
 +
Date: Sun, 24 Feb 2019 20:14:37 GMT
 +
Content-Type: text/html
 +
Content-Length: 185
 +
Connection: close
 +
Location: https://mail.ru
 +
X-XSS-Protection: 1; mode=block; report=https://cspreport.mail.ru/xxssprotection
 +
X-Content-Type-Options: nosniff
 +
 
 +
<html>
 +
<head><title>301 Moved Permanently</title></head>
 +
<body bgcolor="white">
 +
<center><h1>301 Moved Permanently</h1></center>
 +
<hr><center>nginx/1.14.1</center>
 +
</body>
 +
</html></pre>
 +
 
 +
'''curl''' ([https://curl.haxx.se/docs/manpage.html man]) позволяет очень просто делать HTTP-запросы из консоли.
 +
<pre>$ curl -v http://example.org
 +
* Rebuilt URL to: http://example.org/
 +
*  Trying 93.184.216.34...
 +
* TCP_NODELAY set
 +
* Connected to example.org (93.184.216.34) port 80 (#0)
 +
> GET / HTTP/1.1
 +
> Host: example.org
 +
> User-Agent: curl/7.58.0
 +
> Accept: */*
 +
>
 +
< HTTP/1.1 200 OK
 +
< Cache-Control: max-age=604800
 +
< Content-Type: text/html; charset=UTF-8
 +
< Date: Sun, 24 Feb 2019 20:33:38 GMT
 +
< Etag: "1541025663+ident"
 +
< Expires: Sun, 03 Mar 2019 20:33:38 GMT
 +
< Last-Modified: Fri, 09 Aug 2013 23:54:35 GMT
 +
< Server: ECS (phd/FD58)
 +
< Vary: Accept-Encoding
 +
< X-Cache: HIT
 +
< Content-Length: 1270
 +
<
 +
<!doctype html>
 +
<html>
 +
<head>
 +
    <title>Example Domain</title>
 +
 
 +
    <meta charset="utf-8" />
 +
    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
 +
...</pre>
  
 
== SQL injection ==
 
== SQL injection ==
  
Веб-приложения нередко используют SQL-базы данных, т. е. базы данных, взаимодействие с которыми осуществляется через запросы на языке '''SQL''' ([https://ru.wikipedia.org/wiki/SQL википедия], [http://citforum.ru/database/osbd/glava_55.shtml#_5 курс "Основы современных баз данных" С.Д. Кузнецова]. Поиграться с SQL можно просто в [http://sqlfiddle.postgrespro.ru/#!17//5814 SQL Fiddle] или с помощью [https://linux.die.net/man/1/sqlite3 sqlite3]. Пример SQL-запросов и ответов на них:<br>[[Файл:Sql1-annotated.png]]<br>[[Файл:Sql2-annotated.png]]<br>Веб-приложение формирует и отправляет базе SQL-запросы, которые могут зависеть от параметров, пришедших от клиента (взятых из HTTP-запроса). SQL-запросы текстовые и простой способ сделать запрос, зависящий от параметра - просто подставить этот параметр в текст запроса.
+
Веб-приложения нередко используют SQL-базы данных, т. е. такие БД, взаимодействие с которыми осуществляется через запросы на языке '''SQL''' ([https://ru.wikipedia.org/wiki/SQL википедия], [http://citforum.ru/database/osbd/glava_55.shtml#_5 курс "Основы современных баз данных" С.Д. Кузнецова]). Поиграться с SQL можно просто в [http://sqlfiddle.postgrespro.ru/#!17//5814 SQL Fiddle] или с помощью [https://linux.die.net/man/1/sqlite3 sqlite3]. Пример SQL-запросов и ответов на них:<br>[[Файл:Sql1-annotated.png]]<br>[[Файл:Sql2-annotated.png]]<br>Веб-приложение формирует и отправляет базе SQL-запросы, которые могут зависеть от параметров, пришедших от клиента (взятых из HTTP-запроса). SQL-запросы текстовые и простой способ сделать запрос, зависящий от параметра - просто подставить этот параметр в текст запроса.
 
Пример кода (на языке [https://www.python.org/ Python]), подставляющего параметр из HTTP-запроса в SQL-запрос к базе:
 
Пример кода (на языке [https://www.python.org/ Python]), подставляющего параметр из HTTP-запроса в SQL-запрос к базе:
 
[[Файл:Sqli-code.png|650px]]
 
[[Файл:Sqli-code.png|650px]]
Строка 18: Строка 105:
  
 
[[Файл:Sql-req.png|520px]]
 
[[Файл:Sql-req.png|520px]]
 +
 
Значение "testuser" подставилось в строковый литерал в одинарных кавычках. Говорят, что значение попало в '''контекст''' строкового литерала.
 
Значение "testuser" подставилось в строковый литерал в одинарных кавычках. Говорят, что значение попало в '''контекст''' строкового литерала.
 
После такой подстановки может оказаться, что смысл SQL-запроса изменился и данные, подставленые в запрос стали не просто значением параметра запроса (скажем, числовым или стокововым литералом), а какими-то еще конструкциями языка SQL. Вот какой запрос будет сформирован, если параметр "login" будет иметь значение <code>' or 1=1 --</code>:
 
После такой подстановки может оказаться, что смысл SQL-запроса изменился и данные, подставленые в запрос стали не просто значением параметра запроса (скажем, числовым или стокововым литералом), а какими-то еще конструкциями языка SQL. Вот какой запрос будет сформирован, если параметр "login" будет иметь значение <code>' or 1=1 --</code>:
Строка 27: Строка 115:
 
[[Файл:Sql-id.png|520px]]
 
[[Файл:Sql-id.png|520px]]
  
Возможность передать такое значение параметра HTTP-запроса, которое подставится в текст SQL-запроса и при подстановке изменит смысл этого запроса называется '''SQL injection''' ([https://www.owasp.org/index.php/SQL_Injection OWASP]). Хорошую статью про SQL injection можно [https://rdot.org/forum/showthread.php?s=f4292383c9896b773bd98d827eb9411f&t=124 найти тут] и [http://pentestmonkey.net/cheat-sheet/sql-injection/mysql-sql-injection-cheat-sheet еще тут].  
+
Возможность передать такое значение параметра HTTP-запроса, которое подставится в текст SQL-запроса и при подстановке изменит смысл этого запроса называется '''SQL injection''' ([https://www.owasp.org/index.php/SQL_Injection OWASP]). Хорошую статью про SQL injection можно [https://rdot.org/forum/showthread.php?s=f4292383c9896b773bd98d827eb9411f&t=124 найти тут] и [http://pentestmonkey.net/cheat-sheet/sql-injection/mysql-sql-injection-cheat-sheet еще тут].
 +
 
 +
Попробовать эксплуатировать SQL injection можно на этих уязвимых приложениях:
 +
* http://sql1.stands.course.secsem.ru/ ([https://course.secsem.ru/task-src/sql1.tgz исходный код])
 +
* http://sql2.stands.course.secsem.ru/
  
 
Фактически, SQLi это один из представителей класса уязвимостей '''injection''', которые получаются, если в какие-то управляющие команды подставляются параметры-данные от пользователя и эти данные могут выйти из контекста, куда подставляются, перестав быть просто данными, и поменять смысл команды.
 
Фактически, SQLi это один из представителей класса уязвимостей '''injection''', которые получаются, если в какие-то управляющие команды подставляются параметры-данные от пользователя и эти данные могут выйти из контекста, куда подставляются, перестав быть просто данными, и поменять смысл команды.

Версия 07:49, 18 марта 2019

HTTP

Клиенты (например, веб-браузеры) взаимодействуют с веб-приложениями по протоколу HTTP (википедия, стандарт HTTP 1.1: RFC 2616, RFC 7230, RFC 7231). Он работает поверх TCP, стандартный TCP-порт для HTTP это порт 80, а для HTTPS (HTTP поверх SSL, т. е. с шифрованием) это порт 443. Протокол состоит из запросов (которые клиент отправляет серверу) и ответов (которые сервер присылает в ответ). Протокол HTTP версии 1.1 (наиболее используемой в данный момент) и более ранних - текстовый, то есть сообщения этого протокола человекочитаемые. К примеру, вот запрос, который сделает браузер при переходе по URL http://sql1.stands.course.secsem.ru/users:
Http-req-annot.png
Ответ сервера на него:
Http-res-annot.png
Ещё пример, запрос, который сделает браузер при попытке (неудачной) залогиниться на сайте vk.com c почтой "admin@adminmail.ru" и паролем "adminpassword":
Http-req-post-annot.png
Ответ сервера на этот запрос
Http-res-post-annot.png

Еще информация: про основы веб-технологий в слайдах нашего спецкурса 2013 года.

Инструменты

Burp Suite

Для анализа HTTP-взаимодействия между клиентом и сервером, а также для вмешательства в него удобен Burp Suite. Он может работать как HTTP-proxy, то есть получать от клиента запрос и пересылать его серверу, получать ответ сервера и передавать его клиенту. При этом Burp может показывать запросы и ответы пользователю, задерживать и изменять их. Кроме этого, он может формировать и отправлять новые HTTP-запросы сам ("вручную"). Здесь написано как его скачать и начать использовать.

Netcat и curl

Более простые инструменты, позволяющие отправлять HTTP-запросы веб-приложению и получать ответы - netcat и curl.

Netcat (man) позволяет установить tcp-соединение, после чего отправляет на другой конец всё что подано ему на стандартный ввод и печатает на стандартный вывод всё, что получил. Он позволяет буквально "руками" набрать и отправить HTTP-запрос. Вот как можно отправить запрос, соответствующий переходу по URL http://mail.ru:

$ nc mail.ru 80
GET / HTTP/1.1
Host: mail.ru

HTTP/1.1 301 Moved Permanently
Server: nginx/1.14.1
Date: Sun, 24 Feb 2019 20:08:08 GMT
Content-Type: text/html
Content-Length: 185
Connection: keep-alive
Location: https://mail.ru
X-XSS-Protection: 1; mode=block; report=https://cspreport.mail.ru/xxssprotection
X-Content-Type-Options: nosniff

<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.14.1</center>
</body>
</html>
^C

То же самое, но с флагом "-v" (который говорит Netcat выдавать более подробную диагностику, в т. ч. написать об успешности установления TCP-соединения и парой дополнительных HTTP-заголовков (заголовок "Connection: close" говорит серверу что после этого запроса TCP-соединение будет закрыто, новых запросов в нём не будет):

$ nc -v mail.ru 80
Connection to mail.ru 80 port [tcp/http] succeeded!
GET / HTTP/1.1
Host: mail.ru
Accept: */*
Connection: close

HTTP/1.1 301 Moved Permanently
Server: nginx/1.14.1
Date: Sun, 24 Feb 2019 20:14:37 GMT
Content-Type: text/html
Content-Length: 185
Connection: close
Location: https://mail.ru
X-XSS-Protection: 1; mode=block; report=https://cspreport.mail.ru/xxssprotection
X-Content-Type-Options: nosniff

<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.14.1</center>
</body>
</html>

curl (man) позволяет очень просто делать HTTP-запросы из консоли.

$ curl -v http://example.org
* Rebuilt URL to: http://example.org/
*   Trying 93.184.216.34...
* TCP_NODELAY set
* Connected to example.org (93.184.216.34) port 80 (#0)
> GET / HTTP/1.1
> Host: example.org
> User-Agent: curl/7.58.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Cache-Control: max-age=604800
< Content-Type: text/html; charset=UTF-8
< Date: Sun, 24 Feb 2019 20:33:38 GMT
< Etag: "1541025663+ident"
< Expires: Sun, 03 Mar 2019 20:33:38 GMT
< Last-Modified: Fri, 09 Aug 2013 23:54:35 GMT
< Server: ECS (phd/FD58)
< Vary: Accept-Encoding
< X-Cache: HIT
< Content-Length: 1270
< 
<!doctype html>
<html>
<head>
    <title>Example Domain</title>

    <meta charset="utf-8" />
    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
...

SQL injection

Веб-приложения нередко используют SQL-базы данных, т. е. такие БД, взаимодействие с которыми осуществляется через запросы на языке SQL (википедия, курс "Основы современных баз данных" С.Д. Кузнецова). Поиграться с SQL можно просто в SQL Fiddle или с помощью sqlite3. Пример SQL-запросов и ответов на них:
Sql1-annotated.png
Sql2-annotated.png
Веб-приложение формирует и отправляет базе SQL-запросы, которые могут зависеть от параметров, пришедших от клиента (взятых из HTTP-запроса). SQL-запросы текстовые и простой способ сделать запрос, зависящий от параметра - просто подставить этот параметр в текст запроса. Пример кода (на языке Python), подставляющего параметр из HTTP-запроса в SQL-запрос к базе: Sqli-code.png Здесь "request.args.get('login')" считывает значение параметра "login" query string запроса. Вот какой вид примет запрос, если параметр login будет иметь значение "testuser".

Sql-req.png

Значение "testuser" подставилось в строковый литерал в одинарных кавычках. Говорят, что значение попало в контекст строкового литерала. После такой подстановки может оказаться, что смысл SQL-запроса изменился и данные, подставленые в запрос стали не просто значением параметра запроса (скажем, числовым или стокововым литералом), а какими-то еще конструкциями языка SQL. Вот какой запрос будет сформирован, если параметр "login" будет иметь значение ' or 1=1 --:

Sqli-annot.png

В результате выражение в WHERE-части приняло вид login='' or 1=1, оно будет истинным для любой строки таблицы, в результате чего в ответ на этот запрос будут возвращены все строки таблицы. Так же можно изменить смысл запроса и передав специфическое значение параметра id для этого кода (для этого даже не придётся добавлять в значение параметра кавычку):

Sql-id.png

Возможность передать такое значение параметра HTTP-запроса, которое подставится в текст SQL-запроса и при подстановке изменит смысл этого запроса называется SQL injection (OWASP). Хорошую статью про SQL injection можно найти тут и еще тут.

Попробовать эксплуатировать SQL injection можно на этих уязвимых приложениях:

Фактически, SQLi это один из представителей класса уязвимостей injection, которые получаются, если в какие-то управляющие команды подставляются параметры-данные от пользователя и эти данные могут выйти из контекста, куда подставляются, перестав быть просто данными, и поменять смысл команды.