ANTICHAT.XYZ    VIDEO.ANTICHAT.XYZ    НОВЫЕ СООБЩЕНИЯ    ФОРУМ  
Баннер 1   Баннер 2
Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей. Здесь обсуждаются безопасность, программирование, технологии и многое другое. Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
Вернуться   Форум АНТИЧАТ > ИНФО > Статьи > Авторские статьи
   
 
 
Опции темы Поиск в этой теме Опции просмотра

Уязвимое место сессий или несколько слов о синхронизации
  #1  
Старый 28.08.2008, 17:08
desTiny
Reservists Of Antichat - Level 6
Регистрация: 04.02.2007
Сообщений: 1,152
Провел на форуме:
3008839

Репутация: 1502


По умолчанию Уязвимое место сессий или несколько слов о синхронизации

INTRO

Сейчас я опишу грабли, на которые чуть сам не наступил. А они могли бы привести к серьёзным последствиям...

BODY

(показываю на примере PHP)
Пусть у нас есть код, в котором используются сессии. Пусть в сессиях хранится, скажем, уровень доступа пользователя - число, которое может увеличиться, если пользователь что-то сделает. Этот же уровень доступа хранится в БД. Пусть пользователю для увеличения уровня доступа надо ответить на вопрос.
Можно написать такой код, выполняющий соответствующее действие:

1-ый косяк:
PHP код:
// при логине аналогично level берётся из БД.

session_start();
// проверка существования сессии:
(isset($_SESSION['id'])) or die("who r u?");
$answer //из бд получаем ответ к уровню $_SESSION['level'];
if ($_GET['answer'] === $answer){
  print 
"ok";
  
$_SESSION['level']++;
  
//коннект к БД
  
mysql_query("Update `auth` set level=level+1 where id=".$_SESSION['id']);
  
//отключение от БД

2-ой косяк:
PHP код:
// при логине аналогично level берётся из БД.

session_start();
// проверка существования сессии:
(isset($_SESSION['id'])) or die("who r u?");
$answer //из бд получаем ответ к уровню $_SESSION['level'];
if ($_GET['answer'] === $answer){

  print 
"ok";
  
$level = ++$_SESSION['level'];
  if (
$level === $maximum_level){
    
//выполняем секретный код для очень крутых пацанов
  
}

//лирическое отступление, положенное в таких случаях
Казалось бы - всё правильно, но... это не так.
//лирическое отступление закончилось

//Пояснение к первому косяку
Что можно сделать в таком случае? Пусть мошенник (пользуясь именами от Брюса Шнаера) Ева знает ответ на первый вопрос. Сейчас я покажу, что ей этого достаточно, чтобы попасть на любой уровень. Для этого она открывает несколько сессий с первым уровнем (в банальном случае - несколькими броузерами), и в каждой сессии отвечает на вопрос. При каждом ответе инкрементируется как уровень в сессии, так и уровень в БД. Сессии друг от друга не зависят, зато БД - общая! Тем самым мы неограниченное количество раз переходим на следующий уровень.
////Фикс 1
Фикс не очень хороший, ибо при случайном использовании двух сессий (открыл человек двумя броузерами, потом запутался, заново ответил на уже пройденный вопрос) может привести к нежелательному откату назад.
PHP код:
// при логине аналогично level берётся из БД.

session_start();
// проверка существования сессии:
(isset($_SESSION['id'])) or die("who r u?");
$answer //из бд получаем ответ к уровню $_SESSION['level'];
if ($_GET['answer'] === $answer){
 
session_start();
  print 
"ok";
  
$level=++$_SESSION['level'];
  
//коннект к БД
  
mysql_query("Update `auth` set `level`='$level' where id=".$_SESSION['id']);
  
//отключение от БД

////Конец фикса 1
////Фикс 2
PHP код:
// при логине аналогично level берётся из БД.

session_start();
// проверка существования сессии:
(isset($_SESSION['id'])) or die("who r u?");
$bdlev //из бд получаем уровнь пользователя $_SESSION['id'];
($bdlev===$_SESSION['level']) or die("Relogin please!");
$answer //из бд получаем ответ к уровню $_SESSION['level'];
if ($_GET['answer'] === $answer){
  
session_start();
  print 
"ok";
  
$level = ++$_SESSION['level'];
  
//коннект к БД
  
mysql_query("Update `auth` set `level`='$level' where id=".$_SESSION['id']);
  
//отключение от БД

////Конец фикса 2
//Пояснение к первому косяку кончилось
//Пояснение ко второму косяку
Тут аналогичная ошибка, только более общий случай. Мы можем таким образом многократно вызвать один и тот же код, который мог планироваьтся единожды - к примеру, запись в таблицу результатов.
////Фикс
Фикс аналогичен Фиксу 2 из 1-го косяка - надо СИНХРОНИЗИРОВАТЬ данные в БД и сессии.
////Фикс кончился
//Пояснение ко второму косяку кончилось

OUTRO
Эх, сколько же ошибок может спровоцировать неправильная синхронизация и распараллеливание! Притом ошибок - трудноисправимых.

GREETZ
Они сами знают, кому

(с) desTiny, 2008
__________________
Bedankt euch dafür bei euch selbst.

H_2(S^3/((z1, z2)~(exp(2pi*i/p)z1, exp(2pi*q*i/p)z2)))=Z/pZ

Последний раз редактировалось desTiny; 11.09.2008 в 23:19..
 
Ответить с цитированием
 



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Books PHP FRAGNATIC PHP, PERL, MySQL, JavaScript 186 21.02.2010 02:41
Хакер и закон! SladerNon Болталка 17 12.11.2009 09:42
Хакеры и кракеры или "Что такое хорошо и что такое плохо?" foreva Чужие Статьи 12 09.02.2008 12:26
Обнаружение Sql инъекций и Css атак k00p3r Чужие Статьи 0 12.06.2005 20:43
Ловушка для взломщика k00p3r Чужие Статьи 0 08.06.2005 16:48



Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


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




ANTICHAT.XYZ