SQL语义引擎总体概述

int libinjection_sqli(const char* input, size_t slen, char fingerprint[])

判断字符串input是不是SQL注入语句,返回1是,0不是,fingerprint作为指纹出参,其中核心函数如下:

libinjection_sqli_init(&state, input, slen, 0);
issqli = libinjection_is_sqli(&state);

初始化函数:libinjection_sqli_init()

这个函数没干啥,主要注册了一个回调函数sf->lookup = libinjection_sqli_lookup_word;

处理函数:libinjection_is_sqli()

主要是这个函数判断是不是SQL注入攻击,核心函数如下:libinjection_sqli_fingerprint() (指纹识别函数)sql_state->lookup() (初始化阶段的回调函数)

首先概述指纹识别函数:

libinjection_sqli_reset(sql_state, flags);(状态重置一下)
tlen = libinjection_sqli_fold(sql_state);(核心阶段)

处理一下返回值,实际上核心数据都已经记录在sql_state

    if (tlen > 2 &&sql_state->tokenvec[tlen-1].type == TYPE_BAREWORD &&sql_state->tokenvec[tlen-1].str_open == CHAR_TICK &&sql_state->tokenvec[tlen-1].len == 0 &&sql_state->tokenvec[tlen-1].str_close == CHAR_NULL) {sql_state->tokenvec[tlen-1].type = TYPE_COMMENT;}

将所有 tokenvectype 记录在指纹 fingerprint 中,至此我们计算出字符串的指纹,调用回调函数判断是否命中指纹库即可。

    for (i = 0; i < tlen; ++i) {sql_state->fingerprint[i] = sql_state->tokenvec[i].type;}sql_state->fingerprint[tlen] = CHAR_NULL;

判断记录指纹 fingerprint中是否存在 TYPE_EVIL (无法解析)

如果存在,那么做如下处理:

    if (strchr(sql_state->fingerprint, TYPE_EVIL)) {memset((void*)sql_state->fingerprint, 0, LIBINJECTION_SQLI_MAX_TOKENS + 1);memset((void*)sql_state->tokenvec[0].val, 0, LIBINJECTION_SQLI_TOKEN_SIZE);sql_state->fingerprint[0] = TYPE_EVIL;sql_state->tokenvec[0].type = TYPE_EVIL;sql_state->tokenvec[0].val[0] = TYPE_EVIL;sql_state->tokenvec[1].type = CHAR_NULL;}

返回值是计算出来的指纹

    return sql_state->fingerprint;

接下来概述回调函数:

sql_state->lookup(sql_state, LOOKUP_FINGERPRINT,sql_state->fingerprint, strlen(sql_state->fingerprint))

回调函数返回非0,那么就是SQL注入攻击,
返回0,就不是。

char libinjection_sqli_lookup_word(struct libinjection_sqli_state *sql_state, int lookup_type,const char* str, size_t len)
{if (lookup_type == LOOKUP_FINGERPRINT) {return libinjection_sqli_check_fingerprint(sql_state) ? 'X' : '0';} else {return bsearch_keyword_type(str, len, sql_keywords, sql_keywords_sz);}
}

libinjection_sqli_check_fingerprint(sql_state)

函数功能:判断黑名单和非白名单
返回True,那么是SQL注入
返回False,那么不是SQL注入

int libinjection_sqli_check_fingerprint(struct libinjection_sqli_state* sql_state)
{return libinjection_sqli_blacklist(sql_state) &&libinjection_sqli_not_whitelist(sql_state);
}

libinjection_sqli_blacklist(sql_state)

int libinjection_sqli_blacklist(struct libinjection_sqli_state* sql_state)
{char fp2[8];char ch;size_t i;size_t len = strlen(sql_state->fingerprint);int patmatch;fp2[0] = '0';for (i = 0; i < len; ++i) {ch = sql_state->fingerprint[i];if (ch >= 'a' && ch <= 'z') {ch -= 0x20;}fp2[i+1] = ch;}fp2[i+1] = '0';patmatch = is_keyword(fp2, len + 1) == TYPE_FINGERPRINT;if (!patmatch) {return FALSE;}return TRUE;
}

