前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PHP代码审计之wuzhicms

PHP代码审计之wuzhicms

作者头像
亿人安全
发布2023-02-28 09:48:59
8180
发布2023-02-28 09:48:59
举报
文章被收录于专栏:红蓝对抗

环境搭建

漏洞审计

路由分析:

在index.php文件中包含 coreframe 框架下core.php文件并调用load_class加载 然后在application.class.php 文件、core.php 框架核心文件 调用了load_class加载类。然后通过load_class()类实例化wuzhi_application类

通过 load_class() 类实例化 WUZHI_application 类。

实例化 WUZHI_application 类调用下面构造方法

调用 WUZHI_application 类下 run() 方法获取路由信息

抓包查看他的路由访问规律

1.sql注入

漏洞路径/coreframe/app/member/admin/group.php

下的 del() 函数

在代码133行判断是否传入groupid参数且参数是否为空,条件满足在134行代码中判断传入的groupid是否为数组。

跟进delete()函数,在db.class.php中找到对应函数。

而下面223行的delete()函数才是真正去操作数据库的函数,我们跟进这个delete()

在这个过程中我们传入的sql语句并没有进行任何过滤就直接拼接到$sql并通过query()执行,所以这里存在SQL注入漏洞。

在query()函数中如果出现SQL语句错误会直接爆出SQL语句,所以这里存在报错注入。

漏洞复现:

2.任意文件写入

使用工具或者全局搜索file_put_contents函数

通过Seay的审计结果,翻找到一处可能存在任意文件写入的地方。

通过翻找发现一处可以直接控制 data 的文件:oreframe/app/attachment/admin/index.php这里的 ueditor() 函数调用了 set_cache() 并且这里的 GLOBALS['setting'] 参数可控。

假如不设置submit,则会通过 get_cache() 读取缓存文件内容。

漏洞复现:

通过前面路由分析以及上面SQL注入的路由,我们可以构造出调用ueditor()的路由: /index.php? m=attachment&f=index&v=ueditor&_su=wuzhicms&submit=XXX&setting=payload

文件已被成功写入到缓存文件中

读取缓存中文件内容

3.csrf

在测试功能点:系统设置 => 权限管理 => 添加管理员 处我们点击提交

通过提示我们了解到必须存在一个前台账户,然后才可以将前台账户绑定为系统管理员,而前台账户是可以注册的。

路径:

/index.php?m=core&f=power&v=add&&_su=wuzhicms

通过路由找到对应代码

从最上面的注解就可以看出 add() 函数是用于添加管理员的,35-37行代码判断是否点击提交操作,然 后判断用户名是否为空,不为空则将传入的 username 值赋值给 $username

在代码38行处根据用户名 从数据库中取出前台账户,如果该前台用户不存在则会提示如下内容,也就是我们上面的提示,在40行代码判断该用户是否已经是管理员,而44-51行代码是判断添加管理员时是否设置密码.

4.目录遍历

通过全局搜索 glob 函数发现一处功能点处可能存在目录遍历,这里的 glob() 函数中 $dir 参数可控

上面代码29行通过 template() 函数渲染 listing.tpl.php 文件,将我们目录下的内容遍历出来并显示在前端页面。

添加我们所需要的 dir 参数,由于上面的代码存在过滤且这里仅仅是将传入的内容替换为空而且只替 换一次,通过 ...../// 的形式来绕过该处的过滤实现目录遍历

5.任意文件删除

全局搜索危险函数 unlink() ,发现该处存在一个 my_unlink() 函数调用了 unlink() 函数并且通过注解也可以大致了解到该函数是用来删除附件的,这里的 path 参数传递需要删除的文件。接下来我们的思路是两点:一是看哪些功能点调用了 my_unlink() ,二是看调用处 path 是否可以控制。

通过上面的思路,我们 Ctrl+鼠标左键 点击该函数,发现有三处功能点调用了 my_unlink() 函数。 这里我们发现其中一处 del() 函数调用了该功能点进行文件删除.

上面的176、177行代码需要我们传入两个参数id、url,这里需要看看177行代码处的remove_xs()函数中进行了哪些过滤。

通过上面一系列的过滤最终返回我们过滤后的内容。

我们再接着看代码,我们如果传入id参数,这里的path参数是从数据库中拿到的,我们不能控制。

如果不传入id参数则会走下面的else,在207行代码处判断我们传入的 path 是否在数据库中,如果不在就 会进入208行代码,对我们传入的 $path 进行删除

漏洞复现:

我们看到数据包中的路由其实与我们分析的代码是一样的.

