感染したサイトファイルを悪意のあるコードからクリーニングします。 継続

こんにちは、Habrausers様!



この記事は、この記事の論理的な続きです。 ユーザーAgel_Nashが残したコメントの 1つに、新しいウイルス署名が示されました。 攻撃の対象となるファイル-* .js。



FTPアクセスを変更し、マルウェアからマシンをクリーンアップし、FTPクライアントを変更するための推奨事項に従わなかったクライアントのいくつかのサイトは、このウイルスに一度に感染しました。 次のコードが* .jsファイルに書き込まれます: pastebin.com/2PWJycAd 。 これは、1行で厳密にファイルの最後に配置されます。



簡単な操作を使用して、コードの難読化を解除しました。 興味がある人のために、 このコードの読みやすい外観を広めました( MrMYSTICはすでに同様のコードを示しています )。

難読化解除は最も簡単な方法で実行されました。 私はjsfiddleに行き、evalの代わりに生成されたコードをページに持ってきました。 以下のような簡単な操作を行います:url = 305yoy.bdcfwpndqm.is-a-therapist.com/g/を使用して* .jsファイルへのパスを生成します。その後、結果のパスを持つスクリプト要素を収集し、ページの先頭に追加します。うまくいきました。



サイトをきれいにするために、前の記事で書いたスキャナーを使用しました。 ただし、コメントのコメントを考慮して、少し「くし」にすることにしました。 カロンpro100takの建設的な批判に感謝します (投票できたら+を付けます)。



アルゴリズムは古く、ファイルの行ごとに機能します。 そのため、スキャナーが何をキャッチすべきかを特定する必要がありました。



