YCCMS 3.4代码审计
环境搭建
下载地址:https://www.jb51.net/codes/716819.html#downintro2
环境:
- php5.6.9
- MySQL5.7.26
- Apache2.4.39
下载后将文件夹放到phpstudy下的WWW目录下
导入yccms.sql到本地数据库:
接着修改config配置(将数据库名、用户名、密码填入其中):
然后就可以开始审计了
分析框架
第一步依然是分析框架,先看目录结构:
1 | /Admin 后台路径首页,包含/config/run.inc.php文件 |
这里自定义的MVC框架,所以我们优先考虑/controller和/model
XSS
第一处
定位到compile/%25%25D8^D83^D83C04B9%25%25createhtml.tpl.php:
没有任何过滤:
1 | http://127.0.0.1/compile/%25%25D8%5ED83%5ED83C04B9%25%25createhtml.tpl.php?a=html&m=arts&send=%E5%BC%80%E5%A7%8B%E7%94%9F%E6%88%90&art=<script>alert(1)</script> |
第二处
功能点在于文章列表处
定位到controller\ArticleAction.class.php文件:
添加文件功能并没有将我们的输入转义
文章列表显示时也并没有转义,所以可以直接XSS:
命令执行
关键点:绕过file_exists函数
定位到/public/class/Factory.class.php:
首先该代码类名为Factory{},eval在setAction方法中,通过调用self::getA方法获取参数a,接着看是否有admin权限,然后file_exists()函数检查文件路径是否存在,最后调用eval()执行php代码eval('self::$_obj = new '.ucfirst($_a).'Action();');
这里如果我们要执行eval函数,就得绕过file_exist函数验证,但这个函数是有漏洞的,比如/controller/admin;/../,函数允许路径中有一些特殊字符,并且遇到/../会返回到上级目录,可以利用这个策略逃逸出 file_exists()函数检查。所以直接绕过:
1 | Factory();phpinfo();//../ |
Factory()是为了闭合前面的
self::$_obj = new防止报错
接着我们看哪里调用了该方法:
/config/run.inc.php文件调用了:
接着找哪里包含了该文件/config/run.inc.php:
admin\index.php:
1 | http://127.0.0.1/admin/index.php?a=Factory();phpinfo();//../ |
count.php直接构造:
1 | http://127.0.0.1/config/count.php?a=Factory();phpinfo();//../ |
search/index.php:
1 | http://127.0.0.1/search/index.php?a=Factory();phpinfo();//../ |
任意目录文件删除
第一处
定位到controller\PicAction.class.php文件:
pid为删除的图片文件名,这里可以通过路径遍历实现任意文件删除,先创建一个文件测试:
其功能点对应于删除图片功能:
抓包修改:
文件成功删除
第二处
功能点在于清空目录:
定位到\controller\NavAction.class.php:
可以看到navname为要删除清空的目录名,且没有任何过滤,创个文件用于测试:
抓包修改:
成功删除
未授权修改管理员密码
看一下管理员密码修改对应的路由文件:
可以看到这里并没有对用户身份进行验证,所以可以直接更改:








































