网络信息系统安全检测方案设计(下)

接上一篇文章《网络信息系统安全检测方案设计(上)》

HTTP 响应头拆分 CRLF 检测

CRLF 代表回车 (CR, ASCII 13, \r) 以及换行 (LF, ASCII 10, \n),也就是”回车 + 换行”(\r\n)的意思。许多网络协议,包括 HTTP 同样沿用 CRLF 来表示每一行的结束。HTTP 头 header 的定义便是基于这样的"Key: Value"的结构,例如 "Location:"头用来表示重定向的URL地址,"Set-Cookie:"头用来设置 cookies。

CRLF 原理分析

HTTP 头用 CRLF 命令表示一行的结尾,这就意味着用户可以通过 CRLF 注入自定义 HTTP header。例如正常的 302 跳转是这样:

HTTP/1.1 302 Moved Temporarily
Date: Fri, 27 Jun 2014 17:52:17 GMT
Content-Type: text/html
Content-Length: 154
Connection: close
Location: http://www.qq.com

但是我们注入了一个换行,此时的返回就会变成这样:

HTTP/1.1 302 Moved Temporarily
Date: Fri, 27 Jun 2014 17:52:17 GMT
Content-Type: text/html
Content-Length: 154
Connection: close
Location: http://www.qq.com
Set-cookie: JSPSESSID=abc

这个时候这样我们就给访问者设置了一个 Session,造成一个“会话固定漏洞”。

CRLF 检测与防御

通过过滤 Response 的响应头和 Cookie 可以检测与防范大部分的 CRLF 注入。仍然是在 HttpServletResponseWrapper 中重写相关的方法。

@Override
public void addCookie(Cookie cookie) {
    if (length + cookie.getValue().length() > MAX_COOKIE_SIZE)
        return;

    if (!isInWhiteList(cookie))
        throw new RuntimeException("cookie:" + cookie.getName() + " is not in whitelist,not valid.");

    try {
        super.addCookie(CLRF.checkCookie(cookie));
        length += cookie.getValue().length();
    } catch (SecurityException e) {
        e.printStackTrace();
    }
}

@Override
public void setDateHeader(String name, long date) {
    super.setDateHeader(CLRF.filterCLRF(name), date);
}

@Override
public void setIntHeader(String name, int value) {
    super.setIntHeader(CLRF.filterCLRF(name), value);
}

@Override
public void addHeader(String name, String value) {
    super.addHeader(CLRF.filterCLRF(name), XSS.xssFilter(CLRF.filterCLRF(value), null));
}

@Override
public void setHeader(String name, String value) {
    super.setHeader(CLRF.filterCLRF(name), XSS.xssFilter(CLRF.filterCLRF(value), null));
}

上述的过滤方法如下,均是静态方法。

/**
     * 如果 cookie 名称包含 CLRF 则抛出异常;接着过滤 cookie 内容
     * @param inputCookie
     * @return
     * @throws SecurityException
     */
    public static Cookie checkCookie(Cookie inputCookie) throws SecurityException {
        if (inputCookie == null)
            return null;
    
        String name = inputCookie.getName(), value = inputCookie.getValue();
    
        if (CLRF.containCLRF(name))
            throw new SecurityException(" cookie 名称不能包含 CLRF,该 cookie 是:" + name);
    
        String newValue = CLRF.filterCLRF(value);// 已经过滤好的 Cookie value
        // 重新创建 cookie
        Cookie newCookie = new Cookie(name, newValue);
        newCookie.setComment(inputCookie.getComment());
    
        if (inputCookie.getDomain() != null)
            newCookie.setDomain(inputCookie.getDomain());
    
        newCookie.setHttpOnly(inputCookie.isHttpOnly());
        newCookie.setMaxAge(inputCookie.getMaxAge());
        newCookie.setPath(inputCookie.getPath());
        newCookie.setSecure(inputCookie.getSecure());
        newCookie.setVersion(inputCookie.getVersion());
    
        return newCookie;
    }

    /**
     * 过滤  \r 、\n之类的换行符
     * @param value
     * @return
     */
    public static String filterCLRF(String value) {
        if (value == null || value.isEmpty())
            return value;
    
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < value.length(); i++) {
            if (!(value.charAt(i) == '\r' || value.charAt(i) == '\n'))
                sb.append(value.charAt(i));
        }
        return sb.toString();
    }

    /**
     * 是否包含 \r 、\n之类的换行符
     * @param name
     * @return
     */
    public static boolean containCLRF(String name) {
        if (name == null || name.isEmpty())
            return false;
    
        for (int i = 0; i < name.length(); i++) {
            if (name.charAt(i) == '\r' || name.charAt(i) == '\n')
                return true;
        }
        return false;
    }

SQL 注入攻击

SQL 注入攻击是常见的攻击方式。所谓 SQL 注入式攻击,就是攻击者把 SQL 命令插入到 Web 表单的输入域或页面请求的查询字符串,欺骗服务器执行恶意的 SQL 命令。在某些表单中,用户输入的内容直接用来构造(或者影响)动态 SQL 命令,或作为存储过程的输入参数,这类表单特别容易受到 SQL 注入式攻击。

SQL 注入原理分析

假设我们可以通过 http://localhost/test/userinfo.php?username=plhwin 这个 URL 来访问到具体某个会员的详情,正常情况下,如果浏览器里传入的 username 是合法的,那么 SQL 语句会执行:

SELECT uid,username FROM user WHERE username='plhwin'

但是,如果用户在浏览器里把传入的 username 参数变为 plhwin';SHOW TABLES-- hack,也就是当 URL 变为 http://localhost/test/userinfo.php?username=plhwin';SHOW TABLES-- hack 的时候,此时我们程序实际执行的 SQL 语句变成了:

SELECT uid,username FROM user WHERE username='plhwin';SHOW TABLES

SQL 注入检测与防御

防止 SQL 注入有多种方法,这里介绍“使用预编译语句”和过滤器的方法。Java 中使用 PrearedStatement 的 SQL 语句如下:

String sqlString ="INSERT INTO user(id, password, name, email, address) VALUES(?, ?, ?, ?, ?)";  
PreparedStatement pstmt = connection.PreparedStatement(sqlString);  
pstmt.setString(1, user.id);  
pstmt.setString(2, user.password);  
pstmt.setString(3, user.name);  
pstmt.setString(4, user.email);  
pstmt.setString(5, user.address); 

使用占位符?代替参数,将参数与 SQL 语句分离出来,阻止了 SQL 注入。

过滤器的方法原理也十分简单,主要是通过正则匹配敏感字符串进行过滤。代码如下。

import java.io.IOException;
import java.util.Enumeration;
 
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
 
public class AntiSqlInjectionfilter implements Filter {
 
    public void destroy() {
        // TODO Auto-generated method stub
    }
     
    public void init(FilterConfig arg0) throws ServletException {
        // TODO Auto-generated method stub
    }
     
    public void doFilter(ServletRequest args0, ServletResponse args1,
            FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req=(HttpServletRequest)args0;
        HttpServletRequest res=(HttpServletRequest)args1;
         //获得所有请求参数名
        Enumeration params = req.getParameterNames();
        String sql = "";
        while (params.hasMoreElements()) {
            //得到参数名
            String name = params.nextElement().toString();
            //System.out.println("name===========================" + name + "--");
            //得到参数对应值
            String[] value = req.getParameterValues(name);
            for (int i = 0; i < value.length; i++) {
                sql = sql + value[i];
            }
        }
        //System.out.println("============================SQL"+sql);
        //有sql关键字,跳转到error.html
        if (sqlValidate(sql)) {
            throw new IOException("您发送请求中的参数中含有非法字符");
            //String ip = req.getRemoteAddr();
        } else {
            chain.doFilter(args0,args1);
        }
    }
     
    //效验
    protected static boolean sqlValidate(String str) {
        str = str.toLowerCase();//统一转为小写
        String badStr = "'|and|exec|execute|insert|select|delete|update|count|drop|*|%|chr|mid|master|truncate|" +
                "char|declare|sitename|net user|xp_cmdshell|;|or|-|+|,|like'|and|exec|execute|insert|create|drop|" +
                "table|from|grant|use|group_concat|column_name|" +
                "information_schema.columns|table_schema|union|where|select|delete|update|order|by|count|*|" +
                "chr|mid|master|truncate|char|declare|or|;|-|--|+|,|like|//|/|%|#";//过滤掉的sql关键字,可以手动添加
        String[] badStrs = badStr.split("\\|");
        for (int i = 0; i < badStrs.length; i++) {
            if (str.indexOf(badStrs[i]) >= 0) {
                return true;
            }
        }
        return false;
    }
}

在 web.xml 文件中的配置过滤器:

<filter>
        <filter-name>antiSqlInjection</filter-name>
        <filter-class>com.abc.AntiSqlInjectionfilter</filter-class>
