
PrestaShop (1.6.x <= 1.6.1.23 または 1.7.x <= 1.7.4.4) バックオフィス リモートコード実行 (CVE-2018-19126)
これは CVE-2018-19126 の PoC であり、PrestaShop バックオフィスにおける複数の脆弱性を連鎖させ、phar を介したデシリアライゼーションを引き起こし、リモートコード実行を達成するものです。
前提条件:

PrestaShop リリースノート: http://build.prestashop.com/news/prestashop-1-7-4-4-1-6-1-23-maintenance-releases/
脆弱パッケージリンク: https://assets.prestashop2.com/en/system/files/ps_releases/prestashop_1.7.4.3.zip
教育目的のみに使用してください。このスクリプトを違法行為に使用しないでください。作成者は誤用や損害について一切責任を負いません。
エクスプロイトを実行するには、curl 拡張機能を備えた php と、php.ini で phar.readonly = Off を設定する必要があります。
# Download repository
wget https://github.com/farisv/PrestaShop-CVE-2018-19126/archive/master.zip -O PrestaShop-CVE-2018-19126.zip
unzip PrestaShop-CVE-2018-19126.zip
cd PrestaShop-CVE-2018-19126-master
# Run the exploit
# Usage: php exploit.php back-office-url email password func param
php exploit.php http://127.0.0.1/admin-dev/ [email protected] 54l35m4n123 system 'cat /etc/passwd'
アップロードディレクトリはリネームされ、フォルダ名が元に戻されていない限り、悪意のある phar ファイルを再度アップロードすることはできません。永続的な RCE を得るためにリバースシェルを実行するか、ペイロードにフォルダ名を再度リネームするコマンドを含めることを検討してください(アップロードディレクトリへのパスを知っている必要があります)。
[back-office-path]/filemanager/ajax_calls.php の getimagesize() 関数を介して、phar ラッパーによる暗黙のデシリアライゼーション を達成できます。
case 'image_size':
if (realpath(dirname(_PS_ROOT_DIR_.$_POST['path'])) != realpath(_PS_ROOT_DIR_.$upload_dir)) {
die();
}
$pos = strpos($_POST['path'], $upload_dir);
if ($pos !== false) {
$info = getimagesize(substr_replace($_POST['path'], $current_path, $pos, strlen($upload_dir)));
echo json_encode($info);
}
特定のチェックをバイパスして、getimagesize() が phar ラッパー URL をパラメータとして呼び出されるようにする方法を見つける必要があります。
最初の realpath() によるチェックはかなり厳格です。
if (realpath(dirname(_PS_ROOT_DIR_.$_POST['path'])) != realpath(_PS_ROOT_DIR_.$upload_dir)) {
die();
}
$upload_dir 変数は config.php から来ており、デフォルトでは $upload_dir = Context::getContext()->shop->getBaseURI().'img/cms/'; と設定されています。$_POST['path'] に phar://[string] を使用することはできません。なぜなら realpath(dirname(_PS_ROOT_DIR_.$_POST['path'])) が存在しないため false を返すからです。
別の脆弱性 (CVE-2018-19125) が存在し、ユーザーが $upload_dir を削除またはリネームできます。$upload_dir ディレクトリが存在しない場合、realpath(_PS_ROOT_DIR_.$upload_dir) は false を返し、realpath(dirname(_PS_ROOT_DIR_.$_POST['path'])) も false になるため、このチェックをバイパスできます。この脆弱性は、バイパス方法を探している際のコードレビュー中に発見されました:)。
要するに、CVE-2018-19125 では、execute.php の delete_folder または rename_folder アクションへの呼び出しにおいて path パラメータを空にできるため、アプリケーションは代わりに $upload_dir を削除/リネームします。
2 つ目のチェックは単純で、$_POST['path'] に $upload_dir を含める必要があります。
$pos = strpos($_POST['path'], $upload_dir);
if ($pos !== false) {
phar ファイルへのファイルパスの後、phar URL に /img/cms/ を単に追加できます。なぜなら、phar アーカイブ内にディレクトリが存在しなくても、デシリアライゼーションは依然として発生するからです。substr_replace($_POST['path'], $current_path, $pos, strlen($upload_dir)) は /img/cms/ をそのフォルダの絶対パス ($current_path) に置き換えるだけです(例:アプリケーションが /var/www/html/ にインストールされている場合、/var/www/html/img/cms/)。
getimagesize() 関数を制御して phar ラッパー URL を処理できるため、悪意のある phar ファイルをサーバーにアップロードする必要があります。デフォルトでは、PrestaShop の FileManager は 'jpg', 'jpeg', 'png', 'gif', 'bmp', 'tiff', 'svg', 'pdf', 'mov', 'mpeg', 'mp4', 'avi', 'mpg', 'wma', 'flv', 'webm' の拡張子のみを許可します。ペイロードを作成し、有効な拡張子で保存するだけです。PrestaShop で使用されている PHPGGC の Monolog ガジェットチェーン (https://github.com/ambionics/phpggc/blob/master/gadgetchains/Monolog/RCE/1/) を使用できます。
最終的なエクスプロイト手順:
path パラメータとして phar://../../img/renamed/phar.pdf/img/cms/ を使用して image_size アクションを呼び出します。exploit.php スクリプトはすべての手順を自動的に実行します。
手順 3 でアップロードディレクトリはリネームされ、フォルダ名が元に戻されていない限り、悪意のある phar ファイルを再度アップロードすることはできません。ペイロードとしてリバースシェルを使用するか、ペイロードにフォルダ名を再度リネームするコマンドを含めることを検討してください (アップロードディレクトリへのパスを知っている必要があります)。