Mozillaに脆弱性を報告したら3年前から既知だと突っ返された話

さすがに3年放置しているとは思わんわ、あと検索機能馬鹿すぎて見つけられなかったのなんとかして。

概略

  • FirefoxとThunderbirdのインストーラーに特権昇格の脆弱性を見つける
  • 報告する
  • https://bugzilla.mozilla.org/show_bug.cgi?id=1269142 と重複と突っ返される
  • 些末にしろ3年放置はやめろ←今ここ

脆弱性詳細

インストーラーはまずユーザー権限で一時フォルダにファイルを展開し、特権を得てからそのファイルを実行したりProgram Filesにコピーしたりする。

当然一時フォルダはユーザー権限で書き換え可能なので、途中で実行される.exeを書きかえれば特権昇格、その他ファイルを書き換えればProgram Filesへの侵入(を経ての特権昇格)が可能。

またこれらへの対策も一切なく、実行.exeの署名検証やProgram Filesへコピーするファイルのホワイトリストなども存在しない。

よって特権昇格が可能である。

※C:\直下は特権なしではファイルを書き込めないのに書き込めている

PoC本体は https://resemblances.click3.org/product_list/index.cgi/detail/91 を参照のこと。

回答

2016-04-30 12:38投稿の https://bugzilla.mozilla.org/show_bug.cgi?id=1269142 と内容が重複しているとの回答があった。

見間違えじゃないぞ、2016年のとだ。

比較的些末とはいえ3年近くもの間特権昇格の脆弱性を放置するブラウザ……。

結論

Mozillaのインストーラーはこの調子だと何年でも脆弱なまま放置されそうなので、インストールするときは細心の注意を払おうな!

必要になったときだけインストールして即アンインストール運用は特に危険だぞ!

cv2converterリリース

緋想天/非想天則内部形式の.cv2と.pngの相互変換ツールリリース。
http://wordpress.click3.org/garakuta/cv2converter.zip

単独では何の役にも立たないので適当に何かと組み合わせて下さい。
パレット型pngとか8bitカラーや16bitカラーも対応しようと思ったけど、手元の画像編集ソフトがことごとく非対応で作れなかったからもういいかなって。

touhouSE ver1.24リリース

東方系dat展開ツールtouhouSE更新しました。
http://wordpress.click3.org/garakuta/touhouSE.zip

  • コマンドライン引数のselect*/reject*/view-listを追加

以前からたまに発生していた”datから特定のファイル展開だけやらせたい人”がまた観測されたので
いい加減そういった使い方も出来るようにするかと機能追加しました。

具体的には

>touhouSE.exe select-glob *bgm*.ogg reject-glob *_20.ogg #{憑依華datのパス}

みたいにやると20秒版を除いた全BGMファイルだけを展開できます。

view-listつければ展開せずファイル名だけ出力してくれるので、狙った指定ができるまでの試行錯誤も安心!

touhouSE ver1.23aリリース

東方系dat展開ツールtouhouSE更新しました。
http://wordpress.click3.org/garakuta/touhouSE.zip

  • 東方憑依華製品版(Steam/ディスク版)に対応
  • Steins;Gate0 PC版
  • DxArchiveV6に対応
  • nhtex=>dds=>pngといった多段変換に対応
  • コマンドライン引数で動作を変えられるように
  • tfwa形式で24bit形式が変換失敗していたのを修正
  • ファイル名に拡張子以外で.を含むファイルを含むアーカイブを二度連続で展開すると無限ループしていた不具合を修正
  • その他細かな変更色々

東方憑依華対応版です、Steam版と物理ディスク版どちらでも動くのを確認しています。
相変わらずファイル名は一方向ハッシュだったので一週間ほど逆算作業してました、楽しかった。

THxxBGMに東方憑依華製品版(Steam/ディスク)を追加するアプリリリース

THxxBGMに憑依華製品版の曲再生機能を足すアプリを作りました(引き続き深秘録と心綺楼も増える)。
http://wordpress.click3.org/garakuta/thxxbgmTh155Patch.zip

