前述したように、ほとんどの場合、エラーはキーデータの署名を生成するロジックで行われます。 問題は、これらのエラーが実装ではなく概念的なものであることです。
脆弱性番号1
結論:攻撃者は、店舗の製品の代金を支払うときに、ブラウザからLiqpay APIで送信されたフォームデータを変更し、店舗で選択されたものとは異なる製品の代金を支払うことができます。
問題は、署名の形成にあります。署名されたデータは、特にorder_idおよびtypeパラメーターのセパレータなしで「接着」されます。 order_id = '1234'、type = 'buy'としましょう。 攻撃者はorder_id = '123'およびtype = '4buy'を変更し、liqpayサーバーに送信します。 この場合、署名の検証は成功します その形成のためのラインは変更されていません。 ページ上のフォームを編集して、ChromeまたはFirefoxブラウザーでこれらの手順を安全に繰り返すことができます。最後の文字を順序から削除し、最初にtypeパラメーターに設定します。
念のため、何が起こったのかわからないのは、同志全員が脆弱性の結果を理解しているわけではないためです。
購入時に、ストアは一意の注文番号(order_id)を作成し、フォームを作成して署名し、このデータを顧客にLiqpayに送信します。 Liqpayが購入者からの金銭の引き出しに成功すると、彼はそのような注文番号が支払われたことを店舗に通知します。 問題は、Liqpayが完全に異なる注文の支払いについて通知することであり、注文の支払額は異なります。 攻撃者が1つのorder_idが1つの注文の別のorder_idのフラグメントを持つまで、未払いの注文を作成することで十分です。 多くの場合、order_idはランダムに形成されないため、これはある程度可能です。
Privatbankの簡単な解決策:typeパラメーターを検証するだけで、現在は実行されていません。 前述したように、これは概念的に問題を解決しない特別なケースです。
脆弱性番号2
結論:支払いを目的としたストアによって署名されたフォームは、コールバックURLに手動で送信でき、すべてのルールに従って署名が形成されるため、ストアによって受け入れられます。 小さな操作をするだけで十分です。
result_urlフィールドの名前をtransaction_idに変更
server_urlフィールドの名前をsender_phoneに変更
空の値を持つステータスフィールドを追加する
このパッケージはストアで受け入れられます!
これはLiqpayパッケージの署名がどのように考慮されるかです:
private_key . amount . currency . public_key . order_id . type . description . result_url . server_url
そして、OT Liqpayパッケージの署名がどのように考慮されるかを以下に示します。
private_key . amount . currency . public_key . order_id . type . description . status . transaction_id . sender_phone
パッケージは最後の3つのパラメーターのみが異なることがわかります。 フィールドの名前を変更してストアをだまし、署名が一致するため、このパッケージはLiqpayからのものであると考えさせました。
これが支払いの成功であるとストアが考えるためには、もう少しアクションと1つの条件が必要です。
製品の説明では、「成功」の断片である必要があります。
確かに、Liqpayを使用している店舗には、このフラグメントを持つ製品があります。 たとえば、たとえば、「My success story」という本のタイトルを考えます。 支払いのフォームでは、以下を変更します。
- 値の最後にある説明フィールドからテキストを切り取り、「成功」フラグメントと後続のテキストがそれに含まれないようにします。description = 'My'
- フィールドのステータス=「成功」
- フィールドtransaction_id = "success"およびresult_urlの後のテキストの連結:transaction_id = 'ful storyhttps:// blablabla'
- server_urlフィールドの名前をsender_phoneに変更します
一番下の行:署名は変更されません! ストアはパッケージを受け入れます。 フィールドステータス=「成功」-支払いは成功しました。 transaction_idフィールドでは、左側のテキストが受け入れられます。これは、ストアがLiqpayでトランザクションIDがどのように形成されるかを知る必要がないためです(ケースの99%で無視)
結論:説明に「成功」という言葉が含まれていれば、自由に製品を「購入」できます。 Urlコールバックは明示的な形式で利用できるため、パケットの送信先を見つけるのに問題はありません。
操作の意味がわからない場合は、簡単に:パラメーターA = AAA、B = BBB、B = BBBがあるとします。 Liqpayプロトコルに従って、ストアソフトウェアはすべてのパラメーターを特定の順序で1行AAABBBVVVに連結し、署名XXXを受け取ります。 パラメーターの名前と値を変更できます。たとえば、G = AA、B = ABBBV、B = BBとします。 その結果、連結されたストリングは同じ(AAABBBVVV)になり、パラメーターとその値は完全に異なります。
Privatbankの簡単なソリューション:説明のフラグメント「成功」で購入の処理をブロックします。 繰り返しますが、これは問題を概念的に解決するものではありません。
他の支払いシステムにはさらに多くのバグがあるため、PBをあまり蹴らないようにお願いしますが、今のところそれらに時間がない。