職場の同僚に、Xdebugの関数トレースを使えば難読化されたPHPファイルをお手軽に解析できると教えてもらったのでメモ。
Xdebugのインストールと設定
インストール環境は以下の通り。
- OS: Ubuntu 14.04.1 LTS
- PHPバージョン: PHP 5.5.9
- Xdebugバージョン: v2.2.3
公式のインストール・ガイドはこちら。
Xdebugをインストールする前にパッケージをアップデートする。
(sudo) apt-get update
Xdebugをインストールする。
(sudo) apt-get install php5-xdebug
Xdebugのインストール先を確認する。
(sudo) find / -name xdebug.so
$ sudo find / -name xdebug.so
/usr/lib/php5/20121212/xdebug.so
Xdebugのインストールが成功したか確認する。以下のコマンドを実行してXdebugのバージョン番号が表示されればOK。
php -v
$ php -v
PHP 5.5.9-1ubuntu4.29 (cli) (built: Apr 22 2019 18:33:52)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies
with Zend OPcache v7.0.3, Copyright (c) 1999-2014, by Zend Technologies
with Xdebug v2.2.3, Copyright (c) 2002-2013, by Derick Rethans
上記より、Xdebugのバージョン2.2.3がインストールされたことが確認できた。
続いて設定ファイルの場所を確認する。
php --ini
$ php --ini
Configuration File (php.ini) Path: /etc/php5/cli
Loaded Configuration File: /etc/php5/cli/php.ini
Scan for additional .ini files in: /etc/php5/cli/conf.d
Additional .ini files parsed: /etc/php5/cli/conf.d/05-opcache.ini,
/etc/php5/cli/conf.d/10-pdo.ini,
/etc/php5/cli/conf.d/20-json.ini,
/etc/php5/cli/conf.d/20-readline.ini,
/etc/php5/cli/conf.d/20-xdebug.ini
編集対象の設定ファイルは環境により異なる。自分の場合は20-xdebug.ini
というファイルを編集する。
php --ini | grep xdebug
$ php --ini | grep xdebug
/etc/php5/cli/conf.d/20-xdebug.ini
$ cat /etc/php5/cli/conf.d/20-xdebug.ini
zend_extension=xdebug.so
設定ファイルに以下を追記する。以下はXdebugの関数トレースを有効化し、ログの出力先として/var/tmp/xdebug-trace
を指定している。関数トレース関連の構文についてはこちらを参照。
xdebug.auto_trace=on ; enable auto trace
xdebug.trace_output_dir="/var/tmp/xdebug-trace" ; output directory
xdebug.trace_output_name="trace-%u" ; output filename
xdebug.trace_format=0 ; human readable format
xdebug.collect_return=1 ; write the return value of function calls to the trace files
$ cat /etc/php5/cli/conf.d/20-xdebug.ini
zend_extension=xdebug.so
xdebug.auto_trace=on ; enable auto trace
xdebug.trace_output_dir="/var/tmp/xdebug-trace" ; output directory
xdebug.trace_output_name="trace-%u" ; output filename
xdebug.trace_format=0 ; human readable format
xdebug.collect_return=1 ; write the return value of function calls to the trace files
上記はXdebugバージョン2の構文で、Xdebugバージョン3の構文とは一部異なる。例えばXdebugバージョン3ではxdebug.auto_traceが廃止され、代わりにxdebug.mode=trace と xdebug.start_with_request=yesを設定する。
上記の設定変更により、PHPファイルを実行するとトレース・ファイルがディレクトリ/var/tmp/xdebug-trace
に作成される。
Xdebugを使って難読化されたPHPファイルを解析する
以下の難読化されたサンプルPHPファイルobfuscated.php
をXdebugで解析してみる。
<?php
$HOge = 'pr'.'eg_'.'re'. 'place';
$fUgaFuGA = "uryAh33333geloqodjkIQs" ^ "\x5a\x13\x3b\x22\x0c\x76\x75\x54\x5b\x5a\x0d\x0e\x20\x02\x1f\x00\x34\x3b\x39\x1a\x7e\x16";
$HOge($fUgaFuGA, "AEdkqoooohNNpnklmdqOMppMOqdmlknpNNhooooqkdEAxyzqSfj" ^ "\x24\x33\x05\x07\x59\x4d\x06\x09\x47\x01\x3d\x3d\x15\x1a\x43\x30\x31\x40\x17\x20\x22\x59\x59\x6d\x34\x51\x14\x1f\x05\x05\x1a\x58\x69\x06\x0d\x03\x03\x00\x4f\x06\x04\x16\x29\x25\x5f\x50\x41\x51\x2e\x44\x43", "aBcdEFghijkLmnoPQRS");
?>
まずは解析対象のPHPファイルを実行する。
php obfuscated.php
すると/var/tmp/xdebug-trace
にトレース・ファイルが作成される。
$ ls /var/tmp/xdebug-trace/
trace-1654179925_870211.xt
作成されたトレース・ファイルを開く。
$ cat /var/tmp/xdebug-trace/trace-1654179925_870211.xt
TRACE START [2022-06-02 14:25:25]
0.0001 229656 -> {main}() /var/www/html/obfuscated.php:0
0.0002 230232 -> preg_replace() /var/www/html/obfuscated.php:7
0.0003 231464 -> preg_replace() /var/www/html/obfuscated.php:7
0.0003 232632 -> eval('if(isset($foo)) { print(\'Hello world\'); }') /var/www/html/obfuscated.php(7) : regexp code:1
>=> NULL
>=> NULL
>=> ''
>=> 1
0.0004 8304
TRACE END [2022-06-02 14:25:25]
上記より、obfuscated.php
はeval('if(isset($foo)) { print(\'Hello world\'); }')
というPHPコードを実行することが判明した。