个人对XSS攻击的原理认知:
原理:对可以控制传参的位置,比如url链接中,输入框中,首先闭合输出参数位置前后网页标签,在闭合的中间加上JavaScript代码或者其他的html标签,使得网页能够执行你添加的参数功能。
危害:凡是js能做的,大部分xss漏洞都能利用,常见的比如获取当前cookie,获取浏览器保存的账号密码 、获取屏幕截图,获取页面的数据,改变页面的逻辑,向服务器发送数据请求等。
情景:在挖洞的情景下,只要保证能弹个窗,或者执行js代码即可。但是其中会涉及到很多前端相关的知识,比如如何在不同标签下触发弹窗,怎么绕过拦截等等。
xss分三种,分别为反射型,存储型,DOM型。但是按照攻击代码来源可以分成两种:
•反射型:通过URL参数直接注入•存储型:保存到网址数据库,在其他用户访问该数据的时候会被读取并执行,常在留言板,下单栏,文章频率,输入框等。
首先看第一种,通过源码来分析他的原理,首先写一个简单的flask后台,功能很简单,只负责返回输出用户输入的参数,代码如下:
from flask import Flask,request
app = Flask(__name__)
@app.route('/')
def index():
data = request.args.get('id')
return data
if __name__ == '__main__':
app.run()
使用火狐浏览器,打开网址:
http://127.0.0.1:5000/?id=langzi666
页面返回内容为:
因为传入的参数是可以控制的,并且没有任何的过滤机制,直接控制id的变量即可,访问:
http://127.0.0.1:5000/?id=
页面返回内容为:
但是这张插入在url中代码很长很可疑,可以做短网址处理。
第二种存储型,即网页提供一个输入框,你在其中填写js代码后,后台保存到数据库,当其他人或者管理员查看你输入的内容的时候,就会出发js代码。
在下面这些点中可以存在xss注入点:
1.HTML节点内容:网页的内容包含用户输入的信息2.HTML属性:网页的节点的属性是由用户输入的信息组成,跃出节点属性的范围3.JS代码:js代码中由后台注入的变量,或者包含用户输入的信息4.富文本:一大段的html
我的头发呢?
比如这个的节点,中间输出用户输入的内容,那么能够控制输出的内容。变成这样:
我都头发呢
因为中间的变量是可以控制的,所里这里可能存在XSS攻击。
比如有一张图片,图片来自用户的输入(之前上传的图片地址,外部图片地址,等等),正常情况下应该是这样的结果:
但是因为节点变得可控,就有可能变成这样的结果:
# src应该是图片的地址,onerror的意思是如果找不到图片或者加载失败,就执行的功能
如果图片存在,比如:
是不会触发弹窗的,那最上面的flask例子就能证明,分别访问下面两个网址:
http://127.0.0.1:5000/?id=
http://127.0.0.1:5000/?id=
前者不触发,后者触发。有些网站是通过如下方式获取图片的,比如:
http://www.langzi.fun/image/1
这样会调出第一张图,通过下面方式闭合img标签,填写错误不存在的图片即可完成xss
http://www.langzi.fun/image/1dasd122safqas" onerror="alert(1)
后端传递过来的代码应该是这样:
网址中是这样的
http://www.langzi.fun/?data=hello
因为参数可控,所以只需要和上面一样,进行闭合然后加上js代码即可
http://www.langzi.fun/?data=hello';alert(1)'
网址的编辑器都是富文本编辑器,富文本指在编辑的需求下,是需要允许部分HTML标签在渲染后有效的,但是又有部分诸如script这样的标签不应该有效,而且仅仅滤去script还不够,还有更多情况像img这样必不可少、看似安全的标签也会让人有机可乘。
html中的转义:
显示结果:实体名称:实体编号
< : < : <
> : $gt; : >
" : "e; : "
' : %apos; : '
( :(
) : )
xss防御会把这些html中用来闭合的位置进行转义,这些转义后的符号在html的内容中并不会出现异常效果和原来的一样。但是有些位置即使没有引号闭合,如果中间有空格也会造成xss。
如果后端代码会把单引号替换或者屏蔽,可以用上面的实体名称或者实体编号代替,可以简单的绕过拦截。
即访问上面flask的网址也会出现弹窗:
127.0.0.1:5000/?id=
127.0.0.1:5000/?id=
1.
转义,即上面的标签转义,但是必须要用在标签里面
2.
改变大小写
3.
hex,url编码
4.
使用其他标签引用,比如onerror,onchange等
5.
使用js自带的函数编码
6.
使用 ` 代替括号
7.
使用svg标签插入,可以绕过注释
这个网上有许多许多的资料,我对xss还并不是很熟,所以就不班门弄斧了。
bypass xss[1]
即如果你入侵成功后台后,修改登陆成功文件,利用js代码获取每次登陆成功后管理员的cookie,发送到你的服务器。
比如登陆后台地址为:
http://www.langzi.fun/admin.php
登陆成功后会跳转到:
http://www.langzi.fun/admin_manage.php
这个时候修改admin_manage.php代码的文件,就能持续获取管理员的cookie。
一些目录文件会做后门,做后门的方式即获取该目录当前路径和密码,然后发送到箱子的服务器上面。
这个时候如果你能成功抓到数据库,将发送的数据进行篡改,改成一段获取cookie的js代码,这样就能获取到webshell箱子服务器后台的cookie,通过找到该webshell后台,就能实现反向入侵。
不过这是太理想化的情况,实际情况会复杂很多。
xss-labs是国内一个大佬开源的xss漏洞靶子,包含一些常见的xss攻击方法。
为了方便下载,已经保存到当前服务器下
下载地址[2]
进入第一关卡,发现在url中传递的参数为:
name=浪子
并且页面输出浪子
可以推断页面会直接输出name对应的值,那么替换成js代码即可完成。
过关方式为:
1. http://127.0.0.1/xss/level1.php?keyword=test
2. http://127.0.0.1/xss/level1.php?name=test
3. http://127.0.0.1/xss/level1.php?name=test
总结:可以通过/
这一关可以看到和第一关一样,也是直接输出内容,但是输出的内容在一个文本框里面。
通过查看页面的源代码,发现传递的参数输出的位置为:
因为输出的位置在一大段文字中,只需要闭合前后将js标签调用出来就行了
通过方式:
1. http://127.0.0.1/xss/level2.php?keyword="/>
过滤:输出点被一大段文字包围
绕过:输出点在文本框内,能够通过闭合文本框标签进行弹窗
这一关和第二关一样,都是在一大段文本中显示出你输入的参数,这个时候查看源代码,发现是单引号包围,尝试使用单引号闭合,方式:
http://127.0.0.1/xss/level3.php?keyword='/>
这个时候并没有想象中的弹窗,查看源代码,发现被转义了,被转义的是:
< : <
> : >
因为<和>被转义,那么尝试直接用被转义后的实体内容带入呢?
'><script>alert(1)<script>
还是不行,请原谅我都无知- -
查找资料
资料[3]:
两处输出都对双引号、尖括号和&进行了HTML实体编码,但前面的单引号可以被闭合,考虑使用input标签的某些事件执行脚本。
自动聚焦到输入框,打开就弹
http://47.94.13.75/test/level3.php?keyword=' onfocus='alert()' autofocus='
自动聚焦到输入框,打开就弹
http://127.0.0.1/xss/level3.php?keyword=' onfocus='alert()' autofocus='
点击页面非输入框的任何地方以移开焦点
http://127.0.0.1/xss/level3.php?keyword=' autofocus onblur='alert()
点击输入框
http://127.0.0.1/xss/level3.php?keyword=' onfocus='alert()
http://127.0.0.1/xss/level3.php?keyword=' onclick='alert()
在输入框输入
http://127.0.0.1/xss/level3.php?keyword=' oninput='alert()
输入然后点击搜索
http://127.0.0.1/xss/level3.php?keyword=' onchange='alert()
移动鼠标经过输入框
http://127.0.0.1/xss/level3.php?keyword=' onmousemove='alert()
http://127.0.0.1/xss/level3.php?keyword=' onmouseout='alert()
http://127.0.0.1/xss/level3.php?keyword=' onmouseover='alert()
点击输入框,进行按键操作
http://127.0.0.1/xss/level3.php?keyword=' onkeydown='alert()
http://127.0.0.1/xss/level3.php?keyword=' onkeyup='alert()
http://127.0.0.1/xss/level3.php?keyword=' onkeypress='alert()
双击输入框
http://127.0.0.1/xss/level3.php?keyword=' ondblclick='alert()
更多可用事件可以参考这里:https://www.w3schools.com/tags/ref_eventattributes.asp
收获:闭合标签属性的单引号并在标签中添加事件。
过滤:waf对双引号,尖括号,和&符号进行编码
绕过:此时通过标签里面的事件进行触发弹窗
收获:学到了许多在标签内的触发事件
通过上面三道题,逐渐掌握了做xss的套路,首先我们要明白,弹窗所需要的条件是什么,我梳理了一下:
1.<2.
3."4.'5.(6.)7.script,on*事件,alert8.:
以上是可以闭合前后标签,并且能弹窗的条件,如果没有任何拦截的话,直接弹窗就行,但是waf或者后台代码肯定会对这些标签要么转义,要么替换,这个有点类似sql注入,找到哪个标签被过滤,然后进行其他方式的绕过。
第四关中,我输入admin"和admin',然后查看页面的源代码,发现都没有被过滤,然后输入/
过滤:<>
这样就没办法闭合标签,也没办法使用script标签或者img标签实现弹窗,但是因为在第三关中学到了在事件中on*事件触发弹窗,只需要闭合双引号即可。
http://127.0.0.1/xss/level4.php?keyword=" onclick="alert(1)
然后点击输入框,即可完成弹窗。
总结:通过输入一些弹窗的标签条件,查看源码哪些标签被过滤,然后组合其他没有被过滤的进行弹窗,这样就能诞生出自己挖掘xss的方法门路,具体实现在LEVEL 5中实现了
收获:很有必要检查闭合方式
从level4中整理的经验,自己可以整理一下套路方法。尝试对一系列的标签进行检测,找到被过滤和没有被过滤的以及输入框的闭合形式:
闭合形式:
双引号闭合
尝试输入下面的关键标签,找到过滤与没有过滤的:
1. addd"
2. ad'
3. (aaa)
4.
5.
在标签内事件弹窗:
通过js代码弹窗
点我<>
收获:通过javascript可以实现在a标签内弹窗
通过第五关,感觉自己发掘了自己的XSS弹窗秘诀呢,按照套路走一次,看看闭合方式以及被过滤的标签有哪些吧:
闭合方式:
双引号闭合
过滤:
onerror会变成o\_error,
完成弹窗:
http://127.0.0.1/xss/level6.php?keyword=a">
http://127.0.0.1/xss/level6.php?keyword=admin" oNClick="alert(1)
宝贵的经验:
对LEVEL 5的套路上优化,步骤如下:
1.
首先找到输入口闭合方式
2.
找到被过滤的标签,尝试输入下面标签,然后看返回值哪些被过滤了: