![]() |
По мотивам https://krober.biz/?p=3306 (веб-архив), с печальным выводом:
Цитата:
Некоторые PHP разработчики, за каким-то хреном, используют эмуляцию почившего режима Register Globals (RG). Выглядеть это может по разному: PHP код:
Понятное дело, что при вайтбоксе оно нам и даром не нужно, у нас же всё как на ладони. Но вот при блекбоксе пых приложух, фишечка может очень сильно помочь задетектить такой вот своеобразный RG. Соответственно, тут всплывают все прелести атак типа: Код:
Code:Код:
Code:Код:
Code:Парочка примеров: Цитата:
Цитата:
|
Для тех, кто любит автоматизацию, плагин для Nessus, который определяет наличие такой ситуации по наличию в заголовках или теле ответа характерного текста
[CODE] Code: # Pseudo register globals detection include("compat.inc"); if(description) { script_id(10797109); script_version("1.0"); script_cvs_date("$Date: 2019/12/19 13:37:00 $"); script_name(english: "Pseudo Register Globals Detection"); script_set_attribute(attribute: "synopsis", value: "Possible pseudo register globals behavior was detected on the remote host."); script_set_attribute(attribute: "description", value: "Possible pseudo register globals behavior was detected on the remote host."); script_set_attribute(attribute: "solution", value: "Check existing source code. Consider rewriting source code without usage of constructions like: extract($_GET), parse_str($_SERVER['QUERY_STRING']) , etc..."); script_set_attribute(attribute: "see_also", value: "https://antichat.com/threads/474727/"); script_set_attribute(attribute: "risk_factor", value: "Low"); script_set_attribute(attribute: "plugin_publication_date", value: "2019/12/19"); script_set_attribute(attribute: "plugin_type", value: "remote"); script_end_attributes(); script_summary(english: "Reports if response with code 500 occurs upon sending '/?this=abc' request. Additional checks should be made manually."); script_category(ACT_GATHER_INFO); script_copyright(english: "This script is Copyright (C) Kaimi (https://kaimi.io)"); script_family(english: "CGI abuses"); script_dependencie("webmirror.nasl", "DDI_Directory_Scanner.nasl"); script_exclude_keys("Settings/disable_cgi_scanning"); script_require_keys("Settings/enable_web_app_tests"); script_require_ports("Services/www"); script_timeout(1800); exit(0); } include("audit.inc"); include("global_settings.inc"); include("misc_func.inc"); include("http.inc"); app = "PHP"; port = get_http_port(default: 80); dirs = list_uniq(make_list(cgi_dirs(), get_kb_list("www/" + port + "/content/directories"), "")); found_list = make_list(); found_ctr = 0; foreach dir (dirs) { path = dir + '/?this=abc'; res = http_send_recv3( method : "GET", port : port, item : path ); if(isnull(res)) continue; if ( # Check headers first string eregmatch(pattern: '500 Internal Server Error', string: res[0], icase: TRUE) || # Check body eregmatch(pattern: 'Internal Server Error', string: res[2], icase: TRUE) ) { found_list[found_ctr] = path; found_ctr++; } } if(found_ctr > 0) { report = NULL; if (report_verbosity > 0) { report += '\nNessus was able to detect a suspicious behavior by the following paths:\n'; report += '\n'; for (i = 0; i |
Пользуясь случаем, рассмотрим применение кейса на реальном примере, который был раскручен с его помощью до RFI (Remote File Include).
Для локального воспроизведения нам понадобится WordPress 5.5, а так же плагин WP-Live Chat by 3CX версии 9.0.17, который на текущий момент имеет 50 тысяч активных установок. https://i.imgur.com/DDr3YEd.png Запускать всё это дело будем на стенде с Debian 9, веб-сервером Apache/2.4.25 и PHP 7.3.15 с включенным выводом ошибок (display_errors = On). https://i.imgur.com/ircGyq9.png https://i.imgur.com/aoUXR7W.png После нехитрой установки WP и плагина, вычищаем все админские куки и следуем на главную страницу нашего новоиспечённого блога. https://i.imgur.com/p2ISIKI.png Следующим шагом, проверяем теорию описанную в первом посте, при помощи простейшего теста, с подставлением GET параметра "?this=1". https://i.imgur.com/3AOcV6s.png Получаем фатальную ошибку, с раскрытием локальных путей, а так же номером строки где она была вызвана. Далее открываем файл в любимом текстовом редакторе и находим это место. Наш кейс всплывает в функии evaluate_php_template: ./wp-live-chat-support/includes/helpers/utils_helper.php: PHP код:
Если скрипт упал в этом месте, значит пользовательский ввод попадает в $args. Для того чтобы убедиться в этом, поищем в коде плагина места где используется эта функия и в свою очередь обнаружим другую функцию - load_view: ./wp-live-chat-support/includes/wplc_base_controller.php: PHP код:
https://i.imgur.com/dqkozcW.png Или так: https://i.imgur.com/klnpciG.png https://i.imgur.com/pTU8jPD.png Теперь давайте разбираться как так произошло https://i.imgur.com/mDjNNsV.png https://i.imgur.com/QpczfHJ.png https://i.imgur.com/vupK3sS.png На первом скрине видим, что load_view() в плагине используется повсеместно, для отображения различных страниц темплейтов, с предустановленными зарание переменными и юзеринпутом. Важным аргументом для неё является $filepath, который, как видно, при вызове жёстко прописывается и повлиять на него никак нельзя. Далее, подготавливаются некие переменные, для подключаемого шаблона, и массив с этими переменными объединяется с $_GET. И через несколько строк, $view_data, с пользовательскими гет данными, отправляется в функцию evaluate_php_template(), куда так же первым аргументом передаётся захардкоженный $filepath. В следующем методе аргументы $args, возможностями переменных переменных глобализуются или переназначаются (неявно) в контексте нашей функции, вероятно, для заполнения подключаемого темплейта. Всё бы ничего, но мы передав ?path=/etc/passwd сделали так, что один из ключей перебираемого массива $args является "path", что переназначит значение, казалось бы жёстко прописанной, переменной $path переданой заранее! $this is the end |
| Время: 00:42 |