之前高校运维碰到的题目, 当时就我一个人输出 web + 自己太菜了, 就没做出来 _(:3」∠)_, 寒假有时间看看, 复现一下题目.
题目非常良心的给了 docker-compose.yml, 所以搭建环境很简单. 把 install.lock 删掉重新装一遍就 ok.
经过一段时间审计, 可以发现 application/collection/controller/collection_content.class.php
中 collection_test
等函数, 实际上未经任何过滤就将 URL 传给了 collection::get_content
.
1/**
2* 添加采集节点
3*/
4public function add() {
5 if (isset($_POST['dosubmit'])) {
6 if (!$_POST['urlpage']) showmsg('网址配置不能为空!');
7 $res = D('collection_node')->insert($_POST);
8 if ($res) {
9 showmsg(L('operation_success'), U('init'), 1);
10 } else {
11 showmsg(L('operation_failure'));
12 }
13 } else {
14 include $this->admin_tpl('collection_node_add');
15 }
16}
17
18public function collection_test() {
19 $id = isset($_GET['id']) ? intval($_GET['id']) : 0;
20 if (!$id) showmsg(L('lose_parameters'));
21 $data = D('collection_node')->where(array('nodeid' => $id))->find();
22 if ($data['urlpage'] == '') showmsg('网址配置不能为空!', 'stop');
23
24 //目标网址
25 if ($data['sourcetype'] == 1) {
26 $url = str_replace('(*)', $data['pagesize_start'], $data['urlpage']);
27 } else {
28 $url = $data['urlpage'];
29 }
30
31 //定义采集列表区间
32 $url_start = $data['url_start'];
33 $url_end = $data['url_end'];
34
35 if ($url_start == '' || $url_end == '') showmsg('列表区域配置不能为空!', 'stop');
36
37 $content = collection::get_content($url);
1public static function get_content($url) {
2 self::$url = $url;
3
4 $content = '';
5 if (extension_loaded('curl')) {
6 $ch = curl_init();
7 curl_setopt($ch, CURLOPT_URL, $url);
8 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
9 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
10 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
11 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
12 curl_setopt($ch, CURLOPT_HEADER, 0);
13 $content = curl_exec($ch);
14 curl_close($ch);
15 } else {
16 $content = @file_get_contents($url);
17 }
18 return trim($content);
19}
很明显的 SSRF, 再结合 nginx 配置.
1location ~ \.php$ {
2 include snippets/fastcgi-php.conf;
3
4 # With php-fpm (or other unix sockets):
5# fastcgi_pass unix:/run/php/php7.3-fpm.sock;
6 # With php-cgi (or other tcp sockets):
7 fastcgi_pass 127.0.0.1:9000;
8}
明显就是 gopher 打 fastcgi 了.
根据 view 里的文字, 可以猜出是采集功能. 用默认账号密码 yzmcms 登录进后台之后在模块管理里面就能找到, 拿 gopherus 一把梭就可以.
然后我去看了眼最新代码 https://github.com/yzmcms/yzmcms
. 仍然没有修复, 怪不得 wp 还没出来 (逃