Пользователь
0,0
рейтинг
2 февраля 2012 в 15:10

Разработка → Деобфускация PHP кода из песочницы

PHP*
Деобфускация PHP
Так уж случилось, что на днях мне попался один нужный PHP скрипт, но обфусцированный.
По какой-то причине он никак не работал. Я пишу на PHP достаточно давно, и мне очень нравится отлавливать нестандартные ситуации в скриптах, особенно когда при выполнении в логах нет ошибок, а скрипт просто не выполняет своих предназначенных обязанностей, руки так и чесались расшифровать. Последней каплей стало то, что автора этого скрипта не было в сети, чтобы помочь решить мою проблему. Скрипт кстати куплен моим товарищем, собственно он и попросил помочь.

Цель данной статьи, показать принцип дешифровки, зашифрованных скриптов, чтобы например расшифровать залитый злоумышленником вирус на PHP.



Анализирование кода



Вот один из этих скриптов, открывая такой скрипт в блокноте, мы увидим:


Разобьем для начала его на строки:

и сохраним в файл encoded_script.php

Видно что тут код разбит на 4е части. В каждой выполняется eval.
Для удобства дешифровки eval воспользуемся расширением для PHP — Evalhook. Его написал Stefan Esser за что ему большущее спасибо. С помощью него можно расшифровывать в несколько проходов например монстров закодированных через www.php-crypt.com функциями eval, gzuncompress, base64_decode и тд.

Установка evalhook



Требуется:
  1. PHP >= v5.2
  2. php-devel
  3. PHP Zend Optimizer


Скачиваем архив с исходниками
fetch http://php-security.org/downloads/evalhook-0.1.tar.gz


Распаковываем и собираем расширение для PHP
tar xvfz evalhook-0.1.tar.gz
cd evalhook
phpize 
./configure
make
sudo make install


расширение готово, теперь его можно динамически подгружать в консоль и смотреть зашифрованный скрипт.
php -d extension=evalhook.so encoded_script.php


где encoded_script.php — закодированный файл.
Для получения исходного кода просто жмем «Y» несколько раз в процессе деобфускации. Каждый новый Y будет расшифровывать следующий eval. Ну что ж вооружимся консолью и в бой!

Деобфускация и декодирование


1-й проход
%php -d extension=evalhook.so encoded_script.php
Script tries to evaluate the following string.
----
$GLOBALS['_562306928_']=Array(base64_decode('' .'Ym' .'FzZTY' .'0X2RlY2' .'9kZQ=='),base64_decode('Y' .'mFzZTY0X2R' .'lY29' .'kZ' .'Q=='),base64_decode('' .'YmFzZT' .'Y0X2RlY29kZ' .'Q=='),base64_decode('YmF' .'zZTY0X2Rl' .'Y29' .'kZQ=='),base64_decode('YmF' .'zZTY' .'0X2RlY2' .'9kZQ=' .'='),base64_decode('' .'Y' .'m' .'FzZTY0X2RlY29k' .'ZQ=='),base64_decode('YmFzZ' .'TY0X2R' .'l' .'Y' .'29k' .'ZQ' .'=='),base64_decode('Y' .'m' .'FzZTY0X2' .'Rl' .'Y' .'29k' .'ZQ=='),base64_decode('YmFzZT' .'Y0X2RlY2' .'9kZQ' .'=='),base64_decode('YmFzZ' .'T' .'Y0X' .'2' .'RlY29kZ' .'Q=='),base64_decode('' .'Y' .'m' .'FzZT' .'Y0X2RlY2' .'9k' .'ZQ=='),base64_decode('Ym' .'FzZTY0X' .'2Rl' .'Y29' .'kZQ=='),base64_decode('YmF' .'zZT' .'Y0' .'X2RlY29' .'kZ' .'Q=='),base64_decode('YmFzZ' .'TY0X2RlY29kZQ=='),base64_decode('Ym' .'FzZTY0X' .'2RlY29k' .'ZQ=='),base64_decode('YmFzZTY0' .'X2RlY' .'29kZQ=='),base64_decode('Ym' .'FzZTY0X2Rl' .'Y2' .'9kZ' .'Q=='),base64_decode('Ym' .'FzZTY0X2' .'R' .'lY29kZQ=='),base64_decode('Y' .'mFz' .'ZTY' .'0' .'X2R' .'lY29k' .'Z' .'Q=='),base64_decode('Y' .'mFzZT' .'Y0X2R' .'lY2' .'9kZQ=' .'='),base64_decode('' .'YmFzZTY' .'0X' .'2' .'RlY29k' .'ZQ=='),base64_decode('' .'Y' .'mFzZTY0' .'X2R' .'lY' .'29kZQ=='),base64_decode('YmFzZTY0' .'X2Rl' .'Y29k' .'ZQ=='),base64_decode('YmFzZ' .'TY0' .'X2Rl' .'Y' .'29k' .'Z' .'Q=='),base64_decode('YmFzZT' .'Y' .'0X2Rl' .'Y' .'29kZQ=='),base64_decode('YmFzZTY0X2Rl' .'Y29k' .'Z' .'Q=='),base64_decode('' .'Y' .'m' .'FzZ' .'TY0X' .'2RlY29kZQ=' .'='),base64_decode('YmF' .'z' .'ZTY' .'0X2R' .'lY29kZQ' .'=='),base64_decode('YmF' .'zZTY0X2RlY29kZQ=='),base64_decode('YmFz' .'ZTY0X2RlY29kZQ=='),base64_decode('' .'Ym' .'FzZ' .'TY0' .'X2RlY2' .'9' .'kZ' .'Q=='),base64_decode('YmFzZT' .'Y0X2' .'R' .'lY29kZQ=='),base64_decode('YmFzZTY0' .'X2' .'RlY29kZ' .'Q=='),base64_decode('Ym' .'F' .'zZ' .'TY0X2' .'R' .'lY29kZQ=='),base64_decode('Ym' .'FzZTY' .'0X2RlY29kZ' .'Q=='),base64_decode('YmF' .'z' .'ZT' .'Y0X' .'2RlY29kZQ=='),base64_decode('YmFzZ' .'TY0X2RlY29kZQ=' .'='),base64_decode('YmFz' .'ZTY0X2Rl' .'Y29' .'kZQ=='),base64_decode('Y' .'mFzZTY' .'0' .'X2Rl' .'Y2' .'9kZ' .'Q=='),base64_decode('YmFzZ' .'T' .'Y0X2RlY2' .'9kZQ=='),base64_decode('YmFz' .'Z' .'T' .'Y0X2RlY29kZ' .'Q=='),base64_decode('YmFzZT' .'Y0X2RlY29' .'kZQ=' .'='),base64_decode('' .'YmFzZTY0X2RlY29kZ' .'Q=='),base64_decode('YmFz' .'ZTY0X2' .'RlY29kZQ=='),base64_decode('Ym' .'FzZ' .'TY0X' .'2R' .'l' .'Y2' .'9' .'kZQ=='),base64_decode('Ym' .'FzZT' .'Y0X2Rl' .'Y29kZQ=='),base64_decode('YmFzZTY0X' .'2RlY29' .'kZQ=='),base64_decode('YmFzZTY0X2' .'RlY29kZQ' .'=='),base64_decode('' .'Ym' .'F' .'zZT' .'Y0X2RlY29k' .'Z' .'Q' .'=='),base64_decode('YmFzZTY0' .'X' .'2R' .'lY2' .'9kZ' .'Q=='),base64_decode('' .'YmF' .'zZTY0X' .'2RlY29' .'kZQ=='),base64_decode('Y' .'m' .'Fz' .'ZTY0X2R' .'l' .'Y29kZQ=' .'='),base64_decode('Y' .'m' .'FzZ' .'TY0X2R' .'lY' .'2' .'9' .'kZQ=='),base64_decode('YmFz' .'ZTY0' .'X' .'2RlY29kZ' .'Q=='),base64_decode('YmFzZTY0X2' .'RlY' .'29kZQ=='),base64_decode('' .'YmFzZ' .'TY0X2RlY29' .'kZ' .'Q=='),base64_decode('Y' .'mFzZTY0X2R' .'l' .'Y29' .'kZQ=='),base64_decode('Y' .'mFzZ' .'T' .'Y0X2RlY29k' .'ZQ=' .'='),base64_decode('Y' .'mFzZTY0X2' .'RlY2' .'9k' .'ZQ=' .'='),base64_decode('Ym' .'FzZTY0X2RlY' .'29' .'kZQ=' .'='),base64_decode('YmFzZTY0X2R' .'lY29kZQ' .'=='),base64_decode('YmF' .'zZTY0X2RlY29k' .'ZQ=='),base64_decode('' .'YmFzZ' .'T' .'Y0X2' .'R' .'lY29kZQ' .'=='),base64_decode('YmFzZTY0' .'X2R' .'lY29kZQ=='),base64_decode('YmFz' .'ZTY' .'0X2' .'RlY29kZQ' .'=='),base64_decode('' .'YmF' .'zZTY0X2RlY29kZQ=='),base64_decode('Y' .'mF' .'zZTY0X2Rl' .'Y29kZQ' .'=='),base64_decode('Y' .'mF' .'z' .'ZTY0X2' .'RlY29kZQ=' .'='),base64_decode('Y' .'m' .'FzZTY0' .'X2RlY29kZQ=='),base64_decode('Y' .'mFzZTY' .'0X' .'2R' .'lY' .'29kZQ=='),base64_decode('Y' .'mFzZ' .'TY0X' .'2Rl' .'Y' .'29kZ' .'Q=='),base64_decode('YmF' .'zZTY0X2' .'RlY' .'29' .'kZQ' .'=='),base64_decode('' .'YmFzZTY0X2' .'RlY29kZQ=='),base64_decode('YmFzZTY0X2RlY29kZQ=='),base64_decode('YmFzZTY0' .'X2RlY' .'29k' .'Z' .'Q=='),base64_decode('Ym' .'FzZ' .'TY0X2RlY' .'29' .'kZ' .'Q=='),base64_decode('Y' .'mFzZTY0X2RlY29kZQ=='),base64_decode('YmF' .'z' .'ZTY0' .'X2RlY29' .'kZQ=='),base64_decode('YmF' .'zZTY0X' .'2R' .'lY29kZ' .'Q=='),base64_decode('YmFz' .'ZT' .'Y0X2' .'RlY29kZQ=' .'='),base64_decode('Y' .'mF' .'zZ' .'TY' .'0' .'X2R' .'lY' .'29kZQ=='),base64_decode('' .'YmFzZ' .'TY0X2' .'RlY' .'29' .'kZQ=='),base64_decode('Ym' .'F' .'zZTY' .'0X' .'2' .'RlY' .'29' .'kZQ=='),base64_decode('' .'Ym' .'F' .'zZ' .'TY0X' .'2RlY29' .'kZQ=='),base64_decode('' .'Y' .'mFzZTY' .'0' .'X' .'2' .'R' .'lY29kZ' .'Q=='),base64_decode('' .'YmFz' .'Z' .'TY0X2' .'RlY29kZQ' .'=='));
----
Do you want to allow execution? [y/N]


