mysql语义分析_简单分析SQL注入语义分析库

2023-05-16

一、前言

这次主要讲开源SQL注入语义分析库libinjection,如果有发现其他开源SQL语义分析库的欢迎告知。libinjection的程序分析由Simon友情提供,需要看完整报告的可以加群看。

二、libinjection程序分析

67de9ece72e9db6ad97cae34df679fe8.png从流程图上看,libinjection首先是初始化issqlii变量,接着设置数据结构并初始化变量state,libinjection_sqli_init()函数将初始化SQL检测所需的结构体,之后通过libinjection_is_sqli()函数进行具体分析,如果存在issqli,则将SQL注入识别特征复制进fingerprint变量并返回,如果不存在则将fingerprint变量设置为空并返回。

cb868b0fb985b77df293d838de012ab7.png上图是总的函数关系图,libinjection_sqli_init()函数的主要工作是将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;

if (slen == 0) {

return FALSE;

}

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 (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;

}

}

}

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;

}

}

return FALSE;

}

1.判断用户输入的字符串长度是否合法,为零则返回FALSE。(即没有发现SQL注入)

2.执行SQL注入识别函数(libinjection_sqli_fingerprint,无引号,标准SQL语法),获取字符串识别特征码

3.执行结构体内的查询函数(这里为libinjection_sqli_lookup_word,二分查找算法),对比第二步获取的识别特征是否与SQL注入识别特征匹配。

4.如果第三步发现SQL注入特征匹配结果为真,则返回true,并将SQL注入识别特征匹配到的fingerprint写入结构体,如果检测失败,则调用reparse_as_mysql()函数判断是否存在“(dash-dash-[notwhite]) 注释”或“'#' 运算符号”,如果存在则再次执行SQL识别函数(libinjection_sqli_fingerprint,无引号,MYSQL语法),

同时执行结构体的分析函数(libinjection_sqli_lookup_word,二分查找算法)进行特征匹配检测,如果结果为真,则返回true,并将SQL注入识别特征匹配到的fingerprint写入结构体。

7.如果前面的判断没有返回结果,将扫描参数(即用户输入的字符串)查找是否存在单

引号。如果为真接着重复上述检测步骤。

8.如果前面的判断依旧没有返回结果,将扫描参数(即用户输入的字符串)查找是否存

在双引号。如果为真则接着执行SQL注入识别函数

(libinjection_sqli_fingerprint,双引号,MYSQL语法)

同时执行结构体的分析函数(libinjection_sqli_lookup_word,二分查找算法)进行特征匹配检测结果为真,则返回true,并将SQL注入识别特征匹配到的fingerprint写入结构体。

9.如果前面三种判断均无结果则默认该参数(用户输入的字符串)不存在SQL注入。

三、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多的识别特征了基本上把可能的路都堵死了,如有发现能在实际场景中绕过的,欢迎交流。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

mysql语义分析_简单分析SQL注入语义分析库 的相关文章

