Winnyは使わないほうが良い。だけど、どうしても使いたいのなら…

[2007年3月17日 更新] この投稿に対するアクセスが急増しているようだが、「以前のWinnyの投稿へのアクセスが急増しているようだが」も読むようにして欲しい。

会社のブログに書いたWinnyの利用禁止と削除に対して、口頭やメールなどで、いくつかフィードバックをいただいた。

もう使うのは止めよう

いただいたフィードバックの中にはどうしても使いたい人を止められないという意見もあった。

以前ならば、Winnyの技術的な優秀さは理解していたので、情報リテラシーの高いハイスキルの人が、リスクをきちんと把握し、とるべき対策をとった上でならば、使っても良いと考えたかもしれない。

だが、状況は変わった。

バッファーオーバーフローが見つかったということは、いつその脆弱性をついたワームが作成されるとも限らない。そうなったら、悲劇だ。P2Pベースのボットネットが広まるのも時間の問題だろう。現在のIRCベースのものでさえ、発見と対処が難しいのに、P2Pベースはその上をいくと言われている。サイバー犯罪の新たな温床になるだろう。

対策は1つ。Winnyを使わないことだ。

ウィルス対策にはupfolder.txtの監視を

それでもどうしても使わないといられないという人((私にはどういう理由かわからないが))は、upfolder.txtの監視を行うと良いだろう。

開発者である金子氏も「Winnyから情報漏えいを防ぐのは技術的に容易」と言っている。

金子氏の説明によれば、Winnyがネットワークに公開するフォルダ「アップフォルダ」を指定するのは、Winny.exeと同一フォルダに置かれる「Upfolder.txt」というテキストファイルだ。このテキストファイルにはたとえば「Path=D:\Winny\Up」という形で、アップフォルダが指定されることになる。

Winnyそのものはウイルスではない」と語る金子勇氏  Winnyを対象にして情報を公開するウイルスは、このUpfolder.txtを書き換えるなどして、公開するフォルダそのものを変更する。またこれらのウイルスは、Upfolder.txtを「読み込み専用にしても書き込み可能にしてしまうことがある」(金子氏)という。

ならば、このupfolder.txtの監視を行うプロセスをつくり、意図しない変更が加えられた場合には即座にWinnyを停止させてしまえばよいだろう。これは比較的簡単だ。

たとえば、次のようなWSHのスクリプトでもこれは行える。


' ******************************************************************************
' Winnyのupfolder.txt監視スクリプト
'
' 実行方法) c:\>cscript upfoldermon.vbs
'
' upfolder.txtが新たに作成された場合および変更された場合、winny.exeを停止します。
'
' 利用前に下の定数部分の変更が必要です。
'
' このスクリプトの動作により被害を被っても一切責任はとりません。
'
' ******************************************************************************

Option Explicit

Dim strComputer
Dim objWMIService
Dim colMonitoredEvents
Dim objLatestEvent
Dim Process
Dim strMonitoredFolder
Dim strMonitoredFile
Dim strMonitoredProcess
Dim objFSO
Dim regex

' ******************************************************************************
' <<定数>>
'
' strComputer = "." ← ここは変更の必要なし
' strMonitoredFolder = upfolder.txtの作成されるフォルダ名(円マークは四重に)
' strMonitoredFile = upfolder.txtのファイル名(円マークは二重に)
' strMonitoredProcess = Winnyのプロセス名 ← 通常は変更の必要なし
'
' ******************************************************************************

strComputer = "."
strMonitoredFolder = "c:\\\\winny" ' ← 環境にあわせて変更
strMonitoredFile = "c:\\winny\\upfolder.txt" ← 環境にあわせて変更
strMonitoredProcess = "winny.exe"

' upfolder.txtの有無の確認
Set objFSO = CreateObject("Scripting.FileSystemObject")
If (objFSO.FileExists(strMonitoredFile)) Then
' upfolder.txtがある場合は、upfolder.txtの監視を行います。
Call MonitorUpfolder()
Else
' upfolder.txtが無い場合は、フォルダの監視を行います。
Call MonitorWinnyFolder()
' MsgBox "upfolder.txtがありません。", 16, "Winny監視スクリプト"
' WScript.Quit(0)
End If
WScript.Quit(0)

