(360 A-TEAM 长期招收高级安全研究人员,APT 攻防人员,请联系 wufangdong@360.net)
今天,在部门定期的内部分享会上,Luan@360 A-TEAM 与大家分享了 Windows NTLM 的基础知识以及他写的 NTLM Proxy(网络版 Pass the hash 工具)。我则与大家分享了一下本文提到的这个小技巧。
朋友圈里吹过的牛
在没有 Web 服务的目标上运行 Java webshell
全程没有任何文件落地
不会产生任何 Web 访问日志
网络中将抓不到任何访问 Webshell 的 HTTP 流量
要求
目标有原生 Java 反序列化漏洞,并且可以通过某一种方式回显。这个要求也就使得本文的技巧显得实用价值并不是太大,因为一般在有反序列化的情况下,大家往往只要一条命令弹个 Shell 回来就可以搞定后面的事情了。所以看场景吧。
潜在的目标
任何有 Java 原生反序列化漏洞并且可以回显的目标都可以使用此技巧。比如 Weblogic/JBoss/Websphere/RMI Registry。我这里只针对 RMI Registry 做了实现。
实现的大概思路
手动创建 HttpRequest/HttpResponse/HttpSession 三个类,并实现其中必要的方法如 HttpRequest.getParameter,HttpResponse.getWriter,HttpSession.setAttribute 等。
让这三个类实现 Serializable 接口。
将 Jspspy.jsp 改造成 Jspspy 类,将其对 Java EE API 的依赖转变成上面我们自己定义的那三个类的依赖。(这一步实现了不需要 Web 服务运行 Java Webshell,自然也不会产生 Web 访问日志。虽然严格来说这种情况下它已经不算是一个 "Web"shell 了)
使 Jspspy 实现 Serializable 接口,使其可序列化,并在其 readObject 方法内,根据 HttpRequest 来判断并执行要执行的操作。
利用 RMI Registry 的反序列化漏洞,结合适用的 Payload,将 HttpRequest/HttpResponse/HttpSession/Jspspy 四个类上传至目标 Java 进程,并在进程内生成这四个类的 Class(通过 Payload 调用 ClassLoader.defineClass 来实现)(这一步实现了无文件落地)
以上 4 个类在目标 Java 进程内被 defineClass 后,我们就可以直接向 RMI Registry 传送那 4 个类的对象了。
本地启动一个 Tomcat,并用一个过滤器拦截到 jspspy.jsp 的请求。
拦截到这个 HTTP 请求后,过滤器内将此 HTTP 请求封装成 HttpRequest 的对象与 Jspspy 对象,将这两个对象通过序列化的通道发送至目标,在目标进程内反序列化,并执行对应的 Webshell 操作。操作的结果将被封装成 HttpResponse,通过反序列化回传至 Tomcat 的过滤器。
过滤器将 HttpResponse 转换成真正的 HTTP 响应发送回客户端浏览器。 (这一步与上一步实现了网络中抓不到 HTTP 流量,因为用的根本不是 HTTP 协议)
演示
**目标机器:**Kali,IP 为 192.168.33.44, 运行了 RMI Registry,但是没有开启任何 Web。
**本机:**Mac,利用 exp 攻击了目标 Kali 机器,获取 Webshell,访问地址为 http://localhost:8080/jspspy.jsp
虽然 Webshell 访问地址是 http://localhost:8080/jspspy.jsp,但这个 shell 却是真实运行在那台没有 Web 服务的 Kali 机器上的。见下图: