驗證猜想:

想做一個報文攻擊類別分類器是一個比較棘手的問題,今天想用SVM跑一下3分類,分別是正常報文,XSS報文,SQL報文。在嘗試使用rbf核函數的時候,發現正常樣本被分類到XSS中,換成linear就好了,大霧。

由於後面的攻擊檢測引擎是SVM2分類,所以多分類之後再2分類驗證的意義不太大,畢竟都是SVM也沒啥好比較的,直接單引擎寫一個小小的demo驗證一下思路。

首先python文件跑通了,然後ctest跑通了,最後Nginx也跑通了,看上去一個小小的demo就出來了,算是邁出了基於機器學習的WAF模型探究的第一步,後續還需要研究Nginx如何輸送報文給我們的引擎。

AB壓力測試結果:

nginx worker進程1個的結果如下,如果worker進程多點,數據會好看點。因為這個demo是對每一個HTTP請求都檢查,不知道是好還是壞,隱約記得modsecurity只檢查部分HTTP請求,好像是用戶的請求。

Document Path: /
Document Length: 7093 bytes

Concurrency Level: 100
Time taken for tests: 26.555 seconds
Complete requests: 10000
Failed requests: 0
Total transferred: 72450000 bytes
HTML transferred: 70930000 bytes
Requests per second: 376.57 [#/sec] (mean)
Time per request: 265.554 [ms] (mean)
Time per request: 2.656 [ms] (mean, across all concurrent requests)
Transfer rate: 2664.31 [Kbytes/sec] received

模型結構:

├── a.out
├── config
├── data
│ ├── good-10000.txt
│ ├── good.txt
│ ├── sql-10000.txt
│ └── xss-200000.txt
├── model
│ └── waf.pkl
├── ngx_http_aisecurity_module.c
├── run.sh
├── test.c
├── waf.c
├── waf.h
├── waf.h.gch
├── waf.py
└── waf.pyc

部分代碼:

// ngx_http_aisecurity_module.c by ailx10
#include "waf.h"
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>

static ngx_int_t ngx_http_aisecurity_handler(ngx_http_request_t *r);
static ngx_int_t ngx_http_aisecurity_init(ngx_conf_t *cf);
static void *ngx_http_aisecurity_create_main_conf(ngx_conf_t *cf);
char *ngx_str_to_char(ngx_str_t a, ngx_pool_t *p);
const char** get_data(const char* uri,const char* method);
void free_data(const char** pkt_addr);

typedef struct {
PyObject* pEngine;
PyObject* pModule;
ngx_flag_t enable;
void * pool;
} ngx_http_aisecurity_conf_t;

ngx_int_t aisecurity_process_uri(ngx_http_aisecurity_conf_t* cf,const char** pkt_loads);
static ngx_command_t ngx_http_aisecurity_commands[] = {
{
ngx_string("aisecurity"),
NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
ngx_conf_set_flag_slot,
NGX_HTTP_MAIN_CONF_OFFSET,
offsetof(ngx_http_aisecurity_conf_t, enable),
NULL,
},
ngx_null_command
};

static ngx_http_module_t ngx_http_aisecurity_module_ctx = {
NULL,
ngx_http_aisecurity_init,
ngx_http_aisecurity_create_main_conf,
NULL,
NULL,
NULL,
NULL,
NULL
};

ngx_module_t ngx_http_aisecurity_module = {
NGX_MODULE_V1,
&ngx_http_aisecurity_module_ctx,
ngx_http_aisecurity_commands,
NGX_HTTP_MODULE,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NGX_MODULE_V1_PADDING
};

static ngx_int_t ngx_http_aisecurity_init(ngx_conf_t *cf)
{
ngx_http_handler_pt *h_rewrite;
ngx_http_core_main_conf_t *cmcf;
cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
if (cmcf == NULL)
{
return NGX_ERROR;
}
h_rewrite = ngx_array_push(&cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers);
if (h_rewrite == NULL)
{
return NGX_ERROR;
}
*h_rewrite = ngx_http_aisecurity_handler;
return NGX_OK;
}

static void *ngx_http_aisecurity_create_main_conf(ngx_conf_t *cf)
{
ngx_http_aisecurity_conf_t *conf = (ngx_http_aisecurity_conf_t *)
ngx_pcalloc(cf->pool, sizeof(ngx_http_aisecurity_conf_t));
if (conf == NULL || conf == NGX_CONF_ERROR) {
return NGX_CONF_ERROR;
}
PyObject* pModule = aisec_waf_init();
PyObject* pEngine = aisec_waf_load(pModule);
conf->pModule = pModule;
conf->pEngine = pEngine;
conf->enable = NGX_CONF_UNSET;
conf->pool = cf->pool;
printf("(nginx)%p %p
",pModule,pEngine);
return conf;
}

static ngx_int_t ngx_http_aisecurity_handler(ngx_http_request_t *r)
{
ngx_int_t atk = 0;
ngx_int_t ret = 0;
ngx_http_aisecurity_conf_t* cf;
cf = ngx_http_get_module_main_conf(r, ngx_http_aisecurity_module);
if(cf->enable != 1) return NGX_DECLINED;
const char* uri = ngx_str_to_char(r->unparsed_uri,r->pool);
const char* method = ngx_str_to_char(r->method_name,r->pool);
const char** pkt_addr = get_data(uri,method);
atk = aisecurity_process_uri(cf,pkt_addr);
free_data(pkt_addr);
if(atk)
ret = NGX_HTTP_FORBIDDEN;
else
ret = NGX_DECLINED;
return ret;
}

const char** get_data(const char* uri,const char* method)
{
char** pkt_addr = (char**)malloc(2*sizeof(char*));
pkt_addr[0] = (char*)uri;
pkt_addr[1] = (char*)method;
printf("pkt:
%s
%s
",pkt_addr[0],pkt_addr[1]);
return (const char**)pkt_addr;
}

void free_data(const char** pkt_addr)
{
free(pkt_addr);
return;
}

ngx_int_t aisecurity_process_uri(ngx_http_aisecurity_conf_t* cf,const char** pkt_loads)
{
ngx_int_t ret = 0;
ret = aisec_waf_predict(cf->pModule,cf->pEngine,pkt_loads);
return ret;
}

ngx_inline char *ngx_str_to_char(ngx_str_t a, ngx_pool_t *p)
{
char *str = NULL;
if (a.len == 0) {
return NULL;
}
str = ngx_pnalloc(p, a.len+1);
if (str == NULL) {
return (char *)-1;
}
ngx_memcpy(str, a.data, a.len);
str[a.len] =

查看原文 >>
相关文章