PfSense XSS漏洞分析

2015-09-17 252718人围观 ,发现 4 个不明物体 漏洞系统安全

*本文中涉及到的相关漏洞已报送厂商并得到修复,本文仅限技术研究与讨论,严禁用于非法用途,否则产生的一切后果自行承担。

0×00 导言

PfSense是一款基于FreeBSD操作系统的开源网络防火墙软件,已经被世界各地的公司广泛用来保护其基础设施。

在去年的时候,我们在PfSense中发现了一些安全漏洞(FreeBuf曾报道过),并提交给了PfSense的安全团队,到目前为止,时间已经过去一年有余,这段时间足以让使用PfSense的公司和个人通过打补丁升级到了最新的版本。因此,我们打算将这些漏洞公之于众,以便于安全研究人员互通有无,共享信息。

在本文中,我们将向大家介绍在pfSense中发现的CVE-2014-4687漏洞,该漏洞只存在于2.1.3及以下的版本中,此后的版本已经修复了该漏洞。

0×01 Schedules接口中的存储型XSS

如果我们点击Schedules,就会看到如下所示的Web接口。


图1 Schedules页面

打开这个页面之后,我们就可以通过按+按钮来添加时间表了。在这个过程中,我们可以把starttime0这个POST参数的值改为0:00'><script>alert(1);</script><  ,如下图在高亮部分所示。


图2 发送给服务器的恶意JavaScript请求

之后,输入的这段JavaScript代码会被原封不动地写入到响应中,并且没有对特殊字符进行任何的封装处理。这个响应的内容如下图所示。

图3 响应中的恶意JavaScript代码

一旦这个请求被显示于一个Web浏览器中,那么它就会变成一个XSS漏洞,因为其中的JavaScript代码会被浏览器所执行,具体如下图所示。


图4 JavaScript代码被浏览器执行

由于这个漏洞可在用户的Web浏览器中执行任意的JavaScript代码,所以,它能够用来窃取用户的会话cookie。

0×02 Rss.widget.php文件中的存储型XSS漏洞

在PHP脚本widgets/widgets/rss.widget.php中,有一个存储型XSS漏洞,更确切地说,这个漏洞位于名为rssfeed的POST参数中。与这个漏洞相关的代码如下所示,其中高亮显示的部分为漏洞所在的代码。

 <?php
  if($POST[rssfeed]) {
  $config[widgets][rssfeed] = str_replace(n, ,, $POST[rssfeed]);
  $config[widgets][rssmaxitems] = str_replace(n, ,,
POST[rssmaxitems]);
  $config[widgets][rsswidgetheight] = $POST[rsswidgetheight];
  $config[widgets][rsswidgettextlength] = $POST[rsswidgettextlength];
  writeconfig(Saved RSS Widget feed via Dashboard);
  Header(Location: /);
  }
  if($config[widgets][rssfeed])
  $textareatxt = strreplace(,, n, $config[widgets][rssfeed]);
  else
  $textareatxt = "";
  ?>
  <textarea name="rssfeed" class="formfld unknown" id="rssfeed"
ols="40" rows="3">
  <?=$textareatxt;?>
  </textarea>

下面所示的这个请求,会被名为rssfeed的POST参数中的恶意JavaScript代码发送给对应的Web服务器。


图5 POST参数rssfeed中的恶意JavaScript代码

之后,返回的响应中,会包含如下所示的代码,并且其中的特殊字符没有经过适当的安全处理。


图6 之前发送的恶意JavaScript代码被直接放入返回的Web页面中

下面展示的POST参数中也存在安全漏洞,并且它们都是位于同一个脚本中:

-     rssmaxitems
-     rsswidgetheight
-     rsswidgettextlength
-     rsswidgettextlength

攻击者可以将恶意JavaScript代码发送给Web应用,并且该应用也会把这些代码存储到页面中返回给其他用户。

0×03 Services_status.widget.php脚本中的反射型XSS