使い方は、中のwinmm.dllをTHxxBGM.exeと同じディレクトリに置くだけ。
うまいこと行けばpath設定に憑依華と深秘録と心綺楼が増えて、該当ディレクトリを設定すれば聞けるようになるはず。

試行錯誤の最小化は本当に正しいのか?

駄文、もしくはポエムの類だ、嫌いな人はスルーしてほしい。

以降の記述はすべて”情報科学においては”と装飾されているものとする。
また一個人の考えであり、正しさを保証するものではない。


まず世間においては以下のような考えを主張する人が多くいる。
「ほとんどの問題はすでに解決した人がいるので、試行錯誤したら1時間かかることも探せば10分で答えが見つかる、だから試行錯誤は最低限に抑えるのが上達のこつだ」
これは自分も複数人から実際に聞かされているし、大体の場合は正しいと思う。
しかし自分は正しくないこともあると考えている、それも結構な確率で。

前提として探しても答えが見つからない場合にどうするかを考える。
もちろん組み合わせ爆発的な問題があるので実際試せばわかる程度のものは含めない、もっと根本的にそれが何かすらつかめていないレベルのものだ。
「ほとんどの問題はすでに解決した人がいる」を前提に話している以上は探し方が悪いと言いたいのだろう。
なので「答えを見つけられる探し方を探す」方向に進むか「解決不能な問題である」と諦めるべき、ということだと思う。
以降はこの前提を置いて進める。

では本題として前述の主張に対する欠陥を指摘する。
「ほとんどの問題はすでに解決した人がいる」が事実だとしても「解決しても公開する人は圧倒的少数派である」ことが抜けている。
例を出そう。
「ゲームコントローラーの入力を受けて、フォーカスが当たっているゲームに、任意のキーボードイベントを送りたい」という問題を考える。
これはjoytokeyというアプリで実際に解決されていて、具体的な方法はWin32APIのkeybd_eventの極一部のドキュメントにしか記載がないbScanという隠し機能を使うというものだ。
では、探すだけでこの具体的な方法にたどり着けるだろうか?
2018/01/18のgoogleによれば「joytokey」では260,000件あるが「joytokey keybd_event」では244件で「joytokey keybd_event bScan」は20件、実際に記載があったのは2件で、どちらも無関係な第三者が調べた結果だ。
試行錯誤なしにこの情報にたどり着くのは常人では難しいだろう、少なくとも自分だったら無理だ。
このように明確に解決した人がいても公開しないことは普通なのだ。

公開されないと何が問題かと言えば、誰かが解決済みでも自分は解決できないことが多数発生することだ。
少し考えればわかるだろう、ソース非公開の素晴らしいアプリがあったとしてそれを100%模倣することなど普通は出来ないのだから。
普段探して解決している問題は解決した人がたくさんいるから公開する人も多かっただけに過ぎない。
つまりほとんどの問題は探して解決するなどというのは幻想で、探すだけでは解決しない問題は大量に存在しており、ただそういう問題は直面する確率が低いだけなのだ。
そして1%の事象でも100個集まればそれなりに踏むように、これらの問題のどれかは結構な確率で踏む。
そんな時に毎回諦めるのは本当に良いことだろうか?そうして得られる知識だけで本当に上達したと胸を張れるのだろうか?
自分は違うと思う。

成長とはその技能そのもの以外にも、その技能関連問題をどれぐらい解決できるかも含むと自分は思っている。
なので、誰も教えてくれない知識に自力でたどり着けるようになることも成長だと思う。
もちろんたどり着けるようになる方法そのものを探して身に着けるということは否定しない。
しかしプログラミングなどのように実践しようと思えばいくらでも実践できる分野ではないので、ある程度は都度試行錯誤していくのがベターだと思う。
さすがに毎回探す前に試行錯誤するようでは問題あるとは思うが。

以上、試行錯誤しないと手に入らない知識ばかり気になってここまで来たのに否定されまくったことの愚痴でした。


ちなみに初手試行錯誤も自分は否定しない。
0から試行錯誤した経験はその知識に対して多角的視点を与えてくれる(プログラミング作業では車輪の再発明とも呼ぶ)。
コストが高すぎるので全てで行うことは馬鹿げているが、一切やらない人はそれはそれで愚かだと思う。
なので試行錯誤は用法用量を守って正しく行いましょう、というお話だったとさ。

今更だがSplatoon1ロングブラスターの宣伝をしようと思う

Splatoon1ではロングブラスターこそが最優のブラスターなのだが(※感じ方には個人差があります)
いまいち人気がなくSplatoon2にも実装されないので適当に駄文を貼る。

まぞこの表を見てほしい。

重要なのは「先手時キルフレーム」で、奇襲に成功した後に敵に残された猶予だ。
wikipediaを見ると反応に約10フレームかかると見込め
感度最高で背後を向くことだけ考えてコントローラーをブンブンしても平均22フレームかかったので敵がエイム合わせるのに22msはかかると思え
中距離キル最速のスプラシューターはキルフレーム13である。
なので奇襲すると反撃には10+22+13=45フレームは絶対にかかると見込める。

上記を踏まえてカラムを足したのがこちら。

ノヴァブラスターは文句なしで確殺
ホットブラスターも奇襲予知クラスの化け物以外は確殺
ロングブラスターは一切動揺せずエイムが一瞬で合うレベルの使い手以外は確殺
ラピッドブラスターは大幅有利ではあるが負けうる
ラピッドブラスターエリートはただ有利なだけだろう

このように、動き回って先手を取る戦法において確殺と呼べるのはぎりぎりロングブラスターまでだ。
なので、中距離まで接近する立ち回りではロングブラスターとラピッドブラスターの間には超えられない壁のようなものが存在する(そもそもラピッドではそこまで近づかないが)。
一方でロングブラスターは劣化はするがラピッドブラスターの立ち回りも出来る。
なのでロングブラスターとは、ホットブラスターとラピッドブラスターを足して1.7割ったような武器なのだ。
つまりロングブラスターこそ最優のブラスター(※感じ方には個人差があります)、皆ももっと使ってSplatoon2運営に実装圧力をかけよう!

音量ミキサーのアプリ別音量を設定するサンプル

タスクバーアイコンの音量から音量ミキサーを開いたところにあるアプリ別のアレです。
ライブラリやデバイスの都合で音量を調整できないことがありますが、それを無理にでもなんとかする際に便利です。

ではいつものようにコード本体からどうぞ。
http://resemblances.click3.org/product_list/index.cgi/detail/88
http://wordpress.click3.org/garakuta/volum_mixer_example.zip
動作としてはWindows付属の効果音を鳴らしっぱなしにしつつ、音量をひたすら上下させるだけのアプリになります。
また、サンプルの機能をそのままライブラリ化したものもあるので別途貼っておきます。
http://resemblances.click3.org/product_list/index.cgi/detail/87
http://wordpress.click3.org/garakuta/volume_manager.zip

前提

音量調整にはCOMを使用しています。
特別COMに関する説明はしませんので、COMとは何かを知らない場合は理解が難しい可能性があります。
またインスタンスの解放処理など本質的ではないコードも除けてあるので、サンプルそのままでの使用は非推奨です。
自身のコードに組み込む場合はvolume_managerの方を参照してください。

全体の流れ

非同期で効果音をループ再生
=>音声デバイスを取得
=>そのデバイスのセッション管理インスタンスを取得
=>セッションを列挙
=>セッションのプロセスIDを取得、自身のプロセスIDと一致する物を探索
=>音量を調整
となります。

非同期で効果音をループ再生

::PlaySoundW(L"C:\\Windows\\Media\\ringout.wav", nullptr, SND_ASYNC | SND_FILENAME | SND_LOOP);

単にPlaySoundしているだけです。

音声デバイスを取得

IMMDeviceEnumerator *deviceEnumerator;
::CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&deviceEnumerator));
IMMDevice *device;
deviceEnumerator->GetDefaultAudioEndpoint(EDataFlow::eRender, ERole::eMultimedia, &device);

