Вообще на хабре уже проскальзывали ссылки на статьи об использовании undefined variable, так что ничего нового я скорее всего не открою.
В php, как и в любом языке с динамической типизацией, есть моменты скрытые от конечного разработчика, на них мы и сыграем.
Начнем с конца. Мы всегда можем обратится к любому callable- была бы строка для вызова. Функции из SPL не исключение, хоть это и крайне редко применяется.
$v="print_r"; $v([1,2,3,4]);
Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 )
Но обратится таким способом ни к echo ни к print мы не можем, ибо они являются конструкциями языка, а не функциями. Можно было бы использовать printf например, но мне такой подход не понравился. Поэтому мы будем использовать для вывода функцию assert.
assert("print someShit");
Кстати заменить print на echo в выражении выше не выйдет, они оба не функции, но print хотя бы старается таковой казаться.
Строку для вывода нам передадут при вызове. Осталось самая малость. Получить строки «assert» и «print» используя доступный нам набор символов.
Для этого мы используем ряд особенностей языка.
1) В php мы можем обратится к undefined variable через _ (underscore). Нетрудно добится сужения типа и получить 0
var_dump(+_);
int(0)
2) При приведении массива к строке, он будет преобразован в строку со значением Array
//инициализируем пустой массив $_[]++; // В данном случае _ приводится к строке "_" $_[]=$_._; var_dump($_);
array(2) { [0]=> int(1) [1]=> string(6) "Array_" }
3) Как и в большинстве других языков, строка фактически является массивом символов. Символы можно инкрементировать.
Скомбинировав все вышеперечисленное получаем такой код.
<? error_reporting(E_ALL^E_NOTICE); crazyOutput("было нечего"); function crazyOutput($__________){ $_[]++; $_[]=$_._; $_=$_[$_[+_]]; $___=$__=$_[++$__[]]; $____=$_=$_[+_]; $_++;$_++;$_++; $_=$____.++$___.$___.++$_.$__.++$___; $__=+_;$__=++$__+(++$__); $____=$_[$__]; $____++;$____++;$____++; $______=$____; $____++;$____++;$____++;$____++;$____++;$____++;$____++;$____++; $___=$____; $____++;$____++; $______++; $___.=$____.$______; $______++;$______++;$______++;$______++;$______++; $___.=$______; $__=+_;$__++; $______=$___[$__]; $______++;$______++; $___.=$______; $_($___." '".$__________."'"); } ?>
/usr/bin/php /var/www/garbage/brainfuck.php было нечего Process finished with exit code 0
Практической пользы 0 в принципе… но что-то в этом есть =)
ссылка на оригинал статьи http://habrahabr.ru/post/165013/
Добавить комментарий