What is XSS
/search.php?query=<script>alert(1)</script> , to receive:
<div>No results were found for <strong><script>alert(1)</script></strong></div>
● The possibility of stealing session cookies and, consequently, accessing the session of the user who has been attacked.
● The ability to read any data in the context of the compromised domain. For example, XSS in Gmail can allow all user emails to be read.
● The ability to perform any actions in the context of the compromised domain. For example, XSS on Facebook can allow you to like or share any pages.
● Attacks on a user’s network or computer; e.g., using browser exploits or performing basic port scans.
Later in the article we will focus on this third effect—the ability to perform any actions in the context of the attacked domain.
BetterZip and QuickLook
BetterZip is an application for viewing and creating archives (7z, rar, zip, etc.) for the macOS system. In the default installation, BetterZip is also attached to the QuickLook function in the system, by which pressing the space bar in the default file browser on macOS will display the preview of this file. When using QuickLook, archive contents are displayed on the zip files (Figure 1).
As you can see in Figure 1, the fragment of the name in one of the files is underlined. I noticed it once by accident when I ran QuickLook on one of the files that I had on the disk. Then I checked what the real file names were inside the archive, and it came out that the name of this “underlined” file was: something<u>other.jpg. This leads to the conclusion that in QuickLook it is possible inject your own HTML code.
It is therefore necessary to use HTML without a slash, which brings to mind another standard injection of JS: <img src=1 onerror=alert(1)>. The HTML browser action is as follows:
- The browser tries to download a file named “1” (value of the src attribute).
- It is very likely that such a file will not exist or will not be a picture.
- Then the browser triggers the onerror event and, consequently, calls the alert(1) code.
So I prepared a file named <img src=1 onerror=alert(1)>, packed it into the zip archive, and tried to open QuickLook. The picture clearly appeared (Figure 2), but no alert was made.
This behavior could have resulted from one of two main reasons:
- In QuickLook, you can use the HTML code, but there is no JS engine connected to it. This means the code cannot be executed.
- The JS code has indeed been executed, but function alert is not defined in the context in which it is executed.
The second option seemed quite probable, so I decided to use a different JS code. Instead of trying to trigger an alert, I can simply try to replace the full content of the page. From JS, you can do this by referencing the document.body element and its innerHTML properties. So the new file name is: <img src=1 onerror=document.body.innerHTML=’AAAAAA’>. As a result the content of the page should change into several letter A’s. As you can see in Figure 3, it really happened!
“Install the Application for the User and Run”
It turns out that BetterZip provides several options from QuickLook to quickly unpack the archive. They are visible in Figure 4.
The third option is the most interesting: “Install the application for the user and run”. After selecting it, BetterZip unpacks the archive file to the ~/Applications directory and, if there is an executable inside, the application launches automatically!
Let’s look at what the HTML fragment in which the element is defined <select>:
<a href="#" id="presetLink" name="presetLink">
<select name="preset" onchange="extractWithPreset(this);">
<option disabled="disabled" selected="selected">
Extract with preset
1- Click unpack and clear
Install application for user and run
Let’s analyze what happens when the user clicks on the “Install application for user and run” option from the interface. First of all, the index of the selected <option> element is set to 3 (this is the fourth consecutive element <option> with indexing from zero), then the onchange event is triggered, in which the extractWithPreset function is called (this function simply changes the href of the parental link) for which the argument is the <select> element. Finally, as the <select> element is nested in the <a> element, a click is clicked on the link from the <a> element.
- We set the index of the selected element to 3.
- We trigger extractWithPreset function.
- We simulate clicking the link.
From the JS code level, it looks like this:
// We obtain a reference to the <select> element
var select = document.querySelector('select');
// We choose the fourth element
select.selectedIndex = 3;
// We trigger the extractWithPreset function
// We "Simulate" clicking the link with id presetLink
The effect can be as shown in Figure 5.
The article shows, on the example of BetterZip, how the XSS vulnerability, usually associated with web applications, spreads into desktop applications. In this case, it could be used to execute any code on the victim’s computer. Due to the growing popularity of Electron frameworks, one can expect that such attacks in the coming years will become more and more popular.
This error in BetterZip was submitted to the author on June 25, 2016, and it was repaired in the version from July 14, 2016. As a reward for finding it, the author gave me a free license.
Autor Michał Bentkowski