SQL注入语义分析库libinjection简介

目录
  • SQL注入语义分析库libinjection
    • 什么是libinjection
    • libinjection和正则表达式
    • modsecurity 如何使用libinjection
    • ModSecurity只用了libinjection防御sql注入吗?
    • WAF研发领域,语义分析相对于正则表达式先进性的研究
  • 参考文献

SQL注入语义分析库libinjection

什么是libinjection

libinjection是一款用于防御SQL注入攻击的开源软件库。它是由C语言编写的,可以嵌入到任何Web应用程序中,并可以较为准确地检测和防止恶意SQL注入语句。libinjection采用了基于正则表达式的技术来识别和拦截SQL注入攻击,同时其开放源代码的特点也使得其具备了较高的可定制性和扩展性。

libinjection是一个基于C语言的SQLi词法解析分析器,它可以通过对不同语句进行词法分析和语法分析来实现对SQL语句以及HTML语句的解析。

在此之前,市场上绝大多数的WAF都是基于正则匹配(Regex)的,很多的WAF(防火墙)以及NGWAF(下一代防火墙)出于性能方面的考虑,都会选择使用这个库来代替常规的正则表达式。

ModSecurity,它是Apache和nginx的流行WAF。ModSecurity捆绑了libinjection,mod_security从2.7.4版本开始就支持libinjection(dectectSQLi-v2.7.4、detectXSS-v2.8.0)。

libinjection和正则表达式

libinjection和正则表达式都是非常有效的防御SQL注入攻击的技术,但两者之间有一些差异和优劣。

libinjection
libinjection是一个专门用于检测SQL注入攻击的库,其使用了一个基于机器学习的算法来分析请求中的SQL语句。与正则表达式相比,它有以下优点:

  • 更准确:libinjection使用机器学习算法分析SQL语句,因此可以更准确地检测SQL注入攻击,同时减少误报率。
  • 更容易维护:libinjection的规则库相对较小,易于维护。
  • 更快:libinjection的性能要比正则表达式好,响应时间更短。

正则表达式
正则表达式是一种常见的用于检测和防御各种Web应用程序攻击(包括SQL注入攻击)的技术。与libinjection相比,它有以下优点:

更通用:正则表达式不仅可用于检测SQL注入攻击,而且还可用于检测其他类型的Web应用程序攻击。更灵活:正则表达式可以使用各种模式和操作符,从而可以灵活地处理各种复杂情况。更可配置性:正则表达式的规则库可以根据实际情况进行定制和配置。

总体而言,libinjection可能比正则表达式更准确,更容易维护,并具有更快的性能,但正则表达式更通用,更灵活,具有更高的可配置性。因此,为了获得最佳的安全性能,您可能需要考虑同时使用这两种技术。

modsecurity 如何使用libinjection

下面是使用libinjection和ModSecurity进行SQL注入检测和预防的步骤:

安装ModSecurity
安装并配置ModSecurity,使其可以与您的Web服务器一起使用。

安装libinjection
安装libinjection并将其与ModSecurity集成。如果您使用的是Debian或Ubuntu,可以使用以下命令进行安装:

sudo apt-get install libinjection-dev

在ModSecurity中使用libinjection
将ModSecurity配置为使用libinjection来检测SQL注入攻击。以下是一个示例ModSecurity规则,可用于检测SQL注入攻击:

SecRule ARGS "@detectSQLi" \
    "id:1,\
    phase:2,\
    t:none,\
    t:lowercase,\
    t:replaceComments,\
    t:compressWhitespace,\
    ctl:auditLogParts=+E,\
    ctl:debugLogParts=+E,\
    ctl:requestBodyProcessor=XML,\
    ctl:ruleEngine=on,\
    ctl:auditEngine=on,\
    ctl:ruleRemoveByTag=abcd \
    ctl:ruleRemoveById=1 \
    libinjection_check"

SecRule &TX:INJECTION @eq 1 \
    "id:2,\
    phase:2,\
    t:none,\
    ctl:auditLogParts=+E,\
    ctl:debugLogParts=+E,\
    ctl:requestBodyProcessor=XML,\
    ctl:ruleEngine=on,\
    ctl:auditEngine=On,\
    ctl:ruleRemoveByTag=abcd \
    ctl:ruleRemoveById=2 \
    block"

