通过Java表达式实现一句话JSP WebShell
JSP 基础
JSP,全称JavaServer Pages,是一种开发动态Web页面的技术。它允许开发人员将Java代码嵌入到HTML页面中,从而实现页面的动态生成。JSP页面可以包含静态内容(如HTML、XML)和Java代码,这些Java代码通常用于动态生成内容,访问数据库,执行业务逻辑等。
JSP的基本原理是在服务器端将JSP页面编译成Servlet。当客户端请求一个JSP页面时,服务器将首先将该JSP页面编译成Java Servlet,然后再执行Servlet代码,生成最终的HTML页面,最终将HTML页面发送给客户端浏览器。这种方式使得JSP具有了动态生成内容的能力,同时也能够与Java Servlet技术无缝集成。
常规命令执行
Runtime.getRuntime().exec()
ProcessBuilder().start()
反射调用ProcessImpl
EL表达式实现命令执行
Java Expression Language (EL) 是用于在Java EE应用程序(尤其是JSP和JSF)中简化数据访问和表达式计算的语言。EL主要用于在JSP/JSF页面中从Java对象获取数据、调用方法等操作。在JSP中通过EL表达式只能调用静态方法所以一般需要使用反射实现调用方法和创建对象,以下是几个EL表达式的重要特性。
EL表达式标签格式
EL表达式内置的隐式对象如下,常用的param、header、cookie等,这些隐式对象可用于获取webshell的相关参数。
在EL表达式中“ [] ” 和 “ . ”是通用的,其属性取值相当于执行对象的 getter 方法,= 赋值则等同于执行 setter 方法。
通过如上特性可以构造出一个无回显Webshell,在EL表达式中通过反射调用java.lang.Runtime.getRuntime()方法获取Runtime对象,调用其exec方法执行系统命令。
服务端构造一个EL表达式注入点,而payload使用EL表达式,实际上就是将上一步构造的webshell作为参数提交给PageContextImpl.proprietaryEvaluate让其执行EL表达式。
ScriptEngineManager实现命令执行
ScriptEngineManager是一个Java自带的用于解析js的库,根据其特性利用js中eval函数可以执行Java代码,具体操作:使用ScriptEngineManager类来获取一个ScriptEngineManager实例,执行eval函数入参为特定的js代码以实现命令执行和获取执行结果,需要注意的是在JDK大于8时即可以使用Java.type("类名")来引入对应类也可以通过全权限定类名引入,但JDK版本低于8时需要权限定类名来引入使用,因此payload直接使用通用的全限定全类名来引入。
数据包和js内容,参数位置和编码可以自行调整。
ScriptEngineManager实现命令执行的本质是任意代码执行,所以可以实现像冰蝎那样通过自定义类加载器来加载自定义的任意字节码。
两者结合
结合EL表达式和ScriptEngine可以构造一个极短的JSP webshell如下。
有回显,方式一(通过ProcessBuilder,执行系统命令)
有回显,方式二(通过defineClass加载恶意类执行系统命令)
上述方式蚁剑已经集成支持,可以直接使用蚁剑连接。
参考链接:
一种新型Java一句话木马的实现-yzddMr6
《Java表达式攻防下的黑魔法》-yzddMr6
本篇文章来源于微信公众号:卓识网安