绿盟扫漏出现的Web常规漏洞

整理一下最近修复的漏洞

==== =环境:Java、tomcat、Linux====

1、目标URL存在http host头攻击漏洞

解决方案:

(1)将tomcat升级到7及以上版本
(2)修改tomcat中/conf/Server.xml配置文件
将host 节点里面 name名称改为域名,appBase:应用的目录
(3)Linux上增加hostname

     Vi /etc/hosts
     
     修改好确保有成功
     ping hostname

(4)用burpsuite验证漏洞是否通过,具体过程可以百度一下。当时没截图

     ps:这个方案是针对绿盟扫漏访问静态资源url后面不加斜杠导致的Host头攻击。坑死人- - 正常在系统设置白名单、添加host过滤器就行了。 

2、目标主机可能存在缓慢的HTTP拒绝服务攻击

解决方案:

方法一:修改tomcat中 \conf\server.xml 配置文件 connectionTimeout="20000"
*connectionTimeout:网络连接超时。
20000改为5000 (询问了扫漏人员的攻击速度)
\conf\web.xml 中<session-timeout>30</session-timeout>后添加

  <cookie-config> 
  <http-only>true</http-only> 
  <secure>true</secure> 
  </cookie-config>

链接: 参考博客地址.

Ps:如果还是被查出漏洞,说明漏洞攻击速度比改的还要快,根据实际情况去选择时间是否还要再改小一点

方法二
Linux用命令行在apache(不是tomcat)加载两个新模块mod_reqtimeout和mod_qos(如果有就不用重新加载),具体过程可以参考博客地址

链接: 参考博客地址.

3、XSS扫描跨站式漏洞、SQL注入漏洞

解决方案:

在项目中增加过滤器过滤请求的特殊字符

 public class XSSFilter
        implements Filter {
    private static Logger log = Logger.getLogger(XSSFilter.class);

    public void init(FilterConfig filterConfig)
            throws ServletException {
    }

    public void doFilter(ServletRequest servletRequest, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        String requestHost = ((HttpServletRequest) servletRequest).getHeader("host");

        HttpServletRequest request = (HttpServletRequest) servletRequest;
        request.setCharacterEncoding("UTF-8");

        Map parameters = servletRequest.getParameterMap();
        if ((parameters != null) && (parameters.size() > 0)) {
            for (Iterator iter = parameters.keySet().iterator(); iter.hasNext(); ) {
                String key = (String) iter.next();
                String[] values = (String[]) parameters.get(key);
                for (int i = 0; i < values.length; i++) {
                    //过滤请求特殊字符,扫描跨站式漏洞
                    if (("bingo".equals(guolv(values[i])))) {
                        System.out.println("requestStr: ======================== " + values[i]);
                        System.out.println("完整的地址是====" + request.getRequestURL().toString());
                        System.out.println("提交的方式是========" + request.getMethod());
                        System.out.println("======访问地址发现非法字符,已拦截======");
                        return;
                    }
                }
            }

        }

        XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper(
                (HttpServletRequest) request);

        HttpServletResponse resp = (HttpServletResponse) response;
        resp.addHeader("x-frame-options", "SAMEORIGIN");
        resp.addHeader("Set-Cookie", "Path=/; Secure; HttpOnly");

        chain.doFilter(xssRequest, response);
    }

    public void destroy() {
    }

    public static String guolv(String a) {
        return a;
    }

    public String guolv(String a) {
        if ((StringUtils.isNotEmpty(a)) && (
                (a.contains("%22")) || (a.contains("%3E")) || (a.contains("%3e")) || (a.contains("%3C")) || (a.contains("%3c")) || (a.contains("%2Fr%2Fn")) || (a.contains("%2fr%2fn")) || (a.contains("%2Fr")) || (a.contains("%2fr")) || (a.contains("%2Fn")) || (a.contains("%2fn")) || (a.contains("%28")) || (a.contains("%29")) || (a.contains("%20")) || (a.contains("<")) || (a.contains(">")) || (a.contains("\"")) || (a.contains("'")) || (a.contains("/r/n")) || (a.contains("/r")) || (a.contains("\\(")) || (a.contains("\\)")) || (a.contains("/n")) || (a.contains("+")) || (a.contains(" and ")) || (a.contains(" or ")) || (a.contains("1=1")))) {
            return "bingo";
        }
        return a;
    }

web.xml

 <filter>
  <filter-name>xssFilter</filter-name>
  <filter-class>com.xxx.xxx.XSSFilter</filter-class>
 </filter>
 <filter-mapping>
  <filter-name>xssFilter</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>

4、跨站请求伪造(CSRF)漏洞

解决方案:

方案一:
网上很多都是关于解决用户登录后请求产生的漏洞
(1)用户登录时在session上添加token
(2)请求时再去判断这个token是否和请求的token一致

方案二:
针对扫漏访问公共页面,用户无需登录就能访问产生的csrf漏洞(= =再次吐槽什么玩意)
我的做法是
(1)在过滤器里先去判断是否有session。当session为空时添加session;否则判断session是否一致
(2)请求时在jsp页面上将session进行hash算法加密(网上看到说一般扫漏看到hash加密就不愿意去测了也不知道真假,蛮加密一下)
(3)项目中被扫漏的是a标签的url,所以用js去添加token;有用Ajax请求的则添加到header里

	$(function(){
		updateTags();
	});
	
	// javascript的String到int(32位)的hash算法
	function hash(str) {
		var hash = 0;
		if (str.length == 0) return hash;
		for (i = 0; i < str.length; i++) {
			char = str.charCodeAt(i);
			hash = ((hash << 5) - hash) + char;
			hash = hash & hash; // Convert to 32bit integer
		}
		return hash;
	}
	
	function updateTags() {
		var token = "<%=session.getAttribute("token") %>";
		var all = document.getElementsByTagName('a');
		var len = all.length;

		// 遍历所有 a 元素
		for (var i = 0; i < len; i++) {
			var e = all[i];
			updateTag(e, 'href', hash(token));
		}
	}

	function updateTag(element, attr, token) {
		var location = element.getAttribute(attr);
		if (location != null && location != '') {
			var fragmentIndex = location.indexOf('#');
			var fragment = null;
			if (fragmentIndex != -1) {
				//url 中含有只相当页的锚标记
				fragment = location.substring(fragmentIndex);
				location = location.substring(0, fragmentIndex);
			}

			var index = location.indexOf('?');

			if (index != -1) {
				//url 中已含有其他参数
				location = location + '&token=' + token;
			} else {
				//url 中没有其他参数
				location = location + '?token=' + token;
			}
			if (fragment != null) {
				location += fragment;
			}

			element.setAttribute(attr, location);
		}
	}

Ajax添加header

beforeSend: function (XMLHttpRequest){
				XMLHttpRequest.setRequestHeader("token", $("#token").val());
			},

后台代码判断:

  Map parameters = servletRequest.getParameterMap();
        if ((parameters != null) && (parameters.size() > 0)) {
            HttpServletRequest req = (HttpServletRequest)request;
            HttpSession s = req.getSession();
            if (request.getServletPath().toString().contains("/sys/TestAction")) {
                // 从 session 中得到 token 属性
                String sToken = (String) s.getAttribute("token");
                if (sToken == null) {
                    // 产生新的 token 放入 session 中
                    sToken = (System.currentTimeMillis() + new Random().nextInt(999999999)) + "";
                    s.setAttribute("token", sToken);
                } else {
                    // 从 HTTP 头中取得 token
                    String xhrToken = req.getHeader("token");
                    // 从请求参数中取得 csrftoken
                    String pToken = req.getParameter("token");
                    Integer hasha=sToken.hashCode();
                    if (sToken != null && xhrToken != null && sToken.hashCode()==Integer.parseInt(xhrToken)) {
                    } else if (sToken != null && pToken != null && ((sToken.hashCode())==Integer.parseInt(pToken))) {
                    } else {
                        request.getRequestDispatcher("error.jsp").forward(request, response);
                    }
                }
            }
        }

验证是否通过漏洞教程: 参考博客地址.

5、站点存在javascript框架库漏洞

解决方案:

替换jquery版本,根据系统兼容性升级到最高版本

6、HTTP头信息泄露(低危)

解决方案:

修改tomcat中 \conf\server.xml 配置文件中,为connector元素添加server=" ",是空格,在response header中server的信息就变为空了

<Connector server=" " port="8443" URIEncoding="UTF-8"/>

7、点击劫持、缺少HttpOnly属性(低危)

解决方案:

过滤器中添加

HttpServletResponse resp = (HttpServletResponse) response;
        resp.addHeader("x-frame-options", "SAMEORIGIN");
        resp.addHeader("Set-Cookie", "Path=/; Secure; HttpOnly");

8、长时间拒绝服务密码

解决方案:

前后端校验密码长度

9、内容安全策略 (CSP) 、HTTP X-XSS-Protection缺失

解决方案:

过滤器中添加

HttpServletResponse resp = (HttpServletResponse) response;
        resp.addHeader("Content-Security-Policy", "default-src https: http: 'unsafe-inline' 'unsafe-eval';connect-src https: http:");//针对safi和chrome
        resp.addHeader("X-XSS-Protection", "1; mode=block");

10、应用程序错误信息泄露

解决方案:

统一错误页面,删除敏感信息

11、JQuery版本过低引起的XSS漏洞——CVE-2020-11022/CVE-2020-11023

漏洞复现:

1、扫描网站所使用到的所有js

这里使用Retire.js插件,具体安装如下:
(1)火狐浏览器设置-扩展和主题-拓展
在这里插入图片描述

(2)在搜索栏搜索Retire.js

在这里插入图片描述

(3)安装插件(这里我已经安装过了)

在这里插入图片描述
(4)如果右上方菜单栏中没有显示插件,要在扩展里面找到安装好的插件,点击进去,将 在隐私窗口中运行 点击允许
ps:可能因为火狐浏览器开的是隐私还是其他原因,一开始插件没有在菜单栏中显示出来 坑- -

在这里插入图片描述
(5)成功效果
在这里插入图片描述

2、以CSDN为例将漏洞复现

(1)通过插件找出网站所用到的js,将jquery 1.12.4 Found in https://g.csdnimg.cn/??lib/jquery/1.12.4/jquery.min.js,user-tooltip/2.7/user-tooltip.js,lib/qrcode/1.0.0/qrcode.min.js复制下来

在这里插入图片描述

(2)图中 https://g.csdnimg.cn/??lib/jquery/1.12.4/jquery.min.js,user-tooltip/2.7/user-tooltip.js,lib/qrcode/1.0.0/qrcode.min.js 就是我们在上一步中复制的jquery引用路径。
将图中代码保存为html文件到本地,这里命名为 jQuery-xss-poc.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>jQuery XSS Examples (CVE-2020-11022/CVE-2020-11023)</title>
    <script src="https://g.csdnimg.cn/??lib/jquery/1.12.4/jquery.min.js,user-tooltip/2.7/user-tooltip.js,lib/qrcode/1.0.0/qrcode.min.js"></script>
</head>
<body>
<script>
function test(n,jq){
    sanitizedHTML = document.getElementById('poc'+n).innerHTML;
    if(jq){
        $('#div').html(sanitizedHTML);
    }else{
        div.innerHTML=sanitizedHTML;
    }
}
</script>
<h1>jQuery XSS Examples (CVE-2020-11022/CVE-2020-11023)</h1>
<p>PoCs of XSS bugs fixed in <a href="//blog.jquery.com/2020/04/10/jquery-3-5-0-released/">jQuery 3.5.0</a>. You can find the details in my blog post: <a href="//mksben.l0.cm/2020/05/jquery3.5.0-xss.html">English</a> / <a href="//masatokinugawa.l0.cm/2020/05/jquery3.5.0-xss.html">日本語</a></p>

<h2>PoC 1</h2>
<button onclick="test(1)">Assign to innerHTML</button> <button onclick="test(1,true)">Append via .html()</button>
<xmp id="poc1">
<style><style /><img src=x οnerrοr=alert(2)> 
</xmp>

<h2>PoC 2 (Only jQuery 3.x affected)</h2>
<button οnclick="test(2)">Assign to innerHTML</button> <button οnclick="test(2,true)">Append via .html()</button>
<xmp id="poc2">
<img alt="<x" title="/><img src=x οnerrοr=alert("1st")>">
</xmp>

<h2>PoC 3</h2>
<button οnclick="test(3)">Assign to innerHTML</button> <button οnclick="test(3,true)">Append via .html()</button>
<xmp id="poc3">
<option><style></option></select><img src=x οnerrοr=alert("1st")></style>
</xmp>

<div id="div"></div>
</body>
</html>

(3)右键该文件,用浏览器打开
在这里插入图片描述

至此,CVE-2020-11022/CVE-2020-11023漏洞就被我们复现出来了

解决方案:

网上是提出两种方案
(1)更新 jQuery 到 3.5.0 或更高版本:

https://code.jquery.com/jquery-3.5.0.js

(2)使用XSS清理工具清理用户输入的HTML,官方推荐:

https://github.com/cure53/DOMPurify

如果升级jquery版本毫无压力的话,建议还是升级版本吧,比方案二简单。
方案二对简单系统来说,只要引入相应js,按照demo将原来的html重新初始化一下就可以了,但是对于页面多且不统一的系统来说 工作量太大了!
附上官方demo

<!doctype html>
<html>
    <head>
        <script src="../dist/purify.js"></script>
    </head>
    <body>
        <!-- Our DIV to receive content -->
        <div id="sanitized"></div>

        <!-- Now let's sanitize that content -->
        <script>
            /* jshint globalstrict:true */
            /* global DOMPurify */
            'use strict';

            // Specify dirty HTML
            var dirty = '<p>HELLO<iframe/\/src=JavScript:alert&lpar;1)></ifrAMe><br>goodbye</p>';

            // Clean HTML string and write into our DIV
            var clean = DOMPurify.sanitize(dirty);
            document.getElementById('sanitized').innerHTML = clean;
        </script>
    </body>
</html>

ps:= =公司项目升级版本会有问题。之前为了不升级版本,领导命令将jquery版本去掉,现在直接针对jquery进行代码审查,漏洞自然逃不过

最后采用方案二,只针对登录页面

导入js(官方demo中有提供)

<script src="../dist/purify.js"></script>

在提交操作前 将登录框的html进行数据清洗,再塞回div中

var dirty = $("#sanitized").html();
//清洗数据
var clean = DOMPurify.sanitize(dirty);
$('#sanitized').html(clean);

也不懂有没有效果(项目中的登录信息是加密的),反正咱就是做了

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值