vislee / leevis.com

Blog
87 stars 13 forks source link

应用防火墙思考汇总 #145

Open vislee opened 6 years ago

vislee commented 6 years ago

概述

最近在搞一个基于nginx的应用防火墙。通过开源的语义分析的库实现一些拦截,新的CVE也可以快速的通过添加规则实现拦截。 检测的点有URL、ARGS 、HEADERS、BODY。检测的方式通过开源库结合自制配置的规则实现。 前面几部分的检测都简单,因为格式是固定的。 BODY的检测就麻烦多了,格式不固定,检测内容多。

思路

  1. raw body 字符串过滤。

  2. 表单解析 字符串过滤,上传文件过滤 multipart/form-data 协议 文件上传可以通过文件头魔数先做一次检测

    例如:

        // ELF 文件的魔数0x7F454C4602010100
        od -tx a.out  |head -3
        0000000 464c457f 00010102 00000000 00000000
        0000020 003e0002 00000001 00400470 00000000
        0000040 00000040 00000000 00000d10 00000000

        readelf -h a.out
        ELF Header:
        Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00

魔数检测有专门的库libmagic, 在macbook测试,brew install libmagic 例子代码:

#include <stdio.h>
#include <magic.h>

int main(int argc,char **argv)
{
    magic_t cookie;

    cookie=magic_open(MAGIC_MIME_TYPE);
    magic_setflags(cookie, 0);
    magic_load(cookie,NULL);
    puts(magic_file(cookie,argv[1]));
    magic_close(cookie);

    return 0;
}

编译 gcc -o tmp_type tmp_type.c -lmagic

测试

./tmp_type  ./waf_module.pdf
PDF document, version 1.3
  1. xml json 等格式的解析,字符串过滤。

总结


http {
   ......
    sec_rule 1001 "str:rx@[a-z]{1,3}" "s:$BYPASS:1,$SQLI:2" z:V_HEADERS:bar|ARGS;
    sec_rule 1002 "str:sw@/test.php" s:$XSS:3,$BYPASS:3 z:#URL;
    sec_rule 1003 "libinj:sql" "s:$SQLI:9" z:V_ARGS:foo;
    sec_rule 1004 "libinj:xss" "s:$XSS:9" z:V_ARGS:foo "note:test rule by vislee";

    sec_rule 2001 "str:eq@testbody" "s:$BYPASS:2" "z:BODY";
    sec_rule 2002 "str:ct@test file data" "s:$BYPASS:2" "z:V_BODY:input";
    sec_rule 2003 "str:ew@.php" "s:$HANG:2" "z:#FILE";
    sec_rule 2004 "str:ct@testphp" "s:$BYPASS:2" "z:#RAW_BODY";

    map $sec_result $ups {
        "block" block;
        default runtime;
    }

    server {

        location / {
            client_body_buffer_size 1m;

            security on;
            sec_log ./logs/waf.log;

            sec_check $HANG >4 LOG;
            sec_check $BYPASS>8 $sec_result;
            sec_check $SQLI>8 $sec_result;
            sec_check $XSS>8 BLOCK;

            sec_rule w:1003 z:V_ARGS:test;
            sec_rule 90001 str:eq@vislee s:$BYPASS:4 z:V_HEADERS:name;

            proxy_pass http://$ups/;
        }

    }
selboo commented 6 years ago

up up