我们发现,widgets/widgets/services_status.widget.php脚本也没有对用户提供的数据进行恰当地封装处理。例如,对于下面所示的代码,我们可以直接将POST变量servicestatusfilter赋值为 $config[widgets'][servicestatusfilter]',因为该脚本并没有对用户输入进行任何的“消毒”处理。之后,我们可以利用HTML代码来显示这个变量的值。

<?php
  if(isset($_POST['servicestatusfilter'])) {
  $config['widgets']['servicestatusfilter'] =_POST['servicestatusfilter'];
  write_config("Saved Service Status Filter via Dashboard");
  header("Location: ../../index.php");
  }
  ?>
  <input type="text" size="30" name="servicestatusfilter"
lass="formfld unknown" id="servicestatusfilter" value="<?=config['widgets']['servicestatusfilter'] ?>" />

下面的请求中,含有一个POST参数servicestatusfilter,其值为"/><script>alert(1);</script><"。


图7 POST参数servicestatusfilter中的恶意JavaScript代码

通过观察下图可以发现,响应中的值跟之前的值一模一样。


图8 POST参数rssfeed中的恶意JavaScript代码

需要注意的是,这里的JavaScript代码并不会在Web浏览器中执行,因为这里还提供了一个Location头部,因此,JavaScript代码在执行之前就被重定向了。虽然如此,这仍然是一个安全漏洞,同样需要进行修补。因为攻击者能够利用它在用户的浏览器中执行任意的JavaScript代码。

0×04 Log.widget.php脚本中HTTP头部Referer中的XSS漏洞

在widgets/widgets/log.widget.php脚本中也存在一个XSS漏洞,相应的代码如下图所示。其中,HTTP头部Referer被读入变量$filename中,而这个变量随后会被放入响应页面中,但是并没有对特殊字符进行相应的编码处理。

$filename = $_SERVER['HTTP_REFERER'];
if(headers_sent($file, $line)){
echo '<script type="text/javascript">';
echo '//<![CDATA[';
echo 'window.location.href="'.$filename.'";';
echo '//]]>';
echo '</script>';
echo '<noscript>';
echo '<meta http-equiv="refresh" content="0;url='.$filename.'" />';
echo '</noscript>';
}

如果我们利用HTTP头部Referer发送一个字符串<script>,那么,我们就会收到如下所示的响应,表明遇到了一个问题,原因是HTTP头部Referer中的字符串与系统设置的不相符。 


图9 利用HTTP头部referer发送<script>时的响应

之所以出现这种情况,是因为Pfsense实现了HTTP_REFERER重定向检测,并且默认设置会阻止这种行为,要想改变这个设置,可以通过System – Advanced – Admin settings进行修改,如下图所示。


图10 与HTTP头部referer有关的pfsense设置

我们需要禁用强制检查HTTP_REFERER,并保存相应的设置。这样,我们就可以利用HTTP的Referer头来发送字符串"/></noscript><script>alert(1);</script><noscript><"了,具体如下图所示。


图11 在HTTP的Referer头部中含有恶意JavaScipt代码的请求

在下面的响应中,存储在HTTP头部Referer中的这个值,向用户呈现了两次。


图12 恶意JavaScript代码被放入返回的Web页面中

由于我们对<noscript>及其他HTML元素进行了相应的转义处理,所以,这些注入的JavaScript就能够在用户的浏览器中执行了,如下图所示。


图13 执行恶意JavaScript代码

由于Pfsense的默认设置会启用HTTP_REFERER的强制检查功能,因此,这个漏洞是比较难以利用的,不过,这个漏洞的确是存在的,所以必须进行相应的安全处理。除此之外,这个响应中含有的其他一些POST参数也没有经过适当的消毒处理,这使得被攻击的可能性更大了。这些存在安全缺陷的POST参数包括:

-     filterlogentries
-     actpass
-     actblock
-     actreject
-     filterlogentriesinterfaces

此外,攻击者还能向HTTP的Referer头中注入JavaScript代码,并使其在用户的浏览器中被执行。

0×05 Exec.php脚本中的JavaScript注入漏洞
我们知道,The Diagnostics :Execute command 功能允许攻击者向服务器上载文件,具体如下所示。

图14 文件上载功能

为了使用户能够访问这一功能,必须赋予他访问Diagnostics :Command的相应权限,具体如下图所示。


图15 所需的权限

当上传文件的时候,攻击者有机会向参数txtRecallBuffer中注入任意的JavaScript代码。如下图所示,本例在参数txtRecallBuffer注入了一个字符串,即"bbb'); var arrRecalBuffer = new Array('aaa",见图中高亮显示部分。


图16 发送给服务器的恶意输入数据

上面的请求所导致的响应如下所示,这说明注入任意JavaScript代码是可行的。


图17 前面发送的输入数据被直接放入JavaScript代码块中

需要注意的是,我们无法利用这个漏洞,因为整个JavaScript代码块都位于注释中,即被<!—->注释掉了。通常来说,我们是可以设法让这些代码逃出注释符的魔咒的,比如先注入符号>,然后在其后加入任意代码即可。但是就本例来说,我们是不能这样做的,因为<和>这两个特殊字符都会被正确地编码的。
此外,JavaScript代码还可以注入到Web页面中,这样的话,攻击者就可以在用户的浏览器中执行任意JavaScript代码了。

0×06小结

本文详细介绍了我们在PfSense中发现的一些XSS漏洞,希望对读者朋友们有所帮助。

*参考来源:proteansec,投稿/I12016,转载须注明来自FreeBuf黑客与极客(FreeBuf.COM)

发表评论

已有 4 条评论

取消
Loading...

特别推荐

推荐关注

填写个人信息

姓名
电话
邮箱
公司
行业
职位
css.php