CoCreateInstanceのあたりは説明不要ですね。
GetDefaultAudioEndpointは名前の通りデフォルトのデバイスを取得するもので、eRenderはスピーカなどの出力、eMultimediaは何らかのコンテンツ再生用を意味しています。

そのデバイスのセッション管理インスタンスを取得

IAudioSessionManager2 *sessionManager;
device->Activate(__uuidof(IAudioSessionManager2), CLSCTX_INPROC_SERVER, nullptr, reinterpret_cast<void **>(&sessionManager));

これも特に説明はいらないですね。
単にActivateメソッドを呼んでいるだけです。

なお、ここでいうセッションは「アプリの音量セッション」とでも呼ぶべきもので、音量出力APIを利用した後で現在も生きているプロセスに紐づく音量管理セッションのことです。
音量再生系APIを呼んだ後でなくては生成されないので注意が必要です。

セッションを列挙

IAudioSessionEnumerator *sessionEnumerator;
sessionManager->GetSessionEnumerator(&sessionEnumerator);
unsigned int count;
sessionEnumerator->GetCount(reinterpret_cast<int *>(&count));
for (unsigned int i = 0; i < count; i++) {
   IAudioSessionControl *session1;
   sessionEnumerator->GetSession(i, &session1);
   IAudioSessionControl2 *session;
   session1->QueryInterface(&session);
   ...
}

GetSessionEnumeratorの返り値がセッションの個数取得とセッション取得メソッドがあるので、それをforで回して取得しています。
IAudioSessionControlにはプロセスIDのようなプロセスと紐づけられる情報がないのでIAudioSessionControl2にQueryInterfaceしています。

セッションのプロセスIDを取得、自身のプロセスIDと一致する物を探索

DWORD processId;
session->GetProcessId(&processId);
if (processId != ::GetCurrentProcessId()) {
   continue;
}

これも説明はいらないですね、みたままです。

音量を調整

ISimpleAudioVolume *audioVolume;
session->QueryInterface(&audioVolume);
unsigned int volume = 0;
while (true) {
   if (volume <= 100) {
      audioVolume->SetMasterVolume(static_cast<float>(volume) / 100, nullptr);
   } else if(volume < 200) {
      audioVolume->SetMasterVolume(static_cast<float>(200-volume) / 100, nullptr);
   } else {
      volume = 0;
   }
   ::Sleep(10);
   volume++;
}

ISimpleAudioVolumeへQueryInterfaceし、あとは10msごとにSetMasterVolumeする無限ループなだけです。
ここにはないですがGetMasterVolumeやSetMute/GetMuteといったメソッドも存在します。

上手くいけばここで音声が上下に波打つようにして流れ続けるはずです。

おわりに

必要最低限程度ですがこれでアプリ別音量の設定ができます。
ここには書いていませんが少し呼び方を変えれば対象デバイスを指定して同様の処理を行ったりマイク音量の調整といったことも可能です。
あとは必要に応じて該当するインターフェースのドキュメントを参照してください。

Splatoonの距離別命中率計測

最近Splatoonにはまっていまして、命中率について実際に計測しました。
せっかくなので結果をまとめて公開しようかと思います。

※追記:命中率表に信頼区間追加しました

計測方法

測定対象はオーソドックスにシューター13種だけ、またブラスターは対象外とした。
測定する距離は各武器の最大射程である1.5/2.2/2.8/3.1/3.6/4.5(試し撃ち場の点線一個分を1換算)の6種類。
ジャンプによる命中率の低下については今回は対象外。

距離の決定方法は、試し撃ち場にて線が引いてある広場の一番奥の人形相手を対象とし
その距離が最大射程である武器にて、照準が変化せず、なおかつ撃った際のイカ人形へのヒット位置があまり下すぎない程度に目視にて調整。
目視なため距離精度は高くないけれど、その場で武器持ち替えが可能なので、それを駆使して出来るだけ同一の距離で計測するように配慮した。
ただし、もともとは別の計測目的だったことや、計測中にH3リールガンの追加があったこと、WiiUの電源落ちてしまう事故があったなどで同一距離ではない計測も含まれている。

