https://www.freebuf.com/articles/web/286380.html
信呼OA 审计
admin qwer1234
信呼OA是一款自主MVC的办公系统,官网:http://www.rockoa.com/
入口分析
index.php 中 include_once('config/config.php');
跟进到 config/config.php
查看@session_start();
这行代码在 PHP 中用来启动一个新的会话或者继续当前会话。这里解释一下各个组成部分的含义和作用:
session_start()
函数:- 这个函数用来创建一个会话或者恢复基于会话标识符传递的当前已存在的会话。该函数使得 PHP 脚本能够使用
$_SESSION
超全局数组存储和访问会话数据。通过会话,服务器能够存储关于用户的状态信息(如用户身份验证状态、购物车内容等)。 - 会话数据在服务器端保存,通常在服务器的临时目录下,而不是用户的计算机上,从而增加了数据的安全性。客户端浏览器会保存一个会话 ID 的 cookie,该 ID 用来在多个页面请求之间识别用户。
- 这个函数用来创建一个会话或者恢复基于会话标识符传递的当前已存在的会话。该函数使得 PHP 脚本能够使用
@
错误控制运算符:- 在 PHP 中,
@
符号是一个错误控制运算符,用于抑制表达式可能产生的错误消息。当在表达式前加上@
时,任何由该表达式产生的错误都不会显示出来,这使得代码在遇到非致命错误时可以继续执行。 - 使用这个运算符可以防止用户看到一些可能由会话启动问题(例如,当会话已经在另一个脚本中启动时)引起的警告信息。
- 在 PHP 中,
if(function_exists('date_default_timezone_set'))date_default_timezone_set('Asia/Shanghai');
- 这里检查
date_default_timezone_set
函数是否存在(主要是为了向后兼容老版本的PHP)。如果存在,就将默认时区设置为'Asia/Shanghai'
。确保了所有基于时间的函数都将使用这个时区。
- 这里检查
header('Content-Type:text/html;charset=utf-8');
- 这行代码设置HTTP响应的Content-Type头为
text/html
,并指定字符集为UTF-8
。这告诉浏览器返回的内容是HTML文本,并且使用UTF-8编码,有助于正确显示包括中文在内的各种字符。
- 这行代码设置HTTP响应的Content-Type头为
define('ROOT_PATH',str_replace('\\','/',dirname(dirname(__FILE__))));
- 这行代码定义了一个常量
ROOT_PATH
,用于存储系统的根目录路径。它使用dirname(dirname(__FILE__))
来找到当前文件的上级目录的上级目录(即根目录),并将所有的反斜杠(‘\‘)替换为正斜杠(‘/‘),以保证路径在不同操作系统下都是有效的。
- 这行代码定义了一个常量
之后分析包含的其中包含的文件rockFun.php, Chajian.php
,其中都没什么内容,rockclass.php深入分析
Rockclass
1 | public function __construct() |
XSS过滤
1 | public function xssrepstr($str) |
获取客户端IP地址
1 | /* |
iconvsql
方法
1 | public function iconvsql($str,$lx=0) |
功能与作用:
- 这个方法用于处理和清理 SQL 语句,以防止 SQL 注入攻击。
str_ireplace($this->lvlaraa, $this->lvlarab, $str)
替换掉字符串$str
中所有在$this->lvlaraa
数组中定义的SQL关键词为$this->lvlarab
数组中相应的空字符串,这种方法用于尝试清除可能导致SQL注入的语句。str_replace("\n", '', $str)
移除字符串中的所有换行符。- 如果参数
$lx
等于1
,则进一步移除字符串中的所有空格和制表符。这可能用于进一步减少 SQL 语句中不必要的空白,以减小其在数据库查询中的潜在危险。
unstr
方法
1 | private function unstr($str) |
功能与作用:
- 这个私有方法用于检查字符串
$str
是否包含在类变量$this->unarr
定义的特定值中。 - 通过遍历
$this->unarr
数组,并使用contain
方法检查$str
是否包含数组中的任何一个元素。如果是,就将该元素赋值给$ystr
并终止循环。 - 返回的
$ystr
会是$str
中第一个在$this->unarr
数组中找到匹配的字符串,如果没有找到,则返回空字符串。
回到index
1 | include_once('config/config.php'); |
这段代码主要涉及动态 URL 处理和页面导航逻辑的处理,包括模块(m)、动作(a)和数据(d)的参数提取。这样的逻辑通常出现在 MVC 框架或类似的动态 Web 应用中,用于决定哪个控制器和方法应该被调用
结合访问请求,可以看到这些参数对应着MVC框架中的内容
最后一行include_once('include/View.php');
转而看下view.php
1 |
|
用于动态加载和执行 Web 应用的行动 (action) 脚本,处理 AJAX 请求,并动态加载视图模板。代码涵盖了从初始化变量、确定执行哪个控制器的哪个动作,到加载相应的 PHP 文件,以及处理和输出响应。
ok了 明白架构模式了 也知道了具体是怎么拼接的了 对于下面的请求:POST /index.php?a=check&m=login&d=&ajaxbool=true&rnd=469139
访问的是 loginClassAction 的 checkAction 方法,并且是异步请求。
随便找个功能点
修改密码的点,跟进去
1 | public function editpassAction() |
好像没啥能利用的,主要是输入直接被md5了
再多测测看
CVE-2024-7327
还得是公开cve
在信呼OA系统2.6.2版本的/webmain/task/openapi/openmodhetongAction.php文件中,存在一个前台SQL注入漏洞。当$nickName变量经过base64解码后被加入到uarr数组中,并最终传递给$db->record()方法进行SQL查询时,攻击者可以利用此漏洞进行SQL注入攻击。此外,还需要注意父类openapiAction.php中的init方法
1 | public function dataAction() |
跟进该方法 /include/Model.php
1 | public function record($arr, $where='') |
到了 /include/class/mysql.php
1 | public function record($table,$array,$where='') |
在这里带入SQL语句查询 导致注入 同时还要注意下父类openapiAction.php中的init方法 这里的Host需要属于127.0.0.1 或 192.168.x.x 的范围.
1 | public function initAction() |
信呼OA普通用户权限getshell
1 | index.php?d=main&m=flow&a=copymode&ajaxbool=true |
代码分析:
1 | /** |
漏洞代码主要出现在上面,可以看到$bhnu = strtolower(trim($this->post('name')));
接收了外部输入,且在下面的copy中有使用到$to
,这个变量是输入经过
1 | $to = str_replace('{bh}',$bhnu,$file); |
处理的,跟进createtxt函数:
1 | /** |
可以看到可以直接写入文件而没有过滤
写入的文件内容:mode_a{};phpinfo ();class aAction.php
1 |
|
主要原因是在copymodeAjax 中 str_replace 把类名换了 然后 刚好payload可以闭合前面的内容,实现插入代码