} ?>
(структура таблицы users: (id int not null primary key auto_increment, login varchar(255), password varchar(255) )
Вроде все как надо - если пасс и логин верные - разрешен вход, иначе запрещен. Но попробуем написать в форме login - root, password - ' OR 1=1/*
Нам будет разрешен доступ (если юзер root, конечно, существует). Назберемся, почему. Попробуем составить запрос, который отправляется в БД:
select * from users where login='root' and password=' [' OR 1=1/*] '
В квадратные скобки я взял введенный пароль. Итак, запрос сводится к:
select * from users where login='root' and password='' OR 1=1/*'
Как видим, получили совсем не то, что ожидали. Т.к. условие (password='' OR 1=1) всегда истинно, то нас всегда будут пускать, независимо от пароля root'а.
Для устранения данной "дыры" следует либо включить директиву magic_quotes_gpc (сделать ее равной On) в файле php.ini, либо, если нет такой возможности, добавить следущие строки после if(isset($_POST['go'])){ :
Code:
$_POST['login']=str_replace("'", "", $_POST['login']);
$_POST['login']=str_replace("\"", "", $_POST['login']);
$_POST['password']=str_replace("'", "", $_POST['password']);
$_POST['password']=str_replace("\"", "", $_POST['password']);
III. Including
Эта уязвимость существует из-за нефильтрования скриптом параметров,
переданных в процедуру открытия файла. Пример:
Code:
if(isset($_GET['module']))
include("modules/".$_GET['module']);
?>
Тут мы
подключаем модуль из каталога modules. Но кто сказал, что именно из этого
каталога? Попробуем вызвать сценарий так:
including.php?module=../../../../../../../../etc/passwd
Файл будет выведен. Разберемся, что произошло. Мы подключали вроде скрипт из каталога modules, а реальный путь оказался таким:
modules/../../../../../../../../etc/passwd , что равносильно /etc/passwd.
Таким образом, атакующий может читать файлы в системе (естественно, если у демона httpd хватит привиллегий на чтение).
Защита от такой напасти - та же функция str_replace(), которой можно "вырезать" символы /
IV. null-byte poison
Данная уязвимость не используется отдельно, а чаше вместе с другими - including и sql-injection. Поясню в чем тут дело. А дело в том, что интерпретатор языка php написан на C, а в С нулевой байт (символ с кодом 0 - \0) считается ограничителем строки. Для примера возьмем все тот же сценарий из инклудинга и слегка модифицируем его:
Code:
if(isset($_GET['module']))
include("modules/".$_GET['module'].".php");
?>
Он теперь добавляет в конец пути расширение - .php
Т.е. вариант ../../../../../../etc/passwd не прокатит - он будет искать /etc/passwd.php, а не /etc/passwd. Но мы не отчаиваемся и вспоминаем, что байт %00 ограничивает строку, таким образом, у нас есть возможность ее "обрезать" после имени файла и убрать расширение .php
Смотрим: including.php?module=../../../../../../etc/passwd%00
Voila! Все прекрано работает и мы видим содержимое /etc/passwd.
Замечание: при включенной директиве magic_quotes_gpc ничего работать не будет - php добавит \ перед 0-байтом и выйдет вот что:
Цитата:
Warning: main(modules/../../../../../../etc/passwd\0.php) [function.main]: failed to open stream: No such file or directory in /home/great/www/including.php on line 3
Warning: main() [function.include]: Failed opening 'modules/../../../../../../etc/passwd\0.php' for inclusion (include_path='.') in /home/great/www/including.php on line 3
[/qoute]
Тут возможна только xss, а инклудинг идет лесом
V. PHP-including
Включение своего php-кода при использовании eval() и подобных ей.
Пример:
[i]Code:
if(isset($_GET['action']))
eval($_GET['action']."();");
function one()
{
echo "Hi 1!\n";
}
function two()
{
echo "Hi 2\n";
}
?>
Вроде мы хотели, чтобы пользователь выбрал действие - one или two и вызвалась соотв. функция. Но мы попробуем сценарий вызвать так:
phpinc.php?action=system('id');//
Таким образом, выпонится команда id на сервере. Нам даже не помеха magic_quotes_gpc, которая экранирует кавычки - достаточно изменить запрос так:
phpinc.php?action=system($_GET['cmd']);//&cmd=id
Однако нам помешает другая "вредная" директива - Safe_mode. Она запрещает функцию system() и ряд других.
Зщита от данной уязвимости - полный отказ от использования eval()
VI. Remote Command Execution в перл-скриптах в open()
Этот пример будет на перле, т.к. бага существует именно с скриптах, написанных на нем (замечу: в СКРИПТАХ - из-за криворукости кодера, интерпретатор перла тут не при чем).
Сначала пойдет теоритическая часть
В перле для открытия файлов существует функция open().
Ее используют так:
open(DESCRIPTOR, "filename"); ,
где DESCRIPTOR - создаваемый дескриптор файла,
а filename - имя файла. При чем, если указать просто имя вроде "database.dat", то файл открется для чтения. Если указать в виде ">file.txt", то для записи, ">>file" - для добавления. А теперь самое интересное - если указать "|id", то откроется канал (pipe) с указанной программой (id). Таким образом, можно выполнять команды на сервере.
А теперь пример уязвимого скрипта:
Code:
#!/usr/bin/perl
use CGI qw( :standard ); # подключаем библиотеку CGI
print header; # выводим заголовлок (Content-type)
open(FILE, param('file')); # открываем файл, имя файла - переданный параметр file
while($str=) # читаем из файла. Операция означает: прочесть строку из файла
# она возвращает false, когда подошел конец файла, таким образом этим циклом while мы обходим весь файл
{
print $str; # выводим прочитанное
}
close(FILE); # закрываем дескриптор
Я специально не стал сокращать и писать вроде while(){print;} , дабы не запутать не знающих этого языка. Специально для них даны комментарии (они начинаются с #, кроме первой строки - там указан путь к интерпретатору перла).
А мы же попробуем вызвать сценарий так:
open.pl?file=|id
И у нас вместо файла откроется канал с процессом id, и результаты будут выведены на экран.
Последствия: исполнение любых команд (в пределах привиллегий демона httpd) на сервере.
Защита - фильтрование | в параметрах.
На этом позволю себе откланяться. Не серчайте сильно, если что упустил
Great (cribble[at]mail.ru, icq# 893-894), 16.11.2005
ВНИМАНИЕ! Автор статьи не несет ответственности за какое-либо использование данного материала в незаконных целях и за прочиненный этим вред!
Great (02.12.05, 22:01:02)
Совсем забыл, сорьки. Уязвимость php-including так же есть и в функции preg_replace($mask,$replacement,$string). Если указан модификатор /e, то после замены параметр $replacement будет расценен как рнр-код и выполнен интерпретатором. Таким образом поимели phpBB 2.0.15
Автор: Great