代码语言:javascript
复制
GET /www/index.php?v=del&url=qr_image/mobile.png&m=attachment&f=index&_su=wuzhicms&_menuid=29&_submenuid=52 HTTP/1.1
Host: www.wuzhicms.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,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
Referer: http://www.wuzhicms.com/www/index.php?dir=.%2Fqr_image&m=attachment&f=index&v=dir&_su=wuzhicms&_menuid=29&_submenuid=52
Cookie: PHPSESSID=k652a136tnltn7n1obr88jo5h6; fbp_uid=QO%2BEiNPcY77ztIj3VwL07Q%3D%3D; fbp_username=qPFUCdQQfkRNinLQXE3qZA%3D%3D; fbp_wz_name=CfApQiRkuXByfw7AqHDG5A%3D%3D; fbp_siteid=MCakL%2FitF2Mz8zst4dyFvQ%3D%3D; fbp_userkeys=u0CzDoL6HLYQwPI%2Ffgo2bg%3D%3D
Upgrade-Insecure-Requests: 1

在更目录下创建一个 ceshi.txt 用于测试

成功将test.txt删除。

sql注入(后台)

先直接全局搜索select

通过全局搜索 在这个地方 发现调用了这个函数

然后查看传递的参数 主要传递的是55行这个$where参数 传到了函数

继续看keywords 因为这个没调用函数 但是调用了一个GLOBALS来获取值这里就又要介绍下

在这个文件看见了广告管理的注释

前台sql注入

还是在搜索select的时候 发现在mysql.class文件下有一个函数里面有select 并且后面的拼接也没有任何的过滤

然后我们搜索哪里调用了这个函数 首先是在api目录下的sms_check文件中发现调用了get_one函数 并且参数是通过前面的$code拼接

我们可以看到code 先是通过GLOBALS来获取参数param的值 从前面的介绍可以知道 GLOBALS是可以获取post get的值 这个文件前面没有定义param变量 那么 这个param应该就是post 或者get 就是我们可控的 这也是导致注入的点。

code还通过strip_tags() 函数 而这个函数的作用是剥去html标签 应该是过滤xss吧大概 之后就直接传入了函数 继续更进函数 因为这个文件前面还引入了db类

这个函数应该是调用的这个文件里面的 来到这个文件可以看到这个get-one函数里面 还调用了一个array2sql函数来处理$where 那先来看看这个函数的作用。

可以看到这个get-one函数里面 还调用了一个array2sql函数来处理$where 那先来看看这个函数的作用

可以看到这个函数是用来过滤的 如果是数组 这进入if 把括号 单引号这些过滤掉 不是则走else 过滤 %20 %27 然后返回参数 但是二次编码的就不一样了 因为web服务器只解码一次 如果是二次编码这里的else过滤就起效果 return 调用的get_one 则是最开始看见的mysql.class文件里面了 下面就可以开始直接构造payload了 这里通过代码分析可以看到是单引号闭合。

后台sql注入

从前面两个分析 我发现的注入的地方就存在两个函数中get_list get_one 然后直接全局搜索这两个函数 看看什么地方调用

可以看到 在copyfrom.php中listing函数下调用了这个函数,主要传进去的就一个where 和 page

我们看看where 在if内部 想要进入if 就需要通过GLOBALS获取到keywords 相当于就要传参,这里也可以看出 闭合方式是百分号单引号 %'

我们在来到mysql文件中定义的这个函数 也可以看到 是对where没有过滤处理的 那么 有了前面的基础 直接来构造payload: http://192.168.1.7/wuzhicms/index.php?m=core&f=copyfrom&v=listing&_su=wuzhicms&keywords=%27

rce漏洞

源代码分析:/wuzhicms/coreframe/app/attachment/admin/index.php

当用户传递动态函数sumit时,web程序会引用set_cache()方法,其中M为当前模块名attachment,继续跟进:

cache_path为web服务器的缓存路径目录,filename为缓存文件名,然后通过file_put_contents方法,毫无过滤地将

当对象创建时会调用魔术方法__construct(),然后会引入get_cache()方法,继续分析:get_cache()方法会包含并返回缓存文件,那么就可以造成RCE的问题。

敏感信息泄露

看一看代码,没有做任何处理和限制。

逻辑漏洞

和zzcms2021利用方法是一样的。

通过传参可以调用uc_note类的任意方法:

REF:

https://www.sohu.com/a/529635812_99907709 https://blog.csdn.net/hackzkaq/article/details/125595758 https://www.jianshu.com/p/12d28873d4ee

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-01-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 亿人安全 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 环境搭建
  • 漏洞审计
    • 1.sql注入
      • 漏洞复现:
    • 2.任意文件写入
      • 漏洞复现:
    • 3.csrf
      • 4.目录遍历
        • 5.任意文件删除
          • sql注入(后台)
            • 前台sql注入
              • 后台sql注入
                • rce漏洞
                  • 敏感信息泄露
                    • 逻辑漏洞
                    • REF:
                    相关产品与服务
                    云数据库 SQL Server
                    腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档