安装SQL注入检测库libinjection

github: https://github.com/client9/libinjection

wiki:   https://github.com/client9/libinjection/wiki

在libinjection-go做优化: grapeSQLI(https://github.com/koangel/grapeSQLI)

libinjection在2012年在Black Hat黑帽大会上首先被公布,使用指纹而不是正则表达式来检测SQL注入攻击,取得了很好的效果。开源WAF程序ModSecurity就使用了libinjection。

好了,现在我们又有了安装的问题,作为一个小白,再次记录一下libinjection的安装过程。

  1. 首先,要有光,libinjection托管在github上,直接clone或者下载即可。

    wget https://github.com/client9/libinjection/archive/master.zip
    unzip libinjiection.zip
  2. 安装的时候发现autogen.sh这个脚本需要autoconf这个程序,去下个最新版吧

    wget http://ftp.gnu.org/gnu/autoconf/autoconf-latest.tar.gz
    tar xvfz autoconf-latest.tar.gz
    cd autoconf-2.69/
    ./configure
    make
    make install
  3. 安装,这样C语言就可以正常引用libinjection.h了

    cd libinjection-master/
    ./autogen.sh
    ./configure
    make
    make install
  4. Python版的安装还需要先行安装swig,标准的安装流程

    wget http://prdownloads.sourceforge.net/swig/swig-3.0.0.tar.gz
    tar xvfz swig-3.0.0.tar.gz
    cd cd swig-3.0.0
    ./configure
    make
    make install
  5. 安装完swig就可以正常安装Python版的libinjection啦,有一点注意Makefile里源文件路径是../c,但是实际上是../src,重命名一下即可

    cd libinjection-master
    cd python
    make
    python setup.py install
  6. 安装完了import一下看看是否成功吧,不报错就OK

    from libinjection import *
    
    # create the data object
    s = sqli_state()
    
    astr = "-1' and 1=1 union/* foo */select load_file('/etc/passwd')--"
    sqli_init(s, astr, 0)
    
    astr = None
    
    is_sqli(s)
    # initialize it
    # you might wish to turn it into a bool by doing
    # issqli = bool(is_sqli(s))
    
    # if it's true, then you can get the SQLi fingerprint
    # by looking in the state object
    
    print s.fingerprint
    
    # reset and do it again
    

二、libinjection实例分析

上面已经对libinjection的程序进行了简单的分析,下面通过一个具体的例子来了解libinjecton的处理流程。

首先来看libinjection对特征码的定义

typedef enum {
    TYPE_NONE        = 0   /*无实际意义,仅对位数进行填充*/
    , TYPE_KEYWORD     = (int)'k'  /*例如COLUMN,DATABASES,DEC等会被识别为该值*/
    , TYPE_UNION       = (int)'U'  /*EXCEPT,INTERSECT,UNION等会被识别为该值*/
    , TYPE_GROUP       = (int)'B'    /*GROUP BY,LIMIT,HAVING*/
    , TYPE_EXPRESSION  = (int)'E'   /*INSERT,SELECT,SET*/
    , TYPE_SQLTYPE     = (int)'t'  /*SMALLINT,TEXT,TRY*/
    , TYPE_FUNCTION    = (int)'f'   /*UPPER,UTL_HTTP.REQUEST,UUID*/
    , TYPE_BAREWORD    = (int)'n'  /*WAITFOR,BY,CHECK*/
    , TYPE_NUMBER      = (int)'1'   /*所有数字会被识别为1*/
    , TYPE_VARIABLE    = (int)'v'  /*CURRENT_TIME,LOCALTIME,NULL*/
    , TYPE_STRING      = (int)'s'   /*单引号和双引号*/
    , TYPE_OPERATOR    = (int)'o'  /*+=,-=,!>*/
    , TYPE_LOGIC_OPERATOR = (int)'&'   /*&&,AND,OR*/
    , TYPE_COMMENT     = (int)'c'     /*注释符*/
    , TYPE_COLLATE     = (int)'A'  /* COLLATE*/
    , TYPE_LEFTPARENS  = (int)'('     
    , TYPE_RIGHTPARENS = (int)')'  /* not used? */
    , TYPE_LEFTBRACE   = (int)'{'    
    , TYPE_RIGHTBRACE  = (int)'}'
    , TYPE_DOT         = (int)'.'
    , TYPE_COMMA       = (int)','
    , TYPE_COLON       = (int)':'
    , TYPE_SEMICOLON   = (int)';'
    , TYPE_TSQL        = (int)'T'  /* TSQL start */ /*DECLARE,DELETE,DROP*/
    , TYPE_UNKNOWN     = (int)'?'
    , TYPE_EVIL        = (int)'X'  /* unparsable, abort  */   /* “/*!*/”  */
    , TYPE_FINGERPRINT = (int)'F'  /* not really a token */
    , TYPE_BACKSLASH   = (int)'\\'
} sqli_token_types;
 

libinjection将输入的数据依据上述的定义进行转换,之后就会得到SQL注入识别特征,或者说指纹,然后通过二分查找算法,在特征库中进行匹配,匹配到则报SQL注入漏洞。

例如:

我们输入SQL注入的检测语句

‘ and 1=1

libinjection会将其转换为s&1,其中单引号依据定义被转换为s,and被转换为&,数字被转换为1

' UNION ALL SELECT NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL--

libinjection会将其转换为sUEvc,其中单引号依据定义被转换为s,UNION ALL被转换为U,SELECT被转换为E,NULL被转换为v,后面相同的NULL合并为一个v,–注释符被转换为c

libinjection在转换完后,通过二分查找算法对内置的8000多个特征进行匹配,匹配到则将SQL注入识别特征复制进fingerprint变量并返回。

通过上述两个例子就可以知道libinjection对数据的转换逻辑,其中针对一些特殊情况会有特殊处理,文章篇幅有限这里不讲,有兴趣可以去看代码。

三、总结

SQL注入语义分析库libinjection相比传统正则匹配识别SQL注入的好处在于速度快以及低误报,低漏报 。

速度快体现在该库全程比较耗性能的就一二分查找算法,相对于正则对性能的消耗来说可以忽略不计,这点从火焰图上可以很明显的看出来,所以无论特征数是800,8000还是80000,对处理速度来说都不会有太大影响,而正则匹配规则达到千条以上就能明显感觉到性能的变化。

低误报呢,以前在测试modsecurity2.0的owasp规则的时候,那个误报率简直感人。但是如果要把规则写细,降低误报率的话,那规则数必然会上去进而对性能产生一些影响。SQL注入语义好就好在,要想满足他的匹配规则,一般来说必须满足三个特征以上,比如s&1或者sUEvc,而每个特征要么是特殊字符,要么是SQL语句的保留字,所以正常情况下用户输入,很少会出现这种误报这种情况。

低漏报呢,则在于那8000多的识别特征了基本上把可能的路都堵死了,如有发现能在实际场景中绕过的,欢迎交流。

参考: 简单分析SQL注入语义分析库Libinjection http://www.freebuf.com/articles/web/170930.html

猜你喜欢

转载自blog.csdn.net/vevenlcf/article/details/82189994