実際の計測方法は、1000発以上撃ちこんでその間に外れた回数を数えるという方法。
トリガーを引いたままでは目視による計測が難しかったため、1発だけ弾を撃ち着弾したかどうかを確認し再度1発だけ撃つを繰り返す形で行った。

また計測結果を元に命中率、Killを取るのに必要な射撃数の平均、各武器間での勝率計算、勝率有利がつく武器の数のカウントなどを行った。
勝率計算は弾速を考慮せず、1フレームでも先に相手をKill出来れば勝利、同一フレーム内なら引き分け、それ以外なら相手の勝ちとした。
なので通常であれば発射後着弾前の弾により相打ちとなる場合でもどちらかの勝利として数えられていることになる。

当然のことだが、機械的な計測ではなく完全な人力での計測なため、ある程度計測ミスが含まれていると思われる。
そのあたりを理解したうえで結果を読んでもらいたい。

計測結果

まずは命中率の表




次に勝率の表





感想とか雑多に

※※※ここから先は読まなくて大丈夫です※※※

計測を始めた時点ではwikiの拡散値から具体的にどの程度の命中率になるのかを調べるぐらいのつもりだったのですが、実際に計測してみれば
拡散値的には4.5対6で1.5も勝ってるはずの.96対スプラで.96が命中率で負けてる距離があったり
0.5しか差がないデュアルと.96で凄い差がついたり
逆に1違うはずのデュアルとプライムがほぼ同じ命中率だったり
と、明らかに現状の拡散値だけでは説明できない事象が多数観測されました。
これは現状のwikiに載っている拡散値が間違っているか、それと拡散値以外に何か命中率を大きく左右する要素があるか、といった話になります。
このあたりの情報持ってる人だれかいませんかね?

最終的な結果だけ見れば、概ね体感通りかなという印象ではありました。
たとえばボールドマーカーはカタログスペックよりはだいぶKill性能は低めである点、シャープマーカーは短射程組の中では飛びぬけてKill性能が高い点、.96ガロンはスプラシューターと同じぐらいな点などです。
これを新発見に乏しい無駄な計測だったとするか、体感通りの結果が数値付きで示された良い計測だとするかは皆様の判断に任せます。

一部平均Killタイム通りに有利不利がついていない武器がありますが、これはちゃんと「n発撃つのにかかる時間内に敵に撃ち殺される確率」のような計算をしているからです。
平均Killタイムが悪くても最速Killタイムが早ければ気持ち有利がつきやすいなどなど。
高速高威力かつ低命中率のボールドマーカーなんかがわかりやすいですね。

L3リールガンとH3リールガンで命中率に特に差はないと感じていますが、実際の計測結果としてはL3だけわずかに外れるという形になっています。
ですが、実はL3リールガンの距離3.1計測が全体で一番最初に行った計測で、つまり自分の計測経験値が足らなかったためイカ人形復活直後の判定なし状態で撃ちこんでしまったとか、そういう計測ミスの可能性があります。
しかし、そういった理由をつけて計測結果を取捨選択することは統計的にはやってはいけないことなので、最終的にはそのままの数値で出すことにしました。
元気があればL3リールガンだけ3000回ぐらい追加計測して最初の計測がおかしいかどうか検証してみたいですね。

より詳しい計測順序の話をすると
各武器で射程最大から撃った場合の命中率だけ計測しようと考えて計測、その結果をtwitterに投げる
しかし最大射程のしかないため射程が違う武器同士ではどちらが命中率が高いとか撃ちあった場合どちらが強いとかいう計算が出来ない
なら距離を揃えた計測もやろう!ということで今回の計測が始まりました。
29,000発以上イカ人形に撃ちこんだ計算になります、大変だった。
ちなみに、最大射程での計測結果はそのまま今回の計測に使いまわしているため、その距離が最大である武器だけ他とは微妙に違う距離で計測していることになります。