zoukankan      html  css  js  c++  java
  • AppScan9.0.3.5漏洞扫描记录

    1.跨站点脚本编制

    这个安全漏洞拿cookie做文章,而且是将前端的一些弹窗方法,要么通过脚本注入,要么通过url.encode之后注入,看几个变异的版本:

    版本一: 

    cookie  从以下位置进行控制: a5d5b093-a2c1-47e5-9604-b661c124344a 至:a5d5b093-a2c1-47e5-9604-b661c124344a"==aalertlert(15)+"

     之前是将一个alert注入,现在这个软件知道了,只过滤一次,那我就拆成两个,你过滤一个,合起来还是alert。好贱啊这软件

     

    解决处理:好吧,那我就递归处理了,没想到出现了版本二的变体了,厉害了

    版本二:

     var _cookies="bosssoft.com.cn=7717ef32-34a8-4a42-b26cf6804549a370;JSESSIONID=Kzdsb2QTHGkTx08XBhTBNJQN7GQlhmnWv0YhmS2tLDxQQT2YbCvK!-2054262092"+
    [window['location']='x6ax61x76x61x73x63x72x69x70x74x3ax61x6cx65x72x74x2832x29']
    +"";

    我的天,前端那么多脚本注入方式,这么搞不行啊,而且人家还是通过url.encode,前端弹窗还有各种方式。:

    1.window.open()
    2.window.location=javascript:alert(1)
    3.comfirm("xxx")
    4.prompt("xxxx")
    5.alert
    ...

    那不是搞死了?防不胜防啊。

    解决方案:后来想想,反正这个cookie,在业务系统也没用到,但是jsessionid主要用于负载均衡策略session粘滞。

    好吧,一不做二不休。想想既然能够执行的都是函数体,那我就把cookie里头包含以下字符:(、)、[、]、的全部替换了。

                    Pattern scriptPattern = Pattern.compile("\(",
                            Pattern.CASE_INSENSITIVE);
                    if(scriptPattern.matcher(value).find()){
                        flag=true;
                        return flag;
                    }
                    
                    scriptPattern = Pattern.compile("'",
                            Pattern.CASE_INSENSITIVE);
                    if(scriptPattern.matcher(value).find()){
                        flag=true;
                        return flag;
                    }
                    
                    scriptPattern = Pattern.compile("\\",
                            Pattern.CASE_INSENSITIVE);
                    if(scriptPattern.matcher(value).find()){
                        flag=true;
                        return flag;
                    }
                    
                    scriptPattern = Pattern.compile("\[",
                            Pattern.CASE_INSENSITIVE);
                    if(scriptPattern.matcher(value).find()){
                        flag=true;
                        return flag;
                    }
                    
                    scriptPattern = Pattern.compile("\]",
                            Pattern.CASE_INSENSITIVE);
                    if(scriptPattern.matcher(value).find()){
                        flag=true;
                        return flag;
                    }

    好吧,cookie的总算解决了,然这软件,坑爹的,用到了表单上,天啊,表单就不能这么搞了,但是安全漏洞不过,不让上线。后来经理说,能解决再说,我们后面补丁撤回来。

    没想到,这软件绝了,改值,然后通过url.encode。注入表单,厉害了。

    你绝,那我也绝了,把你响应回来的内容,字符我全部给你做了替换了,解决方案如下:

    try {
                    value=URLDecoder.decode(value,"UTF-8");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
                
                value= StringEscapeUtils.escapeJavaScript(value);
                value= StringEscapeUtils.escapeHtml(value);
                value= StringEscapeUtils.escapeXml(value);

    首先通过URLDecoder.decode将编码的恢复正常,然后通过escapeJavaScript、escapeHtml、escapeXml等将输出的返回到前台,嗯嗯,这下总算解决了这个漏洞,当然上线的时候不能这么搞==!

    2.使用 HTTP 动词篡改的认证旁路  

    这个漏洞,首先将它有问题的链接改成指定的方法,然后再通过第一漏洞处理后,这漏洞就没了

    3.会话标识未更新  

    漏洞原因:在我们的cookie里头存有两个session值,一个是jessionid。一个是我们自己业务系统要使用的,在登录前后这两个session值都要发生变化,这个软件才会认为是安全的,但是jessionid如果变了,可能会影响负载均衡的粘滞问题。既然是为了安全扫描,业务系统登录前后的session是有变化的,但是jessionid是没变,所以把jessionid变了,就好了。这个漏洞就可以解决了。

    4.已解密的登录请求 

    这个漏洞主要是因为传递的参数没有通过ssl即https的方式进行传播,将weblogic开启https,此外如果有Nginx也要开通https,这个漏洞就可以解决了。附一份nginx配置: 

    #user  nobody;
    worker_processes  4;
    
    #error_log  logs/error.log;
    error_log  logs/error.log  notice;
    #error_log  logs/error.log  info;
    
    #pid        logs/nginx.pid;
    worker_rlimit_nofile 20000;
    
    events {
        use epoll;
        worker_connections  10240;
    }
    
    http {
        include       mime.types;
        default_type  application/octet-stream;
        server_tokens off;
    
        keepalive_timeout           60 20;
        client_header_timeout       3m;
        client_body_timeout         3m;
        send_timeout                3m;
    
        client_header_buffer_size           16k;
        large_client_header_buffers         4 32k;
        server_names_hash_max_size          512;
        server_names_hash_bucket_size       64;
    
        sendfile        on;
        tcp_nopush      on;
        tcp_nodelay     on;
    
    #    limit_req_zone $binary_remote_addr zone=http:10m rate=10r/s;
    #    limit_req_zone $http_user_agent zone=useragenttrack:10m rate=10r/s;
    
        log_format  main
            '$remote_addr - $remote_user [$time_local] $request '
            '"$status" $body_bytes_sent "$http_referer" '
            '"$http_user_agent" "$http_x_forwarded_for"';
        access_log logs/access.log  main;
    
        map $http_user_agent $is_bot {
            default 0;
            ~[a-z]bot 1;
            ~[sS]pider 1;
            ~spi_der 1;
            ~crawler 1;
            ~ysearch 1;
            ~YahoosPipes 1;
            ~BingPreview 1;
            ~YoudaoFeedFetcher 1;
            'Yahoo!sSlurp' 1;
            'Mediapartners-Google' 1;
            #'Mozilla/5.0' 1;
        }
    
        include appconf/upstream.conf;
        include appconf/gzip.conf;
    
        #lua_need_request_body on;
        #init_by_lua_file conf/waf/init.lua;
        #access_by_lua_file conf/waf/waf.lua;
    
    #    lua_shared_dict limit 50m;
    #    lua_package_path /opt/openresty/nginx/conf/waf/?.lua;
    #    init_by_lua_file conf/waf/init.lua;
    #    access_by_lua_file conf/waf/waf.lua;
    
    
        server {
             listen       18002 ssl;
             server_name  localhost;
    
             ssl_certificate      ./ssl/server.crt;
             ssl_certificate_key  ./ssl/server.key;
    
        proxy_set_header       Host $http_host;
        proxy_set_header  X-Real-IP  $remote_addr;
        proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto  $scheme;
        proxy_set_header Cookie $http_cookie;
        add_header                  Set-Cookie "HttpOnly";
        add_header                  Set-Cookie "Secure";
        add_header                  X-Frame-Options "SAMEORIGIN";
    
             if ($request_method !~ ^(GET|POST|HEAD|DELETE)$ ) {
                return 405;
             }
    
             location ~ ^/(WEB-INF)/ {
                return 404;
             }
    
             location ~ ^/(js|css|img|scripts|stylesheets|uploads)/ {
                root html;
                access_log off;
                expires 30d;
             } 
    
             location ~ .(apk|torrent|htm|html|asp|php|gif|jpg|jpeg|png|bmp|ico|rar|css|js|zip|map|java|jar|txt|flv|swf|mid|doc|ppt|xls|pdf|txt|mp3|wma)$ {
                root html;
                access_log off;
                expires 30d;
             }
             ssl_session_cache    shared:SSL:1m;
             ssl_session_timeout  5m;
             ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers
    "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
             #ssl_ciphers  HIGH:!aNULL:!MD5;
             ssl_prefer_server_ciphers  on;
             location / {
                   root   html;
                   index  index.html index.htm;  
                set $mscheme $scheme;
                if ($http_referer ~* ^https.*) {
                    set $mscheme "https";
                }
                proxy_set_header X-Forwarded-Proto $mscheme;
               }
    
        location /finance-web{
               proxy_pass http://10.56.30.91:7001/finance-web;
                set $mscheme $scheme;
                if ($http_referer ~* ^https.*) {
                    set $mscheme "https";
                }
                proxy_set_header X-Forwarded-Proto $mscheme;
            }
    
            location /appframe-web{
               proxy_pass http://10.56.30.91:7001/appframe-web;
                set $mscheme $scheme;
                if ($http_referer ~* ^https.*) {
                    set $mscheme "https";
                }
                proxy_set_header X-Forwarded-Proto $mscheme;
            }
    
            location /agency-web{
               proxy_pass http://10.56.30.91:7001/agency-web;
    
                set $mscheme $scheme;
                if ($http_referer ~* ^https.*) {
                    set $mscheme "https";
                }
                proxy_set_header X-Forwarded-Proto $mscheme;
            }
      }
        
        
    
    
    #        location ~ ^/nstatus {
    #            stub_status on;
    #            access_log off;
    #            allow 127.0.0.1;
    #            allow 10.236.57.0/24;
    #            deny all;
    #        }
    
        error_page 502 504 /502.html;
        error_page 503 /503.html;
        error_page 404 /404.html;
        error_page 403 /403.html;
        }
        

     5.加密会话(SSL)Cookie 中缺少 Secure 属性

     这个问题主要是因为cookie里头的属性secure未设置true。因为部署的容器是weblogic所以在应用的weblogic.xml文件里头新增属性:

    <?xml version="1.0" encoding="UTF-8"?>
    <weblogic-web-app xmlns="http://www.bea.com/ns/weblogic/90" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <container-descriptor>
            <prefer-web-inf-classes>true</prefer-web-inf-classes> 
            <index-directory-enabled>true</index-directory-enabled>
              <show-archived-real-path-enabled>true</show-archived-real-path-enabled>
        </container-descriptor> 
        <charset-params>
            <input-charset>
                <resource-path>/*</resource-path>
                <java-charset-name>UTF-8</java-charset-name>
            </input-charset> 
        </charset-params> 
        <context-root>/appframe-web</context-root>
        <session-descriptor>
            <cookie-http-only>true</cookie-http-only>
            <cookie-secure>true</cookie-secure>
        </session-descriptor>
    </weblogic-web-app>

    如图要新增

        <session-descriptor>
            <cookie-http-only>true</cookie-http-only>
            <cookie-secure>true</cookie-secure>
        </session-descriptor>

    如何验证呢?

    可以加,

    但是没加前,获取cookie是空的 ,也就是说没有通过https传递cookie,那么document.cookie获取不到cookie

    此外在nginx配置里头也要加上

     

        add_header                  Set-Cookie "HttpOnly";
        add_header                  Set-Cookie "Secure";
        add_header                  X-Frame-Options "SAMEORIGIN"

    另外如果是shiro工程,要在spring-shiro.xml下加上配置:

        <!-- 会话Cookie模板 -->
        <bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
            <constructor-arg value="bosssoft.com.cn"/>
            <property name="httpOnly" value="true"/>
            <property name="secure" value="true"/>
            <!--cookie的有效时间 -->
            <property name="maxAge" value="-1"/>
        </bean>  

    基于安全的考虑,需要给cookie加上Secure和HttpOnly属性,HttpOnly比较好理解,设置HttpOnly=true的cookie不能被js获取到,无法用document.cookie打出cookie的内容。
    Secure属性是说如果一个cookie被设置了Secure=true,那么这个cookie只能用https协议发送给服务器,用http协议是不发送的。换句话说,cookie是在https的情况下创建的,而且他的Secure=true,那么之后你一直用https访问其他的页面(比如登录之后点击其他子页面),cookie会被发送到服务器,你无需重新登录就可以跳转到其他页面。但是如果这是你把url改成http协议访问其他页面,你就需要重新登录了,因为这个cookie不能在http协议中发送。

    6.检查到目标URL存在http host头攻击漏洞 

    上述问题出现的原因为在项目中使用了 request.getServerName 导致漏洞的出现,不要使用request中的serverName,也就是说host header可能会在攻击时被篡改,依赖request的方法是不可靠的,形如JSP头部中的: 

    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"

    这样的使用方法就会被漏洞检测工具查出来,认定有头攻击漏洞。

    解决方案:在CSRFFilter过滤器中加入头部攻击判断:

            String requestHost=((HttpServletRequest) request).getHeader("host");
            if(requestHost!=null&&!isWhiteHost(requestHost)){
                ((HttpServletResponse) response).setStatus(403);
                return;
            }

    7.检查到目标站点存在JavaScript框架库漏洞

    这个问题,主要是因为jquery.js在低版本中存在安全漏洞的问题,只要替换高版本的jQuery.js库就可以解决了,当然要考虑高版本对IE8的兼容问题。可以参考博文《Jquery3.x高版本支持IE8

  • 相关阅读:
    vue路由的两种模式,hash与history
    javascript的继承小结
    attr和prop区别
    ie6、7下 text-indent 问题
    推荐链接
    iphone中 input圆角bug
    gif图片加载问题
    IE7中绝对定位元素之间的遮盖问题
    多行文本溢出显示省略号(...)的方法
    ie6兼容之绝对定位元素内容为空时高度问题
  • 原文地址:https://www.cnblogs.com/shawWey/p/10018630.html
Copyright © 2011-2022 走看看