通达OA11.7漏洞集合
Background
源于塔总在P师傅的小蜜圈发的通达OA11.7的漏洞组合拳:
获取在线用户SESSION => 获取Log路径 => 读取redis配置文件 => ssrf+redis写入webshell
任意文件读取
漏洞文件位于:webroot/ispirit/im/photo.php
首先引入了两个文件, auth.inc.php
和utility_file.php
1 | require_once "inc/auth.inc.php"; |
跟进auth.inc.php看看代码如何实现的认证。
- 从GET或POST中获取PHPSESSID参数的值, 如果该值为字母a-z和0-9的组合且长度为20-32位则设置当前会话id为该值。
- 如果请求头中包含referer, 但referer中不包含主机名的话提示目录访问限制并退出脚本执行。
- SESSION中没有LOGIN_USER_ID键或其值为空, SESSION中没有LOGIN_UID键或其值为空, 接着判断SESSION中如果包含SHARE_ID并且其值不为空则提示无查看权限并退出执行, 反之提示未登录并退出执行, 对应的代码如下。
了解通达的朋友应该知道在 common.inc.php
中会将GPC
(GET, POST, COOKIE)的参数注册为变量, 这里有个小坑。在跟踪时发现代码好像有点问题, 将循环的参数值重复赋值给$s_key变量, 十分不解。最后在Google中搜索到 @xq17
师傅的一篇文章后才发现是Zend解密的问题。 然后把这个文件又拿去重新解密了一遍。
回到漏洞文件的代码中来, 在该文件中包含了 inc/auth.inc.php
, 因此该漏洞的利用需要登录。再看if的条件需要满足 UID
变量存在且大于0。前面说过会将GPC的参数注册为变量, 因此只需要在GPC任意一个未知中传递UID参数且值大于0即可。
接着在代码93~99行处判断 AVATAR_FILE
变量值的文件是否存在, 当文件存在时则使用 readfile
函数直接输出该文件, 无任何防护措施。所以只需要构造AVATAR_FILE参数为任意文件路径就可以读取。
1 | http://192.168.0.106:8080//ispirit/im/photo.php?AVATAR_FILE=filepath&UID=1 |
SSRF + Redis写Webshell
漏洞文件位于: webroot/inc/weixinqy/class/weixinqy.media.funcs.php
在开头中引入了 pda/auth.php
所以该漏洞依旧是需要登录的, 然后从GET中接收 ATTACHMENTS
参数以 ,
号分割问数组, 对应代码:
1 | require_once "pda/auth.php"; |
前面的两个条件在调用 remote_download
函数时会调用 WeiXinQYMedia#getMedia
方法, 会将参数的值拼接到 base_url
属性中, 不满足条件。
而在 $PLATFORM
等于 dd
的if分支中调用的 remote_download
方法是传递的原生的参数值。
在 remote_download
函数中会实例化Curl
类对象, 其就是一个封装curl函数库的一个类。
在get方法中又通过自己封装的一些方法设置curl选项, 在封装的 exec
方法中最终会调用 curl_exec
函数。而整个过程也是没有任何过滤和防护措施, 所以导致ssrf。
1 | http://192.168.0.106:8080/pda/workflow/img_download.php?PLATFORM=dd&ATTACHMENTS=http://5ke3hl.dnslog.cn |
后台SQL注入
漏洞文件:webroot/general/hr/manage/query/delete_cascade.php
开头的文件包含中会从 inc/utility_file.php
包含到 => common.inc.php
, 因此可以传递参数的方式注册变量, 此处因为将转义的单引号又替换为未转义的单引号而导致注入, 不过也需要绕过黑名单的限制。
order by注入
漏洞文件:general/email/inbox/get_index_data.php
只需要关注这一行代码即可:
1 | $email_array = get_email_data($orderby, $asc, $boxid, $email_fliter, $pagelimit, $timestamp, $curnum, $is_webmailbox, $is_main, $boxname, $list_view); |
跟进到get_email_data函数中, 在代码339行处会将 $FIELD
拼接到order by 中:
文件上传
漏洞文件:webroot/general/hr/manage/staff_info/update.php
将文件的拓展名与 $USER_ID
拼接后使用封装的 td_copy
函数移动文件:
首先构造一个用于包含的log或任意非黑名单后缀的文件:
然后在上传 .user.ini
包含这个文件:
上传成功后访问该目录下的任意PHP文件都会在执行之前包含 111.log
文件并执行其中代码。