1-й eval расшифровали, нужный нам код находится между символами"----". Впоследствии после всех шагов нужно будет его скопировать в файл. Нажимаем Y и продолжаем расшифровывать.
2-й проход:
Script tries to evaluate the following string.
----
$GLOBALS['_223713416_']=Array($GLOBALS['_562306928_'][0]('YmFzZTY0' .'X2RlY29kZQ=' .'='),$GLOBALS['_562306928_'][1]('' .'YmFz' .'ZTY' .'0X2' .'RlY29' .'kZQ=='),$GLOBALS['_562306928_'][2]('Ym' .'F' .'zZTY0X2RlY29kZQ=='),$GLOBALS['_562306928_'][3]('YmFz' .'ZTY0X2' .'RlY2' .'9kZQ' .'=='),$GLOBALS['_562306928_'][4]('Ym' .'F' .'zZTY0' .'X2R' .'lY' .'29kZQ' .'=' .'='),$GLOBALS['_562306928_'][5]('YmFz' .'ZT' .'Y' .'0X2' .'RlY29k' .'ZQ=' .'='),$GLOBALS['_562306928_'][6]('YmFzZTY0X2RlY29kZQ=='),$GLOBALS['_562306928_'][7]('' .'YmFz' .'ZTY0X2RlY29kZQ=' .'='),$GLOBALS['_562306928_'][8]('' .'Y' .'mFzZT' .'Y' .'0X2RlY2' .'9kZQ=='),$GLOBALS['_562306928_'][9]('' .'Ym' .'FzZTY0' .'X2R' .'lY2' .'9kZQ=='),$GLOBALS['_562306928_'][10]('Y' .'m' .'Fz' .'ZTY0X2RlY29k' .'ZQ=' .'='),$GLOBALS['_562306928_'][11]('Ym' .'FzZTY0X2Rl' .'Y29k' .'ZQ=='),$GLOBALS['_562306928_'][12]('Y' .'m' .'Fz' .'ZT' .'Y' .'0' .'X2' .'R' .'lY2' .'9kZQ=='),$GLOBALS['_562306928_'][13]('YmF' .'zZTY0X2' .'RlY29kZQ=='),$GLOBALS['_562306928_'][14]('YmFzZTY0X' .'2' .'RlY29kZ' .'Q=='),$GLOBALS['_562306928_'][15]('' .'YmFz' .'ZTY0' .'X2RlY29kZQ=='),$GLOBALS['_562306928_'][16]('Ym' .'FzZT' .'Y0' .'X2R' .'lY' .'29' .'k' .'Z' .'Q=='),$GLOBALS['_562306928_'][17]('YmF' .'z' .'ZTY0X2RlY2' .'9kZQ=='),$GLOBALS['_562306928_'][18]('Y' .'mFzZ' .'TY0X2RlY29kZ' .'Q=='),$GLOBALS['_562306928_'][19]('' .'Ym' .'FzZTY0X2RlY' .'2' .'9k' .'ZQ=' .'='),$GLOBALS['_562306928_'][20]('YmFzZTY0X' .'2RlY29kZQ=='),$GLOBALS['_562306928_'][21]('' .'YmFz' .'ZTY0X2RlY29kZQ' .'=='),$GLOBALS['_562306928_'][22]('YmFzZTY0X2R' .'l' .'Y29k' .'Z' .'Q=='),$GLOBALS['_562306928_'][23]('Y' .'mFz' .'Z' .'TY0X2RlY' .'2' .'9kZQ=' .'='),$GLOBALS['_562306928_'][24]('' .'YmFzZTY0X2RlY29k' .'ZQ=' .'='),$GLOBALS['_562306928_'][25]('' .'Y' .'mFzZTY0' .'X2' .'R' .'lY29kZQ=' .'='),$GLOBALS['_562306928_'][26]('YmF' .'zZTY0X2RlY29kZQ=' .'='),$GLOBALS['_562306928_'][27]('Ym' .'F' .'zZTY0X2' .'R' .'lY29kZQ=='),$GLOBALS['_562306928_'][28]('YmF' .'zZTY' .'0X2' .'RlY2' .'9kZQ=='),$GLOBALS['_562306928_'][29]('YmFzZTY' .'0X2' .'RlY' .'29kZQ' .'=='),$GLOBALS['_562306928_'][30]('Y' .'mFzZTY0X2R' .'l' .'Y29kZ' .'Q=='),$GLOBALS['_562306928_'][31]('Y' .'mFzZTY0X2R' .'l' .'Y29kZQ=='),$GLOBALS['_562306928_'][32]('YmFz' .'ZTY0X' .'2RlY29kZQ=='),$GLOBALS['_562306928_'][33]('Y' .'mFzZTY0X2RlY29kZQ=='),$GLOBALS['_562306928_'][34]('YmFzZ' .'TY' .'0X2RlY29' .'kZ' .'Q=' .'='),$GLOBALS['_562306928_'][35]('YmFzZTY' .'0X2R' .'lY' .'29kZQ=='),$GLOBALS['_562306928_'][36]('Ym' .'FzZTY0X2RlY2' .'9kZQ=='),$GLOBALS['_562306928_'][37]('' .'Y' .'mFzZTY' .'0X2RlY29' .'kZQ' .'=='),$GLOBALS['_562306928_'][38]('Y' .'mFzZTY' .'0' .'X' .'2R' .'l' .'Y29kZQ=='),$GLOBALS['_562306928_'][39]('Ym' .'FzZT' .'Y0X' .'2RlY29k' .'ZQ=='),$GLOBALS['_562306928_'][40]('' .'YmFzZTY' .'0X2RlY2' .'9kZQ=='),$GLOBALS['_562306928_'][41]('Y' .'mFzZTY0X2RlY2' .'9kZQ=='),$GLOBALS['_562306928_'][42]('Ym' .'FzZTY0X2' .'Rl' .'Y' .'29kZQ=' .'='),$GLOBALS['_562306928_'][43]('' .'Ym' .'FzZ' .'TY0' .'X2' .'RlY' .'29' .'k' .'ZQ=='),$GLOBALS['_562306928_'][44]('YmFzZTY0' .'X2R' .'l' .'Y2' .'9kZQ=='),$GLOBALS['_562306928_'][45]('' .'Y' .'mF' .'zZTY0X' .'2Rl' .'Y' .'29' .'kZQ' .'=='),$GLOBALS['_562306928_'][46]('YmF' .'z' .'ZTY0' .'X' .'2RlY29' .'kZQ' .'=='),$GLOBALS['_562306928_'][47]('Ym' .'FzZTY' .'0X' .'2' .'RlY' .'29k' .'Z' .'Q=' .'='),$GLOBALS['_562306928_'][48]('Y' .'mFz' .'ZTY0X' .'2Rl' .'Y29k' .'Z' .'Q=' .'='),$GLOBALS['_562306928_'][49]('YmFz' .'ZT' .'Y0X2Rl' .'Y' .'29kZQ=' .'='),$GLOBALS['_562306928_'][50]('YmFzZTY0X2' .'R' .'lY29kZQ' .'=='),$GLOBALS['_562306928_'][51]('YmFzZTY0X2R' .'l' .'Y29kZQ=='),$GLOBALS['_562306928_'][52]('Y' .'mF' .'zZT' .'Y0X2Rl' .'Y29kZQ=='),$GLOBALS['_562306928_'][53]('YmFzZTY0X' .'2RlY2' .'9kZ' .'Q=' .'='),$GLOBALS['_562306928_'][54]('YmFzZTY0X2' .'RlY29kZQ=='),$GLOBALS['_562306928_'][55]('YmFzZTY' .'0X2' .'R' .'lY29kZQ=='),$GLOBALS['_562306928_'][56]('YmFzZTY' .'0X2RlY2' .'9k' .'ZQ=='),$GLOBALS['_562306928_'][57]('' .'YmFzZ' .'TY0X2Rl' .'Y29kZQ=='),$GLOBALS['_562306928_'][58]('' .'YmF' .'zZTY0X2RlY29kZ' .'Q=='),$GLOBALS['_562306928_'][59]('YmFzZTY0X2R' .'lY29' .'kZQ=='),$GLOBALS['_562306928_'][60]('Ym' .'FzZT' .'Y0X2Rl' .'Y29' .'kZQ=='),$GLOBALS['_562306928_'][61]('YmFzZT' .'Y0X2RlY29kZQ=='),$GLOBALS['_562306928_'][62]('' .'Y' .'m' .'FzZ' .'T' .'Y0X' .'2RlY' .'2' .'9kZQ=='),$GLOBALS['_562306928_'][63]('YmFzZTY0X2RlY29kZQ=='),$GLOBALS['_562306928_'][64]('Ym' .'F' .'zZTY' .'0X' .'2RlY' .'29kZQ=='),$GLOBALS['_562306928_'][65]('YmF' .'zZTY0X2R' .'lY29kZ' .'Q' .'=='),$GLOBALS['_562306928_'][66]('YmFzZ' .'TY0X2' .'R' .'lY' .'29kZQ=='),$GLOBALS['_562306928_'][67]('Ym' .'FzZTY0X2Rl' .'Y2' .'9kZQ=='),$GLOBALS['_562306928_'][68]('YmFzZ' .'TY0' .'X2RlY29kZQ=='),$GLOBALS['_562306928_'][69]('YmFzZTY0X2RlY29kZQ=='),$GLOBALS['_562306928_'][70]('Ym' .'Fz' .'ZT' .'Y0' .'X2RlY29kZQ=='),$GLOBALS['_562306928_'][71]('YmFzZTY0X2' .'RlY29k' .'Z' .'Q=='),$GLOBALS['_562306928_'][72]('YmF' .'zZTY' .'0X2RlY' .'29kZQ' .'=='),$GLOBALS['_562306928_'][73]('YmFzZTY0X' .'2' .'RlY2' .'9kZQ=' .'='),$GLOBALS['_562306928_'][74]('' .'Ym' .'FzZTY0X2R' .'lY29' .'kZQ=='),$GLOBALS['_562306928_'][75]('YmFzZTY0X' .'2RlY29kZQ' .'=='),$GLOBALS['_562306928_'][76]('Y' .'mFzZ' .'TY0X2R' .'lY29kZQ=' .'='),$GLOBALS['_562306928_'][77]('YmFzZTY0X2RlY29kZQ' .'=='),$GLOBALS['_562306928_'][78]('YmFzZT' .'Y0X2' .'RlY29kZQ=='),$GLOBALS['_562306928_'][79]('YmFzZTY0X2' .'RlY2' .'9kZQ=='),$GLOBALS['_562306928_'][80]('YmFzZTY0X2RlY29kZ' .'Q=='),$GLOBALS['_562306928_'][81]('Ym' .'F' .'zZ' .'TY0X2R' .'l' .'Y2' .'9kZQ=='),$GLOBALS['_562306928_'][82]('YmFzZ' .'TY0X2RlY29kZQ=='),$GLOBALS['_562306928_'][83]('YmF' .'zZTY0X2RlY' .'2' .'9kZQ=='),$GLOBALS['_562306928_'][84]('YmFzZT' .'Y0X2RlY' .'29kZQ=' .'='),$GLOBALS['_562306928_'][85]('Y' .'mFzZTY0X2RlY29kZQ=='));
----
Do you want to allow execution? [y/N]