libinjection_sqli_not_whitelist(sql_state)

int libinjection_sqli_not_whitelist(struct libinjection_sqli_state* sql_state)
{char ch;size_t tlen = strlen(sql_state->fingerprint);if (tlen > 1 && sql_state->fingerprint[tlen-1] == TYPE_COMMENT) {if (my_memmem(sql_state->s, sql_state->slen,"sp_password", strlen("sp_password"))) {return TRUE;}}switch (tlen) {case 2:{if (sql_state->fingerprint[1] == TYPE_UNION) {if (sql_state->stats_tokens == 2) {return FALSE;} else {return TRUE;}}if (sql_state->tokenvec[1].val[0] == '#') {return FALSE;}if (sql_state->tokenvec[0].type == TYPE_BAREWORD &&sql_state->tokenvec[1].type == TYPE_COMMENT &&sql_state->tokenvec[1].val[0] != '/') {return FALSE;}if (sql_state->tokenvec[0].type == TYPE_NUMBER &&sql_state->tokenvec[1].type == TYPE_COMMENT &&sql_state->tokenvec[1].val[0] == '/') {return TRUE;}if (sql_state->tokenvec[0].type == TYPE_NUMBER &&sql_state->tokenvec[1].type == TYPE_COMMENT) {if (sql_state->stats_tokens > 2) {return TRUE;}ch = sql_state->s[sql_state->tokenvec[0].len];if ( ch <= 32 ) {return TRUE;}if (ch == '/' && sql_state->s[sql_state->tokenvec[0].len + 1] == '*') {return TRUE;}if (ch == '-' && sql_state->s[sql_state->tokenvec[0].len + 1] == '-') {return TRUE;}return FALSE;}if ((sql_state->tokenvec[1].len > 2)&& sql_state->tokenvec[1].val[0] == '-') {return FALSE;}break;}case 3:{if (streq(sql_state->fingerprint, "sos")|| streq(sql_state->fingerprint, "s&s")) {if ((sql_state->tokenvec[0].str_open == CHAR_NULL)&& (sql_state->tokenvec[2].str_close == CHAR_NULL)&& (sql_state->tokenvec[0].str_close == sql_state->tokenvec[2].str_open)) {return TRUE;}if (sql_state->stats_tokens == 3) {return FALSE;}return FALSE;} else if (streq(sql_state->fingerprint, "s&n") ||streq(sql_state->fingerprint, "n&1") ||streq(sql_state->fingerprint, "1&1") ||streq(sql_state->fingerprint, "1&v") ||streq(sql_state->fingerprint, "1&s")) {if (sql_state->stats_tokens == 3) {return FALSE;}} else if (sql_state->tokenvec[1].type == TYPE_KEYWORD) {if ((sql_state->tokenvec[1].len < 5) ||cstrcasecmp("INTO", sql_state->tokenvec[1].val, 4)) {return FALSE;}}break;}case 4:case 5: {break;}} /* end switch */return TRUE;
}

bsearch_keyword_type(str, len, sql_keywords, sql_keywords_sz)

函数功能:判断str是否命中指纹库sql_keywords 中的指纹。
返回非0,那么命中
返回0,那么没命中

