sqllabs——Less1
目录
第一关
1.字段查询
2.建表
3.连表查询
4.下段看代码
5.查表
总结
第一关
目标:如何从商品表查到--------->管理员表
1.字段查询
可用union进行两表联合查询。也就是good表和user表联合查询,前提是这两表的字段一致。问题是目前不知道good表的字段。
可以使用order by排序,且可以使用任意列排序。
select * from goods order by gid desc这是倒序排序
select * from goods order by gid asc这是正序排序
你会说:“你也不知道他第一列是gid,还是gname还是其他,那你怎么排序?”是,是不知道。但mysql还有一个功能是,可以用1表示第一列,2表示第二列,以此类推。
select * from goods order by 1 desc
同时说明了一个结论:可以用order by验证到底有几列。当 order by 4 的时候回报错,说明这个表只有4列。
2.建表
第一步已得知goods表有三列也就是有3字段,既建立临时表,与goods表进行联合查询
union select 1,2,3
可以把123换成查询语句
union select version(),database(),user();
这样就可以把gid,gname,gprice查出来,但查gid没有意义。因为gid没有显示在前端,页面上只回显gname和gprice
3.连表查询
要逃出单双引号,要么注释掉,要么闭合。
现在相当于gid='1' '
报错了,已成功80%,若没报错也可能有注入点,不过他不显示在前端,看后端的时间(盲注)。
闭合了必定报错,因为单双引号在任何编程语言都要成对出现。继续进行联合查询
gid='1 union select 1,2,3
颜色变了,说明逃逸出来了。因为单引号影响,所以要注释掉。
mysql注释有三种:单行注释 #或-- ,杠杠后面要有一个空格,那么--+或--20%也是可以的。
用--+把单引号注释掉
gid=1%27%20union%20select%201,2,3--+
但查这个没用,与id=1没区别。
源代码得知:会把第一个数组拿出来回现前端。
也就是第一行
正常注入语句在第二行。为什么在第二行走?因为gname,gprice显示在前端了,而2,3是要出数据的,但在2这里注入数据后在前端显示不出,所以一定要保证行数组查不出数据,让第二行查出数据,然后gname:root@localhost才会显示到前端
由于gid=1,第一个表被查出来了
给一个不存在的id,那么第一个表就查不出来,那么就不显示第一个数组而显示第二个
4.下段看代码
现在的gid是刚刚传进的gid=-1',注意+变为空格了,然后22-23行代码是写文件。
最终sql语句为这样。gid=-1,查不到东西,联合查询查到1,2,3就查出来了。
查出来的是一个数组,若这个数组存在,那么gid=2,gprice=3。所以2,3会回显到前端。2和3没意义,把2和3换成查询语句user(),database()。就会在前端回显当前的用户和当前的数据库。
通过联合注入找到了当前数据库,现在少想要注入的表名(管理员表名),管理员列名。
5.查表
想查管理员表名,只能到information_schema库里找tables这个表,因为这个表里放着所以数据库的表,那肯定包含管理员表。又因为tables表里有一个tables_schema字段,这个字段可限制数据库的名称。
进到information_schema库里,里面有应该COLUMNS表
进到这个表里:
从图里可以看到这个表里有数据库名,有表名,有列名。
使用group_concat函数, MySQL 中一个常用的聚合函数,用于将分组查询中某一列的多个值连接成一个字符串(连成一行)。
通过此代码获取表名:
,group_concat(table_name),3 from information_schema.tables where table_schema='security'--+
from%20information_schema.tables
指定从数据库的系统表information_schema.tables
中查询where%20table_schema='security'
筛选出数据库名为security
的表
可得到管理员表在users表,现实中可能是admin表。
group_concat(column_name),3 from information_schema.tables where table_schema='security' and table_name='users'--+
这就把管理员的列查出来了。
group_concat(username,0x3a,password),3%20from%20users-+
group_concat(username,0x3a,password)
表示使用group_concat
函数将username
(用户名)和password
(密码)字段的值连接起来0x3a
是十六进制表示的冒号:
,作为用户名和密码之间的分隔符from users
说明是从users
表中查询数据
至此,所有数据都查出来了。相当于通过商品表查出来管理员的账户和密码,当然正常查出来的密码都是加密过的。
总结
这就完成了字符型注入,从goods表------->user表,用union联合查询,期间用order by判断列,用gid=-1让第一个数组失效,用--+(-- )实现注释,用information_schema实现库表列的查询,用group_concat实现注出管理员的数据。整个流程利用 “字符型注入点 + 报错回显”,通过判断字段数→构造联合查询→获取基础信息→查表名→查列名→获取敏感数据的步骤,从目标表goods
横向渗透到用户表users
,最终获取核心敏感信息。此过程依赖于无过滤的输入拼接和错误信息回显。这是最基础最简单的,没有任何过滤,没有任何防御的注入。第一关比较重要,打好基础,后面的关和第一关差不多,无非就是加入了过滤。
面试可能会问:
1)有没有手工注入的点?说说手工注入的流程?
2)有那种类型的注入?
3)mysql怎么获取getshell?
4)mysql有没有什么绕过机制?过滤怎么绕过?