问答
发起
提问
文章
攻防
活动
Toggle navigation
首页
(current)
问答
商城
实战攻防技术
漏洞分析与复现
NEW
活动
摸鱼办
搜索
登录
注册
cms审计集
漏洞分析
大概是倒数的php CMS漏洞复现审计文章了...
youdiancmsv9.0 -------------- 上次一个项目遇到了该cms二开之后的系统,注释里面标明了是该系统,v9.2的,当时下载了源码去审,没有审出来东西,找了不少低版本的poc,都没打成功,那就先审审低版本的,争取把新版本的给拿下来。 ### write webshell 漏洞点位于后台模板管理-》任一模板文件  `App\Lib\Action\Admin\TemplateAction.class.php#68`  先调用了YdInput类中的`checkFileName`方法对传入的文件名进行了处理,跟进,代码很短,检查文件名不能出现的特殊字符并且替换为空 ```php static function checkFileName($str){ $str = str_replace('..', '', $str); return $str; } ``` 接着调用`ltrim`方法去除文件名开头的空白字符之后拼接成完整的文件路径,接着调用了本类中的`isValidTplFile`方法对模板文件进行校验;可以看到主要的手段就是通过限制文件名的后缀,先进行大小写转换之后再进行白名单检测  后面会调用`htmlspecialchars_decode`进行实体编码的解码,这里不影响写入的`shell`,然后就是调用`file_put_contents`将文件的所有内容写入到模板文件当中;写入的`html`文件本身就会被包含,所以其中的`php`代码就会被`php`解析器执行   Kitecms ------- ### write webshell 以前打比赛的经验,搜索危险函数,`file_put_contents`,这里定位到了这个位置 `application\admin\controller\Template.php#25`  调用Request类中的`param`方法进行获取`path`参数,这里实例化了`Site`类的对象赋值给了`$siteObj`参数,并且调用了类中的方法去数据库中进行查询,这里`$template`的值从数据库中取到值为`default` 经过处理之后的`$rootpath=root_path/theme/default/$path`,`root_path`的值为即是网站根目录下,`$path`路径为可控点 ```php if (!file_exists($rootpath) && !preg_match("/theme/", $rootpath)) { throw new HttpException(404, 'This is not file'); } ``` 这里对处理之后的路径进行校验,必须存在并且路径中包含有`/theme/`,不然就会抛出相应的异常 接着往下  POST有传参就满足条件,接着会调用`is_write`方法对指定路径下的文件进行可写权限判断,如果可写就会调用`file_put_contents`方法,将调用`htmlspecialchars_decode`方法进行实体解码之后的输入内容写入到$rootpath文件当中,实体解码对于我们的`shell`并没有影响,并且前面对路径进行了拼接处理,这里就可以进行路径穿越将`shell`写入到指定的文件当中去 poc ```php POST /admin/template/fileedit HTTP/1.1 Host: localhost 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 Referer: http://localhost/admin/template/fileedit Content-Type: application/x-www-form-urlencoded Content-Length: 44 Origin: http://localhost Connection: close Cookie: PHPSESSID=r0mbjo57rneu1l81c79rbf12e0 Upgrade-Insecure-Requests: 1 Sec-Fetch-Dest: document Sec-Fetch-Mode: navigate Sec-Fetch-Site: same-origin path=../../index.php&html=<?php phpinfo();?> ```   ### any file reading `application\admin\controller\Template.php` 还是一样的位置,接着往下看  只要不是以`post`传参,就会校验指定文件可读权限,如果可读就会调用`file_get_contents`读取,这里一样可以结合目录穿越进行任意文件读取 poc ```php ?path=../../filename ```  ### upload getshell 系统=>上传处这里可以增加上传的图片类型,之前的小结文章中也有提到过这种getshell的后台  之后看到站点=》新建,这里可以开启新建文件,并且可以上传文件,之后抓包跟进代码 `application\admin\controller\Upload.php`  Request类中的file方法获取到上传的文件的所有信息,后面实例化UploadFile类并调用类中的upload方法,跟进 `application\common\model\UploadFile.php#127`,根据传入的fileType=image,只看相关的代码就可以了,这里先看一下默认的图片上传配置  `config\site.php`中的默认配置没有更改,前面增加的上传后缀php实际上是有生效的  接着跟进check方法,`thinkphp\library\think\File.php#226`  可以看到这里判断判断条件为或,只要有一个为`true`那么就会为真,而我们的目的是返回true,也就是if条件判断不能成立;这里`$rule`数组中只有两个键值对,而文件大小是肯定满足的,所以只需要检查后缀就可以了,这里通过调试输出,`$rule['ext'] == 'jpg,png,gif,php'`,上传`php`文件肯定是成立的,所以下面只需要跟进`checkImg`方法  这里还是要返回值为`true`,因为上传的文件后缀是`php`,所以肯定不在数组中,第一个`in_array`返回值为`false`,这里为与逻辑,所以`if`判断恒不成立,返回`true`,所以最后`check`方法返回`true`,那么`shell`文件就上传成功了   PS -- youdianCMS一直在更新中,漏洞均已修复;kitecms已经挺多年没有更新了,官网关站,文中的漏洞均在GitHub的issue中,作者已知悉但未推出迭代版本并且没有使用群体。
发表于 2022-01-05 09:40:34
阅读 ( 6376 )
分类:
漏洞分析
0 推荐
收藏
0 条评论
请先
登录
后评论
joker
19 篇文章
×
发送私信
请先
登录
后发送私信
×
举报此文章
垃圾广告信息:
广告、推广、测试等内容
违规内容:
色情、暴力、血腥、敏感信息等内容
不友善内容:
人身攻击、挑衅辱骂、恶意行为
其他原因:
请补充说明
举报原因:
×
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!