随机推荐

  • PHP解决http和https跨域,PHP解决HTTP和HTTPS跨域共享session的方法及代码实例

    HTTP HTTPS协议下跨域解决session共享的办法 xff0c 也许不是最好的 xff0c 但是比较实用 如下是具体的解决方案 阿里西西小编给您推荐这个PHP解决HTTP和HTTPS跨域共享session的方法及代码实例 xff0c
  • ucosii使用

    当需要同时跑多个任务的时候裸机显然不能很好的完成使命 xff0c 这个时候我们可以给单片机上系统 xff0c 创建多任务 xff0c 完成复杂逻辑 一 首先移植uocii在我们的板上 xff0c 根据mcu型号移植ucosii xff0c
  • QT以POST方法上传文件(文本、图片、excel文件等)

    最近项目需要用QT上传文件给HTTP服务器 之前服务器接收的数据格式都是json xff0c 这次是form data 经查找资料 xff0c 需要用到QHttpMultiPart和QHttpPart这两个类 xff0c 看QT的实例教程可
  • js数组删除元素

    var arr 61 39 a 39 39 b 39 39 c 39 若要删除其中的 39 b 39 有两种方法 xff1a 1 delete方法 delete arr 1 这种方式数组长度不变 此时arr 1 变为undefined了 但
  • 回调函数简单使用

    一 回调函数是什么 xff0c 我们为什么要用它 xff1f 回调函数就是一个通过函数指针调用的函数 如果你把函数的指针 xff08 地址 xff09 作为参数传递给另一个函数 xff0c 当这个指针被用来调用其所指向的函数时 xff0c
  • pwm控制电机原理

    首先我们要明白电机的原理 电机 简单来说就是 实现电能与机械能相互转换的电工设备 那么我们经常使用的直流电机原理就是 xff1a 电生磁 xff1a 通电导线会产生磁场 也就是电磁感应 旋转磁场带动转子转动 电动机是由定子和转子组成 xff
  • FLASH操作记录

    使用的单片机为GD403系列 xff0c 要操作的数据flash地址位于bank1 xff0c 最小操作单位为一页 xff0c 即4k 下面程序演示操作一页中部分内存空间 span class token macro property sp
  • MCU启动异常分析记录

    一 问题背景 量产的产品在品质抽检中出现设备概率无法正常使用的问题 xff0c 经过初步定位确定是MCU上电未正常启动 二 问题分析以及定位 在产品中考虑到MCU程序升级 RF SUB 1G升级 xff0c NB IOT等无线升级方法 xf
  • u-BOOT启动流程

    1 u boot入口 xff1a 入口即第一行程序 xff0c 程序的链接是由链接脚本决定的 xff0c 编译uboot之后 xff0c 可以在根目录下生成u boot lds文件 打开lds文件可以看到代码当前入口点 xff1a xff1
  • qt字符串与字符串数组操作

    QString定义 QString s1 61 abc QString s2 hello 字符串连接 QString s 61 s1 43 s2 组包 s 61 QString a 61 1 b 61 2 c 61 3 arg 250 ar
  • QT中16进制二进制字符串的转换

    最近使用串口通信操作nfc卡的扇区内的内容设及到了很多数据类型之间的转换 xff0c 今天总结一下 1 10进制16进制字符串相互显示 10 gt 16 int a 61 10 Qstring b 61 QString 34 1 34 ar
  • 使用vs安装qt插件过程中遇到的问题

    一直在用qtcreater开发程序 最近安装了vs2017 xff0c 想着慢慢改用vs xff0c 毕竟功能强大嘛 按照网上大神的教程安装qt vs tools 过程中遇到了 qt in the given path was built
  • verilog基础语法 {}

    1 的作用 xff1f 起拼接的作用 如 a 61 b 5 b 4 0 意思为 b的最高位和b的低五位拼接起来 xff0c 组成的a为6位 2 数字表达式 4 d15 4 xff1a 代表位宽 d xff1a 代表进制 15 xff1a 代
  • 从程序员的角度,来拆解物联网系统中的开发工作

    物联网的概念已经被炒了好多年了 xff0c 奇怪的是 xff1a 市场中对这个概念的反应总是不愠不火 随着5G 的迅速普及 xff0c 不知道是否能够再次把这个领域带火起来 但是不管怎样 xff0c 很多大学已经把物联网这个专业给坐实了 前
  • amixer命令用于设置系统音量

    该句为 c选择0的声卡 xff08 貌似 xff09 xff0c PCMvolume设置为增加60 2 61 120 xff08 value值变为加上120 xff09 xff0c 60dB 就是减小60 2 61 120 xff0c 如果
  • jetson nano配置远程桌面连接

    一 jetson nano 远程桌面设置 默认jetson nano 的 Desktop Sharing是打不开的需要进行如下配置 xff1a 1 编辑org gnome Vino gschema xml文件 sudo vi span cl
  • 如何修改访问vnc服务器的密码,修改VNC访问的密码

    vncserver iptables I INPUT p tcp dport j ACCEPT 客户端方式 iptables I INPUT p tcp dport j ACCEPT 浏览器方式 vi root vnc xstartup 注
  • sensor配置项解释

    主要介绍 sensor 的配置项 json 里面的 data 类型 都是 10进制的 以 a 43 g sensor 介绍 所有平台特定的配置文件在 JSON 文件顶层均包含 config 组 json 开头的 就是 config 组 这里
  • xp ie清除css缓存,如何清空浏览器的CSS缓存

    项目需求 xff1a 请求一个网站时 xff0c 浏览器会缓存CSS xff0c 导致每次更新网站的代码后 xff0c 不会自动更新样式 xff0c 甚至需要手动去清空浏览器的缓存 xff0c 但是用户不可能每次都清空缓存 xff0c 这就
  • mysql语义分析_简单分析SQL注入语义分析库

    一 前言 这次主要讲开源SQL注入语义分析库libinjection xff0c 如果有发现其他开源SQL语义分析库的欢迎告知 libinjection的程序分析由Simon友情提供 xff0c 需要看完整报告的可以加群看 二 libinj