Патент на изобретение велосипеда

Новоизобретённые велосипеды встречаю, если не каждый день, то раз в неделю — точно. Но этот случай меня поразил. Давно я ничего не проверял на прочность.

Доделывал старому по просьбе старого клиента скрипт. Год эта доделка ему была не нужна, а теперь понадобилась. Дело всё происходит на заграничном хостинге. Германском, кажется.

Всё написал, закачиваю скрипт. Запрашиваю браузером — работает, но не всё. Скрипт простой. Очень. Ошибок нет, но чувство, что данные не читаются. У меня читаются, а там — нет. Обычная история.

Обвешиваю всё var_dump’ами и смотрю что у меня в переменных. Так и есть — на переменной $fp (результат функции fopen, язык — PHP), мне сообщают, что переменной такой нет. С сожалением сообщаю клиенту, что у него safe_mode, так что прочитать файл я просто не смогу.

«Сейчас свяжусь со службой поддержки» — на плохом английском заявляет клиент. Ок. Жду. От того, что он мне сообщил мне стало как-то невесело. Safe_mode, да? Парни из поддержки, видимо, не даже не знали что это такое. Зато я теперь знаю какими навороченными могут быть изобретённые велосипеды.

Дальнейшее добыто из рук самой технической поддержки и моих попыток заставить это всё работать, много-много раз гоняя файлы по FTP. Оказывается, у них там стоит супер навороченная система защиты. Она синтегрирована с FTP. Как только я лью туда файл (Perl, PHP, Python), она его обрабатывает и заменяет (sic!) «небезопасные» функции на пустышки!

Оооо!!! В частности пострадали мои fopen, flock, fgets и fclose. Запрещены вызовы целой кучи функций, в том числе call_user_func и функций-переменных.

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

Испробовал call_user_func, $func(), include, require файлов с другими расширениями, закачка в Z/gzip/bzip2 с распаковкой — ничего не получается. Кругом стена. Всё предусмотрели. Тут я вспоминаю, что в PHP существуют особые функции, которые умеют вызывать разные другие функции в качестве callback. После проверки оказалось, что система такие функции считает джентльменами — в смысле она им доверяет.

Вот тут мне карта и попёрла! Для начала я написал небольшую функцию, которая, пользуясь новообретённой дыркой, запускает нужные мне функции. Привожу её здесь с небольшим куском кода — вдруг пригодится, если упомянутый велосипед, не дай бог, найдёт широкое применение.


function Xec ()
{
$comm = func_get_arg(0);
$args = array_slice(func_get_args(), 1);

if (func_num_args() == 3)
return array_reduce($args, $comm); else
if (func_num_args() == 2)
{
array_map($comm, $args);
return $args[0];
}

return NULL;
}

$fp = Xec ('fopen', 'c:\\autoexec.bat', 'r');
echo Xec ('fgets', $fp, 1024);
Xec ('fclose', $fp);

А потом просто подставил туда нужные мне значения.

Вопрос к присутствующим: кто-нибудь знает этого монстра? От службы поддержки я не добился ни названия, ни ссылки на какую-нибудь статью. Мне уже начинает казаться, что этого монстрика они в муках родили сами, чем ужасно гордятся. Но моё указание на наличие safe_mode в PHP породило в них комплекс неполноценности и теперь они боятся признаться в том, являются авторами этого творения.

Комментарии 26

xm02 № 1
А, например, файлы с расширнием .jpg они тоже фильтруют, или там .png? Может быть получилось бы закачать, а потом переименовать?
Евгений Степанищев автор № 2
Как переименовать? RNTO сразу инициирует проверку, а rename в PHP не пашет, copy тоже.
Ray № 5
BUG:

Warning: Cannot modify header information — headers already sent by (output started at /var2/home/bolk/public_html/comadd.php:15) in /var2/home/bolk/public_html/comadd.php on line 232

Warning: Cannot modify header information — headers already sent by (output started at /var2/home/bolk/public_html/comadd.php:15) in /var2/home/bolk/public_html/comadd.php on line 233

при добывлении коммента
Ray № 7
Грубиян.

Перечитал текс.
Или я туплю или ты его сам не читал ;)
Евгений Степанищев автор № 8
Я не грубиян. Просто обидно — я пишу, а ты не читаешь. Давай посмотрим.

Твой вопрос: require(«lib.jpg»);
Смотрим в тексте: «Испробовал call_user_func, $func(), include, require файлов с другими расширениями»

Твой вопрос: $f_opn = «f»."open"; $fp = $f_opn(«c:\Мои документы\master.passwd», «r»);
Смотрим в тексте: Запрещены вызовы целой кучи функций, в том числе call_user_func и функций-переменных. [..] Испробовал call_user_func, $func(), include, require файлов с другими расширениями [..]

Мне казалось я всё написал.
Spectator № 11
Голос из зала: Ассемблерные вставки попробуй!
Евгений Степанищев автор № 12
Обязательно попробую в следующий раз. Только вспомню как это в PHP делается. Кстати, удивляюсь почему мне никто до сих пор eval не предложил. Раз уж не предложили, скажу сразу — пробовал.
Svan № 21
Болк, извини, не можешь дать ссылку на инструмент по аненкодингу заенкоденных Зенд Енгкодером файлов? А если уж на лету сможет это всё дело выполнять, так вообще песня.
detail № 23
А SSI они тоже коцают? Можно пробовать что-нибудь им генерить. Но вообще это клиника, лучше бы советовал менять провайдера, потому что они могут дорабатывать это средство и резать всё лучше и лучше. :)
barsic № 25
Евегний, извини, а ты мне можешь ответить про доступ к классу из метода сортировки при его вызове через usort($hash, array($this, «sort_func»))? Можно в почту, если есть время/желание это обсуждать.