Перейти к содержимому

Welcome to 100NT форум администраторов игровых серверов
Register now to gain access to all of our features. Once registered and logged in, you will be able to create topics, post replies to existing threads, give reputation to your fellow members, get your own private messenger, post status updates, manage your profile and so much more. If you already have an account, login here - otherwise create an account for free today!

Переключатель чата Чат

Добро пожаловать в чат 100NT
Horus : (17 May 2012 - 01:17 PM) гуф умер, а форум отжил свое.
Inkognit0 : (17 May 2012 - 01:08 PM) форум умер?
Изменить размер окна сообщений

Взламываем Сервера С Stressweb

* * * - - 2 Голосов

  • Вы не можете ответить в тему
Сообщений в теме: 26

#1
Михаил(zenn)

    Продвинутый пользователь

  • Администраторы
  • 6827 сообщений
  • ГородКерчь
Reputation: 355
Собственно, набрел случайно на данный кусочек кода. Очень удобное место для проведения +union+select запроса.
Адрес уязвимости: /engine/forget.php
Проверена на: 8.0, 8.0+
Уязвимый участок кода:
elseif (isset($_POST["submit_lost"]) && isset($_POST["step2"]))
{
    $lost_l2answer = $_POST["lost_l2answer"];
    $lost_l2login = $_POST["step2"];
    list($lost_l2answer_db, $_l2email) = $ldb->fetch_array($ldb->query("SELECT `l2answer`,`l2email` FROM `accounts` WHERE `login`='{$lost_l2login}' LIMIT 0,1"));
    if ($lost_l2answer != $lost_l2answer_db)
    {
        $error_lost = "<div class='error'>Обнаружены следующие ошибки:<br>Ответ на секретный вопрос не верный!</div>";
    }
    else
    {
        $lost_l2answer = false;
        $tmp_pass = "user" . _code_generate(6);
        $tmp_pass_encode = pass_encode($tmp_pass);
        $ldb->query($ldb->_parse_query($qList[$l2db_ls]["setPassword"], array("pass" => $tmp_pass_encode, "login" => $lost_l2login)));
        if ($ldb->affectedrows() == 1)
        {
            if ($config["site"]["forget"]["method"] == 1 && $_l2email != "null@null" && $_l2email != "")
            {
                $_host = $_SERVER['HTTP_HOST'] ? $_SERVER['HTTP_HOST'] : @getenv('HTTP_HOST');
                $mail_subject = "Восстановление пароля";
                $mail_message = <<<HTML
Уважаемый {$lost_l2login},

Вы сделали запрос на получение забытого пароля на сайте http://{$_host} 
Однако в целях безопасности все пароли хранятся в зашифрованном виде, поэтому мы не можем сообщить вам ваш старый пароль, поэтому для Вас был сгенерирован новый пароль: 

------------------------------------------------
Ваш логин и пароль на сайте:
------------------------------------------------

Логин: {$lost_l2login}
Пароль: {$tmp_pass}

После авторизации на сайте вы сможете изменить данный пароль на любой другой.

С уважением,

Администрация http://{$_host}
HTML;
                $mail_subject = "Восстановление пароля";
                $mail_message = "Здраствуйте! \n\r Согласно Вашему запросу для Вас был сгенерирован новый пароль.\n\rДля входа на сайт используйте следующие данные: \n\r Логин: {$lost_l2login} \n\r Пароль: {$tmp_pass} \n\r После авторизации на сайте вы сможете изменить данный пароль на любой другой. \n\r\n\r С уважением администрация сервера http://" . $_host . "";
                if (send_mail($_l2email, $lost_l2login, "{$config["site"]["reg"]["email"]}", $mail_subject, $mail_message))
                {
                    $error_lost = "<div class='noerror'>На ваш E-Mail адрес, указанный при регистрации, было отправлено уведомление с новым паролем.</div>";
                }
                else
                {
                    $error_lost = "<div class='error'>Обнаружены следующие ошибки:<br>Письмо не было отправлено! Попробуйте позже или обратитесь к Администрации.</div>";
                }
            }
            else
            {
                $error_lost = "<div class='noerror'>Уважаемый посетитель! Согласно Вашему запросу для Вас был сгенерирован новый пароль. Для входа на сайт используйте следующие данные:<br><b>Логин:</b> {$lost_l2login}<br><b>Пароль:</b> {$tmp_pass}<br>После авторизации на сайте вы сможете изменить данный пароль на любой другой.</div>";

            }
        }
        else
        {
            $error_lost = "<div class='error'>Ошибка базы данных! Попробуйте позже.</div>";
        }
    }
}
Уязвимая переменная(не фильтруется) :
    $lost_l2login = $_POST["step2"];
Используется в SQL-запросе:
    list($lost_l2answer_db, $_l2email) = $ldb->fetch_array($ldb->query("SELECT `l2answer`,`l2email` FROM `accounts` WHERE `login`='{$lost_l2login}' LIMIT 0,1"));
Как применить? Я думаю это не составит труда нарушить целостность данного запроса.
П.с. для постояльцев 100НТ фильтр:
[hide posts=50 thank=1]
$lost_l2login = $ldb->safe($_POST["step2"]);
[/hide]

