mt.Goxの攻撃につかわれたTransaction malleabilityについてのテクニカルな説明です
Transaction malleabilityとは、専門用語で、トランザクション展性と呼びます。
ビットコインのトランザクションにおいては、送金の内容は変わらないのですが、結果として、トランザクションのIDに相当するものが変わります。
ビットコインのトランザクションでは、スクリプト部分があります。
(output) OP_DUP OP_HASH160 0f403837793e1e5f707eb0450a145d1940accd10 OP_EQUALVERIFY OP_CHECKSIG
たとえばこういったものなのですが、たとえばマイナーは、スクリプトの結果が変わらない範囲で、いくつかの情報の変更が可能になっています。
その結果はoutputは変わりませんし、そもそもサインされている部分は変えようがないのですが、それでも、面白いことがおきます。
Bitcoinでは、サインされてない部分も含めてトランザクション全体に対して、hashをとり、それをtransaction hashとしています。そして、これがいわゆるtransaction idとして、いままでは利用されててきました。
当然、一部の情報を変えたので、outputは一緒でも、hashをとったら、transaction idは別のものになります。これが、Transaction malleability です。つまり、これを突くと、アウトプットはかわらないが、transaction hashだけを書き換えることができるということです。
もし、このtransaction hash だけをみてIDとして利用しているシステムがあると、危険なことが起こりそうなのは想像がつくでしょう。
この問題は以前から指摘されており、transaction の識別においては単にhashだけでやらないように注意すべきとのことだったようです。
mt.goxにおいては、あるギークの証言では次のような実装がされていたとのこと
①BTCの引き出しが行われると、そのtransaction hash をMt.GoxのDBに記録。
②しばらくして、blockchainを参照し、ブロックに当該transaction hashが含まれているかを確認。含まれていれば、引き出し送金に成功したとみなして終了。
③しかし、ブロックに当該transaction hashが含まれていない場合、そのトランザクションに失敗したとして、再送金のトランザクションを起こしていた(自動)
明らかにまずい実装だということがわかります。transaction hashだけをみて送金確認を指定他店が1点、自動で再送金をしていた点がもう一点。ダブルでまずい。
本来は、送金先、input outputの金額やサインなど複数検証してtransactionを特定すべきです。しかし、transaction hashだけを見るという単純な実装をしていた可能性があります。
悪意ある人が、Transaction malleabilityをつかって、ransaction hashを書き換えれば、mt.Goxは送金を繰り返すというわけです。
なぜ、このような安易な実装を取ったのかは不明ですが、そのギークの推測によれば、
Mt.Goxの送金システムはそもそもトランザクションの仕様に乗っ取らないおかしなトランザクションを生成しており、そのため度々、ネットワークに拒否されることが多かったとのこと。
たとえば、新規に生成されたコインは、100 confirmation終わるまではトランザクションに含めてはいけないルールなのだが、100 confirmに満たない若いコインを送金に含めていたとのこと。
「2年ほど前に、Bitcoin の transactionのルールが変わったが、それにMt.Goxはちゃんと対応出来ておらず、彼らにおいては、拒否されるトランザクションが多発した。その数が相当数にのぼったため、送金トランザクションの再送信も自動化したのではないか」という指摘であった。