简单分析SQL注入语义分析库Libinjection
字数 1864 2025-08-18 11:37:19
Libinjection SQL注入语义分析库详解
一、概述
Libinjection是一个开源的SQL注入语义分析库,相比传统正则匹配方法具有速度快、低误报和低漏报的特点。它通过将输入字符串转换为特征指纹,然后在预定义的特征库中进行匹配来检测SQL注入攻击。
二、核心工作原理
1. 处理流程
-
初始化阶段:
- 初始化
issqlii变量 - 设置数据结构并初始化变量
state libinjection_sqli_init()函数初始化SQL检测所需的结构体
- 初始化
-
检测阶段:
- 通过
libinjection_is_sqli()函数进行具体分析 - 如果存在SQL注入,将识别特征复制进
fingerprint变量并返回 - 如果不存在,将
fingerprint变量设置为空并返回
- 通过
2. 主要检测函数分析
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;
}
// 标准SQL语法检测(无引号)
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)) {
// MySQL语法检测(无引号)
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;
}
3. 检测步骤详解
- 判断用户输入的字符串长度是否合法,为零则返回FALSE
- 执行SQL注入识别函数(
libinjection_sqli_fingerprint),无引号,标准SQL语法 - 执行结构体内的查询函数(
libinjection_sqli_lookup_word,使用二分查找算法),对比获取的识别特征 - 如果匹配成功,返回TRUE并将指纹写入结构体
- 如果检测失败,调用
reparse_as_mysql()判断是否存在MySQL特有语法(如--注释或#运算符号) - 如果存在MySQL语法,再次执行识别函数(无引号,MySQL语法)并进行特征匹配
- 扫描输入字符串查找单引号,如果存在则重复检测步骤
- 扫描输入字符串查找双引号,如果存在则执行识别函数(双引号,MySQL语法)并进行特征匹配
- 如果所有判断均无结果,则判定不存在SQL注入
三、特征码定义与转换
1. 特征码类型定义
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)')',
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;
2. 输入转换示例
-
输入:
' and 1=1- 转换结果:
s&1 - 解释:
- 单引号(
') →s and→&(逻辑运算符)1→1(数字)=→ 忽略
- 单引号(
- 转换结果:
-
输入:
' UNION ALL SELECT NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL--- 转换结果:
sUEvc - 解释:
- 单引号(
') →s UNION ALL→USELECT→ENULL→v- 相同
NULL合并为一个v --注释符 →c
- 单引号(
- 转换结果:
四、技术优势分析
1. 性能优势
- 快速处理:主要性能消耗在于二分查找算法,相对于正则表达式匹配可以忽略不计
- 扩展性强:特征库大小(800、8000或80000)对处理速度影响很小
- 火焰图分析:显示性能消耗极低
2. 准确性优势
-
低误报率:
- 需要同时满足多个特征(如
s&1或sUEvc) - 每个特征要么是特殊字符,要么是SQL保留字
- 正常用户输入很少会触发这些特征组合
- 需要同时满足多个特征(如
-
低漏报率:
- 内置8000多个识别特征,覆盖广泛
- 支持多种SQL方言(ANSI SQL和MySQL)
- 处理了引号、注释等特殊情况
五、与传统方法的对比
| 特性 | Libinjection | 传统正则匹配 |
|---|---|---|
| 性能 | 高(二分查找) | 低(正则引擎) |
| 误报率 | 低 | 高(如modsecurity2.0的owasp规则) |
| 漏报率 | 低 | 高(规则有限) |
| 规则维护 | 特征库维护 | 正则表达式维护 |
| 扩展性 | 强(特征库扩展不影响性能) | 弱(规则增加影响性能) |
六、实际应用建议
-
集成方式:
- 可作为独立库集成到WAF或其他安全产品中
- 适合高性能要求的场景
-
特征库更新:
- 定期更新特征库以应对新型SQL注入技术
- 可自定义特征库以适应特定应用场景
-
组合使用:
- 可与其他检测方法(如正则、机器学习)结合使用
- 作为第一道快速检测防线
-
性能监控:
- 虽然性能影响小,但仍建议监控实际使用情况
- 火焰图分析有助于优化集成方式
七、总结
Libinjection通过创新的语义分析和特征指纹技术,实现了高效、准确的SQL注入检测。其核心优势在于:
- 将输入转换为标准化特征指纹
- 使用高效的二分查找匹配预定义特征
- 支持多种SQL方言和特殊情况处理
- 性能几乎不受特征库大小影响
- 误报率和漏报率显著低于传统方法
对于需要高性能、高准确率SQL注入防护的场景,Libinjection是一个值得考虑的解决方案。