#2
rwx

    Продвинутый пользователь

  • Пользователи
  • 134 сообщений
  • ГородМариуполь
Reputation: 76
Нашел вроде бы рабочий "недочет":
- Возможность телепорировать чужих игроков в город :)

Часть кода в файле profile.php
<?php
// ...
/**************************
* teleport
**************************/
// ...
if (isset($_POST["teleport"]))
{
	$tp_char_id = $_POST["charid"];
	$_server = $_POST["server"];
	$town = $_POST["town"];
	$tp_error = "";
	if ($l2db["gameserver"][$_server]["teleport"]["allow"] == 1)
	{
		$l2db_gs_tp = $versionList[$l2db["gameserver"][$_server]["version"]];
		//include_once INC_DIR . '/l2db/l2j_' . $l2db_gs_tp . '.php';

		$lastTeleport_data = $gdb[$_server]->fetch_array($gdb[$_server]->query($gdb[$_server]->_parse_query($qList[$l2db_gs_tp]["getLastTeleport"], array("charID" => $tp_char_id))));

		if (($lastTeleport_data["lastteleport"] + 60 * $l2db["gameserver"][$_server]["teleport"]["time"]) > time())
		{
			$tp_error = "<div class='error'>До следующего использования телепорта осталось " . date("i мин. s сек.", ($lastTeleport_data["lastteleport"] + ($l2db["gameserver"][$_server]["teleport"]["time"] * 60)) - time()) . "</div>";
		}
		if (intval($lastTeleport_data["online"]))
		{
			$tp_error = "<div class='error'>Персонаж <b>{$lastTeleport_data["char_name"]}</b> находится онлайн.</div>";
		}
		if (intval($lastTeleport_data["in_jail"]))
		{
			$tp_error = "<div class='error'>Персонаж <b>{$lastTeleport_data["char_name"]}</b> находится в тюрьме.</div>";
		}
		if (intval($lastTeleport_data["accesslevel"] < 0))
		{
			$tp_error = "<div class='error'>Персонаж <b>{$lastTeleport_data["char_name"]}</b> забанен.</div>";
		}

		if ($tp_error == "")
		{
			$gdb[$_server]->query($gdb[$_server]->_parse_query($qList[$l2db_gs_tp]["setTeleport"], array("x" => $coordinats[$town]["x"], "y" => $coordinats[$town]["y"], "z" => $coordinats[$town]["z"], "lastteleport" => time(), "charID" => $tp_char_id)));
			if ($gdb[$_server]->affectedrows() > 0)
			$tp_error = "<div class='noerror'>Персонаж <b>{$lastTeleport_data["char_name"]}</b> успешно телепортирован в <b>" . $coordinats[$town]['name'] . "</b></div>";
			else
			$tp_error = "<div class='error'>Ошибка базы данных</div>";
		}

	}
	else
	{
		$tp_error = "<div class='error'>Возможность телепортации на этом сервере отключена администратором</div>";
	}
	$error_msg = $tp_error;
}
// ...
?>
Чего здесь не хватает? Правильно! Не хватает проверки на принадлежность игрока к аккаунту.
Написав простенький скриптик, который бы формировал и остылал специальные GET и POST запросы, можно нервировать весь сервер :rolleyes:

P.S: Не проверял. Должно работать.

Сообщение отредактировал rwx: 25 August 2010 - 17:05


#3
rwx

    Продвинутый пользователь

  • Пользователи
  • 134 сообщений
  • ГородМариуполь
Reputation: 76
Там ещё и $tp_char_id не фильтруется:
$tp_char_id = $_POST["charid"];
// ...
$lastTeleport_data = $gdb[$_server]->fetch_array($gdb[$_server]->query($gdb[$_server]->_parse_query($qList[$l2db_gs_tp]["getLastTeleport"], array("charID" => $tp_char_id))));
// ...
Используется в SQL-Заросе:
SELECT `char_name`,`online`,`accesslevel`,`in_jail`,`lastteleport` 
FROM `characters` 
WHERE `obj_Id`='{charID}'",
* {charID} = $tp_char_id = $_POST["charid"];

Сообщение отредактировал rwx: 25 August 2010 - 17:17


#4
Михаил(zenn)

    Продвинутый пользователь

  • Администраторы
  • 6827 сообщений
  • ГородКерчь
Reputation: 355
Да смотрю если нормально пошерстить можно найти дырочки и не одну.
$tp_char_id = $_POST["charid"];
Это серьезно тоже ))
Фикс:
$tp_char_id = (int)$_POST["charid"];
Дерзайте ) B)

#5
UltraKill

    Продвинутый пользователь

  • Пользователи
  • 385 сообщений
Reputation: 125

Просмотр сообщенияzenn (25 August 2010 - 20:03) писал:

Да смотрю если нормально пошерстить можно найти дырочки и не одну.
$tp_char_id = $_POST["charid"];
Это серьезно тоже ))
Фикс:
$tp_char_id = (int)$_POST["charid"];
Дерзайте ) B)
Ну и где ты это нарыл? ))) в какой версии ?

