C, PHP, VB, .NET

Дневникът на Филип Петров


* Уязвимост в PHP с mod_cgid за версии <= 5.4.2

Публикувано на 04 май 2012 в раздел ОСУП.

На 3 май 2012г изтече информация за ужасяваща уязвимост, която е налична във всички версии на PHP от последните 8 години. Важи за всички версии на PHP, включително най-новата към момента 5.4.2, за която разработчиците твърдят, че оправя проблема (а не го). В тази статия ще се опитам да опиша кратка хронология и актуална информация.

Първо да успокоим (почти) всички потребители, че уязвимостта засяга само тези инсталации, които използват PHP като чист CGI или mod_cgid модул. Ако използвате PHP като Apache модул, FastCGI или suPHP, то уязвимостта не ви засяга.

В какво се състои проблемът? Както пише в новината на сайта php.net, при „някои CGI инсталации на PHP“ може да подавате командни параметри директно към php приложението ако в query string не присъства знакът „=“. Това всъщност е описано в RFC на CGI, но очевидно през 2004г. не е отчетено от разработчиците на PHP (докато например при Apache са го отбелязали много коректно) и така нещата продължават и до днес.

Един пример за възползване от уязвимостта е чрез отваряне на URL подобен на „http://www.yourwebsite.dom/phppage.php?-s“ би се извикала команда „/<път до php>/php-cgi -s /<път до файла>/phppage.php“, което от своя страна ще отпечата сорс кода на файла директно в браузъра! Разбира се това е най-грубия възможен пример и почти най-опасния. За да видите с какви параметри можете да си „играете“ пуснете „php -h“ – повечето от тях може да се използват. Тази уязвимост най-общо позволява правенето на следните „поразии“:

  • Чрез директно отпечатване на сорс кода на PHP файловете атакуващия може да открие парола за базата от данни, пътища до важни файлове, SALT кодове, да търси други налични пропуски в сигурността и т.н.;
  • Ако атакуващият има възможност да качи php файл на сървъра, то може да го изпълни, а от там да получи достъп до много пикантни възможности – запис на файлове с phishing сайтове, качване на вирус в оригиналния сайт, подмяна на файлове за download, „хакване“ на оригиналния сайт, изпращане на спам и т.н.;
  • Да се направи напълно ефективна self-DoS атака (сървъра атакува самия себе си).

Предполагам, че има и по-засукани възможности, но тези са първите, които ми дойдоха на ум. Честно казано аз лично не съм виждал по-тежка и едновременно с това лесна за използване уязвимост, като изключим ерата на „ранния IIS“, където имаше няколко подобни истории.

Сега малко хронология:

На 13.01.2012г. хора от холандския сайт eindbazen.net (последвайте връзката, за да прочетете статията от първоизточника) откриват уязвимостта по време на конференция свързана с информационната сигурност.

На 17.01.2012г. написват e-mail до security@php.net с пълна информация относно проблема. По всяка вероятност никой не обръща внимание.

На 01.02.2012г. хората отново питат екипа на PHP по e-mail с въпрос „какво става“. Тогава получават отговор, че техния доклад е препратен „до когото трябва“. Вероятно точно тогава наистина са му обърнали (някакво) внимание.

На 23.02.2012г. разработчитите се свързват обратно и потвърждават наличието на уязвимостта.

… zzz …

На 05.04.2012г. хората от блога отново питат екипа на PHP „какво става бе хора?“. Получават отговор, че „ние от PHP работим по въпроса“.

На 20.04.2012г. хората от блога пак настояват за нещо повече по въпроса, като този път са „малко по-настоятелни“. Шест дни по-късно получават информация, че е подготвен „draft advisory“.

На 02.05.2012г. екипа на PHP им пише, че „в момента изпробват кръпка (patch) и искат малко повече време, преди да я пуснат в публичното пространство“.

На 03.05.2012г. някой в екипа на PHP прави фатална грешка – без да иска маркира въпросния bug report като „публичен“, т.е. видим от всички, при това без да е дадено дори временно решение. В китайски, руски и всякакви други форуми моментално се реагира и информацията изтича в публичното пространство. Веднага „плъзват“ ботове, които правят опити за намиране на уязвими сайтове. Колко от намерените такива са хакнати остава отворен въпрос.

Още същия ден екипа на PHP реагира и изважда версии 5.3.12 и 5.4.2, които включват въпросния „patch, който все още се тества“, но промотиран като „работещ“. Оказва се, че тази кръпка никак НЕ работи, т.е. не работи както се очаква. Сайтовете работещи на PHP-CGI и mod_cgid все още продължават да са уязвими при определени условия (кръпката не отчита възможността за вмъкване на whitespace преди query string). Към момента (05.05.2012г.) единственото привидно правилно работещо решение е налично на eindbazen.net.

Използването на PHP като CGI модул (всеки скрипт се изпълнява като отделен процес) се счита за по-сигурния начин за управление при многопотребителски системи. Традиционният подход с mod_cgid обаче се счита за остарял и се използва рядко (но стари сървъри може би продължават да го използват). В днешно време предимно се се използват suPHP, FastCGI или PHP-FRM.

Ако все пак имате сайт на споделен хостинг сървър, който използва подобна уязвима инсталация, то едва ли имате достъп да слагате подобни „third party“ кръпки. Разбира се, че администраторите биха решили проблема (ако са достатъчно отговорни) временно, докато излезе истински работещ официален patch. Ако обаче администраторите са безотговорни (а такива има много – университетски сървъри, които са зарязани някъде незнайно в коя зала; сървър в министерство, зарязан също незнайно къде и все такива подобни примери), то се намирате пред реално изпитание. Най-бързото работещо решение на проблема е следното – създайте .htaccess файл, който филтрира заявките с mod_rewrite по следния начин (взех го от коментарите в блога на eindbazen):

RewriteEngine on
RewriteCond %{QUERY_STRING} ^[^=]*$
RewriteCond %{QUERY_STRING} %2d|\- [NC]
RewriteRule .? - [F,L]

Обобщение: Е не очаквах точно от екипа на PHP подобни безобразия. Не толкова, че се е получил подобен „бъг“, а по-скоро за отношението към него.

Редакция 08.05.2012г. – от екипа на PHP извадиха нова версия 5.4.3, в която уязвимостта е премахната коректно.

 



Добави коментар

Адресът на електронната поща няма да се публикува


*