2005/01/12

ROのはなし

続・PT機能に脆弱性

12日昼前に緊急メンテが入ってPT乗っ取りバグが修正されました。ってことで、どういう話だったのかをご紹介。

侵入手法

侵入したいPT名に対して、17バイト目に何か半角1文字を付け加えて/organizeする。「ぽわわストリーム」などのPT名が16バイトの場合は/organize ぽわわストリームAなどとやれば、まず「ぽわわストリームA」というPT名のPTができたようにみえます。が、そこでリログすると当時のROのPT名の長さは16バイトまでになっていたので、「ぽわわストリーム」というPT名に見た目切りつめられます。

で、これは既存のPT名なので、それまで「ぽわわストリーム」という名前のPTにいた人は内部的に「ぽわわストリームA」のほうのPTへ移動させられてしまうので、コレにより乗っ取られ側はPT機能が死んだように見えます。リログすれば「ぽわわストリームA」のほうの「ぽわわストリーム」というPTが読み込まれるので、そちらでまた普通にPTが利用可能になります。

また、16バイトに満たない場合の侵入手法ですが、16バイトまでを半角スペースで詰めてから、17バイト目に半角でゴミをつめてPTを作成すると、乗っ取りが可能になります。例えば、「ぽわぽわ」というPT名を乗っ取りたければ、/organize "ぽわぽわ        A"といった要領で、半角スペースを含むPT、ギルド名を作成する場合はクォーテーションで囲む必要があることに気をつけてください。これにより、16バイトに満たないPT名も乗っ取ることが可能でした。

脆弱性の概要

ROサーバーではPT名を16バイト+ターミネータ(NULL)の17バイトで管理していました。

今回の脆弱性は、ROクライアントが24バイトでPT名作成要求を送るときに、鯖が16文字でPT名を切っていたのにもかかわらず17バイト目にNULLを詰めておらず、サーバー側でも17バイト目をNULLにせずPT名を格納しているために、"ぽわわストリーム\0""ぽわわストリームA"が別のPTとして作成可能になってしまい、しかもPT名とDBの関連づけは16バイトに詰めて行われるので、DB上では「ぽわわストリーム」のPTのIDが「ぽわわストリームA」のほうのPTのIDで上書きされてしまうことが起こっていると思われます。

要は17バイト目のNULLであるべき文字がバッファオーバーフローしているという(まぁ微妙に意味が違うかもだけど)ことに他ならないということのようです。

また、乗っ取り直後に乗っ取った人間がPTから脱退すると、普通PTから抜けるとPTメンバーが残っていればPTが残るものですが、乗っ取り直後だとPTに1人しかいないことになってしまうため、その乗っ取りPTは解散され、乗っ取られた方のPTは行き場を失って、DB上にのこってるっぽいPTの残骸に移動させられます。よって、これにより無理矢理PT名が変わったように見えます。

最後のPT名を強制的に変えるって言うのは、なんかDB上のゴミデータを指すことになってしまうので、非常に危険な状態でした。実際に、ゴミデータを指した結果、みためPT名のないPTというのが実験時にできてしまうことを確認しています(危ないので当然解散しましたが)。まぁSSをとっておいたのでご紹介。

名前なきPT
こんなSSでごめんなさい

あと、このPTで加入要請をするとどうなるかというと…

名前バグりPT
なんだこのPT名は…

とりあえず全部修正されたようなので、現在このようなことはできなくなっています。

うされもん @acidlemonについて

|'-')/ acidlemonです。鎌倉市在住で、鎌倉で働く普通のITエンジニアです。

30年弱住んだ北海道を離れ、鎌倉でまったりぽわぽわしています。

外部サイト情報

  • twitter
  • github
  • facebook
  • instagram
  • work on kayac