安全平台介绍
身处互联网浪潮中的弄潮儿们,你是否了解那潮水中的暗流(安全漏洞)?
你是否已经掌握了安全知识,但苦于无的放矢,而渐渐淡忘?
你是否对黑客技术痴迷,却苦于无处着手?
今天,给大家推荐一个工具:kb-security
-
深入的理论讲解
-
丰富的实战操作
-
平台化的演练耙场
开源项目地址: kb-security ,如果能帮到你,请帮忙点个星。谢谢~
kb-security 是一站式的解决方案:深入的理论讲解、丰富的实战操作、平台化的演练耙场…助你,解锁“安全技术包”。
跨站点脚本攻击简介
跨站脚本(Cross Site Scripting)为了避免与样式CSS混淆,所以简称为XSS。
XSS是一种经常出现在web应用中的计算机安全漏洞,也是web中最主流的攻击方式。那么什么是XSS呢?
XSS是指恶意攻击者利用网站没有对用户提交数据进行转义处理或者过滤不足的缺点,进而添加一些代码,嵌入到web页面中去。使别的用户访问都会执行相应的嵌入代码。
从而盗取用户资料、利用用户身份进行某种动作或者对访问者进行病毒侵害的一种攻击方式。
XSS攻击的危害包括:
1、盗取各类用户帐号,如机器登录帐号、用户网银帐号、各类管理员帐号
2、控制企业数据,包括读取、篡改、添加、删除企业敏感数据的能力
3、盗窃企业重要的具有商业价值的资料
4、非法转账
5、强制发送电子邮件
6、网站挂马
7、控制受害者机器向其它网站发起攻击
原因分析
- 主要原因:过于信任客户端提交的数据!
- 解决办法:不信任任何客户端提交的数据,只要是客户端提交的数据就应该先进行相应的过滤处理然后方可进行下一步的操作。
- 进一步分析细节:
客户端提交的数据本来就是应用所需要的,但是恶意攻击者利用网站对客户端提交数据的信任,在数据中插入一些符号以及javascript代码,那么这些数据将会成为应用代码中的一部分了。那么攻击者就可以肆无忌惮地展开攻击啦。 - 因此我们绝不可以信任任何客户端提交的数据!!!
XSS攻击类型
- 1、反射型
又称为非持久性跨站点脚本攻击,它是最常见的类型的XSS。漏洞产生的原因是攻击者注入的数据反映在响应中。一个典型的非持久性XSS包含一个带XSS攻击向量的链接(即每次攻击需要用户的点击)。
举个栗子:
打开安全平台后,输入反射型XSS攻击的链接地址:
http://localhost:8080/#/chat_room?id=x&title=
- 2、存储型
又称为持久型跨站点脚本,它一般发生在XSS攻击向量(一般指XSS攻击代码)存储在网站数据库,当一个页面被用户打开的时候执行。每当用户打开浏览器,脚本执行。持久的XSS相比非持久性XSS攻击危害性更大,因为每当用户打开页面,查看内容时脚本将自动执行。
举个栗子:
打开聊天室页面链接:http://localhost:8080/#/chat_room ,在聊天输入框内输入相应的信息,如下图所示:
- 3、DOMBase型
当用户能够通过交互修改浏览器页面中的DOM(DocumentObjectModel)并显示在浏览器上时,就有可能产生这种漏洞,从效果上来说它也是反射型XSS。
通过修改页面的DOM节点形成的XSS,称之为DOMBasedXSS。
前提是易受攻击的网站有一个HTML页面采用不安全的方式从document.location 或document.URL 或 document.referrer获取数据(或者任何其他攻击者可以修改的对象)。<html> <title> 安全无小事,开启你的安全之旅! </title> <body> 欢迎您... </body> <script> var pos=document.URL.indexOf("name=")+5; document.write(document.URL.substring(pos,document.URL.length)); </script> </html> 这个例子是个欢迎页面,name是截取URL中传递过来的name参数 正常打开页面的链接如下:http://xx.xx.xx/welcome.html?name=lucy DOMBase攻击的链接如下:http://xx.xx.xx/welcome.html?name=<script>alert(document.cookie)</script> 当执行下面的链接时,页面会截取url中传递的name的值并执行相应的XSS攻击脚本,最终导致XSS攻击。
攻击实例演示
- 简单的弹框攻击
打开聊天室页面,在聊天内容中输入:<script>alert("XSS")</script>
, 发布聊天内容后,页面将弹出XSS提示 - 获取被攻击网站页面截屏
打开聊天室页面,在聊天内容中输入:<script src='http://localhost:8080/api/xss/screen.js?id=XX'/>
,发布聊天内容后,在XSS攻击支持平台查看被攻击站点的信息,如下图所示:
- 获取被攻击网站页面cookie
打开聊天室页面,在聊天内容中输入:<script src='http://localhost:8080/api/xss/screen.js'/>
,发布聊天内容后,d在XSS攻击支持平台查看被攻击站点的信息,如下图所示:
- 简单蠕虫
打开聊天室页面http://localhost:8080/#/chat_room,在聊天内容中输入:<img src='http://localhost:8080/api/chat/praise?id=x'>
,发布聊天内容后,查看聊天信息,当页面被访问时点赞数量会自动增长,如图(示例只展示一个简单dome,没有自动繁殖功能):
- 任意命令攻击,操作被攻击者浏览器
打开聊天室页面,在聊天内容中输入:<script src='http://localhost:8080/api/xss/command.js'/>
,发布聊天内容后,在XSS攻击支持平台查看被攻击站点的信息,如下图所示:
- 更多攻击可能,待你补充哦…
漏洞修复
- 前端转义
主要需要转义的标签列表如下:<、>、&、’、" - 后端过滤
public class XssParameterRequestWrapper extends HttpServletRequestWrapper {
private Map<String, String[]> params = new HashMap<>();
public XssParameterRequestWrapper(HttpServletRequest request) {
super(request);
Map<String, String[]> requestMap = request.getParameterMap();
this.params.putAll(requestMap);
this.modifyParameterValues();
}
/**
* 重写getInputStream方法 post类型的请求参数必须通过流才能获取到值
*/
@Override
public ServletInputStream getInputStream() throws IOException {
//非json类型,直接返回
if (!super.getHeader(HttpHeaders.CONTENT_TYPE).contains(MediaType.APPLICATION_JSON_VALUE)) {
return super.getInputStream();
}
//为空,直接返回
String json = IOUtils.toString(super.getInputStream(), "utf-8");
if (StringUtils.isEmpty(json)) {
return super.getInputStream();
}
Map<String, Object> map = JSON.parseObject(json);
Set<String> set = map.keySet();
Iterator<String> it = set.iterator();
while (it.hasNext()) {
String key = it.next();
Object values = map.get(key);
if (values instanceof String) {
values = HtmlUtils.htmlEscape((String) values);
}
map.put(key, values);
}
ByteArrayInputStream bis = new ByteArrayInputStream(JSON.toJSONString(map).getBytes("utf-8"));
return new MyServletInputStream(bis);
}
/**
* 将parameter的值去除空格后重写回去
*/
public void modifyParameterValues() {
Set<String> set = params.keySet();
Iterator<String> it = set.iterator();
while (it.hasNext()) {
String key = it.next();
String[] values = params.get(key);
values[0] = HtmlUtils.htmlEscape(values[0]);
params.put(key, values);
}
}
/**
* 重写getParameter 参数从当前类中的map获取
*/
@Override
public String getParameter(String name) {
String[] values = params.get(name);
if (values == null || values.length == 0) {
return null;
}
return values[0];
}
/**
* 重写getParameterValues
*/
@Override
public String[] getParameterValues(String name) {//同上
return params.get(name);
}
class MyServletInputStream extends ServletInputStream {
private ByteArrayInputStream bis;
public MyServletInputStream(ByteArrayInputStream bis) {
this.bis = bis;
}
@Override
public boolean isFinished() {
return true;
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setReadListener(ReadListener listener) {
}
@Override
public int read() throws IOException {
return bis.read();
}
}
}
上一篇: 安全平台kb-security:注册与登录【三】
下一篇: 安全平台kb-security:跨站点脚本攻击【五】