3.
Script tries to evaluate the following string.
----
$GLOBALS['_888028985_']=Array($GLOBALS['_223713416_'][0]('' .'c3Ry' .'X' .'3JlcG' .'xhY2U='),$GLOBALS['_223713416_'][1]('' .'dW5s' .'aW' .'5r'),$GLOBALS['_223713416_'][2]('cHJl' .'Z' .'1' .'9t' .'YXRja' .'A=' .'='),$GLOBALS['_223713416_'][3]('bXlz' .'cWx' .'f' .'Y29u' .'bmVjdA=='),$GLOBALS['_223713416_'][4]('bX' .'lzcW' .'x' .'fZ' .'XJyb3I='),$GLOBALS['_223713416_'][5]('b' .'XlzcW' .'xfc2VsZWN0X2Ri'),$GLOBALS['_223713416_'][6]('bX' .'l' .'zcWxfZXJ' .'yb3I='),$GLOBALS['_223713416_'][7]('bXlzcWxfc' .'XVlcnk' .'='),$GLOBALS['_223713416_'][8]('b' .'X' .'lz' .'cWx' .'fcXV' .'lcnk='),$GLOBALS['_223713416_'][9]('bXlzcWxf' .'ZX' .'NjYXBlX3' .'N0cm' .'luZ' .'w=='),$GLOBALS['_223713416_'][10]('bXlzcWxfZX' .'J' .'y' .'b3I='),$GLOBALS['_223713416_'][11]('bXl' .'zc' .'WxfZmV0Y2hfYX' .'Nzb2M='),$GLOBALS['_223713416_'][12]('bX' .'l' .'zc' .'Wx' .'fcXVlcnk='),$GLOBALS['_223713416_'][13]('' .'bXl' .'zcW' .'xfZX' .'N' .'jYXBlX3' .'N0cmluZw=='),$GLOBALS['_223713416_'][14]('bX' .'lzc' .'WxfZX' .'J' .'y' .'b3I='),$GLOBALS['_223713416_'][15]('bXl' .'zcWx' .'faW5zZXJ0' .'X2lk'),$GLOBALS['_223713416_'][16]('Zmx1c' .'2g='),$GLOBALS['_223713416_'][17]('b2J' .'fZmx' .'1c2g='),$GLOBALS['_223713416_'][18]('Zmx' .'1c2g' .'='),$GLOBALS['_223713416_'][19]('Zmx' .'1c' .'2g='),$GLOBALS['_223713416_'][20]('b2JfZm' .'x' .'1c2g='),$GLOBALS['_223713416_'][21]('Zmx1c2g' .'='),$GLOBALS['_223713416_'][22]('bXl' .'zc' .'WxfY2' .'xvc2U='),$GLOBALS['_223713416_'][23]('cHJlZ19' .'tYXRj' .'aA=='),$GLOBALS['_223713416_'][24]('' .'cmFu' .'ZA=='),$GLOBALS['_223713416_'][25]('c3RyX3J' .'l' .'cGxhY' .'2U='),$GLOBALS['_223713416_'][26]('cHJlZ' .'19tYXRj' .'aF9hb' .'Gw' .'='),$GLOBALS['_223713416_'][27]('ZmlsZV9leGlzdHM='),$GLOBALS['_223713416_'][28]('dHJp' .'bQ=='),$GLOBALS['_223713416_'][29]('c' .'3RyaXBf' .'dGFn' .'cw=' .'='),$GLOBALS['_223713416_'][30]('bXlzcWxfY29' .'ubmVj' .'dA' .'=='),$GLOBALS['_223713416_'][31]('b' .'Xlzc' .'WxfZX' .'Jyb3I='),$GLOBALS['_223713416_'][32]('' .'b' .'X' .'lzcWxf' .'c2VsZWN0' .'X2' .'R' .'i'),$GLOBALS['_223713416_'][33]('bXlzc' .'WxfZXJyb3' .'I='),$GLOBALS['_223713416_'][34]('bXlzc' .'WxfcXVl' .'c' .'nk='),$GLOBALS['_223713416_'][35]('' .'bX' .'lz' .'cWxfc' .'XVlcnk' .'='),$GLOBALS['_223713416_'][36]('bXlzcWxfZXNjYX' .'BlX3N' .'0c' .'mluZw' .'=='),$GLOBALS['_223713416_'][37]('b' .'XlzcWxfZXJyb3I='),$GLOBALS['_223713416_'][38]('' .'bXlzcWxfY2' .'xvc2U='),$GLOBALS['_223713416_'][39]('bXlzcW' .'xfZmV0Y' .'2hfYXNzb2M='),$GLOBALS['_223713416_'][40]('' .'c3' .'V' .'ic3Ry' .'X2NvdW5' .'0'),$GLOBALS['_223713416_'][41]('Zm' .'x1c' .'2' .'g='),$GLOBALS['_223713416_'][42]('b2JfZ' .'mx1c2g='),$GLOBALS['_223713416_'][43]('Zmx' .'1' .'c2g='),$GLOBALS['_223713416_'][44]('dHJpbQ' .'=='),$GLOBALS['_223713416_'][45]('c' .'H' .'JlZ1' .'9tYX' .'RjaA=='),$GLOBALS['_223713416_'][46]('' .'dHJpbQ=='),$GLOBALS['_223713416_'][47]('cHJlZ' .'19tYXRjaA=' .'='),$GLOBALS['_223713416_'][48]('c' .'HJlZ19tY' .'XRjaA' .'=' .'='),$GLOBALS['_223713416_'][49]('cHJlZ19tYX' .'RjaF' .'9h' .'bGw' .'='),$GLOBALS['_223713416_'][50]('cH' .'JlZ19tYXRjaF9hbGw='),$GLOBALS['_223713416_'][51]('cHJlZ19tYX' .'R' .'jaA=='),$GLOBALS['_223713416_'][52]('' .'dHJpbQ=='),$GLOBALS['_223713416_'][53]('cH' .'JlZ' .'19yZX' .'BsYWNl'),$GLOBALS['_223713416_'][54]('c' .'HJlZ' .'1' .'9y' .'ZX' .'BsYWN' .'l'),$GLOBALS['_223713416_'][55]('c' .'HJ' .'lZ19tYXRj' .'aA=='),$GLOBALS['_223713416_'][56]('dGltZQ=='),$GLOBALS['_223713416_'][57]('ZmlsZV9w' .'dXRfY2' .'9u' .'dGVu' .'dHM='),$GLOBALS['_223713416_'][58]('' .'bXl' .'zc' .'WxfY2' .'9ubm' .'V' .'jd' .'A=='),$GLOBALS['_223713416_'][59]('b' .'XlzcWxf' .'ZXJyb3' .'I='),$GLOBALS['_223713416_'][60]('b' .'XlzcWxfc2' .'VsZW' .'N0' .'X' .'2Ri'),$GLOBALS['_223713416_'][61]('bXl' .'zc' .'Wx' .'fZXJyb' .'3I' .'='),$GLOBALS['_223713416_'][62]('bX' .'lzcW' .'xfc' .'XVlc' .'nk' .'='),$GLOBALS['_223713416_'][63]('bXlzcWxfZXNjY' .'XB' .'lX3N0cml' .'uZ' .'w' .'=='),$GLOBALS['_223713416_'][64]('' .'c' .'3' .'RyX3JlcG' .'xhY' .'2' .'U='),$GLOBALS['_223713416_'][65]('cmFuZA=='),$GLOBALS['_223713416_'][66]('bXlzcWxfcX' .'Vlcnk='),$GLOBALS['_223713416_'][67]('' .'bXlzc' .'W' .'x' .'fZXJyb' .'3I='),$GLOBALS['_223713416_'][68]('' .'bXlzcWxfa' .'W5zZXJ' .'0X2lk'),$GLOBALS['_223713416_'][69]('b' .'XlzcWxfcXVlcnk='),$GLOBALS['_223713416_'][70]('bX' .'lzcWx' .'fZm' .'V0' .'Y2h' .'fYXJ' .'yYXk='),$GLOBALS['_223713416_'][71]('bXlzc' .'Wxf' .'cXVlcnk='),$GLOBALS['_223713416_'][72]('' .'b' .'XlzcWxfa' .'W5zZ' .'XJ0' .'X' .'2lk'),$GLOBALS['_223713416_'][73]('b' .'Xl' .'zcWxfcXVl' .'cn' .'k='),$GLOBALS['_223713416_'][74]('bXlzcWxfZ' .'m' .'V0Y2' .'hfYXJ' .'yYXk='),$GLOBALS['_223713416_'][75]('bXlzcWxfcXV' .'l' .'cnk' .'='),$GLOBALS['_223713416_'][76]('bX' .'lzc' .'WxfaW5zZ' .'XJ0X2lk'),$GLOBALS['_223713416_'][77]('' .'bXlzcWxf' .'c' .'XVlcnk' .'='),$GLOBALS['_223713416_'][78]('' .'bXlzc' .'WxfcXVlc' .'nk='),$GLOBALS['_223713416_'][79]('bXlz' .'cW' .'x' .'fY2' .'x' .'v' .'c2U='),$GLOBALS['_223713416_'][80]('Zmx1c2g='),$GLOBALS['_223713416_'][81]('b2JfZm' .'x1' .'c2g='),$GLOBALS['_223713416_'][82]('' .'Zmx1c' .'2' .'g' .'='),$GLOBALS['_223713416_'][83]('Zm' .'x1c2g='),$GLOBALS['_223713416_'][84]('b' .'2J' .'fZmx' .'1' .'c2g='),$GLOBALS['_223713416_'][85]('Zmx' .'1c2g='));
----
Do you want to allow execution? [y/N]

4.
Script tries to evaluate the following string.
----
echo "<b>MarketGid</b><br />";$_GET['link']=$GLOBALS['_888028985_'][0]("%%","&",$_GET['link']);include('functions.php');@$GLOBALS['_888028985_'][1]('stop.txt');if($mainstop){die("<center>Приобрести полноценную версию Вы можете на сайте <a href='http://www.zuziken.ru'>www.zuziken.ru</a><br>По вопросам покупки обращайтесь в ICQ 315-625-299</center>");}if($_GET['link']== '')die('<b>Забыли ввести ссылку в форму.</b>');$p=get_page($_GET['link']);$GLOBALS['_888028985_'][2]('/<ul class="hmenu-1 clearfix hmactive-1">[^<]*<li class="tm-1"><span>(.+)<\/span><\/li>/isU',$p,$t);$cat_name=$t[1];$connect=$GLOBALS['_888028985_'][3]($host,$login,$password)or die($GLOBALS['_888028985_'][4]());$select_db=$GLOBALS['_888028985_'][5]($database,$connect)or die($GLOBALS['_888028985_'][6]());$GLOBALS['_888028985_'][7]("set names cp1251");$q=$GLOBALS['_888028985_'][8]("select `id` from `category` where `cat_name` = '" .$GLOBALS['_888028985_'][9]($cat_name) ."'")or die($GLOBALS['_888028985_'][10]());$cat_id=0;while($q_r=$GLOBALS['_888028985_'][11]($q))$cat_id=$q_r['id'];if($cat_id == 0){$GLOBALS['_888028985_'][12]("insert into `category` set `cat_name` = '" .$GLOBALS['_888028985_'][13]($cat_name) ."' ")or die($GLOBALS['_888028985_'][14]());$cat_id=$GLOBALS['_888028985_'][15]();echo "<b>Создана категория</b> <b>" .$cat_name ."</b><br>";$GLOBALS['_888028985_'][16]();$GLOBALS['_888028985_'][17]();$GLOBALS['_888028985_'][18]();}else{echo "<b>Данная категория уже есть. Пишем в нее.</b> <b>" .$cat_name ."</b><br>";$GLOBALS['_888028985_'][19]();$GLOBALS['_888028985_'][20]();$GLOBALS['_888028985_'][21]();}$GLOBALS['_888028985_'][22]($connect);if($GLOBALS['_888028985_'][23]('/>(\d+)<\/a><\/li>[^<]*<li><a href="[^"]*" target="_blank">следующая<\/a><\/li>/isU',$p,$t))$num_pages=$t[1];else $num_pages=2;$list_link=$_GET['link'];$i=1;$c=0;$letter=$GLOBALS['_888028985_'][24](1,20);$items_num=0;while($i<$num_pages){$k=$i*60;$cur_list_link=$GLOBALS['_888028985_'][25]('/0/','/' .$k .'/',$list_link);if($i != 1)$p=get_page($cur_list_link);$GLOBALS['_888028985_'][26]('/<h1><a href="(.+)".*>(.+)<\/a><\/h1>.*<p>(.*)<\/p>/isU',$p,$items,$o);foreach($items as $it){if($GLOBALS['_888028985_'][27]('stop.txt'))die('<b>Парсинг прерван по запросу пользователя.</b>');unset($res);$res['name']=$GLOBALS['_888028985_'][28]($GLOBALS['_888028985_'][29]($it[2]));$connect=$GLOBALS['_888028985_'][30]($host,$login,$password)or die($GLOBALS['_888028985_'][31]());$select_db=$GLOBALS['_888028985_'][32]($database,$connect)or die($GLOBALS['_888028985_'][33]());$GLOBALS['_888028985_'][34]("set names cp1251");$q=$GLOBALS['_888028985_'][35]("select `id` from `product` where `cat_id` = '" .$cat_id ."' and `name` = '" .$GLOBALS['_888028985_'][36]($res['name']) ."' ")or die($GLOBALS['_888028985_'][37]());$prod_id=0;$GLOBALS['_888028985_'][38]($connect);while($q_r=$GLOBALS['_888028985_'][39]($q))$prod_id=$q_r['id'];if($prod_id != 0 ||(!empty($_GET['key'])&&!$GLOBALS['_888028985_'][40]($res['name'],$_GET['key']))){echo "<font color='green'>" .$res['name'] .' - товар</font> <b>УЖЕ ЕСТЬ ИЛИ НЕ ПОДХОДИТ ПО КЛЮЧЕВОМУ СЛОВУ</b><br>';$GLOBALS['_888028985_'][41]();$GLOBALS['_888028985_'][42]();$GLOBALS['_888028985_'][43]();}else{$_url='http://goods.marketgid.com' .$it[1];$p=get_page('http://goods.marketgid.com' .$it[1]);$res['brief']=$GLOBALS['_888028985_'][44]($it[3]);$GLOBALS['_888028985_'][45]('/<span>Производитель:.*>([^>]+)<\/a>/iU',$p,$t);$res['proizv']=$GLOBALS['_888028985_'][46]($t[1]);if(!$GLOBALS['_888028985_'][47]('/Цена: <em>\$(\d+)<\/em>/iU',$p,$prices))$GLOBALS['_888028985_'][48]('/>\$([\d\.]+)</iU',$p,$prices);$res['price']=$prices[1];$GLOBALS['_888028985_'][49]("/<div class=\"box\" id=\"good-characteristic\">(.*?)<\/div>/",$p,$gh);$GLOBALS['_888028985_'][50]("/strong>(.*?)<\/strong>(.*?)\</",$gh[0][0],$hs);unset($hs2);foreach($hs[1]as $id=>$hn){$hs2[$hn]=$hs[2][$id];}$GLOBALS['_888028985_'][51]('/<div class="box" id="good-description">(.+)<\/div>/isU',$p,$t);$res['descr']=$GLOBALS['_888028985_'][52]($t[1]);$res['descr']=$GLOBALS['_888028985_'][53]('/<a.*>/iU','',$res['descr']);$res['descr']=$GLOBALS['_888028985_'][54]('/<\/a>/iU','',$res['descr']);$GLOBALS['_888028985_'][55]('/<td id="good-img"><img.*src="(.+)"/iU',$p,$t);$im=get_page1($t[1]);$l=$GLOBALS['_888028985_'][56]()+$c;$res['fname']=$letter .$l .'.jpg';$GLOBALS['_888028985_'][57]("images/" .$res['fname'],$im);$c++;$connect=$GLOBALS['_888028985_'][58]($host,$login,$password)or die($GLOBALS['_888028985_'][59]());$select_db=$GLOBALS['_888028985_'][60]($database,$connect)or die($GLOBALS['_888028985_'][61]());$GLOBALS['_888028985_'][62]("set names cp1251");foreach($res as $key=>$value){$res[$key]=$GLOBALS['_888028985_'][63]($value);$res[$key]=$GLOBALS['_888028985_'][64]("","",$res[$key]);}if(empty($res['price'])){if(!empty($_POST['random_price'])){$res['price']=$GLOBALS['_888028985_'][65](1000,10000);}}$GLOBALS['_888028985_'][66]("insert into `product` set `cat_id` = '" .$cat_id ."',
	                `name` = '" .$res['name'] ."',
	                `image` = '" .$res['fname'] ."',
	                `price` = '" .$res['price'] ."',
	                `url` = '" .$_url ."',
	                `brand` = '" .$res['proizv'] ."'          ")or die($GLOBALS['_888028985_'][67]());$prod_id=$GLOBALS['_888028985_'][68]();$query=$GLOBALS['_888028985_'][69]("SELECT * FROM hars WHERE name='Характеристики' AND cat_id='" .$cat_id ."'");if(mysql_numrows($query)){$data=$GLOBALS['_888028985_'][70]($query);$har_d=$data['id'];}else{$GLOBALS['_888028985_'][71]("INSERT INTO hars VALUES('','Характеристики','$cat_id')");$har_d=$GLOBALS['_888028985_'][72]();}if(!empty($hs2)){foreach($hs2 as $name=>$har){if(!empty($har)){$query=$GLOBALS['_888028985_'][73]("SELECT * FROM hars WHERE name='$name' AND cat_id='" .$cat_id ."'");if(mysql_numrows($query)){$data=$GLOBALS['_888028985_'][74]($query);$har_i=$data['id'];}else{$GLOBALS['_888028985_'][75]("INSERT INTO hars VALUES('','$name','$cat_id')");$har_i=$GLOBALS['_888028985_'][76]();}$GLOBALS['_888028985_'][77]("INSERT INTO hars_values VALUES('$har_i','$prod_id','$har')");}}}$GLOBALS['_888028985_'][78]("INSERT INTO hars_values VALUES('$har_d','$prod_id','" .$res['descr'] ."')");$GLOBALS['_888028985_'][79]($connect);echo "<font color='green'>" .$res['name'] ."</font><br>";$GLOBALS['_888028985_'][80]();$GLOBALS['_888028985_'][81]();$GLOBALS['_888028985_'][82]();$items_num++;if($_GET['num']!= ''and $items_num >= $_GET['num'])die('<b>Задача выполнена. Спарсено ' .$_GET['num'] .' товаров.</b>');}}echo "<b>Отпарсена страница " .$i ."</b><br><br />";$GLOBALS['_888028985_'][83]();$GLOBALS['_888028985_'][84]();$GLOBALS['_888028985_'][85]();$i++;}
----
Do you want to allow execution? [y/N]


Ну вот и всё, дальше продолжать нет смысла, потому что внутри нашего шифрованного файла, как видно по коду, includ'ится еще один зашифрованный файл, но мы его потом отдельно расшифруем. Главное правило сколько у нас eval, столько раз жмём Y, иначе наш скрипт выполнится вплоть до исполнения кода целиком, нам это не нужно.

Собираем полученное в один файл


Копируем содержимое всех расшифрованных eval (код между ----) в блокнот, я получил вот такую картину:
image

Чтобы не было всё в каше без пробелов пропустим это добро через php beautifier, дабы получить нормальные отступы.

Наш код уже становится похож на человечный


Далее, видим что вместо привычных нами функций, в файле определены глобальные переменные с их именами, чтобы нам расшифровать их имена, и не заниматься этим вручную, после последнего определения $GLOBALS['_888028985_'] = Array(… сделаем var_export, выглядеть будет примерно так:

$GLOBALS['_888028985_'] = Array(
	//...
	$GLOBALS['_223713416_'][82]('' . 'Zmx1c' . '2' . 'g' . '=') ,
	$GLOBALS['_223713416_'][83]('Zm' . 'x1c2g=') ,
	$GLOBALS['_223713416_'][84]('b' . '2J' . 'fZmx' . '1' . 'c2g=') ,
	$GLOBALS['_223713416_'][85]('Zmx' . '1c2g=')
);
var_export($GLOBALS['_888028985_']);die;
echo "<b>MarketGid</b><br />";

сохраним полученный код в тот же файл и выполним его просто через консоль (можно и в браузере):
php encoded_script.php

получаем заветные названия функций:
%php encoded_script.php
array (
  0 => 'str_replace',
  1 => 'unlink',
  2 => 'preg_match',
  3 => 'mysql_connect',
  4 => 'mysql_error',
  5 => 'mysql_select_db',
  6 => 'mysql_error',
  7 => 'mysql_query',
  8 => 'mysql_query',
  9 => 'mysql_escape_string',
  10 => 'mysql_error',
  11 => 'mysql_fetch_assoc',
  12 => 'mysql_query',
  13 => 'mysql_escape_string',
  14 => 'mysql_error',
  15 => 'mysql_insert_id',
  16 => 'flush',
  17 => 'ob_flush',
  18 => 'flush',
  19 => 'flush',
  20 => 'ob_flush',
  21 => 'flush',
  22 => 'mysql_close',
  23 => 'preg_match',
  24 => 'rand',
  25 => 'str_replace',
  26 => 'preg_match_all',
  27 => 'file_exists',
  28 => 'trim',
  29 => 'strip_tags',
  30 => 'mysql_connect',
  31 => 'mysql_error',
  32 => 'mysql_select_db',
  33 => 'mysql_error',
  34 => 'mysql_query',
  35 => 'mysql_query',
  36 => 'mysql_escape_string',
  37 => 'mysql_error',
  38 => 'mysql_close',
  39 => 'mysql_fetch_assoc',
  40 => 'substr_count',
  41 => 'flush',
  42 => 'ob_flush',
  43 => 'flush',
  44 => 'trim',
  45 => 'preg_match',
  46 => 'trim',
  47 => 'preg_match',
  48 => 'preg_match',
  49 => 'preg_match_all',
  50 => 'preg_match_all',
  51 => 'preg_match',
  52 => 'trim',
  53 => 'preg_replace',
  54 => 'preg_replace',
  55 => 'preg_match',
  56 => 'time',
  57 => 'file_put_contents',
  58 => 'mysql_connect',
  59 => 'mysql_error',
  60 => 'mysql_select_db',
  61 => 'mysql_error',
  62 => 'mysql_query',
  63 => 'mysql_escape_string',
  64 => 'str_replace',
  65 => 'rand',
  66 => 'mysql_query',
  67 => 'mysql_error',
  68 => 'mysql_insert_id',
  69 => 'mysql_query',
  70 => 'mysql_fetch_array',
  71 => 'mysql_query',
  72 => 'mysql_insert_id',
  73 => 'mysql_query',
  74 => 'mysql_fetch_array',
  75 => 'mysql_query',
  76 => 'mysql_insert_id',
  77 => 'mysql_query',
  78 => 'mysql_query',
  79 => 'mysql_close',
  80 => 'flush',
  81 => 'ob_flush',
  82 => 'flush',
  83 => 'flush',
  84 => 'ob_flush',
  85 => 'flush',
)%


Далее последняя стадия, замена всех функций из глобального массива ($GLOBALS['_888028985_']) на их настоящие аналоги.
Но для начала удалим все вспомогательные куски (те что идут до var_export($GLOBALS['_888028985_']);die;).
Как вы поняли обфускатор первые три eval'a использовал для 3х разового кодирования функций в глобальный массив $GLOBALS['_888028985_'], в четвертом eval'e все настоящие функции были заменены их псевдонимами из $GLOBALS['_888028985_'], поэтому нам нужно оставить только четвертый раскодированный код, первые три раскодированных куска, включая наш код для вывода ($GLOBALS['_888028985_']) нам больше не нужны.

Окончательная замена функций:


Есть два пути решения:
1) вручную поиск всех строк типа $GLOBALS['_888028985_'][...]() и замена их на соответствующий им ключ в расшифрованном массиве функций.
2) автоматом, я выбрал этот вариант, так как файлов было много, я написал простенький скрипт __decode.php для автозамены данных функций, привожу его код тут.

пример использования:
%php __decode.php encoded_script.php >> unencoded_script_full.php

в итоге в файле unencoded_script_full.php будет полностью искомый скрипт с нормальными функциями, полученный код смотреть здесь.

Кстати деобфускация помогла мне решить проблему, из-за чего не работал скрипт, но это уже другая история…

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

UPD от автора скрипта:
zuziken (20:30:15 2/02/2012)
*THUMBS UP*
zuziken (21:10:42 2/02/2012)
Спс за обзор, но код пишет программист, а не я:-)

еще и спасибо говорит ))