static char bsearch_keyword_type(const char *key, size_t len,const keyword_t * keywords, size_t numb)
{size_t pos;size_t left = 0;size_t right = numb - 1;while (left < right) { // 二分查找pos = (left + right) >> 1;if (cstrcasecmp(keywords[pos].word, key, len) < 0) {left = pos + 1;} else {right = pos;}}if ((left == right) && cstrcasecmp(keywords[left].word, key, len) == 0) {return keywords[left].type; // 命中} else {return CHAR_NULL; // 没有命中}
}

sql判断为0_SQL简单语义分析概述相关推荐

  1. sql判断基数_SQL Server中的基数估计框架版本控制

    sql判断基数 This is a small post about how you may control the cardinality estimator version and determi ...

  2. SQL判断某列中是否包含中文字符、英文字符、纯数字,数据截取

    SQL判断某列中是否包含中文字符.英文字符.纯数字 一.包含中文字符 select * from 表名 where 列名 like '%[吖-座]%' [吖-座]是中文字符集第一个到最后一个的范围,虽 ...

  3. oracle判断非空并拼接,oracle sql 判断字段非空,数据不重复,插入多跳数据

     oracle sql 判断字段非空,数据不重复 select distinct(mobile) from wx_user_mobile where active_time is not null ...

  4. 学习:双机热备、集群、负载均衡、SQL故障转移群集简单理解(转)

    双机热备.集群.负载均衡.SQL故障转移群集简单理解平常,大家常提到几个技术名词:双机热备.集群.负载均衡.SQL故障转移群集.这里,就我的理解,和大家简单探讨下,有不足或错误之处还请各位指出! 这些 ...

  5. python条件语句-Python中条件判断语句的简单使用方法

    最简单的条件语句: if expression: expr_true_suite 如上,if是关键字,expression是条件表达式,条件表达式支持多重条件判断,可以用布尔操作符and.or和not ...

  6. sql判断数据库类型数据_SQL数据类型

    sql判断数据库类型数据 SQL | 资料类型 (SQL | Data Types) Just like other programming languages, facilities of defi ...

  7. php 检测密码,php 判断密码是否简单

    php 判断密码是否简单 原理:正则表达式/((^[0-9]{6,})|(^[a-z]{6,})|(^[A-Z]{6,}))$/ 弱密码 /((^[0-9,a-z]{6,})|(^[0-9,A-Z]{ ...

  8. SQL Server中的登录触发器概述

    This article gives you an overview of Logon triggers in SQL Server and its usage to control SQL Serv ...

  9. 使用php函数判断数字,PHP 几个常用数字判断函数的简单示例

    这篇文章主要为大家详细介绍了PHP 几个常用数字判断函数的简单示例,具有一定的参考价值,可以用来参考一下. 对PHP的几个常用数字判断函数代码感兴趣的小伙伴,下面一起跟随512笔记的小编两巴掌来看看吧 ...

  10. yolo系列算法思想流程简单讲解概述————(究极简单的讲述和理解)

           在我想学习算法的时候,我看某些大佬特别喜欢上来就讲论文,给我搞的贼难受,毕竟本人太辣鸡了,上来这么搞看不懂,经过诸多算法的这样折磨.我打算根据自己的亲身经历和学习过程中遇到的问题出一期, ...

最新文章

  1. coverity代码检测工具介绍_兴业证券:静态代码检测最佳实践
  2. python中的拷贝
  3. ironpython3发布时间_.NET 基金会项目介绍-DLR/IronPython2/IronPython3
  4. SpringCloud入门简述
  5. 打破“单点防护”缺陷,山石网科发布“云网端”XDR解决方案
  6. GNN 模型在生物化学和医疗健康中的典型应用
  7. 在ListView控件中绘底图
  8. file watchers怎么默认打开_python默认字典defaultdict进阶
  9. docker命令的使用
  10. Java基础——常用对象API(2):StringBuffer类
  11. Windows系统如何修改Hosts文件
  12. Linux 五个最牛视频编辑软件
  13. 参考文献在论文中进行引用标注
  14. 工厂模式及在项目中的应用
  15. Canvas 炫彩小球
  16. 数字经济潮起 融360科技领航
  17. python爬虫实践之下载轻音乐
  18. 将正方形矩阵顺时针转动90度(Java)
  19. Vue-报错cb() never called!
  20. Android端视频播放器源码分析

热门文章

  1. Oracle管理监控之如何对数据库进行监控检查
  2. SSD5_ Exam 2分析
  3. JVM堆内存设置调优
  4. 几种常见单例的写法和问题
  5. 最常用的springmvc注解使用技巧
  6. Spring依赖注入的三种方式
  7. Sql语句优化-查询两表不同行NOT IN、NOT EXISTS、连接查询Left Join
  8. Mysql Too many connections解决方案
  9. QT虚拟小键盘设计--qt事件循环,事件发送的理解
  10. RTMP vs RTMFP