リリースされたばかりのエクスプロイト: https://www.drupal.org/sa-core-2018-002 --- Drupal core-非常に重要-リモートでコードが実行される- SA-CORE-2018-002
どうなるか
私は個人的にDrupal Drupalgeddon中にハッキングされたサイトであり、類似の重大度の悪用(タイプは異なります)でした。「何が起こるか」という点では、ハッカーはいくつかの「バックドア」ファイルをコードベースに追加しました(その時点では開発についてほとんど知識がなく、Gitリポジトリもありませんでした)。そこから彼はスパムメールを送信できました。関係するドメインはスパムフィルターでブラックリストに登録されていました。そのドメインからメールを送信できるようになったので、その後数か月間保管していました。
この脆弱性によりリモートでコードが実行されるため、攻撃者はおそらくフィッシング攻撃を実行するためのモジュールをインストールし、php exec()を使用してコマンドラインでコマンドを実行し、パスワードを盗み、サーバーの多くを危険にさらす可能性があります。被害は、マシンがスパムエンジンまたはボットネットノードとして募集されているような単純なものから、機密情報がある場合、攻撃者がそれを盗み、再販するか、または情報や攻撃者の動機に応じて脅迫する可能性があります。
ハッキングされたかどうかを確認する方法
ほとんどの場合、サイトは改ざんされません。 14歳のスクリプトキディの2つのグループが互いに近づくと、Goatse画像(NSFW)で改ざんされたサイトが表示される可能性がありますが、ハッカーが個人的に何かをしている場合を除いて、ハッカーはこれを行いません。ハッカーの目標は、お金か、他の誰かのコンピューターで犯罪を犯す能力のどちらかです。
これを念頭に置いて、一般的に表示されるのは新しいユーザー(特に管理ユーザー)の作成であり、ログでは特定のIPが1種類の(異常な)リクエストのみを送信しているのを確認できます。 Drupalgeddonのケースでは、アクセスログのphpファイルへのPOSTリクエストを確認することで、それを理解することができました。
すぐにサイトにパッチを適用できない場合
今すぐサイトにパッチを適用できない場合は、Apache/nginxサーバーをカットして、誰もサイトにアクセスできないようにすることをお勧めします。または、メンテナンスのためダウンしていることを説明するHTMLページ(すべて「ハードメンテナンスモード」)にすべてのトラフィックを送信するようサーバーに指示します。すべての場合において、アップグレードまたはパッチを配置できるまで、訪問者がDrupalをブートストラップすることを許可しないでください。
ハッキングされた私のサイトを思い出してください。最初のDrupalgeddon攻撃はリリース後7時間に始まり、それはスクリプトの形でした。何千ものサイトを自動ハッキング。素早く移動!
ハッキングされた場合
うまくいけば、あなたはバックアップを持っているでしょう。その場合の最善の策は、「サイト全体を軌道から核に入れて」、新しいサーバーでやり直すことです。 Gitと定期的なバックアップを用意していなかったため、手動でDBとファイルの監査を1回行いました-very時間がかかりますが、起こり、深呼吸し、Gitを学び、適切なバックアップ環境をセットアップする方法を学びます。あなたがビジネスとその顧客サイトを持っているなら、真実を彼らに前もって伝えなさい。あなたはおそらくそれらを失うでしょうが、あなたの評判よりも顧客を失う(あなたは新しいものを得ることができます)方が良いです。
誰かがこのエクスプロイトを使用してサイトをハッキングしたかどうかはどうすればわかりますか?
Drupal 7または8のサイトでは、データの損失や盗難が発生したり、データの削除、削除、変更が行われたり、さまざまな方法でサイトに大混乱をもたらす可能性があります。
Webサイトがハッキングされていないかどうかを確認する一般的な情報については、この Stack Exchangeの投稿 を参照してください。
適切に実行された場合、このエクスプロイトで何ができますか?
エクスプロイトは、リモートコード実行の脆弱性です。つまり、すべてのデータが影響を受ける可能性があります。
このエクスプロイトには、21/25のリスクスコアが与えられています。このリスクスコアは、特に次の脆弱性も定義します。
リスクのスコアリングと定義の詳細についてはこちらをご覧ください 。
私は自分のDrupalサイトを更新できません。この穴を簡単にパッチするための良い代替手段は何ですか?
コアをすぐに更新できない場合に利用できるパッチがあります。 Drupal.orgから:
7.xを実行している場合は、 Drupal 7.58 にアップグレードします。 (すぐに更新できない場合は、 このパッチ を適用して、完全に更新できるようになるまで脆弱性を修正できます。)
8.5.xを実行している場合は、 Drupal 8.5.1 にアップグレードします。 (すぐに更新できない場合は、 このパッチ を適用して、完全に更新できるようになるまで脆弱性を修正できます。)
詳細については、 ここにFAQ)があります
パッチの適用方法Drupal 7.x Drupalコア-非常に重要-リモートコード実行-SA-CORE-2018-
Drupal 7.xを使用していて、ライブサイトを7.58に更新できない、パッチの適用に慣れていない、またはDrupalパッチが失敗したバージョンは次のとおりです。
1>ダウンロードして解凍Drupal 7.58。
2> /includes/request-sanitizer.incファイルを7.58ディストリビューションからWebサイトの/ includesディレクトリにコピーします(FTPまたはホスティングコントロールパネルのファイルマネージャーを使用するのが最も簡単です)。
3>ライブWebサイトで/includes/bootstrap.incのバージョンを編集します(最初にバックアップを!)。関数_drupal_bootstrap_configuration()を見つけます。ステートメントdrupal_settings_initialize();の後に次の3行を追加します。 :
// Sanitize unsafe keys from the request.
require_once DRUPAL_ROOT . '/includes/request-sanitizer.inc';
DrupalRequestSanitizer::sanitize();
セーブ。
リラックス。
ここに簡単な1-2-3プロセスがあります:
SSHまたはターミナルアクセスがない場合。ユーザーの@elbソリューションを使用して手動で手動で行う必要があります。
diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc
index 655db6d..880557e 100644
--- a/includes/bootstrap.inc
+++ b/includes/bootstrap.inc
@@ -2632,6 +2632,10 @@ function _drupal_bootstrap_configuration() {
timer_start('page');
// Initialize the configuration, including variables from settings.php.
drupal_settings_initialize();
+
+ // Sanitize unsafe keys from the request.
+ require_once DRUPAL_ROOT . '/includes/request-sanitizer.inc';
+ DrupalRequestSanitizer::sanitize();
}
/**
diff --git a/includes/request-sanitizer.inc b/includes/request-sanitizer.inc
new file mode 100644
index 0000000..1daa6b5
--- /dev/null
+++ b/includes/request-sanitizer.inc
@@ -0,0 +1,82 @@
+<?php
+
+/**
+ * @file
+ * Contains code for sanitizing user input from the request.
+ */
+
+/**
+ * Sanitizes user input from the request.
+ */
+class DrupalRequestSanitizer {
+
+ /**
+ * Tracks whether the request was already sanitized.
+ */
+ protected static $sanitized = FALSE;
+
+ /**
+ * Modifies the request to strip dangerous keys from user input.
+ */
+ public static function sanitize() {
+ if (!self::$sanitized) {
+ $whitelist = variable_get('sanitize_input_whitelist', array());
+ $log_sanitized_keys = variable_get('sanitize_input_logging', FALSE);
+
+ // Process query string parameters.
+ $get_sanitized_keys = array();
+ $_GET = self::stripDangerousValues($_GET, $whitelist, $get_sanitized_keys);
+ if ($log_sanitized_keys && $get_sanitized_keys) {
+ _drupal_trigger_error_with_delayed_logging(format_string('Potentially unsafe keys removed from query string parameters (GET): @keys', array('@keys' => implode(', ', $get_sanitized_keys))), E_USER_NOTICE);
+ }
+
+ // Process request body parameters.
+ $post_sanitized_keys = array();
+ $_POST = self::stripDangerousValues($_POST, $whitelist, $post_sanitized_keys);
+ if ($log_sanitized_keys && $post_sanitized_keys) {
+ _drupal_trigger_error_with_delayed_logging(format_string('Potentially unsafe keys removed from request body parameters (POST): @keys', array('@keys' => implode(', ', $post_sanitized_keys))), E_USER_NOTICE);
+ }
+
+ // Process cookie parameters.
+ $cookie_sanitized_keys = array();
+ $_COOKIE = self::stripDangerousValues($_COOKIE, $whitelist, $cookie_sanitized_keys);
+ if ($log_sanitized_keys && $cookie_sanitized_keys) {
+ _drupal_trigger_error_with_delayed_logging(format_string('Potentially unsafe keys removed from cookie parameters (COOKIE): @keys', array('@keys' => implode(', ', $cookie_sanitized_keys))), E_USER_NOTICE);
+ }
+
+ $request_sanitized_keys = array();
+ $_REQUEST = self::stripDangerousValues($_REQUEST, $whitelist, $request_sanitized_keys);
+
+ self::$sanitized = TRUE;
+ }
+ }
+
+ /**
+ * Strips dangerous keys from the provided input.
+ *
+ * @param mixed $input
+ * The input to sanitize.
+ * @param string[] $whitelist
+ * An array of keys to whitelist as safe.
+ * @param string[] $sanitized_keys
+ * An array of keys that have been removed.
+ *
+ * @return mixed
+ * The sanitized input.
+ */
+ protected static function stripDangerousValues($input, array $whitelist, array &$sanitized_keys) {
+ if (is_array($input)) {
+ foreach ($input as $key => $value) {
+ if ($key !== '' && $key[0] === '#' && !in_array($key, $whitelist, TRUE)) {
+ unset($input[$key]);
+ $sanitized_keys[] = $key;
+ }
+ else {
+ $input[$key] = self::stripDangerousValues($input[$key], $whitelist, $sanitized_keys);
+ }
+ }
+ }
+ return $input;
+ }
+
+}