0%

SQL注入重学,专题强化练

常规注入

库>表>字段

常用的几个sql注入语句:
show database(列出所有数据库);
use test(进入名为test的数据库);
show tables(在进入test数据库的情况下,列出当前数据库中的所有表)
增删改查:查 select id from users where username=”admin”&id=””1”;
select后面跟着的是列名
这个是要根据实际情况来改变(alt text如此处的列名(表头位置)叫做name,在课程里还有另外一个列名叫做id),
from后面跟着的得是具体的表名(如此处是users)
如果在users表中想查不止一个列呢,例如此处可以改成:select id,name from users;(只需要用逗号分隔一下即可)alt text,这个是结果图
通配符:当有很多列的内容,我们不想一个一个输入列名,想一次性全部都输出,这个时候就需要用到通配符*,
select * from users;
这样就可以把users这个表底下所有列的内容都显示出来alt text如图
可以指定一列中什么样的数据被查出来,这个很有说法,select id from users where id=1;(注意每个语句后面都要加上分号;)alt text这个是结果图
多条件查询:select id,name from users where id>1 and name=”test”
这个是结果图alt text(and语句)
多条件查询的or语句:select id,name fromusers where id=1 or name=”test”
这个是结果图alt text
多个条件嵌合的话就用括号把条件约束起来,如:select id,name from users where (id>1 and name=”bb”) or (id=1)
建表:不重要
改表:updata users set name=”test1” where id=2;update后面更正的是表名,set后面是列名=改完之后的新名字。后面必须得跟上where id=什么什么的,因为要是不指定要改名的变量的id,那么name列的所有变量名都会变成test1

联合注入

alt text

第一步————判断注入类型

主要就四种闭合方式:啥也没有包裹,””,’’,(),这之后只是排列组合,例如(“”),(‘’)
‘$id’($id)(“$id”)_(((‘$id’)))
这里一定要通过自己不断的尝试判断出sql注入的闭合方式,这个是最为重要的(接下来会列一些常见的判断的注入语句),然后再去联合注入什么的
第一种是直接#注释掉后面的闭合符号来判断闭合类型,注意”1’”是允许的,而’1”‘,(1’)是不被允许的,在url中注释符号是会被转义成一个锚点,因此我们需要直接把#进行url编码,写为23%
在单引号会报错的情况下,可以用alt text来接着判断闭合方式,确定是’闭合之后,不确定后面是不是有括号,可以用alt text来判断,然后重复套娃就是了
alt text注意这两种情况是都不会报错的,理由很简单,第二行就算有注释符,但是被单引号报过来,也只会被理解为字符串
– 这个也是一个注释符,注意,是两个横杠加一个空格
若注释符被过滤了,那还有以下的方式alt text,要是他没有任何包裹,那么就会正常执行,因为1=1恒成立,所以会把所有的内容都查出来,但是要是有包裹,如’1 or 1=1’,这个就会被理解为字符串,这样子只会取到1(跟php类似,只能取到这个字符串的第一个数字)

第二步————查列数

判断完闭合方式之后直接干就行了,例如1’ union select 1,2,3 #这样子,但是一般来说会报错,因为列数可能不止一,这个时候可以自己写一个脚本来爆破,或者说使用二分法来逐步确定范围
在此处使用select语句很低效,因此使用另外一种关键字,只需要输入一个数(不需要上面那样输入1,2,3)就能够成功,这个关键字就算order byalt text,这里主要还是用第二种方法
当order by后面的数字是大于实际上含有的列数,他什么排序都成功不了了,会报错,通过报错,我们就可以知道具体的列数有多少

第三步——确定字段位置

为什么要去做其实很好懂,因为他就算有100000列,只有前2个列有字段存在,那么我们在查库名,表名的时候在没有字段出现的位置去查是很愚蠢的,是很荒谬的,因此我们要确定有字段的列是从哪到哪,这样子方便我们进行下一步去查库名和表名,其实爷很简单,我截个图给你看alt text

第四步–查表名

这个主要就是用到一些sql注入的语法,很好也很好理解,这些查询函数放在有字段的位置上就可以进行查询了
查到库之后,我们的目的是查表名,具体的原理很好懂,我们对数据库进行的每一步操作都是被记录在案的,因此我们不需要通过去查库里的表,我们只需要查我们曾经进行过什么操作(比如创建某个表之类的),接下来具体来看看
在一个叫information_schema的数据库中有一个叫做table的表,他里面记录了所有库有什么表的信息,所以查这个就可以了(查information_schema.table)完整语句是
select table_name from information_schema.tables where table_schema=’题目中要我们查的数据库名’;
很好理解,table_schema就是指要我们查的数据库名,这里可以准确的定位到我们所需要查的表的内容,其中这里的数据库名table_schema的内容可以用show database()查出来(但是为了全面,建议使用通配符来全查selcet * from …)alt text
最后再用这个我们写好的语句写入联合注入:
(select) id=2 union select table_name from information_schema.tables where table_schema=’database()’;
(此处直接用database()的返回值来作为这个要查询的数据库名,很天才,直接省略了一步)

第五步–查列名(这样子就可以select)

也是一样的道理,这里有一个黑奴,这个表专门存列名的(和上面那个很像),因此只要查这个表就可以了这个表叫做columns
所以语句是
select column_name from information_schema.columns where table_name=’上一步查的表名’
(table_name的意义在上面就写了,是表名的意思,columns_name就是列名的意思)
接下来就很常规,select 列名 from 表名(上面分别从两个黑奴数据库中查出来的列名和表名,然后就可以查出来列里面的所有内容了(简称爆列))
有的题目的表不在当前数据库中,因此要借助一个存库名的黑奴数据库来查所有数据库的名字,而不能使用database()
select schema_name from information_schema.schemas
可以查出来所有的数据库名alt text,注意啊,这里的数据库名叫schema_name,而上面第四步的where后面的数据库名为table_schema