Web应用安全测试-综合利用(三)
XML注入
漏洞描述
可扩展标记语言 (Extensible Markup Language, XML) ,用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。 XML是标准通用标记语言 (SGML) 的子集,非常适合 Web 传输。XML 提供统一的方法来描述和交换独立于应用程序或供应商的结构化数据。发现目前一些普遍使用xml的场景中都存在一种古老的XML实体注入漏洞,这可能导致较为严重的安全问题,使得攻击者可能可以任意访问服务器以及应用所在网络的任何资源。
测试方法
通过手工篡改网站中xml实体中的头部,加入相关的读取文件或者是链接,或者是命令执行等,如file:///path/to/file.ext;http://url/file.ext;php://filter/read=convert.base64-encode/resource=conf.php
,类似如下代码所示:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE nsfocus-sec [
<!ELEMENT methodname ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<methodcall>
<methodname>&xxe;</methodname>
</methodcall>
篡改以后,如果可读取file文件或者达到植入命令的效果,则说明存在该漏洞。
风险分析
XML注入攻击广泛用于Web系统的攻击。攻击方式主要有以下几种:
-
使用超长标签像
<AAAAAAA/>
,多达1024个A,或者使用超多的属性像<AA a=‘a’b=‘b’…>
,由于XML文件本身标签所占用的资源通常比内容多,在数据和属性比较多时,XML文件将变得非常庞大,给XML文件的传输和解析带来困难; -
递归负载攻击,注入深层次的循环嵌套的XML数据,造成服务器上XML分析器崩溃,造成系统计算资源耗尽而被Dos ;
-
外部实体攻击,利用
<!Entityname SYSTEM “URI”>
。XML文件的解析依赖libxml库,而libxml2.9以前的版本默认支持并开启了外部实体的引用,服务端解析用户提交的XML文件时,未对XML文件引用的外部实体(含外部普通实体和外部参数实体)做合适的处理,并且实体的URL支持file://和ftp://等协议,攻击者可以在XML文件中声明URI指向服务器本地的实体造成攻击。实体攻击可导致信息泄露、任意文件读取、DOS攻击和代码执行等问题。
风险等级
【高危】:额外数据字段注入导致权限提升或原始数据修改
【中危】:批量数据提交并成功被解析
修复方案
-
严格检查用户输入的字符;
-
检查使用的底层XML解析库,使用JAVA语言提供的禁用外部实体的方法:
DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);
- 操作XML时对格式字符进行转义处理,常见的格式字符如下表:
注意事项
暂无
XXE
漏洞描述
外部实体攻击,利用<!Entityname SYSTEM “URI”>
。XML文件的解析依赖libxml库,而libxml2.9以前的版本默认支持并开启了外部实体的引用,服务端解析用户提交的XML文件时,未对XML文件引用的外部实体(含外部普通实体和外部参数实体)做合适的处理,并且实体的URL支持file://和ftp://等协议。
测试方法
通过手工篡改网站中xml实体中的头部,加入相关的读取文件或者是链接,或者是命令执行等,如file:///path/to/file.ext;http://url/file.ext;php://filter/read=convert.base64-encode/resource=conf.php
,类似如下代码所示:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE nsfocus-sec [
<!ELEMENT methodname ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<methodcall>
<methodname>&xxe;</methodname>
</methodcall>
风险分析
攻击者可以在XML文件中声明URI指向服务器本地的实体造成攻击。实体攻击可导致信息泄露、任意文件读取、DOS攻击和代码执行等问题。
风险等级
【高危】:实体注入可读取服务器文件或执行命令
修复方案
-
严格检查用户输入的字符;
-
检查使用的底层XML解析库,使用JAVA语言提供的禁用外部实体的方法:
DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);
-
操作XML时对格式字符进行转义处理,常见的格式字符如下表:
注意事项
暂无
XPATH注入
漏洞描述
XPath注入攻击是指利用XPath 解析器的松散输入和容错特性,能够在URL、表单或其它信息上附带恶意的XPath查询代码,以获得权限信息的访问权并更改这些信息。XPath注入攻击是针对Web服务应用新的攻击方法,它允许攻击者在事先不知道XPath查询相关知识的情况下,通过XPath查询得到一个XML文档的完整内容。
测试方法
XPath注入攻击主要是通过构建特殊的输入,这些输入往往是XPath语法中的一些组合,这些输入将作为参数传入Web 应用程序,通过执行XPath查询而执行入侵者想要的操作,下面以登录验证中的模块为例,说明XPath注入攻击的实现原理和检测方法,在Web应用程序的登录验证程序中,一般有用户名(username)和密码(password)两个参数,程序会通过用户所提交输入的用户名和密码来执行授权操作。若验证数据存放在XML文件中,其原理是通过查找user表中的用户名(username)和密码(password)的结果来进行授权访问,例存在user.xml文件如下:
<users>
<user>
<firstname>Ben</firstname>
<lastname>Elmore</lastname>
<loginID>abc</loginID>
<password>test123</password>
</user>
<user>
<firstname>Shlomy</firstname>
<lastname>Gantz</lastname>
<loginID>xyz</loginID>
<password>123test</password>
</user>
则在XPath中其典型的查询语句如下:
//users/user[loginID/text()='xyz' and password/text()='123test']
但是,可以采用如下的方法实施注入攻击,绕过身份验证。如果用户传入一个login和password,例如loginID = 'xyz'
和password = '123test'
,则该查询语句将返回true。但如果用户传入类似'' or 1=1 or ''=''
的值,那么该查询语句也会得到true 返回值,因为XPath查询语句最终会变成如下代码:
//users/user[loginID/text()='' or 1=1 or ''='' and password/text()='' or 1=1 or ''='']
这个字符串会在逻辑上使查询一直返回true 并将一直允许攻击者访问系统。攻击者可以利用XPath在应用程序中动态地操作XML文档。攻击完成登录可以再通过XPath盲注技术获取最高权限帐号和其它重要文档信息。
风险分析
XPath注入攻击利用两种技术,即XPath扫描和XPath查询布尔化。通过该攻击,攻击者可以控制用来进行XPath查询的XML数据库。这种攻击可以有效地对付使用XPath查询(和XML数据库)来执行身份验证、查找或者其它操作。XPath注入攻击同SQL注入攻击类似,但和SQL注入攻击相比较,XPath在以下方面具有优势。
(1)广泛性。
XPath注入攻击利用的是XPath语法,由于XPath是一种标准语言,因此只要是利用XPath语法的Web应用程序如果未对输入的XPath查询做严格的处理都会存在XPath注入漏洞,所以可能在所有的XPath实现中都包含有该弱点,这和SQL注入攻击有很大区别。在SQL注入攻击过程中根据数据库支持的SQL语言不同,注入攻击的实现可能不同。
(2)危害性大。
XPath语言几乎可以引用XML文档的所有部分,而这样的引用一般没有访问控制限制。但在SQL注入攻击中,一个“用户”的权限可能被限制到某一特定的表、列或者查询,而XPath注入攻击可以保证得到完整的XML文档,即完整的数据库。只要Web服务应用具有基本的安全漏洞,即可构造针对XPath应用的自动攻击。
风险等级
【高危】:通过构造Xpath查询语句进行注入,操作XML数据。
修复方案
目前专门的 XPath 攻击防御技术还不是太多,但是 SQL 注入攻击防御技术 可以加以改进,应用到 XPath 注入攻击防御。
具体技术总结如下:
-
数据提交到服务器上端,在服务端正式处理这批数据之前,对提交数据的合法性进行验证。
-
检查提交的数据是否包含特殊字符,对特殊字符进行编码转换或替换、删除敏感字符或字符串。
-
对于系统出现的错误信息,以IE错误编码信息替换,屏蔽系统本身的出错信息。
-
参数化XPath查询,将需要构建的XPath查询表达式,以变量的形式表示,变量不是可以执行的脚本。
如下代码可以通过创建保存查询的外部文件使查询参数化:
declare variable $loginID as xs:
string external;
declare variable $password as xs:
string external;
//users/user[@loginID=$loginID and @password= $password]。
- 通过MD5、SSL等加密算法, 对于数据敏感信息和在数据传输过程中加密,即使某些非法用户通过非法手法获取数据包,看到的也是加密后的信息。
注意事项
暂无
命令注入
漏洞描述
Command Injection,即命令注入攻击,是指由于Web应用程序对用户提交的数据过滤不严格,导致黑客可以通过构造特殊命令字符串的方式,将数据提交至Web应用程序中,并利用该方式执行外部程序或系统命令实施攻击,非法获取数据或者网络资源等。在命令注入的漏洞中,最为常见的是PHP的命令注入。PHP命令注入攻击存在的主要原因是Web应用程序员在应用PHP语言中一些具有命令执行功能的函数时,对用户提交的数据内容没有进行严格的过滤就带入函数中执行而造成的。例如,当黑客提交的数据内容为向网站目录写入PHP文件时,就可以通过该命令注入攻击漏洞写入一个PHP后门文件,进而实施下一步渗透攻击。
测试方法
通过web扫描工具进行扫描,也可以通过手工进行验证:打开网站,在URL中传入命令的参数输入所要执行的命令,如下图所示的http://192.168.1.3/?cmd=net user
,可以发现命令能够成功执行:
风险分析
Web应用程序没有过滤类似system(),eval(),exec()
等函数是恶意命令执行的最主要原因。
风险等级
【高危】:成功执行系统命令或脚本命令
修复方案
PHP中命令注入攻击漏洞带来的危害和影响很严重。防范命令注入攻击漏洞的存在可以通过以下几种方法:
-
尽量不去执行外部的应用程序或命令。
-
使用自定义函数或函数库实现外部应用程序或命令的功能。
-
在执行system、eval等命令执行功能的函数前,校验参数内容。
-
使用escapeshellarg函数处理相关参数。Escapeshellarg函数会将任何引起参数或命令结束的字符进行转义,如单引号“’”会被转义为“\’”,双引号“””会被转义为“\””,分号“;”会被转义为“;”,这样escapeshellarg会将参数内容限制在一对单引号或双引号里面,转义参数中所包含的单引号或双引号,使其无法对当前执行进行截断,实现防范命令注入攻击的目的。
-
使用safe_mode_exec_dir执行可执行的文件路径。将php.ini文件中的safe_mode设置为On,然后将允许执行的文件放入一个目录中,并使用safe_mode_exec_dir指定这个可执行的文件路径。在需要执行相应的外部程序时,程序必须在safe_mode_exec_dir指定的目录中才会允许执行,否则执行将失败。
注意事项
暂无
任意文件上传
漏洞描述
一般情况下文件上传漏洞是指用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的能力。文件上传本身是web中最为常见的一种功能需求,关键是文件上传之后服务器端的处理、解释文件的过程是否安全。一般的情况有:
-
上传文件WEB脚本语言,服务器的WEB容器解释并执行了用户上传的脚本,导致代码执行;
-
上传文件FLASH策略文件crossdomain.xml,以此来控制Flash在该域下的行为;
-
上传文件是病毒、木马文件,攻击者用以诱骗用户或管理员下载执行;
-
上传文件是钓鱼图片或包含了脚本的图片,某些浏览器会作为脚本执行,可用于实施钓鱼或欺诈;
测试方法
上传方式根据不同的web语言,检测方法也各式各样,以下列举基于JS验证的上传的几种常见的文件上传绕过方法:
- 直接删除代码中onsubmit事件中关于文件上传时验证上传文件的相关代码即可。如图:
- 直接更改文件上传JS代码中允许上传的文件扩展名你想要上传的文件扩展名,如图所示:
- 使用本地提交表单即可,如图所示:
- 使用burpsuite或者是fiddle等代理工具提交,本地文件先更改为jpg,上传时拦截,再把文件扩展名更改为asp即可,如图所示:
- 当然也有不是基于JS验证的上传,例如一些中间件IIS,Nginx,,PHP,FCK编辑器等等的解析漏洞,其上传绕过方式也是多种多样。通过对上传页面进行检查,常见的文件上传检查针对文件类型进行,可以使用手动修改POST包然后添加%00字节用于截断某些函数对文件名的判断。除了修改文件名来绕过类型检查外,还可以修改文件头来伪造文件头,欺骗文件上传检查,如图,修改文件头中的类型来进行绕过:
以上为几种常见的上传,更多的还需自行研究,进行上传绕过。
以下为总体的测试流程:
-
登录网站,并打开文件上传页面
-
点击“浏览”按钮,并选择本地的一个JSP文件(比如hacker.jsp),确认上传。
-
如果客户端脚本限制了上传文件的类型(比如允许gif文件),则把hacker.jsp更名为hacker.gif;配置HTTP Proxy(burp)进行http请求拦截;重新点击“浏览”按钮,并选择hacker.gift,确认上传。
-
在WebScarab拦截的HTTP请求数据中,将hacker.gif修改为hacker.jsp,再发送请求数据。
-
登录后台服务器,用命令
find / -name hacker.jsp
查看hacker.jsp文件存放的路径。如果可以直接以Web方式访问,则构造访问的URL,并通过浏览器访问hacker.jsp,如果可以正常访问,则已经取得WebShell,测试结束。如果hacker.jsp无法通过web方式访问,例如hacker.jsp存放在/home/tmp/
目录下,而/home/tomcat/webapps
目录对应http://www.example.com/
,则进行下一步 -
重复1~3,在burp拦截的HTTP请求数据中,将hacker.gif修改为
../tomcat/webapps/hacker.jsp
,再发送请求数据。 -
在浏览器地址栏输入
http://www.example.com/hacker.jsp
,访问该后门程序,取得WebShell,结束检测。
风险分析
攻击者直接上传webshell到服务器,从而远程控制服务器。
风险等级
【高危】:成功上传恶意脚本文件,并解析webshell。
修复方案
-
最有效的,将文件上传目录直接设置为不可执行,对于Linux而言,撤销其目录的’x’权限;实际中很多大型网站的上传应用都会放置在独立的存储上作为静态文件处理,一是方便使用缓存加速降低能耗,二是杜绝了脚本执行的可能性;
-
文件类型检查:建议使用白名单方式,结合MIME Type、后缀检查等方式(即只允许允许的文件类型进行上传);此外对于图片的处理可以使用压缩函数或resize函数,处理图片的同时破坏其包含的HTML代码;
-
使用随机数改写文件名和文件路径,使得用户不能轻易访问自己上传的文件;
-
单独设置文件服务器的域名。
注意事项
暂无
反序列化漏洞
漏洞描述
Java序列化就是把对象转换成字节流,便于保存在内存、文件、数据库中,Java中的ObjectOutputStream类的writeObject()方法可以实现序列化。Java反序列化即逆过程,由字节流还原成对象。ObjectInputStream类的readObject()方法用于反序列化。Apache Commons Collections允许链式的任意的类函数反射调用。攻击者通过允许Java序列化协议的端口,把攻击代码上传到服务器上,再由Apache Commons Collections里的TransformedMap来执行。
测试方法
在java编写的web应用与web服务器间java通常会发送大量的序列化对象例,如以下场景:
-
HTTP请求中的参数,cookies以及Parameters。
-
RMI协议,被广泛使用的RMI协议完全基于序列化
-
JMX 同样用于处理序列化对象
自定义协议 用来接收与发送原始的java对象
常见中间件,如JBoss、Weblogic、WebSphere、jenkins
等存在java反序列化漏洞,可利用工具进行测试,如DeserializeExploit.jar、WebLogic_EXP.jar、attackRMI.jar
。
风险分析
java反序列化漏洞存在于各大业务系统中,影响范围大,且自动化利用工具比较成熟,攻击成本较低。
风险等级
【高危】:成功执行系统命令或脚本命令
修复方案
Apache官方发布了commons-collections的新版本,下载地址:
http://commons.apache.org/proper/commons-collections/download_collections.cgi
,修复方法为替换有漏洞的commons-collections组件。
注意事项
暂无