Muzzy's research about Sony's XCP DRM systemより。
MuzzyによるソニーXCP DRMシステム調査報告
ソニーのXCP DRM rootkitについて独自に調査した結果をいくらか集めてみた。 どうぞごゆっくり。 新情報を発見するたびにページを書き換えているから、後日また確認するといい。
簡潔なXCP DRMシステムのまとめと、 切り離してある意見のページもある。 このページは事実にこだわろうとするものなので、何かバイアスがかった表記や間違いがあると思ったら、 メールで知らせてくれると嬉しい。
最近の更新
- ECDPlayerControl.ocxからGPLコードが発見された。するとDMCAおよび EUCDにまで違反することになるのかな? 詳しいことはページの下のほうに書いてある。
- Sabre Securityの助力もあって、 Sebastian PorstがECDPlayerControl.ocxにmpglibが含まれていることを確認した。
- 同じファイルからさらに複数の著作権侵害行為が発見された。
- Sam Hocevar(GPLなDRMSコードの共同開発者)がXCPで実際に使われている実装について、彼自身のGPLなコードに起源を持つものであることを確認した。
アンインストーラ
このアンインストーラは、ちょうどユーザがアンインストーラのURLをリクエストできるようになる直前、 あるActiveXコントロールをシステムにインストールすることを命じる。 アンインストーラのActiveXは自身の安全を確保すべく注意を払って書かれているのだけれど、結局、 盛りだくさんの興味深いメソッドを、誰もが利用できるようにしてしまう性質を持ってしまっている。 これらについてはそれほど深く検証していないのだけど、とりあえずひとつだけ試してみたら、 そうなるだろうと思った通りに動いた。これはいわゆる「RebootMachine」というやつだ。 もしソニーのActiveXコントロールをインストールしたことがあるなら、 invoke the RebootMachine methodのリンクを踏んでみなよ。(訳注:危ないから踏むなよ) ともかく、ExecuteMethodメソッドのなんたるかは十分わかってもらえたと思う。
このInstallUpdateメソッドは、実はもっと大きなセキュリティホールを持ってるんだけど、それはfreedom-to-tinker.com's post about the uninstaller hole.を参照のこと。 彼らは、脆弱性があるかどうかを試すのに僕のリブート・デモが使われることで、事態が悪化するかもしれないと懸念している。 なぜならこれは、F4Iのサイトからhtmlをコピー&ペーストしたもので、 元々はActiveXコントロールのインストールを催促するのに使われていたからだ。 F4Iだっていつでもどんな方法でもインターフェイスを変更することはできたはずなのだけど。 僕のは変更しといたから、デモにインストール能力を持たせるような用途には役に立たないはずだよ。
アンインストーラが置き去りにしていくスクリプト・メソッドの数々
問題のアンインストーラは数々のメソッドを置き去りにしていく。これはそのリストだ。
- GenerateRequestPacket
- ExecuteCode (ブラクラに悪用できる。どうも最新のocxでは除去されているようだ。)
- Uninstall
- RebootMachine (デモを見ればわかるとおり、悪用される。)
- GetProgress
- OnLoaded
- InitializeDiscScan
- GetNumberOfDiscs
- IsDRMServerValid
- GetAlbumArtist
- GetAlbumName
- GetMaxBurnCount
- GetCurrentBurnCount
- GenerateIncrementPacket
- IsContentOwnerValid
- DoIncrement
- GetInstalledSoftwareVersion
- IsXCPDiscPresent
- InstallUpdate (exploitable)
- GetInstallProgress
- GetCompletionStatus
- IsXCPDiscPresentAsLong
- IsAdministrator
これらを使えば誰でもコンピュータを再起動させられることを考えると、 これを開発している間、1秒たりともセキュリティについて考えたことがないのではとさえ思える。 ウィルス作者やその手の世界はこうしたメソッドを解析することにとても興味を持つことだろう。 これらのうちのいくつかは間接的に利用できるだろうから・・・意図的に。
マジックリスト
問題のインストーラとプレイヤーは両方とも、ある興味深いリストを含んでいる。 実行ファイル名、ウィンドウ名、などなどが載っているものだ。 現段階ではこれらが何に使われる物なのかはわからないが、およそブラックリストシステムであろうと推測できる。 あなたも同じような推測をすることだろうけど、だがしかし実は問題のDRMシステムは2秒毎にリストを読み取っているのだ。
これらのリストに載っているプロセスのAPIをフックして、DRMシステムがノイズ付加を行うと伝えてきたけど、 今のところまだ確証は得られていない。
LAMEとの関係は?
問題のCDにあるファイル「Contents\GO.EXE」が、とある文字列を含んでいるのだ。
00056c18 68 74 74 70 3a 2f 2f 77-77 77 2e 6d 70 33 64 65 http://www.mp3de
00056c28 76 2e 6f 72 67 2f 00 00-30 2e 39 30 00 00 00 00 v.org/..0.90....
00056c38 4c 41 4d 45 33 2e 39 35-20 00 00 00 33 2e 39 35 LAME3.95 ...3.95
00056c48 00 00 00 00 33 2e 39 35-20 00 00 00 00 00 00 00 ....3.95 .......
GO.EXEにLAMEがリンクされているのはうっかりミスのように見えるが、 少なくともECDPlayerControl.ocxにおいては完全に利用されており、どう見てもうっかりリンクされたものではない。 LAMEを検知するのに使ったのではないかと推測する人もいるかもしれないが、それは事実と異なる。 GO.EXEはこのデータとはどう見ても無関係、つまりそこでは全く使われていないということだ。 つまり、彼らは混乱してついうっかりインストーラに対してLAMEをリンクしてしまったのである。 本来LAMEが使われ必要とされるはずの、DRMシステムの別のコンポーネントにだけリンクされるべきところを。
問題のCDには、LAMEの文字列を含むファイルが全部で4つもあり(うち3つはXCP.DATに圧縮格納されている)、 その上少なくとも1つは、LAMEのコードをも含んでいるように見える。これは確実に著作権侵害である。 なお、Sebastian Porstのblog記事にもLAMEが問題のDRMとともに出荷されている旨の記載がある。
多くの人々が気づいていることだろうが、ソニーBMGもF4Iも MP3特許のライセンス供与を受けているようには見えない。LAMEのコードを盗用したことは特許権侵害をも引き起こすのである。 しかし昨今、まったくもってとんでもない量の特許があり、表に出ているソフトウェアのほとんどは何らかの意味でそれに囲まれていると考えられることには留意すべきである。 この件に限って言えば事の起こりからしてあまりに露骨すぎる。なにしろ既知の特許範囲にある既知のソフトウェアを含んでいるのだから。 また、ソニーBMGが少しでもリストアップの手を休めたなら、ソニーにも、そして少なくとも僕にも、 特許ライセンス供与というものが実際のところどう働き、誰がそれを求めるのかということの糸口すら見出すことはできやしないのだ。 特許事情に関わらないで何かを公表しようと企図するなら、己の中に真実を問うしかないと考えておいたほうがいい。
XCP.DATにある謎の物体
CDからXCP.DATを取り出して展開してみたところ、あまりに驚くべき代物が中に入っていることを発見してしまった。 その物体達を一見したところ、どうもmpglib.dll、とあるバージョンのbladeenc.dll、などなどのようだ。 両方ともLGPLで、僕の理解が及ぶところでは、これらについては付属文書にて言及しない限り利用してはならない。 (頒布も駄目なんだったかな?)
問題のCDにはAdaptecのASPIなブツも含まれているが、頒布の許可を取ってあるようには見えない。 まああれだ。この上何を調査したものかと途方に暮れてしまったよ。 とはいえこれらのファイルは最終的にシステムにインストールされ、とても目立つ場所(windows\system32\TMPX)に置かれるわけだから、 もしかすると、いくらF4Iでもそこまで露骨な侵害行為を行うほど馬鹿じゃないかもしれん。
この上Id3Libまである。それも極めて目立つ形式でだ。問題のCDに記載はないが、 ソニーは一方でOpenMG関連物と一緒に自社サイトでId3Libのソースを配布しているわけで、 問題のDRMがLGPL版を使っているのか、古いパブリックドメイン版を使っているのかは不明だ。
ECDPlayerControl.OCXファイルはこれらのLGPLライブラリを実際に使っていると考えられ、 付属文書にはライセンスも言及もないのだから、それはおそらくLGPLに従っていないことを意味し、 また、それ故に複数のオープンソースプロジェクトの著作権をも侵害していることになる。 これらのファイルを誰もが等しく確認できるように共有できたらいいなあと思うけれど、 それをやったらそれこそ著作権侵害になってしまうね。
ECDPlayerControl.ocx
LGPLおよびGPLコードの著作権を侵害し、DMCAおよび EUCDにおいて非合法となるもの。
まさに祭り進行中という感じだ。上で述べたLAMEのコード発見に加えて、 GPLなコードまでもが同じように出現してくる。僕は法律家ではないけれど、これはDMCAおよび EUCD違反でもあるんじゃないのか? 問題となっているコードはVLCのdemux/mp4/drms.c−ほかでもないApple社のDRMを回避するための対DRMSコードである。 制御フローは同一で定数はすべて等しく(どうやらひとつだけ例外があるらしいが)、2つのマジックナンバーで構成された配列も同様に一致。 p_secret2という文字列配列も含まれていて、それはrot13暗号化されたAppleの著作権表示文字列だったという(特定のアルゴリズムでデータとして使われているらしい)。
もしXCPをシステムで飼っているなら、system32ディレクトリにECDPlayerControl.ocxを見に行ける。 こいつの中身に"Nccyr"で検索をかけてみるといい。もし逆アセンブラを持っているなら、仮想アドレス0x10089E00にある関数を見て、 drms.cのDoShuffle()関数と比べてみよう。類似点に気づくはずだ。
この件について読んでおくべき記事を挙げるなら、Sebastian Porstのmpglib code found in ECDPlayerControl.ocxと、 それがVLCにおける彼自身の書いたコードに起源を持つものであることを確認した、Sam Hocevar's confirmationがおすすめかな。
First4Internetのocxファイルをダンプしたもの
00108018 aa aa aa aa 00 77 75 01-80 45 55 00 00 45 72 01 .....wu..EU..Er.
00108028 80 45 42 00 00 77 42 01-80 00 00 00 01 9d d5 c1 .EB..wB.........
00108038 81 49 14 80 01 89 5c 81-81 49 54 80 01 5d d4 81 .I....\..IT..]..
00108048 80 00 00 00 03 bb a3 81-82 aa a2 00 03 bb a3 01 ................
00108058 82 a2 22 00 02 a2 3b 81-80 00 00 00 37 57 57 6d .."...;.....7WWm
00108068 a5 75 52 4a 25 57 52 6d-a5 54 52 4a 37 54 72 6b .uRJ%WRm.TRJ7Trk
00108078 80 00 00 00 38 b9 dd d5-92 a0 55 54 13 a0 95 5d ....8.....UT...]
00108088 92 a1 15 44 3a 39 dd c5-80 00 00 00 55 55 55 55 ...D:9......UUUU
00108098 70 62 63 6c 65 76 74 75-67 20 28 70 29 20 4e 63 pbclevtug (p) Nc
001080a8 63 79 72 20 50 62 7a 63-68 67 72 65 2c 20 56 61 cyr Pbzchgre, Va
001080b8 70 2e 20 20 4e 79 79 20-45 76 74 75 67 66 20 45 p. Nyy Evtugf E
001080c8 72 66 72 65 69 72 71 2e-00 00 00 00 d4 ee 0a 10 rfreirq.........
VLC、drms.c、DoShuffle()関数より抜粋した変数宣言部
p_secret2文字列はAppleの著作権表示文字列をrot13アルゴリズムで暗号化したもので、 DRM処理の過程でデータとして使われている。 僕はこれを、Appleが法廷闘争を想定して埋め込んでおいたものではないかと想像している。 彼らがこのDRMシステムを作った明瞭な印だし、 これでプロテクトされた著作物をデコードしようとする人は誰でもその文字列を使わなければならないのだ。 そしてJonはrot13をプレーンテキスト形式にしてみせることなく処理していた。 もっとも、この文字列がたとえAppleによって作られたものであろうと、 これが存在することだけではAppleの著作権が侵害されているということの印にはなるまい。
static uint32_t p_secret1[] =
{
0xAAAAAAAA, 0x01757700, 0x00554580, 0x01724500, 0x00424580,
0x01427700, 0x00000080, 0xC1D59D01, 0x80144981, 0x815C8901,
0x80544981, 0x81D45D01, 0x00000080, 0x81A3BB03, 0x00A2AA82,
0x01A3BB03, 0x0022A282, 0x813BA202, 0x00000080, 0x6D575737,
0x4A5275A5, 0x6D525725, 0x4A5254A5, 0x6B725437, 0x00000080,
0xD5DDB938, 0x5455A092, 0x5D95A013, 0x4415A192, 0xC5DD393A,
0x00000080, 0x55555555
};
static char p_secret2[] =
"pbclevtug (p) Nccyr Pbzchgre, Vap. Nyy Evtugf Erfreirq.";
ECDPlayerControl.ocxを逆アセンブルしたもの
最初の3つのswitch・case文は逆アセンブルしたものの外側にあるのに、ジャンプがあることに注目して欲しい。 defaultの場合も明白にコードが一致することを見て取れるだろう。
.text:10089E90 mov eax, [edx] ; p_commands[i]
.text:10089E92 test eax, eax ; if zero,
.text:10089E94 jz loc_10089F21 ; continue loop
.text:10089E9A mov cl, al ; i_index
.text:10089E9C shr eax, 8 ; source code ands first
.text:10089E9F and eax, 3 ; same as (&0x300)>>8
.text:10089EA2 dec eax
.text:10089EA3 jz short loc_10089F03 ; case 1
.text:10089EA5 dec eax
.text:10089EA6 jz short loc_10089EE5 ; case 2
.text:10089EA8 dec eax
.text:10089EA9 movzx eax, cl
.text:10089EAC jz short loc_10089EC9 ; case 3
.text:10089EAE mov ecx, eax
.text:10089EB0 add eax, eax
.text:10089EB2 mov ebx, offset unk_100C5D46
.text:10089EB7 sub ebx, eax
.text:10089EB9 movsx eax, word ptr [ebx]
.text:10089EBC shr ecx, 4 ; i_index>>4
.text:10089EBF mov ebx, [esi+ecx*4]
.text:10089EC2 lea ecx, [esi+ecx*4]
.text:10089EC5 add ebx, eax
drms.cから抜粋したコード
if( !p_shuffle->p_commands[ i ] )
{
continue;
}
i_command = (p_shuffle->p_commands[ i ] & 0x300) >> 8;
i_index = p_shuffle->p_commands[ i ] & 0xff;
switch( i_command )
{
case 0x3:
p_bordel[ i_index & 0xf ] = p_bordel[ i_index >> 4 ]
+ p_bordel[ ((i_index + 0x10) >> 4) & 0xf ];
break;
case 0x2:
p_bordel[ i_index >> 4 ] ^= p_shuffle_xor[ 0xff - i_index ];
break;
case 0x1:
p_bordel[ i_index >> 4 ] -= p_shuffle_sub[ 0xff - i_index ];
break;
default:
p_bordel[ i_index >> 4 ] += p_shuffle_add[ 0xff - i_index ];
break;
}
DeDRMSがこんなところで何をしているのか?
目下憶測であるが、F4IはGPLコードを非合法に使うことにより、 開発をスピードアップさせたかったのだろうと想像している。 VLCについてもおそらくそうで、結果的に諸々の残存物とともにDeDRMSの欠片を持つ羽目になってしまったのだろう。 BinDiffで照合してみれば、VLCのlibmp4とXCPとの間にいくらか一致する部分はある。 とはいえ、合法的にコードを再利用していた別のやはりGPLなプロジェクトからコードを拾ってきた可能性も捨てきれない。 解析されたコードにおけるVLCとXCPとの間のごくわずかな相違点は、コードのバージョン違いか、 あるいは別のプロジェクトに由来することで説明できるのではあるまいか。 Sebastian Porstによる注釈付き逆アセンブルは、問題のソースとdrms.cとの同一性を如実に表している。 ただひとつの例外を除いてではあるが。
責任は誰にある?
これについて僕は度が過ぎるほどに激しい意見を持っているのだが、それを知りたいと思うなら隔離してあるページ、Rant and Whineを読んでくれるといい。
ソニーの主張するところでは、開発はF4Iによってなされ、 ただ単にソフトウェアのライセンスを受けただけだから自らは潔白だという。 けれどもECDPlayerControl.ocxが、デバッグにでも使われていたであろう興味深い文字列を含んでいる。 開発者のファイルシステム情報を浮き彫りにする文字列だ。 問題となっているプロジェクトの開発に使われたディレクトリ名は「XCP Player Code\Sony ActiveX Player\XCPPlayerControl\」。 これはソニーがF4Iに製品をあつらえるよう依頼したことを示唆している。 ことによると、完全な特注品ということすらあり得るだろう。 問題のDRMシステムがはらむ専門的性質につき、ソニーBMGにどれだけの理解があったかは不明だが、 明らかに知っていたであろうある主要な特性がある−消費者のシステム支配権を奪取する特性だ。 彼らはこれに関していくつもの訴訟に直面している。 もはや彼らが法を破ったのか否か、裁判所の判決を待つのみということだ。
2005/11/23更新 Matti Nikki

