Web应用安全测试-综合利用(二)
Host头攻击
漏洞描述
Web应用程序获取网站域名一般是依赖HTTP Host header
(比如在JSP里通过request.getHeader()
获取),这里的header很多情况下是不可靠的。
攻击者恶意利用HTTP Host header
会导致HTTP Host
头攻击发生。
测试方法
- 密码重置污染攻击,点击重置密码的链接时,
url::abs_site
这一部分使用的Host header是来自用户重置密码的请求,那么可以通过一个受他控制的链接来污染密码重置的邮件,例如替换host:当然这种攻击方式一定要能骗取用户点击访问这个受污染的链接,如果用户警觉了没有点击,那么攻击就会失败
> POST /password/reset HTTP/1.1
> Host: evil.com
> ...
> csrf=1e8d5c9bceb16667b1b330cc5fd48663&name=admin
- 通过Host header来污染缓存的攻击方法:
因此为了能使缓存能将污染后的response返回给用户,我们还必须让缓存服务器看到的host header 和应用看到的host header 不一样, 比如说对于Varnish(一个很有名的缓存服务软件),可以使用一个复制的Host header。Varnish是通过最先到达的请求的host header来辨别host的,而Apache则是看所有请求的host,Nginx则只是看最后一个请求的host。这就意味着你可以通过下面这个请求来欺骗Varnish达到污染的目的
> GET / HTTP/1.1
> Host: example.com
> Host: evil.com
- 利用web漏洞扫描工具进行检测。
风险分析
大部分的Web应用程序未经html编码直接把header输出到了页面中。比如:<link href=http://request.getHeader(“Host”) >
。有些URL中还包含有secret key和token,如:<a href="http://request.getHeader(“Host”)?token=topsecret">
。这样处理header一般会产生两种常见的攻击:缓存污染和密码重置。缓存污染是指攻击者通过控制一个缓存系统来将一个恶意站点的页面返回给用户。密码重置这种攻击主要是因为发送给用户的内容是被污染的,即间接的劫持邮件。
风险等级
【中危】:请求数据包包中 host 值直接拼接到生成链接中。
修复方案
服务器方面
-
由于http请求的特点,host header的值其实是不可信的。唯一可信的只有SERVER_NAME,这个在Apache和Nginx里可以通过设置一个虚拟机来记录所有的非法host header。在Nginx里还可以通过指定一个SERVER_NAME名单,Apache也可以通过指定一个SERVER_NAME名单并开启UseCanonicalName选项。建议两种方法同时使用。
-
Varnish很快会发布一个补丁。在官方补丁出来前,可以通过在配置文件里加入:
import std;
sub vcl_recv {
std.collect(req.http.host);
}
应用方面
在网站安装和初始化的时候,要求管理员提供一个可信任的域名白名单。如果这个实现起来比较困难,那至少也要保证使用使用getServerName()代替getHeader(“Host”)。
注意事项
暂无
SQL注入
漏洞描述
所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。具体来说,它是利用现有应用程序,将(恶意)SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句。 造成SQL注入漏洞原因有两个:一个是没有对输入的数据进行过滤(过滤输入),还有一个是没有对发送到数据库的数据进行转义(转义输出)。
测试方法
- 通过web漏洞扫描工具进行对网站爬虫后得到的所有链接进行检测,或者手工判断是否存在注入点,一旦确认存在漏洞,可利用自动化工具sqlmap去尝试注入。几种常见的判断方法:
数字型
http://host/test.php?id=100 and 1=1
返回成功
http://host/test.php?id=100 and 1=2
返回失败
字符型
http://host/test.php?name=rainman ’ and ‘1’=‘1
返回成功
http://host/test.php?name=rainman ’ and ‘1’=‘2
返回失败
搜索型
搜索型注入:简单的判断搜索型注入漏洞是否存在的办法是:
-
先搜索('),如果出错,说明90%存在这个漏洞。
-
然后搜索(%),如果正常返回,说明95%有洞了。
-
然后再搜索一个关键字,比如(2006)吧,正常返回所有2006相关的信息。
-
再搜索(
2006%'and 1=1 and '%'='
)和(2006%'and 1=2 and '%'='
)
绕过验证(常见的为管理登录)也称万能密码
-
用户名输入:
‘ or 1=1 or ‘
密码:任意 -
Admin’ - -(或‘ or 1=1 or ‘ - -)(admin or 1=1 --) (MS SQL)
(直接输入用户名,不进行密码验证) -
用户名输入:
admin
密码输入:’ or ‘1’=’1
也可以 -
用户名输入:
admin' or 'a'='a
密码输入:任意 -
用户名输入:
‘ or 1=1 - -
-
用户名输入:
admin‘ or 1=1 - -
密码输入:任意 -
用户名输入:
1'or'1'='1'or'1'='1
密码输入:任意
不同的SQL服务器连结字符串的语法不同
比如MS SQL Server使用符号+来连结字符串,而Oracle使用符号||来连结:
http://host/test.jsp?ProdName=Book’
返回错误
http://host/test.jsp?ProdName=B’+’ook
返回正常
http://host/test.jsp?ProdName=B’||’ook
返回正常说明有SQL注入
如果应用程序已经过滤了’和+等特殊字符,我们仍然可以在输入时过把字符转换成URL编码(即字符ASCII码的16进制)来绕过检查。
风险分析
在输入URL和表单处,攻击者通过输入精心构造的SQL语句,对数据库记录进行增删改查,或直接获取服务器权限。攻击者实施SQL注入攻击时大多借助自动化注入工具,如穿山甲、明小子、sqlmap、Havij等。
风险等级
【高危】:存在SQL注入,无论能否爆出数据
修复方案
SQL注入的主要原因是程序没有严格过滤用户输入的数据,导致非法数据侵入系统。
- 对用户输入的特殊字符进行严格过滤,如
’、”、<、>、/、*、;、+、-、&、|、(、)、and、or、select、union
-
使用参数化查询(PreparedStatement),避免将未经过滤的输入直接拼接到SQL查询语句中。
-
Web应用中用于连接数据库的用户与数据库的系统管理员用户的权限有严格的区分(如不能执行drop等),并设置Web应用中用于连接数据库的用户不允许操作其他数据库。
-
设置Web应用中用于连接数据库的用户对Web目录不允许有写权限。
-
使用Web应用防火墙。
sql注入防范编码供开发者参考
方法一:参数化查询
利用PreparedStatement对象的set方法给参数赋值。参数化查询强制要求给每个参数定义类型,这种方式使得数据库能够区分出哪些属于代码段哪些属于数据段。
String custname = request.getParameter("customerName");
String query = "SELECT account_balance FROM user_data WHERE user_name = ? ";
PreparedStatement pstmt = connection.prepareStatement( query );
pstmt.setString( 1, custname);
ResultSet results = pstmt.executeQuery( );
方法二:输入合法性验证。
检查输入字符串中是否包含敏感的SQL字符,是否包含SQL关键字、是否是典型的SQL注入语句。检查到非法字符之后,可以直接结束数据库查询并返回告警,也可以把非法字符替换为空或进行其他形式的修正。需要注意的是这种防御方式的可靠性建立在目前情况下攻击者无法构造绕过合法性验证的恶意SQL语句。
通用的SQL语句合法性验证如下:
public static boolean sql_inj(String str)
{
String inj_str = "'|and|exec|insert|select|delete|update|count|*|%|chr|mid|master|truncate|char|declare|;|or|-|+|,";
String inj_stra[] = split(inj_str,"|");
for (int i=0 ; i < inj_stra.length ; i++ )
{
if (str.indexOf(inj_stra)>=0)
{
return true;
}
}
return false;
}
方法三:使用OWASP提供的ESAPI
ESAPI (OWASP企业安全应用程序接口)是一个免费、开源的、网页应用程序安全控件库,它使程序员能够更容易写出更低风险的程序。ESAPI接口库被设计来使程序员能够更容易的在现有的程序中引入安全因素。ESAPI库也可以成为作为新程序开发的基础。
ESAPI详细介绍请参考:http://www.owasp.org.cn/owasp-project/ESAPI/
。
注意事项
暂无
NoSQL注入
漏洞描述
攻击者伪造一个带有注入代码的Web访问请求,当数据库客户端或协议包装器进行处理时,将会执行预期的非法数据库操作。如下图所示:
测试方法
NoSQL相关的攻击大致分为以下五类:
-
重言式。
又称为永真式。此类攻击是在条件语句中注入代码,使生成的表达式判定结果永远为真,从而绕过认证或访问机制。例如,MongoDB注入攻击,用$ne
(不相等)操作符, 构造请求http://www.xxx.com/index.php?username[$ne]=1&password[$ne]=1
,绕过认证进入系统。 -
联合查询。
联合查询最常用的用法是绕过认证页面获取数据。通过增加永真的表达式利用布尔OR运算符进行攻击,从而导致整个语句判定出错,进行非法的数据获取。 -
JavaScript注入。
这是一种新的漏洞,由允许执行数据内容中JavaScript的NoSQL数据库引入的。JavaScript使在数据引擎进行复杂事务和查询成为可能。传递不干净的用户输入到这些查询中可以注入任意JavaScript代码,这会导致非法的数据获取或篡改。 -
背负式查询。
在背负式查询中,攻击者通过利用转义特定字符(比如像回车和换行之类的结束符)插入由数据库额外执行的查询,这样就可以执行任意代码了。 -
跨域违规。
HTTP REST APIs是NoSQL数据库中的一个流行模块,然而,它们引入了一类新的漏洞,它甚至能让攻击者从其他域攻击数据库。在跨域攻击中,攻击者利用合法用户和他们的网页浏览器执行有害的操作。在本文中,我们将展示此类跨站请求伪造(CSRF)攻击形式的违规行为,在此网站信任的用户浏览器将被利用在NoSQL数据库上执行非法操作。通过把HTML格式的代码注入到有漏洞的网站或者欺骗用户进入到攻击者自己的网站上,攻击者可以在目标数据库上执行post动作,从而破坏数据库。
案例详情请参考:http://www.infoq.com/cn/articles/nosql-injections-analysis
。
风险分析
在输入URL和表单处,攻击者通过输入精心构造的语句,获取数据库内容,或绕过认证。
风险等级
【高危】:存在NoSQL注入,无论是否能够爆出数据
修复方案
防止数组中的运算操作即可防御该漏洞。可以使用一下两种方式:
- 采用implode()方法,如下图:
implode()函数返回由数组元素组合成的字符串。这样就只能得到一个对应的结果。
- 使用addslashes()函数,这样攻击者便不能破坏查询语句。同时,也可以用正则表达式把一些特殊符号替换掉,如使用如下正则:
$u_name =preg_replace(‘/[^a-z0-9]/i’, ‘\’, $_GET[‘u_name’]);
注意事项
暂无
LDAP注入
漏洞描述
LDAP(Lightweight Directory Access Protocol),轻量级目录访问协议,是一种在线目录访问协议,主要用于目录中资源的搜索和查询。如果在用户可控制的输入中没有对 LDAP 语法进行除去或引用,那么生成的 LDAP 查询可能会导致将这些输入解释为 LDAP 而不是普通用户数据。这可用于修改查询逻辑以绕过安全性检查,或者插入其他用于修改后端数据库的语句,可能包括执行系统命令。
测试方法
可参考 https://www.cnblogs.com/nuomin/p/7063654.html
风险分析
利用LDAP注入技术的关键在于控制用于目录搜索服务的过滤器。使用这些技术,攻击者可能直接访问LDAP目录树下的数据库,及重要的公司信息。
风险等级
【高危】
修复方案
-
使用不允许此弱点出现的经过审核的库或框架,或提供更容易避免此弱点的构造。
-
使用自动实施数据和代码之间的分离的结构化机制。这些机制也许能够自动提供相关引用、编码和验证,而不是依赖于开发者在生成输出的每一处提供此能力。
-
使用完成必要任务所需的最低特权来运行代码。
-
如果在有风险的情况下仍需要使用动态生成的查询字符串或命令,建议对参数正确地加引号并将这些参数中的任何特殊字符转义。
-
使用“接受已知善意”输入验证策略:严格遵守规范的可接受输入的白名单。拒绝没有严格遵守规范的任何输入,或者将其变换为严格遵守规范的内容。不要完全依赖于通过黑名单检测恶意或格式错误的输入。但是,黑名单可帮助检测潜在攻击,或者确定哪些输入由于格式严重错误而应直接拒绝。
注意事项
暂无