連日投稿30日目。昨日のDay29でサーバーのシェルを操作できたので、そこから機密情報にアクセスできるのかを検証します。
今回の目的
今週はこちらに沿って進めていきます。
正直、リバースシェルを確立したはいいものの、ここからどうやって重要な情報にたどり着くのか、まだ全くイメージが湧いていない。
一旦のゴールは”脆弱性診断を行えるようになる!”なので、やっぱり侵入したサーバー内で、ウェブアプリ(DVWA)が使っているデータベースのパスワードを見つけ出す事(内部においてたらダメだよの診断)ができたらOKかなと。
このチャレンジについて
目的: セキュリティエンジニアとしての技術力向上
手段: シェルスクリプト作成を通じて学習
実施する事: 自動化,監視,ツール開発基礎学習など
目次
結果のイメージ
DVWAのDBのパスワード等はconfig.inc.php
にあるそうな。なのでこれをリバースシェルで見つけるイメージ。
サーバのシェルを操作できるようになった後にこの操作。
# とりあえず /var/www/html を探す...
$ ls /var/www/
ls: cannot access '/var/www/': No such file or directory
# こういう時はfindコマンドで探す。今回はDocker上の作成しているのでこんなところに
$ find / -name "config.inc.php" 2>/dev/null
/var/lib/docker/overlay2/<container_ID>/var/www/html/config/config.inc.php
# 中身を拝見。
$ cat /var/www/html/config/config.inc.php
<?php
# ... (snip) ...
$_DVWA = array();
$_DVWA[ 'db_server' ] = '127.0.0.1';
$_DVWA[ 'db_database' ] = 'dvwa';
$_DVWA[ 'db_user' ] = 'root';
$_DVWA[ 'db_password' ] = 'password'; # <-- こいつ!
# ... (snip) ...
?>
今回も前回同様、DVWAのアカウント権限の問題で、全てリバースシェルで操作可能とまでは行きませんでした。”どうやって脆弱性をつく攻撃から防御するか”に絞って深堀りしています。
実行環境
- クラウド環境: AWS
- コンテナ技術: Docker
- 接続元(ローカルPC): Windows 11
- ターミナルソフト: Windows Terminal
- 接続先(サーバー): DVWA (Dockerコンテナ)
- 使用言語: Shell (bash)
- 外部ライブラリ: なし
- テスト対象: DVWA
ステップ
-
状況確認: リバースシェルで接続後、一般的なWebサーバーのパス
/var/www/html
を探すも、存在せずにはまる。 -
方針転換: パスを推測するのをやめ、
find
コマンドでファイル名config.inc.php
を直接探す方針に切り替える。 -
情報特定:
find
で発見したパスを元にcat
コマンドを実行し、ファイル内からDBのパスワードを特定する。 - 考察: どのようにこれらを防御するべきか
実際のところ、ファイルを探すためにクローラを用いたり、もっと根本を詰める必要があるんだろうけど、全部網羅するのは一旦やめにして、4を今回はメインにしたいなと。
気づき
Dockerのファイルシステム自体が、良い防御策になるのでは?
find
コマンドを実行してファイルが見つかったから良いんだけど、本来DVWAの公式情報では/var/www/htmlにあるはずファイルがなく焦っていた。おかしい....。
数日前の記事でも書いたが、Dockerのコンテナ上で稼働しているのでファイルは別の場所にある。
ここで意識するのは、”DVWAのCommandInjectionテストページで、実際にリバースシェルで確認できるのは、Dockerコンテナに対して" であり、サーバ自体にリバースシェルが仕掛けられる状態ではないこと。
/var/lib/docker/overlay2/<container_ID>/var/www/html/config/config.inc.php
今回の検証では"www-data"の権限の問題で、リーバスシェルを実現するためのnetcatをコマンドインジェクションしても、実際に効果が発揮はされなかった。
(なので前回の検証では、Dockerコンテナでは無くサーバ自体にリバースシェルしてシミュレーションしたが、サーバのシェルを操作→Dockerコンテナにアクセスの流れもできない ※以下参照)
$ su www-data
permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.44/containers/216c2168eee8/json": dial unix /var/run/docker.sock: connect: permission denied
なので、"どう対策を施せばリバースシェルへの脆弱性リスクを減らす事ができるか" というテーマにおいて、
* サーバ自体のシェルにアクセスできないユーザをWEBアプリケーションに割り当てる。
* そのためにDockerコンテナ上でアプリケーションを稼働させる事は、セキュリティの観点から有効。
* (今回はroot権限でDokerを操作かつ、サーバ自体にリバースシェルしたときのユーザが、ec2-userだったため)root権限を奪取できないと、Container IDを確認できず、設定ファイルの確認もできない。
という1つのベストプラクティスが見えてきた気がする。
コード全文
# サーバーのファイルシステム全体から "config.inc.php" という名前のファイルを探す
# "2>/dev/null" は権限エラーを非表示にするためのおまじない。これがないとエラーで画面が埋まる。
find / -name "config.inc.php" 2>/dev/null
# 発見したファイルのパスを指定して、その内容を表示する
cat /var/www/html/config/config.inc.php
コードの詳細な解説
-
find / -name "config.inc.php" 2>/dev/null
- なぜこれが必要か?→侵入直後はサーバーのディレクトリ構成が全く不明だから。闇雲に
ls
を打つより、ファイル名が推測できるならfind
で一発で見つけにいくのが効率的。良いトラブルシューティング経験になった。
- なぜこれが必要か?→侵入直後はサーバーのディレクトリ構成が全く不明だから。闇雲に
-
cat /var/www/html/config/config.inc.php
- なぜこれが必要か?→見つけた設定ファイルから、次の攻撃の足がかりとなる認証情報を抜き出すため。内部偵察の最終目的。
実行方法
- Day29で確立したリバースシェル経由で、標的サーバーに接続する。
- 上記の「コード全文」セクションにあるコマンドを順に実行する。
まとめ
今日は考察がメインだが、「コンテキスト」の重要性を学んだ一日だった。ホストOSとコンテナ、外側と内側。自分がどの視点に立っているのかを理解していないと、正しいコマンドを打っても正しい結果は得られない。
ともあれ、これでDBのパスワードは手に入ったので明日はこれを使って、いよいよDBへの水平展開をやってみます。