记一次对wuzhicms的审计

VSole2022-03-14 10:23:03

前言

在网上漫游发现的一个cms cnvd也是有提交的

也是初次审计这种

官网:https://www.wuzhicms.com/

现在也已经好像没更新了

也是先看了一会代码 才知道这是MVC的 之前由于也没有了解过MVC 就很懵

开始啥都没看懂

后来经过百度 和 求助了一波团队的时候 总算是有一点点明白了 能把代码走动

MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中。(百度的)

而在之后的路径中会看见m f v这几个参数

m就是文件夹 f就是文件 v就是方法

就先大概介绍这些

下面开始审计

sql注入肯定是容易找的 就先找sql注入了

工具:seay phpstorm phpstudy

第一处 sql注入(可惜是后台的)

先直接全局搜索select

这个函数 展示没有发现有过滤

然后找哪里调用了这个函数

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

然后查看传递的参数

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

然后我们看$where参数的组成 里面有两个变量$siteid $keywords

我们是可能可控的

先看$keywords 因为这个没调用函数 但是调用了一个$GLOBALS来获取值

这里就又要介绍下$GLOBALS 因为刚开始我也没懂这个是怎么用来获取值的 知道我百度一阵之后

和代码翻翻之后 在一个文件中发现了

这个cms用$GLOBALS来获取全部的变量 直接把GET POST代替了

具体怎么代替的就不跟进解释了 一句话 就是$GLOBALS可以取到get post的传的值

那么这个keywords 前面又没有定义变量啥的 大概率是 传参的 (后面经过验证 也的确如此)

那另一个参数就不用看了 就先控制这个参数才进行注入了

有了可控参数 现在就需要找到整个payload了

可能熟悉MVC的师傅 就知道该怎么构造payload了 但我没学过MVC 也不了解 就只能用其他方式来找了

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

那我就去后台找这个功能了

又因为调用的函数是search嘛 那就是这个搜索框 八九不离十了

直接输入1 然后搜索 但是这样看不出来

就输入1然后抓包 看看包了

好了 这样路径参数什么的也出来了

就全部复制到url

然后构造

payload :SELECT COUNT(*) AS num FROM wz_promote_place WHERE siteid=’1’ AND name LIKE ‘%1%’ or extractvalue(1,concat(0x7e,(select database())))%23

闭合%‘%23

这里我尝试了下 盲注 和报错都是可以的


如果现在到过头来看 就一个简单的搜索框的注入没什么花里胡哨的 过滤也没 但审计来看 还是绕了一大圈子

第二处 前台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

那先来看看这个函数的作用

可以看到这个函数是用来过滤的

如果是数组 这进入if 把括号 单引号这些过滤掉

不是则走else 过滤 %20 %27

然后返回参数

但也就是这个过滤的地方 没有防护到位

我们传的参数不是数组 所以就没有走if

而else里面过滤的却是 %20 %27

我们传参的时候尽管是经过url编码的 但是web服务器会自动解码一次 所以 我们传到后端代码处的时候是没有进行url编码 相当于

但是二次编码的就不一样了 因为web服务器只解码一次

如果是二次编码这里的else过滤就起效果

return 调用的get_one 则是最开始看见的mysql.class文件里面了

下面就可以开始直接构造payload了 这里通过代码分析可以看到是单引号闭合


单引号报错

闭合显示正常页面

就进行盲注

我用的报错