ただし、指定されたAgel_Nashに基づいて、スキャナは予想外に少数の感染ファイルを示しました。 プロジェクトには数千個ではなくても、数百個の* .jsファイルがあるのは確かです。 私は掘り始め、正しく、信頼するが検証する。 選択された署名は、有限ではないという事実を考慮して、どこでも見つかりませんでした。 他のディレクトリから異なる距離にある複数のファイルを選択的にチェックすると、いくつかのオプションが明らかになりました。

)try{Boolean().prototype.q}catch(egewgsd){f=[
      
      





そして

 )try{Date().prototype.q}catch(egewgsd){f=[
      
      





違いは小さく、いくつかの言葉で構成されています。

 Date()  Boolean()
      
      





おそらく、日付、数値、文字列など、すべてのデータ型をこの方法で並べ替えることができます。 それでは、残りの行、つまり:

 ().prototype.q}catch(egewgsd){f=[
      
      





今回、スキャナはこのウイルスに感染したすべてのファイルを表示しました。 必要なもの! Jquery、fancybox、および使用されるいくつかのライブラリを確認する必要があります。 純粋に...ソースコードにエントリが見つかりませんでした。 素晴らしい、あなたはそれを使用することができます。



スキャナーを少し再設計し、開始しました。 彼は再び計画通りに働き、がっかりしなかった。



変更点:

-署名のリストの収集を開始しました(2つある時点で、目的の行のパラメーターなしでスキャナーを開始できます)。

-ファイルで見つかった署名を示します。

-バックアップを削除する機能を追加(delete_backups());

-関数はパラメーターなしで呼び出すことができます(この場合、デフォルトのものが使用されます)

  $dron->find(); $dron->scan(); $dron->restore_backups(); $dron->delete_backups();
      
      





-スキャナーが作業中にディレクトリの所有者を変更する機能を追加しましたが、このセクションをコメントアウトしました。 私はテストできませんでした:

  /* //     $unformated_path_stat = stat($path); $path_stat = posix_getpwuid($unformated_path_stat['uid']); $path_user_name = $path_stat['name']; //     chown($path, 'www'); */ ... //     // chown($path, $path_user_name);
      
      





-すべてのファイルを配列に収集する関数dir_content()を追加しました。これは、他のすべての関数で使用されます。

-スキャン時に、自身を無視します。



更新されたスキャナーのコードを、詳細なコメントとともにお届けします。

 <? /* ---------------------------------------------------------------------------------- dScaner Class - START ---------------------------------------------------------------------------------- */ /** * @param : dScaner * @param :          *    * * @param :   * @param  : 0.0.5 (13-04-2012) * */ Class dScaner { //   private $arr_files = array(); //     public $signatures = array( '=Array.prototype.slice.call(arguments).join(""),', '().prototype.q}catch(egewgsd){f=[' ); /** *      * * @param string $get_str   * @param string $separator     * @return array -    FALSE */ function request($get_str, $separator) { if (!empty($get_str)) { //        $obj = explode($separator, $get_str); return $obj; } else { return false; } } /** *       * * @param string $path -   ,      * @param string $files_allowed -  ,    */ function dir_content($path = './', $files_allowed = '.') { //      ,    $dir_disallow = array('.', '..', '.htaccess', '.git', 'zlordwaters'); if(is_dir($path)) { $temp = opendir($path); while (false !== ($dir = readdir($temp))) { if ((is_dir($path . $dir)) && (!in_array($dir, $dir_disallow)) ) { //   -   $sub_dir = $path . $dir . '/'; $this->dir_content($sub_dir, $files_allowed); } elseif ((is_file($path . $dir)) && (!in_array($dir, $dir_disallow)) && (strpos($dir, $files_allowed) == true) && (strpos($dir, '_BACKUP') == false) && (strpos($dir, trim($_SERVER['SCRIPT_NAME'], '/')) === false) ) { //  ,     $this->arr_files[] = $path . $dir; } } closedir($temp); } } /** *       : * * @param string $path -   ,      * @param string $files_allowed -  ,    * @param string $requested_string -   */ function find($path = './', $files_allowed = '.', $requested_string = '().prototype.q}catch(egewgsd){f=[') { //      $this->dir_content($path, $files_allowed); foreach($this->arr_files AS $in_dir_file) { //     $temporary_file = file_get_contents($in_dir_file); //      $file_founded = false; //     $tf_strings = explode("\n", $temporary_file); //    foreach ($tf_strings AS $item) { //     $item = strval($item); if (strpos($item, $requested_string) !== false) { $file_founded = true; $founded_str = $requested_string; } //     foreach ($this->signatures AS $signa) { $signa = strval($signa); if (strpos($item, $signa) !== false) { $file_founded = true; $founded_str = $signa; } } } //      if ($file_founded) { //         print "<span style='display:block; padding:5px; border:1px solid #1f4f18; background-color:#d5f5ce; font-size:12px; line-height:16px; font-family:tahoma, sans-serif; margin-bottom:-15px;'><h3>" . $in_dir_file . "</h3>     . <br> C: <b>" . $founded_str . "</b> </span><br>"; } } } /** *    : * * @param string $path -   ,      * @param string $files_allowed -  ,    * @param string $requested_string - ,       */ function scan($path = './', $files_allowed = '.', $requested_string = '().prototype.q}catch(egewgsd){f=[') { //      $this->dir_content($path, $files_allowed); foreach($this->arr_files AS $in_dir_file) { //     $temporary_file = file_get_contents($in_dir_file); //    $create_backup = false; //         $tf_strings = explode("\n", $temporary_file); //    $str_index = 0; //     foreach ($tf_strings AS $item) { //     $item = strval($item); if (strpos($item, $requested_string) !== false) { //        //   ,      $create_backup = true; //       unset($tf_strings[$str_index]); $founded_str = $requested_string; } //     foreach ($this->signatures AS $signa) { $signa = strval($signa); if (strpos($item, $signa) !== false) { //        //   ,      $create_backup = true; //       unset($tf_strings[$str_index]); $founded_str = $signa; } } //     $str_index++; } //   if ($create_backup) { /* //     $unformated_path_stat = stat($path); $path_stat = posix_getpwuid($unformated_path_stat['uid']); $path_user_name = $path_stat['name']; //     chown($path, 'www'); */ //              chmod($path, 0777); //     $temp_file_backup = $in_dir_file.'_BACKUP'; //       file_put_contents($temp_file_backup, $temporary_file); //      $scanned_file = implode("\n", $tf_strings); //    if (file_put_contents($in_dir_file, $scanned_file)) { //   print "<span style='display:block; padding:5px; border:1px solid #1f4f18; background-color:#d5f5ce; font-size:12px; line-height:16px; font-family:tahoma, sans-serif; margin-bottom:-15px;'><h3>" . $in_dir_file . "</h3>  . (+ BACKUP) <br> C: <b>" . $founded_str . "</b> </span><br>"; } else { //    print "<span style='display:block; padding:5px; border:1px solid #822121; background-color:#ea7575; font-size:12px; line-height:16px; font-family:tahoma, sans-serif; margin-bottom:-15px;'><h3>" . $in_dir_file . "</h3>   . C: <b>" . $founded_str . "</b> </span><br>"; } //          755 chmod($path, 0755); //     // chown($path, $path_user_name); } } } /** *     * * @param string $path -   ,      * @param string $files_allowed -  ,    */ function restore_backups($path = './', $files_allowed = '.') { //      $this->dir_content($path, $files_allowed); foreach($this->arr_files AS $in_dir_file) { if (is_file($in_dir_file.'_BACKUP')) { //  ,    $temporary_file_from_backup = file_get_contents($in_dir_file.'_BACKUP'); //    if (file_put_contents($in_dir_file, $temporary_file_from_backup)) { //   unlink($_SERVER['DOCUMENT_ROOT'].'/'.$in_dir_file.'_BACKUP'); //   print "<span style='display:block; padding:5px; border:1px solid #1f4f18; background-color:#d5f5ce; font-size:12px; line-height:16px; font-family:tahoma, sans-serif; margin-bottom:-15px;'><h3>".$in_dir_file ."</h3> . </span><br>"; } else { //    print "<span style='display:block; padding:5px; border:1px solid #822121; background-color:#ea7575; font-size:12px; line-height:16px; font-family:tahoma, sans-serif; margin-bottom:-15px;'><h3>".$in_dir_file ."</h3>  . </span><br>"; } } } } /** *     * * @param string $path -   ,       * @param string $files_allowed -  ,    */ function delete_backups($path = './', $files_allowed = '.') { //      $this->dir_content($path, $files_allowed); foreach($this->arr_files AS $in_dir_file) { if (is_file($in_dir_file.'_BACKUP')) { //  ,   if (unlink($_SERVER['DOCUMENT_ROOT'].'/'.$in_dir_file.'_BACKUP')) { print " <span style='display:block; padding:5px; border:1px solid #1f4f18; background-color:#d5f5ce; font-size:12px; line-height:16px; font-family:tahoma, sans-serif; margin-bottom:-15px;'><h3>".$in_dir_file ."_BACKUP</h3> . </span><br>"; } else { //    print "<span style='display:block; padding:5px; border:1px solid #822121; background-color:#ea7575; font-size:12px; line-height:16px; font-family:tahoma, sans-serif; margin-bottom:-15px;'><h3>".$in_dir_file ."_BACKUP</h3>  . </span><br>"; } } } } } /* ---------------------------------------------------------------------------------- dScaner Class - END ---------------------------------------------------------------------------------- */ ?>
      
      





さて、基本的な検索パラメーターの使用例。

 <? //    -  $dron = new dScaner; //       $dron->find('./', '.'); //   // $dron->scan('./', '.'); //    // $dron->restore_backups('./', '.'); //    // $dron->delete_backups('./', '.'); ?>
      
      







実際に私があなたと共有したかったのはそれだけです。

クリーンなサーバーとその安定した動作。

よろしく!



All Articles