这个规则中包含了两个SecRule。第一个将对输入请求进行规范化和过滤,然后使用libinjection检测SQL注入攻击。第二个SecRule将根据检测结果来做出相应的动作,例如阻止访问请求或将其记录在日志中。

ModSecurity只用了libinjection防御sql注入吗?

ModSecurity不仅使用了libinjection,还使用了正则表达式等多种技术来进行SQL注入攻击防御。实际上,在ModSecurity中使用正则表达式是非常常见的一种方法,因为这种方法可以用于检测和阻止各种类型的Web应用程序攻击,包括SQL注入攻击。

以下是一个示例ModSecurity规则,使用正则表达式检测SQL注入攻击:

SecRule ARGS "@detectSQLi" \
    "id:1,\
    phase:2,\
    t:none,\
    t:lowercase,\
    t:replaceComments,\
    t:compressWhitespace,\
    ctl:auditLogParts=+E,\
    ctl:debugLogParts=+E,\
    ctl:requestBodyProcessor=XML,\
    ctl:ruleEngine=on,\
    ctl:auditEngine=on,\
    ctl:ruleRemoveByTag=abcd \
    ctl:ruleRemoveById=1 \
    libinjection_check"

SecRule &TX:INJECTION @eq 1 \
    "id:2,\
    phase:2,\
    t:none,\
    ctl:auditLogParts=+E,\
    ctl:debugLogParts=+E,\
    ctl:requestBodyProcessor=XML,\
    ctl:ruleEngine=on,\
    ctl:auditEngine=On,\
    ctl:ruleRemoveByTag=abcd \
    ctl:ruleRemoveById=2 \
    block"

虽然语义分析引擎能够更准确地识别和阻止恶意流量,但是正则表达式仍然是一种非常重要的检测方式,可以用来完成一些特定的任务。

例如,对于某些规则化的数据格式,如邮件地址、电话号码和身份证号码等,使用正则表达式可以快速、准确地进行匹配判断。此外,正则表达式还可以用来检测各种类型的注入攻击(如SQL注入和XSS攻击)等漏洞利用行为。

因此,在实际的安全防御中,WAF通常会同时采用多种技术手段,包括语义分析引擎和正则表达式等,以提高其检测能力,并最大程度地保护Web应用程序免受攻击威胁。

WAF研发领域,语义分析相对于正则表达式先进性的研究

多年以来,WAF对攻击的检测,通常使用正则表达式,典型的如ModSecurity。作为老牌的WAF,其拥有庞大的正则规则库。其检测率高,但也正因为规则数量庞大,正则逐一匹配,此过程速度慢,性能低。

对于同步检测的WAF产品,部署并对网站提供防护后,会带来不小的访问性能影响。

新兴的WAF产品,渐有使用语义分析引擎取代正则表达式检测。
其优势究竟何在,性能又能提升多少?

WAF研发领域,语义分析相对于正则表达式先进性的研究
直接查看原文链接: https://www.toutiao.com/article/6944906084217799207/

libinjection架构和使用

官方使用示例

#include <stdio.h>
#include <string.h>
#include "libinjection.h"

int main(int argc, const char* argv[])
{
    char fingerprint[8];
    const char* input;
    size_t slen;
    int issqli;

    if (argc < 2) {
        fprintf(stderr, "Usage: %s inputstring\n", argv[0]);
        return -1;
    }

    input = argv[1];
    slen = strlen(input);

    issqli = libinjection_sqli(input, slen, fingerprint);
    if (issqli) {
        printf("sqli with fingerprint of '%s'\n", fingerprint);
    } else {
        printf("not sqli\n");
    }

    return issqli;
}

具体的检查sql注入实现为 libinjection_is_sqli