#6
Hop6

    Продвинутый пользователь

  • Пользователи
  • 1858 сообщений
  • ГородМагадан
Reputation: 155

Просмотр сообщенияUltraKill (25 August 2010 - 21:20) писал:

Ну и где ты это нарыл? ))) в какой версии ?
8+ и ниже
Изображение

#7
rwx

    Продвинутый пользователь

  • Пользователи
  • 134 сообщений
  • ГородМариуполь
Reputation: 76
Прошу прощения за up.

Stress Web 10.08
---
Открываем: engine\robokassa.php,
Смотрим код:
// ...
        if ((isset($_POST['InvId']) && !empty($_POST['InvId'])) && (isset($_POST['OutSum']) && !empty($_POST['OutSum'])) && (isset($_POST["Shp_lid"]) && $_POST["Shp_lid"] != ''))
        {
            $rb_lid = intval($_POST["Shp_lid"]);
            if (isset($ldb[$rb_lid]))
            {
                // чтение параметров
                $rb_out_summ = $_POST["OutSum"];
                $rb_inv_id = $_POST["InvId"];
                $rb_shp_rnd = $_POST["Shp_rnd"];
// ...
                    $QUERY = "SELECT * FROM `stress_robokassa` WHERE `id`='{$ldb[$rb_lid]->Safe($rb_inv_id)}' AND `InvId`='{$rb_shp_rnd}' AND stage='S'";
// ...
                            $ldb[$rb_lid]->Query("UPDATE `stress_robokassa` SET `stage`='P',`comment`='Покупка оплачена, но не доставлена' WHERE `id`='{$ldb[$rb_lid]->Safe($rb_inv_id)}' AND `InvId`='{$rb_shp_rnd}'");
// ...
                                $ldb[$rb_lid]->Query("UPDATE `stress_robokassa` SET `stage`='F',`success`='1',`comment`='Покупка доставлена' WHERE `id`='{$ldb[$rb_lid]->Safe($rb_inv_id)}' AND `InvId`='{$rb_shp_rnd}'");
// ...
Обращаем внимание на то, что $rb_shp_rnd не фильтруется... м Магия? :blink:

Сообщение отредактировал rwx: 17 September 2010 - 21:16


#8
rwx

    Продвинутый пользователь

  • Пользователи
  • 134 сообщений
  • ГородМариуполь
Reputation: 76
узнай что должно передаваться в переменную $rb_shp_rnd (Скорее всего число)

если число:
$rb_shp_rnd = intval($_POST["Shp_rnd"]);

если число с плавающей точкой:
$rb_shp_rnd = floatval($_POST["Shp_rnd"]);

если набор (английские буквы + цифры):
$rb_shp_rnd = ((ereg("[a-zA-Z0-9]", $_POST["Shp_rnd"]) ? $_POST["Shp_rnd"] : "");

Сообщение отредактировал rwx: 19 September 2010 - 20:12


#9
aninya

    Кавайная няка

  • Пользователи
  • 891 сообщений
  • ГородВеликие Луки
Reputation: 105
ereg что это такое?) этой функции не существует only
preg_match('\w+',$_POST["Shp_rnd"]) ? $_POST["Shp_rnd"] : "")


#10
57486

    Новичок

  • Пользователи
  • 2 сообщений
Reputation: 0
А може тктото по подробнее обяснить что делать нада? Полный гайд написать ато непонятно((

#11
x_M0use

    It`s my Life

  • Пользователи
  • 1504 сообщений
  • ГородЖоржия
Reputation: 222
что именно не понятно, уточняй
Изображение

#12
Akumu

    Продвинутый пользователь

  • Старший модератор
  • 1372 сообщений
Reputation: 1168

Просмотр сообщенияrwx (19 September 2010 - 20:12) писал:

если набор (английские буквы + цифры):
$rb_shp_rnd = ((ereg("[a-zA-Z0-9]", $_POST["Shp_rnd"]) ? $_POST["Shp_rnd"] : "");

Для этого есть ctype_alnum()
Изображение

#13
rwx

    Продвинутый пользователь

  • Пользователи
  • 134 сообщений
  • ГородМариуполь
Reputation: 76

Просмотр сообщенияAkumu (22 September 2010 - 16:02) писал:

Для этого есть ctype_alnum()
у) вылетело из головы :lol:

#14
NiceSleep

    Продвинутый пользователь

  • Пользователи
  • 674 сообщений
  • ГородУкраина - Рівне
Reputation: 64
Для всех кто не понимает о чем в теме идет речь просьба обходить тему стороной, а не просить писать вам мануалы.

#15
YK_Sirius

    Продвинутый пользователь

  • Пользователи
  • 581 сообщений
Reputation: 28

Просмотр сообщенияAkumu (22 September 2010 - 16:02) писал:

Для этого есть ctype_alnum()
Но не у всех может быть расширение Ctype.
[img width=300 height=16]http://img80.imageshack.us/img80/1897/lineage5.png[/img]
Нікотинамідаденіндинуклеотидфосфат - Никотинамидадениндинуклеотидфосфат





Количество пользователей, читающих эту тему: 1

0 пользователей, 1 гостей, 0 скрытых пользователей