</filter>
<filter-mapping>
        <filter-name>antiSqlInjection</filter-name>
        <url-pattern>/*</url-pattern>
</filter-mapping>

结束语

本文通过相对简单的手段检测了 XSS 攻击、CSRF 攻击、CRLF  注入和 SQL 注入攻击,用户只需要配置 Servlet 过滤器即可。由于考虑的地方可能不是太周全,加上水平有限,希望可以提出指正。
深信服网络安全监测解决方案 背景与需求分析 网络安全已上升到国家战略,网络信息安全是国家安全的重要一环,2015年7月1号颁布的《国家安全法》第二十五条指出:加强网络管理,防范、制止和依法惩治网络攻击、网络入侵、网络窃密、散布违法有害信息等网络违法犯罪行为,维护国家网络空间主权、安全和发展利益。国家《网络安全法》草案已经发布,正式的法律预计不久后也会正式颁布。保障网络安全,不仅是国家的义务,也是企业和组织机构的责任。对于企业来说,保障网络信息安全,防止网络攻击、网络入侵、网络窃密、违法信息发布,不仅能维护自身经济发展利益,还能避免法律风险,减少社会信誉损失。 Gartner认为,未来企业安全将发生很大的转变,传统的安全手段无法防范APT等高级定向攻击,如果没有集体共享的威胁和攻击情报监测,将很难全方位的保护自己网络安全。因此过去单纯以被动防范的安全策略将会过时,全方位的安全监控和情报共享将成为信息安全的重要手段。 因此,仅仅依靠防护体系不足以应对安全威胁,企业需要建立全面的监测机制,扩大监控的深度和宽度,加强事件的响应能力。安全监测和响应能力将成为企业安全能力的关键,在新的安全形势下,企业需要更加关注威胁监控和综合性分析的价值,使信息安全保障逐步由传统的被动防护转向"监测-响应式"的主动防御,实现信息安全保障向着完整、联动、可信、快速响应的综合防御体系发展。 然而,传统的网络安全设备更多关注网络层风险及基于已知特征的被动保护,缺乏对各种系统、软件的漏洞后门有效监测,缺乏对流量内容的深度分析及未知威胁有效识别,不具备多维全面的安全风险监测响应机制,已不能满足新形势下网络安全的需求。 深信服网络安全监测解决方案 网络安全监测方案全文共9页,当前为第1页。深信服创新性的推出了网络安全监测解决方案,该方案面向未来的安全需求设计,帮助企业实现多层次、全方位、全网络的立体网络安全监测。该方案主要采用了深信服下一代防火墙NGAF作为监测节点,通过对应用状态、数据内容、用户行为等多个维度的全方位安全监测,并结合深信服云安全中心海量威胁情报快速共享机制,帮助企业构建立体化、主动化、智能化综合安全监测防御体系,有效弥补了传统安全设备只能防护已知常规威胁的被动局面,实现了安全风险全面识别和快速响应。 网络安全监测方案全文共9页,当前为第1页。 实现网络安全威胁内容的全面监测,帮助用户深度的了解和评估网络安全风险,是深信服下一代防火墙(NGAF)设计目的之一。NGAF能够深入分析流量内容,有效识别网络中的用户、应用、内容和威胁。NGAF提供了更加全面的安全威胁监测能力,除了传统的黑名单、木马病毒特征签名检测外,还提供了实时漏洞监测、僵尸主机监测、数据风险监测、黑链风险监测、对外DoS攻击等多种威胁监测,全面满足网络安全监测和防御体系建设的需求。 网络安全监测方案全文共9页,当前为第2页。NGAF可以旁路部署在网络中,通过将相关业务数据流镜像到下一代防火墙进行实时监测,该方式对用户业务系统的完整性、可用性可以做到零影响。NGAF能够协助用户进行业务系统安全风险评估,并结合黑客攻击行为进行关联分析,帮助用户找到真正存在风险的薄弱环节。NGAF也可以串接在网络中在线监测,实时监控入侵、漏洞、僵尸主机、数据泄漏、黑链等安全风险,并提供专业的安全风险运维加固参考方案,助您快速实现自助化安全运维。配合使用NGAF的外置数据中心,您可以将监测设备的安全日志集中存储和汇总分析,外置数据中心能够给出监测设备当前网络环境的安全概况、最近的攻击事件详情、漏洞详情,并支持综合日志查询功能,可以查询监测到的多种类型安全日志。 网络安全监测方案全文共9页,当前为第2页。 NGAF可以将监测到的安全风险在WEB页面展现,大部分威胁类型都可以在NGAF设备页面的系统状态查看到,进一步点击进去还能看到每一类风险的详细信息,并且提供了客观的威胁描述及参考解决方案。 入侵风险监测 NGAF提供了入侵风险监测功能,能够自动收集被保护网络遭受到的入侵风险状况,并基于今天、昨天、最近7天分别展示。入侵风险包含了多维的风险类型,包括WEBSHELL、XSS攻击、SQL注入、信息泄露、恶意链接、网站扫描、DNS漏洞攻击、FTP漏洞攻击、系统漏洞攻击、后门漏洞攻击等。 网络安全监测方案全文共9页,当前为第3页。 网络安全监测方案全文共9页,当前为第3页。 登录NGAF设备就能看到系统状态中的入侵风险情况(如上图),进一步点击入侵风险,还能看到详细的入侵风险状况,包括入侵风险的类型TOP10、入侵风险排行详情、每种攻击的数量、有效攻击数量、攻击类型、被攻击IP等信息,如果配置了深信服外置数据中心,还能进一步看到每个攻击的详细信息,包括源IP、目的IP、时间、类型、攻击描述等详细的入侵信息,并能够导出
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值