int libinjection_is_sqli(struct libinjection_sqli_state * sql_state)
{
    const char *s = sql_state->s;
    size_t slen = sql_state->slen;

    /*
     * no input? not SQLi
     */
    if (slen == 0) {
        return FALSE;
    }

    /*
     * test input "as-is"
     */
    libinjection_sqli_fingerprint(sql_state, FLAG_QUOTE_NONE | FLAG_SQL_ANSI);
    if (sql_state->lookup(sql_state, LOOKUP_FINGERPRINT,
                          sql_state->fingerprint, strlen(sql_state->fingerprint))) {
        return TRUE;
    } else if (reparse_as_mysql(sql_state)) {
        libinjection_sqli_fingerprint(sql_state, FLAG_QUOTE_NONE | FLAG_SQL_MYSQL);
        if (sql_state->lookup(sql_state, LOOKUP_FINGERPRINT,
                              sql_state->fingerprint, strlen(sql_state->fingerprint))) {
            return TRUE;
        }
    }

    /*
     * if input has a single_quote, then
     * test as if input was actually '
     * example: if input if "1' = 1", then pretend it's
     *   "'1' = 1"
     * Porting Notes: example the same as doing
     *   is_string_sqli(sql_state, "'" + s, slen+1, NULL, fn, arg)
     *
     */
    if (memchr(s, CHAR_SINGLE, slen)) {
        libinjection_sqli_fingerprint(sql_state, FLAG_QUOTE_SINGLE | FLAG_SQL_ANSI);
        if (sql_state->lookup(sql_state, LOOKUP_FINGERPRINT,
                              sql_state->fingerprint, strlen(sql_state->fingerprint))) {
            return TRUE;
        } else if (reparse_as_mysql(sql_state)) {
            libinjection_sqli_fingerprint(sql_state, FLAG_QUOTE_SINGLE | FLAG_SQL_MYSQL);
            if (sql_state->lookup(sql_state, LOOKUP_FINGERPRINT,
                                  sql_state->fingerprint, strlen(sql_state->fingerprint))) {
                return TRUE;
            }
        }
    }

    /*
     * same as above but with a double-quote "
     */
    if (memchr(s, CHAR_DOUBLE, slen)) {
        libinjection_sqli_fingerprint(sql_state, FLAG_QUOTE_DOUBLE | FLAG_SQL_MYSQL);
        if (sql_state->lookup(sql_state, LOOKUP_FINGERPRINT,
                              sql_state->fingerprint, strlen(sql_state->fingerprint))) {
            return TRUE;
        }
    }

    /*
     * Hurray, input is not SQLi
     */
    return FALSE;
}

这段代码是用于检测 SQL 注入攻击的,通过调用 libinjection 库对输入的 SQL 查询语句进行指纹识别,并判断是否存在于已知的 SQL 注入指纹库中。

  • 首先获取输入字符串 s 和其长度 slen。如果输入字符串长度为0,则直接返回 FALSE,不需要进行检测。
  • 接着,对输入的 SQL 查询语句进行指纹识别,并标记 FLAG_QUOTE_NONE 和 FLAG_SQL_ANSI 标志位。然后通过 sql_state->lookup 函数查找该指纹是否已经存在于数据库中,如果存在则返回 TRUE。

“test input as-is” 的意思是对输入的 SQL 语句进行原样测试,即不进行任何转义或处理。这相当于将输入的 SQL 语句作为一个整体进行指纹识别,并标记 FLAG_QUOTE_NONE 和 FLAG_SQL_ANSI 标志位,在已知的 SQL 注入指纹库中查找是否存在相同的指纹。如果存在,则说明该输入可能是 SQL 注入攻击,否则继续进行其他检测。通常情况下,如果输入字符串包含单引号或双引号字符或者 SQL 关键字,就需要进行进一步的检测和处理。

  • 如果该指纹不存在于数据库中,则尝试将查询语句解析为 MySQL 语法,通过 reparse_as_mysql 函数进行转换。如果转换成功,则再次调用 libinjection_sqli_fingerprint 函数对转换后的 SQL 查询语句进行指纹识别,并标记 FLAG_QUOTE_NONE 和 FLAG_SQL_MYSQL 标志位。最后再次通过 sql_state->lookup 函数查找该指纹是否存在于数据库中,如果存在则返回 TRUE。
  • 接下来,如果输入的字符串中包含单引号字符,则调用 libinjection_sqli_fingerprint 函数对 SQL 查询语句进行指纹识别,并标记 FLAG_QUOTE_SINGLE 和 FLAG_SQL_ANSI 标志位。然后通过 sql_state->lookup 函数查找该指纹是否已经存在于数据库中,如果存在则返回 TRUE。
  • 如果该指纹不存在于数据库中,则尝试将查询语句解析为 MySQL 语法,通过 reparse_as_mysql 函数进行转换。如果转换成功,则再次调用 libinjection_sqli_fingerprint 函数对转换后的 SQL 查询语句进行指纹识别,并标记 FLAG_QUOTE_SINGLE 和 FLAG_SQL_MYSQL 标志位。最后再次通过 sql_state->lookup 函数查找该指纹是否存在于数据库中,如果存在则返回 TRUE。
  • 最后,如果输入的字符串中包含双引号字符,则调用 libinjection_sqli_fingerprint 函数对 SQL 查询语句进行指纹识别,并标记 FLAG_QUOTE_DOUBLE 和 FLAG_SQL_MYSQL 标志位。然后通过 sql_state->lookup 函数查找该指纹是否已经存在于数据库中,如果存在则返回 TRUE。
  • 如果输入字符串没有被识别为 SQL 注入攻击,则最后返回 FALSE。

