script (⏱,💰)

script (⏱,💰)

NG#10 - 無序多署名アカウント

NG10

合約アカウントには 3 つのサブタスクがあり、これらはすべて「bad account」シリーズを構成しています。この記事はシリーズの 3 番目のタスクである「Orderless Hashing」です。

分析#

この問題は前の問題と同様に 2 つのコントラクトがあり、アカウントコントラクト「GrandPharaoh」のコンストラクタで特定の公開鍵が指定されています。__validate__内のget_multicall_hashは、各 Call に対して再帰的にハッシュを計算し、最後に XOR 演算子 (^) を使用してハッシュを組み合わせます。ハッシュは u256 型で、low * high が最終的な messageHash です。私たちは、署名に渡すために r と s を構築する必要がありますが、これらは ECDSA で検証できるようになっています。

実行する必要がある Call は、別のコントラクトのRoyalSpear.equip(0)ですが、これはアカウントコントラクト「GrandPharaoh」によってのみ呼び出すことができます。

秘密鍵がないため、ECDSA の脆弱性を見つけて解読する必要があります。

過程#

まず、Call リストの計算結果がどのようなものかを確認する必要があります。これは[equip(0)][equip(1),equip(0)]、またはそれ以上の値である必要がありますが、最後の値がequip(0)である必要があります。

この部分は、cairo のテストを書くために snforge を使用して、アカウントコントラクトに(multicall_hash.low.into() * multicall_hash.high.into()).print();を追加して読み取ることができます。

明らかに、[equip(0),equip(0)]に対応するハッシュは 0 であることがわかります。これを利用して解決できます。

次に、check_ecdsa_signatureの詳細を調べて、具体的にどのように署名が検証されるかを確認します。

use ecdsa::check_ecdsa_signature;をコメントアウトし、ソースコードをテストに貼り付けて、必要な場所に print を追加します。

まず、let zG: EcPoint = gen_point.mul(message_hash);に注意します。message_hash が 0(無限の点)であるため、楕円曲線上で P*0=0 となります。したがって、zG は 0 です。以下のコードを使用して確認すると、'zG_x not exist' と出力されます。なぜなら、無限の点には x 座標が存在しないからです。

    match zG.try_into() {
        Option::Some(pt) => {
            let (x, _) = ec::ec_point_unwrap(pt);
            'zG_x'.print();
            x.print();
        },
        Option::None => { 'zG_x not exist'.print(); },
    };

コメントには、検証の式が(zG +/- rQ).x = sR.xであることが明記されており、zG + rQに対応するコードは次のようになります:

    match (zG + rQ).try_into() {
        Option::Some(pt) => {
            let (x, _) = ec::ec_point_unwrap(pt);
            if (x == sR_x) {
                return true;
            }
        },
        Option::None => {},
    };

ここで、zG は 0 なので、rQ.x = sR.xが必要です。r は渡されたsigature.r、Q は公開鍵に対応する曲線上の点、s は渡されたsigature.r、R は r に対応する曲線上の点です。

明らかに、r=s かつ Q=R であれば、検証に合格します。公開鍵はブロックチェーンエクスプローラーのデプロイトランザクションから見つけることができます。

最後に、前の問題と同じ方法で、特定の署名と calls を Starknet.js の invokeFunction に渡してタスクを完了します。

結論#

NG10 end

ECDSA を深く学習し、楕円曲線の演算規則を知っていれば、この問題は非常に簡単に解決できます。コントラクトのマルチサイン設計は非常に単純であり、署名のリプレイ攻撃を利用することができます。

これでアカウントセクションの 3 つの問題がすべて解決されました。Cairo シリーズ全体には、Cairo で仮想マシンを書くものがありますが、私はそれをやるつもりはありません。アルゴリズム問題は嫌いです。将来的には、Starknet で実際に開発中に遭遇した興味深いものを更新する予定ですので、お楽しみに。

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。