SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。
这是百度百科给的定义,我们通俗来讲: 就是恶意用户构造SQL语句插入到原有SQL语句中,被服务正常的执行利用,从而获得了超出当前用户权限的数据库内部资料。
所以我们就要把握好侧重点,你的SQL语句被服务执行!
判断注入的类型(字符,数字,搜索...)
判断后端数据库类型(Oracle,MySQL,Mssql,PostgreSql...)
判断语句是否被成功执行(构造差异条件...)
判断当前环境可以利用的注入方式(sqlmap的分类: 堆叠注入,联合查询,报错注入,布尔盲注,时间盲注..利用效率从高到低)
判断后端安全方式(无防护,黑名单,白名单,WAF...利用难度依次递增)
我们可以通过当前也去环境交互的数据来判断,与数字型相比,需要逃逸字符,后续闭合逃逸出的字符,在真实情况下,最多的情况!数字型会执行我们构造的运算条件,而字符型则会异常或不执行
\
,发现为单引号闭合'
判断为字符型,反之\
后无字符,为数字型:字符型,正常情况:
字符型,添加运算条件后(加减乘除都可以加,主要url编码):
数字型,添加运算条件后(加减乘除都可以加,注意url编码),因为SQL语句正确被执行,导致数据库内部错误,显示的内容,也会异常:
1). 搜索型注入通过 %
来闭合
2). 字符型需要通过fuzz来测试闭合,常用: '
"
')
")
:
'
"
''
'"
;
)
')
")
");
';
";
%'
%"
%')
%")
'))
"))
")))
#
--
,判断返回页面差异,从而准确判断闭合的字符结果判断,因为正常执行会输出Your Login name:Dumb
,我们如果成功闭合则内部SQL就会执行1/0
的操作,从而内部错误,显示异常,不输出登录名,以此为差异来判断结果:
√
号的是存在字符,不标记的为不存在关键字paylaod
的共同点,都存在单引号'
,通过此我们便可以知道需要闭合的字符为单引号'
,其他的同样如此:我们找一个单引号括号')
的例子来看,构造个减的条件,id=2,name: Angelina id=3, name: :Dummy,如果语句正常执行,将返回id=2的内容:
同理找共同点,为 单引号括号')
,所以闭合方式为: 单引号括号')
会直接报出 Sql server
的相关错误,从而可以判断
MySQL
(1)如果说既能够使用–--作为注释标志,又能够使用#做注释标志,那么基本可以确定是 MySQL
(2)行间注释 /!version command/,这样的语法是 MySQL 专属,其中 version 是一个数字,如果 MySQL 的版本大于这个数字的话就会把 command 作为 SQL 语句的一部分。 /!50000SELECT/
Oracle
(1) 通过/**/ -- 来注释,则为oracle数据库
MySQL
(1)既能使用substr
也可以使用substring
,判断为MySQL
(2) 能够使用 trim
函数、 rtrim
函数、 ltrim
函数,但是不能使用 btrim
函数(Postgresql 以及 AWS Redshift SQL 所有)
(3) conv、load_file(读取文件的函数需要权限)、benchmark...
(4) database()
user()
@@datadir
等等内置函数
Oracle
(1) 版本探测方式:select version from v$instance;
(2) 当前数据表探测方式: select name from v$database';
(3) : 支持 minus select
是 ORACLE
的显著特征..等等
mssql
(1) waitfor delay time
延时注入,可以确定是 SQL Server
(2) Top
语法的使用
''
来连接字符串||
来连接字符串+
来连接字符串Mysql,information_schema
Oracle, SYSAUX表,SYSTEM表,TEMP表,UNDO表,USERS表
Mssql, master..sysmessages、master..sysservers
php
java
.net
SELECT ... WHERE title REGEXP BINARY '^(An?|The) +'; -- MySQL
SELECT ... WHERE REGEXP_LIKE(title, '^(An?|The) +', 'c'); -- Oracle
SELECT ... WHERE title LIKE '%[^A-Z]%' -- Mssql
SELECT ... WHERE title ~ '^(An?|The) +'; --postgreSQL
MySQL的特性,隐式类型转换
来判断,(要结合具体环境来使用):(1). 构造 && 3<>1+--+ ,等价于and,注意url编码:
(2). 构造 false || 3>1+--+
(MySQL为或等价于or
,Oracle为连字符)
(3)通过条件判断语句配合1/0
来判断(我最常用的方式)
此Payload适用于MySQL和ORacle
http://192.168.111.1/sqli/Less-1/?id=-1' DIV (case when 3>1 then 1 else end)+--+
cash when 条件
为真执行: then 1,就是最终结果为1,1/1=1,语句正确
为假执行:else 0,就是最终结果为0,1/0 Mysql返回空 Oracle内部报错
(4)短路and
报错来判断注入:
适用于回显为: (1) SQL语句正确,返回一种情况; SQL语句错误返回一种情况
http://192.168.111.1/sqli/Less-1/?id=1'+and+1=(case when 3<1 then 1 else 0 end)+and+pow(999,999)--+
同理的有很多,只要构造好报错条件,短路and即可,可以用&&代替and
http://192.168.111.1/sqli/Less-1/?id=1'+and+1=(case when 3<1 then 1 else 0 end)+and+~0--+
堆叠注入如果存在,直接通过;
闭合上一段语句构造新语句即可执行
联合查询注入,如果目标业务存在显示位,我们先判断列数,在判断显示位,从而后续构造语句直接查询,适用于直接返回SQL错误的目标
报错注入,构造报错条件,通过报错带出我们查询的数据,适用于直接返回SQL错误的目标
时间盲注,判断条件为时间条件,或者是大量运算所造成的高于正常的延时操作,以此为条件查询数据
布尔盲注,我重点叙述,上面SQL判断阶段的描述配合查询数据即可,与时间盲注为我们真实测试中最常遇到的情况
就是在业务编写阶段为防止SQL注入,而禁用了一些特殊字符,比如数据库函数,注释符等等
漏网之鱼
的函数,配合逻辑语句查询数据内容bypass
里面的详细专题:ascii()函数 可以用 char() ,函数代替
and逻辑判断,可以使用 && 代替
or逻辑判断, 可以使用||代替
空格, 可以使用 %00-%0z 注释符 /**/替代
/!50000SELECT/ MySQL 特性 如果 MySQL 的版本大于5.00.00的话就会把 SELECT 识别出来。这个特性同样可以用来探测 MySQL 的版本号
一些WAF在进行数据包解析处理时,可能会存在类似的设计缺陷。例如在处理普通的GET、POST型请求时,会进行SQL注入、XSS等攻击特征的匹配。但是在处理multipart请求时,很可能只对类似恶意文件上传等攻击(文件上传包相关)进行检测, SQL注入等攻击就不再进行规则匹配了。那么此时若尝试以multipart方式进行业务提交,并且植入恶意的注入攻击语句,若服务器能解析的话,即可绕过WAF进行注入深入利用。
有些WAF,因为性能的需要向业务做出妥协,当数据包超过WAF的规定阈值后,有的会丢弃掉数据包,而有的也会直接通过数据包,利用这个特性,我们构造超长的数据包便可以绕过waf
分块传输编码(Chunked transfer encoding)是超文本传输协议(HTTP)中的一种数据传输机制,允许HTTP由网页服务器发送给客户端应用( 通常是网页浏览器)的数据可以分成多个部分。分块传输编码只在HTTP协议1.1版本(HTTP/1.1)中提供。
推荐查看大佬文章:https://gv7.me/articles/2019/chunked-coding-converter/
利用方式以及工具,里面都有;目前新版的Sqlmap已经支持分块传输,参数为:--chunked
order by
update
insert
limit
等等的注入,后续补充whoami
私我!!