'
' Winnyフォルダの監視
'
Sub MonitorWinnyFolder()
' WMIによるファイルの監視オブジェクトの作成
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & _
strComputer & "\root\cimv2")
Set colMonitoredEvents = objWMIService.ExecNotificationQuery _
("SELECT * FROM __InstanceCreationEvent WITHIN 10 WHERE " _
& "Targetinstance ISA 'CIM_DirectoryContainsFile' and " _
& "TargetInstance.GroupComponent= '" _
& "Win32_Directory.Name=""" & strMonitoredFolder & """'")
' & "Win32_Directory.Name=""c:\\\\winny""'")

' 作成されたファイルがupfolder.txtかどうかの確認
Do
set regex = new RegExp
regex.Pattern="upfolder.txt"
regex.IgnoreCase = True
Set objLatestEvent = colMonitoredEvents.NextEvent
if regex.Test(objLatestEvent.TargetInstance.PartComponent) Then
Call KillWinny() ' Winnyの停止
End If
Loop
End Sub

'
' upfolder.txtの監視
'
Sub MonitorUpfolder()
' WMIによるファイルの監視オブジェクトの作成
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & _
strComputer & "\root\cimv2")
Set colMonitoredEvents = objWMIService.ExecNotificationQuery _
("SELECT * FROM __InstanceModificationEvent WITHIN 10 WHERE " _
& "TargetInstance ISA 'CIM_DataFile' and " _
& "TargetInstance.Name= '" _
& strMonitoredFile & "'")

' ファイルが変更されたかどうかの確認
Do
Set objLatestEvent = colMonitoredEvents.NextEvent
If objLatestEvent.TargetInstance.FileSize <> _
objLatestEvent.PreviousInstance.FileSize Then
Call KillWinny() ' Winnyの停止
End If
Loop
End Sub

'
' Winnyプロセスの停止
'
Sub KillWinny()
for each Process in _
GetObject("winmgmts:{impersonationLevel=impersonate}").ExecQuery _
("select * from Win32_Process where Name='" _
& strMonitoredProcess & "'")
Process.terminate
Next
MsgBox "upfolder.txtが変更されので、Winnyの実行を停止しました。",_
16, "Winny監視スクリプト"
WScript.Quit(0)
End Sub

このスクリプトは次の動作をする。

  • upfolder.txtが存在していない(Winnyでアップロード設定をしていない)場合、スクリプト実行後にupfolder.txtが作成されるとWinnyを停止する
  • upfolder.txtが存在している場合、スクリプト実行後にupfolder.txtが変更されるとWinnyを停止する

Winnyの中から適切な操作でアップロード設定をした場合もupfolder.txtが作成されたり、変更されたりするので、その間はこのスクリプトを止めておく必要がある。

使い方としては、スクリプトを実行させた後にWinnyを起動すると良いだろう。ただし、このスクリプトはあくまでもWinnyの起動中にupfolder.txtを監視するものだ。WinnyからダウンロードしたファイルをWinnyを終了後に起動し、upfolder.txtが追加/変更されてしまうようなケースには対応していない。このようにWinnyがオフラインの際のupfolder.txtの変更を検出するには、Winny起動前にupfolder.txtの内容を確認するのが良いのだろう。

なお、注意して欲しいが、このスクリプトはわずか数十分で片手間に作成したあくまでもサンプルだ。このスクリプトを使って、意図した動作をしなかったり、意図しない問題を引き起こしたとしても、私は一切責任を負わない。また、私はWinny常用者ではない(というか、ほとんど使ったことが無い)。Winnyがupfolder.txtを何かのタイミングで更新することがある場合には、このスクリプトはそれもupfolder.txtへの異常なアクセスと判断し、Winnyを停止させる。私はこのようなケースがあるかどうかを知らないので、このスクリプトがそもそも実際のWinnyの実行時にどこまで使い物になるのかもわからない。もし試される方はこれらを理解した上で試用されたい。