总结,这段代码是用于检测 SQL 注入攻击,通过指纹识别技术来进行检测和防御。同时支持 ANSI SQL 和 MySQL 两种语法,并能够检测包含单引号和双引号字符以及 SQL 关键字的字符串。

例如,输入常用的SQL注入的检测语句 :’ and 1=1
libinjection会将其转换为s&1,其中单引号依据定义被转换为s,and被转换为&,数字被转换为1。

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

转换 搜索关键字: sql_keywords ,在文件libinjection_sqli_data.h 中~!

在libinjection中,将SQL关键字转换为单个字母时使用的字符集通常是a-z或A-Z。这意味着只有26个不同的字母可以用来表示所有的SQL关键字。

为了解决这个问题**,libinjection使用了一些技巧来扩展字母表的大小。其中一个技巧是引入数字后缀。例如,对于两个关键字SELECT和SET,它们都会被转换为字母s。为了避免冲突,第二个关键字SET会被转换为字母s2。**

另一个技巧是使用大写字母表示特殊的关键字。例如,LIMIT和OFFSET是MySQL和PostgreSQL中常用的关键字,它们被分别映射为L和O。这样做的好处是,即使一个关键字被映射为小写字母,仍然可以通过使用大写字母来表示其他特殊关键字,以避免冲突。

需要注意的是,虽然仅有26个字母可以用来表示所有的SQL关键字,但由于上面提到的技巧,libinjection能够支持更多的关键字,并确保每个关键字都使用唯一的单个字母来表示。

参考文献

【技术分享】如何绕过WAF/NGWAF的libinjection实现SQL注入
参考URL: http://www.52bug.cn/hkjs/3025.html
SQL注入与libinjection分析(1)SQL注入
参考URL: https://blog.csdn.net/lqy971966/article/details/105269658

