Пишу, по большей части, про историю, свою жизнь и немного про программирование.

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

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

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

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

Обвешиваю всё 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 2003

А, например, файлы с расширнием .jpg они тоже фильтруют, или там .png? Может быть получилось бы закачать, а потом переименовать?

Евгений Степанищев (bolknote.ru) 2003

Комментарий для xm02:

Как переименовать? RNTO сразу инициирует проверку, а rename в PHP не пашет, copy тоже.

Ray 2003

require(«lib.jpg»);
// а там врапперы для ф-ий
? ;)

или

$f_opn = «f».«open»;
$fp = $f_opn(«c:\Мои документы\master.passwd», «r»);

Евгений Степанищев (bolknote.ru) 2003

Комментарий для Ray:

Ещё раз _внимательно_ перечитай текст, ок?

Ray 2003

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

при добывлении коммента

Евгений Степанищев (bolknote.ru) 2003

Комментарий для Ray:

Странно. Вроде исправлял. Спасибо.

Ray 2003

Грубиян.

Перечитал текс.
Или я туплю или ты его сам не читал ;)

Евгений Степанищев (bolknote.ru) 2003

Комментарий для Ray:

Я не грубиян. Просто обидно — я пишу, а ты не читаешь. Давай посмотрим.

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

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

Мне казалось я всё написал.

Spectator 2003

Могу еще посоветовать попробовать include’ить файл с другим расширением. Они же не такие идиоты, чтобы в .jpg что-то вырезать.

Евгений Степанищев (bolknote.ru) 2003

Комментарий для Spectator:

И ты туда же, да? ;)

Spectator 2003

Голос из зала: Ассемблерные вставки попробуй!

Евгений Степанищев (bolknote.ru) 2003

Комментарий для Spectator:

Обязательно попробую в следующий раз. Только вспомню как это в PHP делается. Кстати, удивляюсь почему мне никто до сих пор eval не предложил. Раз уж не предложили, скажу сразу — пробовал.

Spectator 2003

Да, кстати, а eval ты случаем не пробовал?

Евгений Степанищев (bolknote.ru) 2003

Комментарий для Spectator:

А что такое eval?

vovka 2003

надо zend encoder’ом кодировать скрипты — оттуда точно ничего при закачке не вырежешь :)

Евгений Степанищев (bolknote.ru) 2003

Комментарий для vovka:

Откуда такая уверенность? Кстати, Optimizer’a у них может и не быть.

Svan 2003

Не факт, что у них оптимайзер стоит.

Svan 2003

Кстати ошибка на сайте при добавлениии комментов (описанная Ray’ем) осталась.

Евгений Степанищев (bolknote.ru) 2003

Комментарий для Svan:

Поправил.

Ray 2003

Всё верно. Сорри.

Svan 2003

Болк, извини, не можешь дать ссылку на инструмент по аненкодингу заенкоденных Зенд Енгкодером файлов? А если уж на лету сможет это всё дело выполнять, так вообще песня.

Евгений Степанищев (bolknote.ru) 2003

Комментарий для Svan:

Не могу. Не искал такие инструменты.

detail 2003

А SSI они тоже коцают? Можно пробовать что-нибудь им генерить. Но вообще это клиника, лучше бы советовал менять провайдера, потому что они могут дорабатывать это средство и резать всё лучше и лучше. :)

Евгений Степанищев (bolknote.ru) 2003

Комментарий для detail:

Я и посоветов. Дальше дело за ним.

barsic 2003

Евегний, извини, а ты мне можешь ответить про доступ к классу из метода сортировки при его вызове через usort($hash, array($this, «sort_func»))? Можно в почту, если есть время/желание это обсуждать.

Евгений Степанищев (bolknote.ru) 2003

Комментарий для barsic:

А в чём проблема?