ANTICHAT.XYZ    VIDEO.ANTICHAT.XYZ    НОВЫЕ СООБЩЕНИЯ    ФОРУМ  
Баннер 1   Баннер 2
Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей. Здесь обсуждаются безопасность, программирование, технологии и многое другое. Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
Вернуться   Форум АНТИЧАТ > ИНФО > Статьи > Авторские статьи
   
 
 
Опции темы Поиск в этой теме Опции просмотра

Пишем Php скрипты без багов
  #1  
Старый 16.09.2007, 18:24
Аватар для Dr.Z3r0
Dr.Z3r0
Leaders of The World
Регистрация: 06.07.2007
Сообщений: 246
Провел на форуме:
2030482

Репутация: 1796
По умолчанию Пишем Php скрипты без багов

Пишем PHP скрипты без багов.

Автор: Dr.Z3r0
Написанно специально для antichat.ru

0.INTRO

Для начала хотелось бы рассказать вкратце о чем эта статья. В этой статье будут описаны все функции неверное использование которых может привести к уязвимостям в ваших скриптах, также будут рассмотрены функции которые могут защитить от уязвимостей, к каждому пункту буду стараться приводить самый простой пример. Здесь не будут рассмотрены любые шаманства с php.ini, .htacsess-ами и прочее так это совсем другая тема.

Для усвоения данной информации вам бы не помешало бы иметь следующее: что нибудь в голове (имеется ввиду серое вещество, а не пустота ;) ), знание PHP и желательно прямые руки.

Ну что же начнем…

1.SQL injection

Опасные функции:
mysql_query() mssql_query() и др.