到此这篇关于SQL注入语义分析库libinjection的文章就介绍到这了,更多相关SQL注入语义分析库内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • MySQL慢查询分析工具pt-query-digest详解

    目录 一.简介 二.安装pt-query-digest 三.pt-query-digest语法及重要选项 四.分析pt-query-digest输出结果 五.用法示例 一.简介 pt-query-digest是用于分析mysql慢查询的一个工具,它可以分析binlog.General log.slowlog,也可以通过SHOWPROCESSLIST或者通过tcpdump抓取的MySQL协议数据来进行分析.可以把分析结果输出到文件中,分析过程是先对查询语句的条件进行参数化,然后对参数化以后的查询进

  • SQL注入语义分析库libinjection简介

    目录 SQL注入语义分析库libinjection 什么是libinjection libinjection和正则表达式 modsecurity 如何使用libinjection ModSecurity只用了libinjection防御sql注入吗? WAF研发领域,语义分析相对于正则表达式先进性的研究 参考文献 SQL注入语义分析库libinjection 什么是libinjection libinjection是一款用于防御SQL注入攻击的开源软件库.它是由C语言编写的,可以嵌入到任何Web

  • 利用SQL注入漏洞拖库的方法

    想在本地测试的话,可以在此免积分下载:利用SQL注入漏洞拖库 同上一篇文章一样,我们需要创建数据表,并在表中出入几条数据以备测试之用. 在数据库中建立一张表: 复制代码 代码如下: CREATE TABLE `article` ( `articleid` int(11) NOT NULL AUTO_INCREMENT, `title` varchar(100) CHARACTER SET utf8 NOT NULL DEFAULT '', `content` text CHARACTER SET

  • Sql注入原理简介_动力节点Java学院整理

    一.什么是sql注入呢? 所谓SQL注入,就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令,比如先前的很多影视网站泄露VIP会员密码大多就是通过WEB表单递交查询字符暴出的,这类表单特别容易受到SQL注入式攻击.当应用程序使用输入内容来构造动态sql语句以访问数据库时,会发生sql注入攻击.如果代码使用存储过程,而这些存储过程作为包含未筛选的用户输入的字符串来传递,也会发生sql注入. 黑客通过SQL注入攻击可以拿到网站数据库的访问

  • 利用SQL注入漏洞登录后台的实现方法

    早在02年,国外关于SQL注入漏洞的技术文章已经很多,而国内在05年左右才开始的. 如今,谈SQL注入漏洞是否已是明日黄花,国内大大小小的网站都已经补上漏洞.但,百密必有一疏,入侵是偶然的,但安全绝对不是必然的. 前些天,网上传得沸沸扬扬的"拖库"事件给我们敲响了安全警钟. 在开发网站的时候,出于安全考虑,需要过滤从页面传递过来的字符.通常,用户可以通过以下接口调用数据库的内容:URL地址栏.登陆界面.留言板.搜索框等.这往往给骇客留下了可乘之机.轻则数据遭到泄露,重则服务器被拿下.

  • PHP与SQL注入攻击防范小技巧

    下面来谈谈SQL注入攻击是如何实现的,又如何防范. 看这个例子: 复制代码 代码如下: // supposed input $name = "ilia'; DELETE FROM users;"; mysql_query("SELECT * FROM users WHERE name='{$name}'"); 很明显最后数据库执行的命令是: SELECT * FROM users WHERE name=ilia; DELETE FROM users 这就给数据库带来

  • 最详细的SQL注入相关的命令整理 (转)第1/2页

    1.   用^转义字符来写ASP(一句话木马)文件的方法: ?   http://192.168.1.5/display.asp?keyno=1881;exec master.dbo.xp_cmdshell 'echo ^<script language=VBScript runat=server^>execute request^("l"^)^</script^> >c:\mu.asp';-- ?   echo ^<%execute^(reques

  • sql注入过程详解_动力节点Java学院整理

    SQL注入攻击的总体思路是: 1.发现SQL注入位置: 2.判断后台数据库类型: 3.确定XP_CMDSHELL可执行情况 4.发现WEB虚拟目录 5. 上传JSP木马: 6.得到管理员权限: 一.SQL注入漏洞的判断 一般来说,SQL注入一般存在于形如:HTTP://xxx.xxx.xxx/abc.jsp?id=XX等带有参数的jsp或者动态网页中,有时一个动态网页中可能只有一个参数,有时可能有N个参数,有时是整型参数,有时是字符串型参数,不能一概而论.总之只要是带有参数的动态网页且此网页访问

  • sql注入之手工注入示例详解

    前言 这篇文章就是一个最基本的SQl手工注入的过程了.基本上在sqlilabs上面的实验,如果知道了其中的全部知识点,都可以通过以下的步骤进行脱裤.下面的这个步骤也是其他的脱裤手段的基础.如果想要精通SQL注入,那么这个最基本的脱裤步骤是必须了解和掌握的. 为了方便说明,我们还是用之前的数字型的注入点为例来进行说明. 得到字段总数 在前面的介绍中,我们已经知道在http://localhost/sqlilabs/Less-2/?id=1id是一个注入点. 后台的SQL语句的写法大致为 selec

  • 整理比较全的Access SQL注入参考

    Access SQL注入参考 版本 0.2.1(最近更新 10/10/2007)原作者不详 描述 SQL查询及注释 注释符 Access中没有专门的注释符号.因此"/*", "--"和"#"都没法使用.但是可以使用空字符"NULL"(%00)代替: ' UNION SELECT 1,1,1 FROM validTableName%00 语法错误信息 "[Microsoft][Driver ODBC Microsoft

  • asp.net利用HttpModule实现防sql注入

    1.新建一个类,实现IHttpModule接口 代码 复制代码 代码如下: public class SqlHttpModule : IHttpModule { public void Dispose() { } public void Init(HttpApplication context) { context.AcquireRequestState += new EventHandler(context_AcquireRequestState); } } 在实现接口的Init方法时,我们选

随机推荐