payload:[http://192.168.1.7/wuzhicms/api/sms_check.php?param=1%27+or%20extractvalue(1,concat(0x7e,(select%20database())))%23](http://192.168.1.7/wuzhicms/api/sms_check.php?param=1'+or extractvalue(1,concat(0x7e,(select database())))%23)

第三处 后台sql注入

从前面两个分析 我发现的注入的地方就存在两个函数中get_list get_one

然后直接全局搜索这两个函数 看看什么地方调用

可以看到 在copyfrom.php中listing函数下调用了这个函数

然后我们网上分析 看看什么是可控的

主要传进去的就一个$where 和 $page

可以看到page会被intval()函数 转化为整数 所以我们不考虑它

我们看看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

报错了 直接插入报错注入的

payload:http://192.168.1.7/wuzhicms/index.php?m=core&f=copyfrom&v=listing&_su=wuzhicms&keywords=1%%27%20or%20extractvalue(1,concat(0x7e,(select%20database())))%23

第四处 后台任意文件删除

通过全局搜索unlink函数 来找文件删除

在这个文件下找到一个删除文件的函数 然后我们继续找哪里调用了这个函数

还是在这个文件 找到了一个del函数 里面调用了删除文件的函数

然后来分析调用的过程 调用删除的时候通过把$path和ATTACHMENT_ROOT 拼接

而ATTACHMENT_ROOT是前面定义的一个默认路径

path则是前面的$url 来的

在看前面的if 如果path有值则进入到if里面 然后经过的数据库的get_one查询操作 应该这里是要查出一个东西

但是因为我数据库是空的 则进入的是第一个if里面 哪怕是查出1条 也是可以的

这里也没有其他过滤

然后网上看url的来源

GLOBALS 那就可以直接通过传参的 前面也介绍了 id为空的话 也就进入到了else里面

到这里也就可以构造payload了

先在根目录下创建一个文件

然后构造

http://192.168.1.7/wuzhicms/index.php?m=attachment&f=index&v=del&_su=wuzhicms&url=../1.txt

这里我把最终删除的路径 打印了出来

文件也是成功删除

第五处 后台任意文件上传

直接搜索file_put_contents函数

在set_cache函数下发现写入文件的函数 $data并且没有过滤是直接通过参数传过来的

然后全局搜索 在哪里调用了这个函数

这个set函数下调用了这个函数

并且写入文件的内容是可控的

通过打印 知道了 写入的路径 文件名

并且这里也没有过滤

直接构造payload

然后访问文件

后面又发现一个函数调用的set_cache

过程是一样的 基本上 就没有演示了

这里还要注意一点 这里是写入的缓存文件 不是一直存在的 我重启之后 写入的内容就还原了

应该是还有的 就没有继续找这个了

第六处 信息泄露

最后在后台页面发现一出phpinfo

一个垃圾的信息泄露

最后

肯定还有审漏的

经过这个cms的审计过后 对MVC这种框架的也有了基本的认识了 以后遇到也不至于这样的无厘头 不知道怎么搞路由 怎么调用的

有了一个新的开始

如果此文有什么不对点 师傅们指出 学习学习 这也是继前面几篇之后新的一次尝试把 但回过头来看这个cms 也就因为mvc 所以调用的时候不同 其他的点 漏洞的地方还是规规矩矩 大差不差的和以前的比较的话

函数调用payload
本作品采用《CC 协议》,转载必须注明作者和本文链接
Latte-SSTI-Payloads总结
2021-12-14 16:56:16
TL;DR最近西湖论剑有一道使用Latte的题目,当时我也是用的偷鸡办法做的,当时时间限制就没有仔仔细细的去寻找逃逸的办法。直到赛后我发现逃逸的办法很简单{="${system}"}. 这里使用的是php的基础语法,我就不过多赘述了。这个复杂变量网上也有很多文章。赛后我无聊的时候简单看了下Latte,找了点后续的利用,比如获取$this变量,还有任意代码执行。
就需要了解一下名称空间python的名称空间,是从名称到对象的映射,在python程序的执行过程中,至少会存在两个名称空间。python中一切均为对象,均继承于object对象,python的object类中集成了很多的基础函数,假如我们需要在payload中使用某个函数就需要用object去操作。
利用该漏洞可能会授予对 MOVEit Transfer 数据库的未经授权的访问,从而允许攻击者操纵和泄露敏感信息。变量,则很容易受到 SQL 注入攻击。有了这种理解,研究人员重点转向寻找一种绕过清理并以未经清理的方式操纵 Arg01 参数的方法,因此了解 MOVEit 软件如何处理请求非常重要。由于与未经身份验证的操作相关而脱颖而出。
BurpCrypto在Web渗透测试中有一个关键的测试项:密码爆破。使用方法BurpCrypto安装完成后会在BurpSuite中添加一个名为BurpCrypto的选项卡,打开选项卡可进入不同加密方式的具体设置界面。找的密文对应的明文BurpSuite中有一个饱受诟病的问题,在测试器的测试结果中,无法显示原始Payload,也就是字典内容。因为Java内置的JavaScript不包含浏览器中的window、document、console等API,不过好在此类组件一般不会对加密的核心功能造成影响,但是还是需要将调用此类组件的相关代码进行删除或者调整。
CVE-2021-24086漏洞分析
2022-07-19 16:41:30
漏洞信息2021年,Microsoft发布了一个安全补丁程序,修复了一个拒绝服务漏洞,编号为CVE-2021-24086,该漏洞影响每个Windows版本的IPv6堆栈,此问题是由于IPv6分片处理不当引起的。
恶意软件为了规避沙盒检测使用了各种各样的方法,API Hammering 不会是最后一个,以后也会有各种各样的变种。
CS-Shellcode分析(一)
2021-10-18 08:21:57
本文是CS的shellcode分析的第一篇文章,该系列文章旨在帮助具有一定二进制基础的朋友看懂cs的shellcode的生成方式,进而可以达到对shellcode进行二进制层面的改变与混淆,用于免杀相关的研究。执行后可以得到shellcode的原始文件然后我们再用IDA打开这个文件进行分析:先看第一个call的内容这里pop rbp?
WebSocket 测试入门篇
2023-02-08 15:56:52
这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而 HTTP 请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。浏览器通过 JavaScript 向服务器发出建立 WebSocket 连接的请求,连接建立以后,客户端和服务器端就可以通过 TCP 连接直接交换数据。
最近写了点反序列化的题,才疏学浅,希望对CTF新手有所帮助,有啥错误还请大师傅们批评指正。php反序列化简单理解首先我们需要理解什么是序列化,什么是反序列化?本质上反序列化是没有危害的。但是如果用户对数据可控那就可以利用反序列化构造payload攻击。
一般情况下,SSRF针对的都是一些外网无法访问的内网,所以需要SSRF使目标后端去访问内网,进而达到我们攻击内网的目的。
VSole
网络安全专家