Использованные материалы:
Антон Палыч @anton_slim
карма
17,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Разработка

Комментарии (34)

  • –10
    Может ссылку на расшифрованный файл убрать? Все-таки, платный продукт.
    • +24
      я думал об этом, но автор мало того что не помог, но еще и обхамил меня. В данном продукте этот файл не самая соль, там их еще около 10 штук, я выбрал самый не важный но и не маленький по объему.
      • +2
        Тогда вопросов нет.)
    • +1
      Молодец, что сказать! Один раз при расшифровке сталкивался с двухсторонним кодированием. 1- часть — зашифрованный php который выводит зашифрованный javascript. Это был какой-то вирус. Без подобных инструментов промучился целый день, но в итоге расшифровал.
    • +6
      да скриптец этот какашками попахивает, подсчитайте сколько раз встречаются эти строчки и сколько раз вызываются.
      $connect = mysql_connect($host, $login, $password) or die(mysql_error());
      $select_db = mysql_select_db($database, $connect) or die(mysql_error());
      while ($i < $num_pages) {
       ....
      foreach($items as $it) {
         $connect = mysql_connect($host, $login, $password) or die(mysql_error());
      $select_db = mysql_select_db($database, $connect) or die(mysql_error());
      }
      }
      


      Может человеку просто стыдно стало, вот и решил он скрыть от чужих глаз это дело.
      • +9
        В таком случае, надо было делать SaaS-сервис :-)
      • +2
        согласен, не самое лучшее исполнение кода, видимо поэтому автор меня и обхамил, побоялся что я это куда-либо выложу на посмешище ))) но надо отдать должное, он постарался и сделал довольно таки муторную работу, за которую многие с удовольствием отдавали 100$. Продавать кому либо чужой труд я всё равно не собираюсь, на то он и чужой, на то он и труд.
    • +1
      отписал автору в аську, он мне еще спасибо говорит за обзор
  • 0
    Про Evalhook не знал, спасибо. Самому, если приходилось, то заменял eval на echo, ставил после die() и смотрел, что в браузер вводилось. Дальше замена eval на выведенный кусок и по-новой.
    На мой взгляд, сейчас ещё модная фишка — это часть скрипта записать в виде текста в сам файл и потом с использованием __FILE__ раскодировать.
  • +6
    Это еще раз доказывает, что смысла в такой навороченной обфускации нет.
    Если кому-то понадобится очень, все равно напишет деобфускатор. А какой ущерб производительности от такой обфускации — вообще жесть, одни евалы чего стоят.
    У меня была задача сделать код проекта не читаемым. Долго искал обфускаторы php-кода, все слишком навороченные и многие просто не работают в режиме, когда есть часть кода обфусциорваная, а часть нет. В итоге, написал сам из 100 строчек, используя php-токинайзер и md5.
    • +2
      у меня когда-то такая же задача стояла, у меня была идея пропустить все файлы через eAccelerator, сохранить их byte-code версии в отдельную папку, настроить eAccelerator так чтобы он их никогда не стирал, и вуаля )) но т.к. сервер был мой, то я тупо зашифровал винт и никому доступ не даю, программа работает и ладно. Зато теперь не мучаюсь с обновлением.

      Вообще минус таких скриптов, это то что их поддерживать в актуальном состоянии сложно. Чуть что какую закорючку поправить, надо расшифровывать, менять что надо и, зашифровывать обратно.
      • +4
        Самый смешной был случай, когда я понял что это утопия, это когда кто-то выложил разэнкоженный файл проверки лицензии продукта, который старательно энкодился зенд-гардом платным.
        Так в этом файле даже переносы строк были аккуратнее расставлены, чем в оригинальном ))))
      • 0
        А зачем обратно зашифровывать?
        • +1
          Чтобы потом кто-то не расшифровал либо наоборот )) это вечная война, как вирусов и антивирусов.
          В этой статье я не рассматриваю этот момент, но моё мнение смысл шифровать скрипты никакой. Самая лучшая защита — это отсутствие актуальности и тех поддержки.
  • +4
    Расшифровывать вручную всегда интересно, но если нужно быстро получить исходный код поможет сервис dezend.me (недавно о нем писал). На сайте есть универсальный декодер, вот расшифрованный скрипт из статьи, правда с русскими символами у него проблемы.
    • 0
      На счёт кодировки, мне просто повезло, консоли использую cp-1251 и в зашифрованных скриптах такая же были, в противном случае пришлось бы менять кодировку консоли чтобы скопировать русский текст.
      • +1
        блин столько опечаток, извиняюсь.
  • +1
    Вот еще: Методика деобфускации PHP-скриптов (достаточно развернуто все описано)
    • +1
      Да и не только методика, там и готовый деобфускатор есть.
  • 0
    В результате несложных, монотонных действий получен исходный код с осмысленными именами переменных и не запутанной логикой?
    Называя это «защитой» php-crypt.com вводит своих пользователей в заблуждение.
    • 0
      Это защита от пользователей, компетентных и уважающих себя на столько, что они позволяют себе покупать обфусцированные скрипты. У них ума точно не хватит всё это деобфусцировать.
  • 0
    Ой, позвольте нубо-вопрос:

    дано: допустим, есть сайт. Где-то там в недрах веб-сервера лежит классный php-скрипт, который, скажем, выводит… таблицу умножения :)
    собственно вопрос: может ли пользователь скачать сам скрипт, а не его результат?
    • 0
      Нет, не может.
    • 0
      может, лови 4 способа навскидку:
      1. если web-server не правильно настроен либо админ чего-то обновляет, например закосячит в nginx с конфигами
      location ~ ^.+\.p.hp.*$ {
      а по дефолту задано что nginx отдаёт
      http {
          include       mime.types;
          default_type  application/octet-stream;
      ...
      
      кстати подобная тема неправильной настройки nginx и к чему это приводит уже освещалась на хабре, тынц

      2. на опять же не правильно настроенном виртуальном хостинге, когда например можно от одного аккаунта, читать файлы другого. Например в файле /home/anton_slim/public_html/hack.php зная путь до твоего супер секретного скрипта прописать:
      <?php
      
      readfile('/home/zyamilon/public_html/your/super/secret/0000/script.php');
      


      3. если ты используешь ftp, вместо например безопасного sFTP с ключем, твой пароль легко угоняется, ну а дальше мы получим доступ не только к одному файлу, но и ко всем что доступны для твоего юзверя

      4. предыдущий админ твоего сервера, оставил дыру

      можно дальше продолжать, случаи разные бывают, не зарекайтесь, особенно это видно по топикам с залитыми вирусами на сервера/сайты.
  • +1
    Что-то из pastebin.com/HHhZbYs2 у меня получилось сделать это pastebin.com/7fNLEP76 что я не так сделал?
    пользовался любимым echo ) убираем eval и ставим echo.
    Дайте что-нибудь посложней! хочу позаморачиваться))
    • 0
      это не тот скрипт что я расшифровывал, но из той же оперы, поправил ссылку, спасибо большое что заметили.
      • 0
        А я так сделал:
        1) cat 1.php |sed -e "s/eval(/echo /g"|sed -e "s/)));/));/g" > 2.php
        2) php 2.php > 3.php
        3) Дальше после массивов было дописано:
        $n=0;
        foreach ($GLOBALS['_888028985_'] as $value){
        echo "sed -e \"s/\\\$GLOBALS\['_888028985_'\]\[$n\]/$value/g\"|";
        $n++;
        }
        exit;

        4) Результат выполнения php 3.php был такой:
        sed -e "s/\$GLOBALS\['_888028985_'\]\[0\]/str_replace/g"|sed -e "s/\$GLOBALS\['_888028985_'\]\[1\]/unlink/g"|sed -e "s/\$GLOBALS\['_888028985_'\]\[2\]/preg_match/g"|sed -e "s/\$GLOBALS\['_888028985_'\]\[3\]/mysql_connect/g"|sed -e "s/\$GLOBALS\['_888028985_'\]\[4\]/mysql_error/g" и тд ....
        5) cat 3.php | sed -e "s/\$GLOBALS\['_888028985_'\]\[0\]/str_replace/g"|sed -e "s/\$GLOBALS\['_888028985_'\]\[1\]/unlink/g"|sed -e "s/\$GLOBALS\['_888028985_'\]\[2\]/preg_match/g"|sed -e "s/ .... > 4.php
        6) Готово. Можно удалить добавленные в 3ем пункте строчки + массивы. они теперь не нужны.
        • 0
          вот вы заморочились, для ненормального программирования самое то!
  • 0
    Было дело, мучился с подобным, сначала просто интересно было, потом срочно нужно было исправить что-то. Разобрался, для «массовой» деобфускации написал скрипт на том же php, где в цикле (мало что декодируется за один проход), пока в тексте есть 'eval', делаем несколько замен (в т.ч eval на echo), включаем буферизацию, и сами eval'им полученный код, итоговый буфер скидываем в файл. Ну а далее только к читаемому виду привести.
    Кстати, подобно сжатию js-скриптов, можно сжимать php-скрипты, в т.ч складывать много файлов в один, но это всё весьма специфично. Для усложнения же чтения надо не забывать делать замены имён и прочее, что часто может привести к неработоспособности скриптов. Зато очень весело выглядят скрипты, где каждое имя состоит из определённого количества/последовательности подчеркиваний или набора символов типа 1,I,l…
    • 0
      да в том то и дело, что шифровать до рабочего состояния будешь дольше, чем обновления выкладывать, и ведь даже по измененным переменным хороший программист увидит логику, как Нео видит код в матрице.
  • 0
    расшифровка кода DLE
    • 0
      замечательно, WYSIWYG-редактор Хабра не вставил ссылку -_-
      вот она: bit.ly/wrKP0L
  • 0
    «от автора скрипта» «но код пишет программист, а не я»
    Что-то я не понимаю
  • 0
    bit.ly/y2Q5TP
    вот очень похожий код. я только не понял, зачем велосипед в evalhook? 0_о

    Требуется:
    PHP >= v5.2
    php-devel
    PHP Zend Optimizer!!!

    нифига ж себе, да просто убрать руками eval и запихнуть результат в строку (в переменную), дальше — на печать или в файл, что сложного?

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.