写在前面:
本篇文章写于笔者初步学习SQL注入后,针对自己入门时的疑惑、经常犯下的错误、易错易混的难点进行了反思,并且整理了下来。在本文中也有许多个人对于SQL注入语句书写的一些经验之谈,旨在能帮助到入门SQL注入的朋友们。当然,鉴于本人也属于入门水平,难免有纰漏之处,也欢迎各位前辈老师们指点迷津,提出宝贵的建议。
目录
1.新手入门时对SQL注入思路的疑惑、以及必须记住的几个库名表名
1.新手入门时对SQL注入思路的疑惑、以及必须记住的几个库名表名
SQL注入目的是什么?为了查到某一张表里的信息。很多刚入门SQL注入的同学可能会感觉对查询步骤没有清晰的概念,思维混乱。注入思路到底是什么?需要注入哪张表?笔者这里就浅谈一下自己的经验。
首先我们了解:数据库结构:库->表->列,即一个数据库中有很多表,一个表中有很多列。
注入思路:先找信息所在的数据库,再找表名,最后确定要查找的信息所在列项。即
找库->找表->找列
几个重要的数据库和表:
information_schema 数据库:里面有columns和tables两张表。columns里面存放了所有列名,
而tables里面存放了所有表名。
我们用information_schema.columns和information_schema.tables分别表示columns表和tables表。
database() :当前数据库的名字
table_name :表的名字
column_name:列的名字
前面说过,我们SQL注入是为了查找某一张表里的信息,第一步:查表名。
在哪找呢?information_schema.tables里找
结果太多,如何筛选呢?where table_schema=database()
找出来表若干:emails,address,users...
假设我们要查找用户的账号密码,那么根据推断账号密码应该在user表中。
那么user表中具体有哪些列呢?第二步:查列名。
在哪找呢?information_schema.colunms里找
结果太多,如何筛选呢?where table_schema=database() and table_name = 'users'
结束。
我在做的时候遇到的需要注意的细节:
table_name='users'(加单引号)
select * from users(不加单引号)
2.关于书写注入语句中那些让人头大的繁多的“括号”
2.1 怎么“读”括号?
在报错注入中,有很多括号,初学者往往因为经验不足在括号出犯错误。
读括号时,从内向外读。
与小学数学括号运算一样,优先级也是从里往外看,养成这样从里往外一对一对找的习惯不容易出错。
2.2 写注入语句时,括号太多太乱,有什么方法吗?
写注入语句时,可以先把框架写出来,再改内容
比如,先写个格式:select 1,1,concat_ws(1,2,3) as x from tables group by x
再改:select 1,count(*),concat_ws('-',(select database()),floor(rand(0)*2)) as x from tables group by x
2.3 什么时候加括号,什么时候不加?在哪里加?
这里以substr/substring为例,在注入时有两个地方可以添加。(只部分片段举例)
第一种情况,substr函数直接占用concat函数第二个参数,把select整个语句包含进去(因为select是语句,所以充当substr第一个参数时需要加括号):
concat(0x7e,substr((select group_concat(xxx) from users),1,30))
第二种情况,substr函数作为select语句查询的列名(因为substr是函数,所以作为select查询的列名时不需要加括号)
concat(0x7e,(select substr(group_concat(xxx),1,30)from users))