Описание:
Сейчас многие скрипты будь то форумы, гостевые, портальные системы в своем большинстве при работе используют базы данных (Чаще всего MySQL, MsSQL, PostgreSQL, OracleSQL). Принцип этой работы основывается на запросах к этой БД. Что то типа SELECT * FROM tables WHERE column='[value]'. Так вот SQL injection это бага при котором взломщиком модифицируется оригинальный запрос к БД таким образом чтобы при выполнении запроса была выведена нужная ему информация из БД. Рассмотрим пример:
Код:
<?php
...
mysql_query("SELECT * FROM news WHERE id='".$_GET['id']."'");
...
?>
Ну вообщем по идее разработчика запросом должны возвращаться все записи из таблицы где их значение в столбце id равно переменной $_GET['id']. Но переменная $_GET['id'] не проходит фильтрации на содержание одинарной кавычки что дает взломщику возможность модифицировать этот запрос скажем до вот такого:
Код:
SELECT * FROM news WHERE id='-1' UNION SELECT 1,login,password,4,5,6 FROM admins /* '
Вообще на тему SQL injection я уже писал статью http://forum.antichat.ru/showthread.php?p=407239

Защита:
Использовать функцию mysql_escape_string() Пример:
Код:
<?php
...
mysql_query("SELECT * FROM news WHERE id='".mysql_escape_string($_GET['id'])."'");
...
?>
Также стараться не использовать оператор LIKE без фильтрации символов % и _ в тех местах где это не нужно. Не использовать в запросах переменные без обрамляющих их кавычек.

2. PHP-including

Опасные функции:
include() include_once() require() require_once()

Описание:
Данные функции позволяют включить в тело выполняемого скрипта какой нибудь файл с php-кодом. Отсутствие фильтрации либо плохая фильтрация символов может привести к так называемому инклудингу файлов. Пример:
Код:
<?php
...
include('modules/'.$_GET['mod'].'.php');
...
?>
Отсюда видно что переменная $_GET['mod'] вставляется в параметр без фильтрации что само по себе дает инклудинг файлов с расширением .php а при отсутствии фильтрации нулевого байта (обозночает конец строки) это чтение файлов на которые хватает прав на сервере, а при включенной директиве allow_url_open и при отсутствии строки 'modules/' перед переменной как и вообще любой другой строки возможен удаленный инклуд, то есть инклуд своего проивольного php кода, тогда опасность этой баги возрастает на порядок.

Защита:
Самое простое это функция basename(). Она извлекает из пути файла его имя. Плюс, не побоюсь этого слова, обрезание расширения, либо удаление точки. Пример:

Код:
<?php
...
$mod=str_replace('.','',basename($_GET['mod']));
include('modules/'. $mod.'.php');
...
?>
3. Чтение произвольных файлов

Опасные функции:
fopen() file() readfile() show_source() highlight_file()

Описание:
Ну думаю понятно что это за бага из ее названия ;). Рассмотрим пример:
Код:
<?php
...
readfile('content/'.$_GET['action'].'.html');
...
?>
Возможности эксплуатирования этой баги варьируются в зависимости от включены ли magic_qoutes в php.ini или нет. Если да то ничего полезного кроме, как чтение любых html файлов нам не вытрясти так, как нулевой символ будет слешироваться, а если нет, то эта уязвимость приведет к чтению любых доступных файлов на сервере.

Защита:
Тоже самое как и при инклудинге:

Код:
<?php
...
$action=str_replace('.','',basename($_GET['action']));
readfile('content/'. $action.'.html');
...
?>
4. Обход авторизации/отсутствие авторизации

Описание:
Все что называется данной багой рассмотреть просто не возможно, но некоторые вещи я опишу. Очень часто программисты допускают "детские" уязвимости, например после прохождения авторизации в адресную строку дописывается переменная которая говорит о том что пользователь успешно прошел авторизацию и в остальных скриптах проверяется существует ли такая переменная, например http://site/script.php?auth=1. Разумеется так делать нельзя. Либо вот такая ошибка:

Код:
<?php
...
if(super_mega_proverka())$user=true;
...
if($user)echo("Вы успешно залогинились ;)");
...
?>
При включенной директиве register_globals в php.ini мы имеем возможность "успешно залогинится" написав в адресной строке, что-то типа http://site/script.php?user=1
Очень часто встречаются незапароленные админки, которые почему-то запрещены к индексации поисковиками в файлике robots.txt. Это не значит, что не надо вписывать незапароленные админки в этот файлик, это значит, что нужно писать авторизацию. Люди не ленитесь пишите проверку на авторизацию! Не так уж это и сложно…

5. Выполнение произвольного кода в командной строке.

Опасные функции:
exec() shell_exec() system() passthru()

Описание:
Очень-очень редкая бага встретить практически которую просто невозможно. Блин даже придумать не могу как и где ее можно использовать. Но думаю понятно к чему это может привести.

Защита:
Использовать функцию escapeshellcmd().

6. Выполнение php кода

Опасные функции:
eval()

Описание:
Ну как вам известно эта функция интерпретирует переданный ей параметр как php код. Ну вот допустим пример (функция для объявления переменных если register_globals=off, еле-еле придумал что сюда можно написать ;) ):
Код:
<?php
...
if(is_array($_GET)) {
	foreach($_GET as $k => $v){
		eval('if(empty($'.$k.'))$'.$k.'="'.$v.'";<br>');
	}
}
...
?>
Как видим любое значение любой переменной вставляется в строку и следовательно может быть произведена модификация исходного php кода в функции eval путем подобного обращения к скрипту http://site/script.php?bla=1"; phpinfo();// что разумеется выведет нам phpinfo().

Защита:
Использование слеширования опасных символов функцией addslashes(). Пример:
Код:
<?php
...
if(is_array($_GET)) {
	foreach($_GET as $k => $v){
	eval('if(empty($'.addslashes($k).'))$'.$k.'="'.addslashes($v).'";<br>');
	}
}
...
?>
7. Загрузка и выполнение произвольного php кода

Описание:
Данная уязвимость возникает при загрузки файла на сервер при отсутствии, либо неполной фильтрации типа загружаемого файла. Например:
Код:
<?php
...
$attach = $_FILES['attach'];
if (!empty($attach['name']) && is_uploaded_file($attach['tmp_name'])) {
	move_uploaded_file($attach['tmp_name'], "upload/".$attach['name']);
}
...
?>

Либо проверка присутствует но она проходит по его mime типу получаемому от браузера который можно легко подделать. Пример
Код:
<?php
...
$attach = $_FILES['attach'];
if (!empty($attach['name']) && is_uploaded_file($attach['tmp_name'])) {
	if(substr($attach['type'],0,5)==='image')
	move_uploaded_file($attach['tmp_name'], "upload/".$attach['name']);
}
...
?>
Защита:
Решением будет использование вот такого кода:
Код:
<?php
...
$loadext=Array('bmp','jpeg','jpg','png');
$attach = $_FILES['attach'];
if ((!empty($attach['name'])) && (is_uploaded_file($attach['tmp_name']))) {
	$attach_name=explode('.',$attach['name']);
	$attach_ext=$attach_name[count($attach_name)-1];
	$attach_name=$attach_name[0];
	if(in_array($attach_ext, $loadext))
	{
		if((preg_match("/^[-0-9A-Z_\[\]]+$/i", $attach_name))&&($attach['size'] <=5000)) 		{
			move_uploaded_file($attach['tmp_name'], "upload/".$attach_name.$attach_ext);
		}
	}
}
...
?>
Будут отсеяны файлы у которых расширение не bmp, jpeg, jpg или png, размер которых больше 5000 байт и имя которого не соответствует регулярному выражению "/^[-0-9A-Z_\[\]]+$/i". Таким образом мы убиваем двух зайцев, мы не даем грузится файлам не нужного типа, имени, размера и мы убираем всякие лишние, так сказать вторые расширения у файла, так, как благодаря им файл может интерпретироваться как php код.

Хотелось бы сказать поподробнее о двойных расширениях. Дело в том что файл blaa.php.rar будет интерпретирован как php-файл если последнее расширение не внесено в mime.types. Только к сожалению данный способ не спасет от загрузки php кода с разрешенным расширением, что при наличии инклудинга может привести к взлому вашего сайта.

8. Раскрытие пути

Описание:
Данную багу трудно назвать багой, но это порой необходимая вещь при взломе. Благодаря ей взломщик может узнать путь от корня сервера до папки где находится сайт. Собственно возникает она при отображении ошибок.

Защита:
В самом начале скрипта вписать error_reporting(0); скроет отображение всех ошибок, причем лучше писать сам код скрипта так чтобы никаких ошибок не появлялось, а эту директиву вписывать на всякий случай.

9. Перезапись переменных

Опасные функции:
import_request_variables() extract() parse_str()

Описание:
Эти функции - почти замена включенной директиве register_globals. И все они позволяют переписать любые переменные объявленные раньше будь то простая переменная либо переменная из массивов _SESSION, _SERVER и т.д. Что приводит к непредсказуемым последствиям ;). Ну вот пример:
Код:
<?php
...
import_request_variables ("GPC");
...
if(!empty($_SESSION['user']))
{
	echo('Добрый день пользователь '. $_SESSION['user']);
	...
}
...
?>
Если обратиться к этому скрипту вот так http://site/script.php?_SESSION[user]=гыгы…лол то мы получим интересный результат ;)

Защита:
Использовать функцию extract с флагом EXTR_SKIP вот пример:
Код:
<?php
…
extract($_GET, EXTR_SKIP);
extract($_POST, EXTR_SKIP);
…
?>
10.XSS

Описание:
Cross Site Scripting (Межсайтовый скриптинг). Собственно принцип этой баги заключается в выводе значения нефильтрованной переменной с целью изменения исходного кода страницы. В основном это вписывание java скрипта отправляющего cookies пользователя на сниффер взломщика. Но на самом деле применений этой баги много. Пример:
Код:
<?php
...
echo('Открыта страница номер '.$_GET['id']);
...
?>
Обратившись к скрипту так http://site/script.php?id=<script>alert(document.cookie)</script> мы увидим свои cookies.

Защита:
Использовать функцию htmlspecialchars() с флагом ENT_QUOTES. Пример:
Код:
<?php
...
echo('Открыта страница номер '.htmlspecialchars($_GET['id'],ENT_QUOTES));
...
?>
Опять откроем [/b]http://site/script.php?id=<script>alert(document.cookie)</script>[/b] в браузере и мы увидим на экране мирную надпись "Открыта страница номер <script>alert(document.cookie)</script>"

11. Подбор пароля

Описание:
Во многих форумах и портальных системах есть возможность подобрать пароль какого-нибудь юзера через форму авторизации либо через cookies(про cookies очень часто кодеры забывают), то есть при проверке пароля/логина нет, допустим, картинки с числом или задержки между неверным вводом пароля.

Защита:
Прикрутить временную задержку между неверными вводами пароля и неверных авторизаций с помощью cookies. Плюс банить тех кто неверно регестрировался больше определнного количества раз. Спасибо groundhog за совет...

12. Соц. инженерия

Описание:
Не знаю как назвать правильно ;). Нигде еще ни читал о таком методе атаки. Вообщем вспоминаем те форумы/cms где допустим можно сменить пароль в профиле без ввода старого, либо вспоминаем про панель администратора где для авторизации достаточно только cookies. Рассмотрим на примере:
Код:
<?php
...
if(super_mega_proverka()){
	if($_GET['action']==='changepass')change_pass($_POST['new_pass']);
	...
}
...
?>
Где функция super_mega_proverka() проверяет залогинен ли юзер или нет, а функция change_pass() меняет текущий пароль юзера на новый. Теперь мы создаем другую страницу
Код:
<form name='abra' action='http://site/script.php?action=changepass' method='post'>
<input type='hidden' name='new_pass' value='123456'>
</form>
<script>this.abra.submit();</script>
И заставим жертву посетить эту страницу. После посещения у жертвы в профиле пароль изменится на 123456. Таким же образом можно заставить и админа выполнить какие-либо действия в админ панели.

Защита:
Использовать индетификатор юзера. Примеры
Код:
<?php
...
//Генерируем индетификатор юзера на основе его пароля 
//и который мы будем вставлять во все ссылки.
$uid=md5(substr(md5(get_user_password()),0,16)); 
...
?>
И собственно второй скрипт где этот индетификатор проверяется:
Код:
<?php
//Ну и собственно проверяем этот индетификатор на валидность
if(!empty($_GET[' uid '])){
	if($_GET[' uid ']!= md5(substr(md5(get_user_password()),0,16))) {
		header("Location: index.php");
		die();
	}
}else{
	header("Location: index.php");
	die();
}
...
?>
Теперь пояснение. Вообщем в первом скрипте собственно генерируется индитефикатор юзера который будет вставляться во все ссылки для проверки валидности индитификатора, который и будет обозначать что юзер пришел не от куда то там со стороны а выполняет то что он сам хочет ;). Кто не понял может приглядеться как работает админ панель в cms PHP fusion.

13. OUTRO

Старайтесь по мере возможности проверять переменные на то:
1) Существуют ли они? (empty() is_set())
2) Подходит ли тип переменной? (is_int() is_str() is_array())
Используйте error_reporting(0) -полезная вещь.
Проверяйте значение referer, пусть можно и подделать, но это доставит неприятность взломщику.

Вот я думаю и все. Я надеюсь эта статья вам чем то помогла. Ну что много уязвимостей нашли у себя в скриптах по прочтению ;) ? Надеюсь, нет.

P.S. Машину глючит, а человека тем более, поэтому буду рад услышать объективные комментарии по теме.
__________________
Кто я?..

Последний раз редактировалось Dr.Z3r0; 06.05.2010 в 22:24..
 
Ответить с цитированием
 



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
#antichat. Логи, лолы. Gh0s7 Болталка 694 07.06.2010 20:01
Books PHP FRAGNATIC PHP, PERL, MySQL, JavaScript 186 21.02.2010 02:41
На PHP, как на "Новые ворота"... Mertvii-Listopad Чужие Статьи 7 18.09.2006 12:42
Безопасность в Php, Часть Iii k00p3r Чужие Статьи 0 11.07.2005 19:02
Защищаем Php. Шаг за шагом. k00p3r Чужие Статьи 0 13.06.2005 11:31



Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


Быстрый переход




ANTICHAT.XYZ