Xdebugの関数トレースで難読化されたPHPファイルを動的解析する

職場の同僚に、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.phpeval('if(isset($foo)) { print(\'Hello world\'); }')というPHPコードを実行することが判明した。

Leave a Reply

Your email address will not be published. Required fields are marked *