SQL注入"Strange-Tps"汇总

0x01 什么是SQL注入?

SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。

这是百度百科给的定义,我们通俗来讲: 就是恶意用户构造SQL语句插入到原有SQL语句中,被服务正常的执行利用,从而获得了超出当前用户权限的数据库内部资料。

所以我们就要把握好侧重点,你的SQL语句被服务执行!

0x02 漏洞探测

一. 基础的测试流程大致为:

  • 判断注入的类型(字符,数字,搜索...)

  • 判断后端数据库类型(Oracle,MySQL,Mssql,PostgreSql...)

  • 判断语句是否被成功执行(构造差异条件...)

  • 判断当前环境可以利用的注入方式(sqlmap的分类: 堆叠注入,联合查询,报错注入,布尔盲注,时间盲注..利用效率从高到低)

  • 判断后端安全方式(无防护,黑名单,白名单,WAF...利用难度依次递增)

二. 步骤细节:

一. 注入类型判断:

我们可以通过当前也去环境交互的数据来判断,与数字型相比,需要逃逸字符,后续闭合逃逸出的字符,在真实情况下,最多的情况!数字型会执行我们构造的运算条件,而字符型则会异常或不执行

(1) 服务直接报错! 插入\,发现为单引号闭合' 判断为字符型,反之\后无字符,为数字型:
  • 字符型
image-20200813214826967
  • 数字型:
image-20200813215919713
(2) 加入算数运算符,SQL语句异常,页面会不变,因为我们加入的算数条件没有被正常执行,所以无异常,判断为字符型,反之为数字型:
  • 字符型,正常情况:

    image-20200813215358513
  • 字符型,添加运算条件后(加减乘除都可以加,主要url编码):

    image-20200813220132309
  • 数字型,添加运算条件后(加减乘除都可以加,注意url编码),因为SQL语句正确被执行,导致数据库内部错误,显示的内容,也会异常:

image-20200813220357615

搜索型注入和字符型一样都需要闭合语句,后续注释逃逸出的字符:

1). 搜索型注入通过 % 来闭合

2). 字符型需要通过fuzz来测试闭合,常用: ' " ') "):

  1. fuzz姿势如下,总结所有的可能的闭合方式:
'
"
''
'"
;
)
')
")
");
';
";
%'
%"
%')
%")
'))
"))
")))
  1. BurpSuit标记字符的位置,同时加上注释符 # --,判断返回页面差异,从而准确判断闭合的字符
image-20200813221658293
  1. 结果判断,因为正常执行会输出Your Login name:Dumb,我们如果成功闭合则内部SQL就会执行1/0的操作,从而内部错误,显示异常,不输出登录名,以此为差异来判断结果:

    • 标记号的是存在字符,不标记的为不存在关键字
    image-20200813222145479
    • 我们查看不存在标记的数据包,paylaod的共同点,都存在单引号',通过此我们便可以知道需要闭合的字符为单引号',其他的同样如此:
    image-20200813222358571
    • 我们找一个单引号括号')的例子来看,构造个减的条件,id=2,name: Angelina id=3, name: :Dummy,如果语句正常执行,将返回id=2的内容:

      image-20200813223025467

      同理找共同点,为 单引号括号'),所以闭合方式为: 单引号括号')

image-20200813223350609

二.后端数据库类型判断:

1. 直接回显错误! 通过报错语句来判断:
  • MSQL
image-20200813224326812
  • Oracle
image-20200814104123071
  • mssql

会直接报出 Sql server的相关错误,从而可以判断

2. 通过特定注释符号来判断:
  • MySQL

    (1)如果说既能够使用–--作为注释标志,又能够使用#做注释标志,那么基本可以确定是 MySQL

    (2)行间注释 /!version command/,这样的语法是 MySQL 专属,其中 version 是一个数字,如果 MySQL 的版本大于这个数字的话就会把 command 作为 SQL 语句的一部分。 /!50000SELECT/

  • Oracle

    (1) 通过/**/ -- 来注释,则为oracle数据库

3. 通过特定函数来判断:
  • 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 selectORACLE 的显著特征..等等

  • mssql

    ​ (1) waitfor delay time延时注入,可以确定是 SQL Server

    ​ (2) Top语法的使用

4. 通过字符串连接符来判断
  • MySQL,通过使用''来连接字符串
  • Oracle,通过 ||来连接字符串
  • Mssql,通过+来连接字符串
5. 通过特定数据库数据表来判断
  • Mysql, information_schema

  • Oracle, SYSAUX表,SYSTEM表,TEMP表,UNDO表,USERS表

  • Mssql, master..sysmessages、master..sysservers

6. 通过主流搭配方案来判断:
  • MySQL, 常用于后端为php
  • Oracle, 常用于后端为java
  • Mssql, 常用于后端为.net
7. P牛的集大成测试方式:
  • MySQL SELECT ... WHERE title REGEXP BINARY '^(An?|The) +'; -- MySQL
  • Oracle SELECT ... WHERE REGEXP_LIKE(title, '^(An?|The) +', 'c'); -- Oracle
  • MSsql SELECT ... WHERE title LIKE '%[^A-Z]%' -- Mssql
  • PostgreSQL SELECT ... WHERE title ~ '^(An?|The) +'; --postgreSQL

三.语句执行构造:

注意: 在测试时避免使用 and 1=1 这样大概率被拦截的语句,来探测SQL注入漏洞

(一)MySQL 数据库的注入探测技巧:

  • 构造运算符来判断:
image-20200814112505138
  • 除法(加减乘取余同理):
image-20200814114915339
image-20200814114935157
  • 取余:
image-20200814115202053
image-20200814115251410
image-20200814115333038
  • 在参数后添加注释符,页面正常返回
image-20200814115810994
image-20200814115844726
  • 通过MySQL的特性,隐式类型转换来判断,(要结合具体环境来使用):
image-20200814121028097
  • 通过构造逻辑运算符,配合比较运算符来判断:
image-20200814121230778
image-20200814121252543

Example(相互配合起来灵活应用):

(1). 构造 && 3<>1+--+ ,等价于and,注意url编码:

  • 真:
image-20200814121802787
  • 假:
image-20200814121826831

(2). 构造 false || 3>1+--+ (MySQL为或等价于or,Oracle为连字符)

  • 真:
image-20200814135954318
  • 假:
image-20200814140013568

(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内部报错
  • 真:
image-20200814140609679
  • 假:
image-20200814140630664

(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--+
  • 为真,语句正常执行,报错条件执行,语句报错
image-20200814141258784
  • 为假,语句正常执行,报错条件因为and短路,不执行报错语句,内部错误
image-20200814140921498

把握好重点即可,配合不同函数,能够成功判断并且确认,语句被正常执行了,就是存在SQL注入,配合延时也是同样道理

三 判断当前环境可以利用的注入方式

注入方式优先级排序(个人认为):

堆叠注入 >= 联合查询注入 > 报错注入 > 布尔盲注 > 时间盲注

  1. 堆叠注入如果存在,直接通过;闭合上一段语句构造新语句即可执行

  2. 联合查询注入,如果目标业务存在显示位,我们先判断列数,在判断显示位,从而后续构造语句直接查询,适用于直接返回SQL错误的目标

  3. 报错注入,构造报错条件,通过报错带出我们查询的数据,适用于直接返回SQL错误的目标

  4. 时间盲注,判断条件为时间条件,或者是大量运算所造成的高于正常的延时操作,以此为条件查询数据

  5. 布尔盲注,我重点叙述,上面SQL判断阶段的描述配合查询数据即可,与时间盲注为我们真实测试中最常遇到的情况

四 判断后端安全方式

黑名单,白名单:

就是在业务编写阶段为防止SQL注入,而禁用了一些特殊字符,比如数据库函数,注释符等等

测试流程:
  1. 通过Fuzz模糊测试,判断后端具体过滤函数,从而找出缺陷函数,来绕过黑名单限制,通常SQL注入的CTF所选用的方式
  2. 找到漏网之鱼的函数,配合逻辑语句查询数据内容
  3. 找常用注入语句中关键字的替代品

WAF

(Web应用防护系统(也称为:网站应用级入侵防御系统。英文:Web Application Firewall,简称: WAF)。利用国际上公认的一种说法:Web应用防火墙是通过执行一系列针对HTTP/HTTPS的安全策略来专门为Web应用提供保护的一款产品。)

我只写出我在测试中常用的方法,全部方法可以看公众号bypass里面的详细专题:

一. 找缺陷函数和替代品以及数据库特性:

ascii()函数 可以用 char() ,函数代替

and逻辑判断,可以使用 && 代替

or逻辑判断, 可以使用||代替

空格, 可以使用 %00-%0z 注释符 /**/替代

/!50000SELECT/ MySQL 特性 如果 MySQL 的版本大于5.00.00的话就会把 SELECT 识别出来。这个特性同样可以用来探测 MySQL 的版本号

二. 改变请求方式,get post 转换为上传文件类型的 multipart类型

一些WAF在进行数据包解析处理时,可能会存在类似的设计缺陷。例如在处理普通的GET、POST型请求时,会进行SQL注入、XSS等攻击特征的匹配。但是在处理multipart请求时,很可能只对类似恶意文件上传等攻击(文件上传包相关)进行检测, SQL注入等攻击就不再进行规则匹配了。那么此时若尝试以multipart方式进行业务提交,并且植入恶意的注入攻击语句,若服务器能解析的话,即可绕过WAF进行注入深入利用。

测试方法:
  1. BurpSuit 右键,选择:
image-20200814150219925
  1. 转换为下面效果:
image-20200814150337175
三.垃圾数据填充

有些WAF,因为性能的需要向业务做出妥协,当数据包超过WAF的规定阈值后,有的会丢弃掉数据包,而有的也会直接通过数据包,利用这个特性,我们构造超长的数据包便可以绕过waf

测试方法:
  1. 添加无用的字符串,SQL注入注释符中添加
  2. 添加多个同样的Cookies(截图为随意添加,真实环境把原有Cookies复制粘贴,增加即可),增大数据包的体积
image-20200814151043219
四 分块传输

分块传输编码Chunked transfer encoding)是超文本传输协议(HTTP)中的一种数据传输机制,允许HTTP由网页服务器发送给客户端应用( 通常是网页浏览器)的数据可以分成多个部分。分块传输编码只在HTTP协议1.1版本(HTTP/1.1)中提供。

测试方法:

推荐查看大佬文章:https://gv7.me/articles/2019/chunked-coding-converter/

利用方式以及工具,里面都有;目前新版的Sqlmap已经支持分块传输,参数为:--chunked

0x03 总结

  1. 先写这么多,还有 order by update insert limit 等等的注入,后续补充
  2. 持续更新,有错私信我修改
  3. 点击 whoami私我!!