简述
记一次低版本禅道绕waf getshell。在针对某公司授权攻防项目时,外网有一禅道多年多次多支队伍都没能拿下来,此次缺乏有效突破点,无奈之下决定啃下这块硬骨头。waf策略较严格,利用多个php trick 绕过获得权限。
低版本禅道绕waf
首先进行版本确认,企业版 3.3 版本
首先得说明禅道及各种路径模式, 如果对禅道不熟悉的情况下,使用网上的poc快速检测响应为404 很容易认为漏洞不存在,其实是对应版本和路径模式不了解
不通版本访问路径说明
开源版本访问路径 /zentao
映射文件处理路径 /opt/zbox/app/zentao/www/
专业版 访问路径 /pro
映射文件处理路径 /opt/zbox/app/zentaopro/www/
企业版 访问路径 /biz
映射文件处理路径 /opt/zbox/app/zentaoep/www/
不同pathinfo配置说明
令人眼花缭乱的poc格式
在网上找了一些历史poc,长这样
/api-getModel-api-sql-sql=select+account,password+from+zt_user
仔细研究一下,发现禅道分静态访问和GET方式访问
可以在配置文件 config/my.php
中修改
$config->requestType = 'PATH_INFO';
也可配置都兼容 PATH_INFO|GET
, 其中GET方式为常见的m=module&f=method形式传递模块和方法名,而PATH_INFO则是通过路径和分隔符的方式传递模块和方法名。路由方式及分隔符定义在config/config.php中,
其中,在目标版本的一键安装模式中,使用的是静态访问
/api-getModel-api-sql-sql=select+account,password+from+zt_user
url及参数介绍如下, 通过传参确定进入的control文件为api,对应的method为getModel,接着开始对参数进行赋值,其中moduleName为api,methodName=sql,最后的param为sql=select+account,password+from+zt_user
确认漏洞存在
历史:11.6 版本后台存在多个漏洞,授权用户可通过 module/api/control.php中getModel方法,调用module目录下所有的model模块和方法,从而实现SQL注入、任意文件读取、远程代码执行、文件包含等攻击
确认任意文件写,和任意文件包含两个漏洞存在
任意文件写:当前目录下写test文件。
任意文件包含:包含test文件
这不是轻轻松松getshell
boom,当上传字符出现 <?
php的标签字符时,waf 直接阻拦提示 502
有WAF,采用常规思路
小小WAF能拦住我
采用常规思路
- 分块传输 chunk 编码
- 垃圾字符填充
- url 编码
HTTP/1.1 502 Bad Gateway 响应岿然不动
WAF策略非常严格
常规提权测试
如果可以确认环境,那么本地1比1模拟搭建,降低环境干扰
既然可以写文件,那我就先试试写文件的常规提权操作
这里有一个请求响应给了很大的误导
可以将文件写到 /tmp/
目录,那必然台linux呀
- 定时任务
- .bashrc
- 公钥文件
- ……
全部报错无权限
禅道一键安装版本linux ,推荐目录是 /opt/zbox, 再尝试绝对路径、相对路径,全部返回无权限。
提示也是还是 chmod 777 -R xxxx,暗搓搓嘲讽,你没找对位置
接近绝望时,在源码中找到一个奇怪命名的 x.php
,就想看眼到底啥作用,bingo!
是台windows 机器,安装目录在c盘,采用一键安装版本,。
禅道特性发掘
在确认目标环境后,可以在本地搭建环境,使用白盒角度观察
观察apache 配置 etc/apache/http.conf
文件,针对业务访问路径 biz
,pro
, zentao
配置一致
# setting for zentaoep.
Alias /biz "C:/zentao/xampp/zentaoep/www/"
<Directory "C:/zentao/xampp/zentaoep/www">
Order deny,allow
Allow from all
AllowOverride All
Require all granted
<Files "index.php">
SetHandler application/x-httpd-php
</Files>
.......
</Directory>
<DirectoryMatch "C:/zentao/xampp/zentaoep/www/.+/.*">
<FilesMatch ".+\.ph(p[3457]?|t|tml)$">
SetHandler text/plain
</FilesMatch>
</DirectoryMatch>
关注重点 .htaccess
配置可以覆盖
Options FollowSymLinks:
AllowOverride All:
指定下列文件被当做php解析
<Files "index.php">
SetHandler application/x-httpd-php
</Files>
指定了 index.php、upgrade.php、install.php、checktable.php、api.php、x.php 这几个文件被当作 PHP 文件解析。
其他php 文件只按照文本类型
<DirectoryMatch "/opt/zbox/app/zentaoep/www/.+/.*">
<FilesMatch ".+\.ph(p[3457]?|t|tml)$">
SetHandler text/plain
</FilesMatch>
</DirectoryMatch>
挑战
从这里可以看到两个难点
- 无法使用php标签
<?
- 非指定php文件不会解析
php 标签绕过
php 标签选择
首先需要在标签处进行绕过,先了解背景知识,有哪些php 标签, 是否能使用其他的php标签
- 标准标签(Standard Tags)
<?php ... ?>
- 短标签(Short Tags)
<? ... ?>
需在 php.ini 中开启 short_open_tag=On(PHP 5.3 及之前默认关闭,PHP 5.4+ 默认开启部分功能)
- ASP 风格标签(ASP-style Tags)
ASP 风格标签(ASP-style Tags)
- 使用条件:
- 需在 php.ini 中开启 asp_tags=On
- PHP 7.0 起已完全移除(不再支持)
- Script 标签(Script Tags)
<script language="php"> ... </script>
- 使用条件
- PHP 7.0 起已移除(不再支持)
本地搭建一键安装版,可以看到php 版本为7.0.19 ,无法使用其他标签
编码绕过
可以看到,无其他可选标签,那还有一个办法,编码绕过。
查看php 资料,是否支持其他编码解析
关注 zend.multibyte
配置,在配置 multibyte 为true 后,可以设置 script_encoding
编码
编码可选为 支持多种编码
zend.script_encoding 支持以下编码(取决于 PHP 版本和 mbstring 扩展):
- “UTF-8”
- “SJIS”(Shift-JIS,日文编码)
- “EUC-JP”(日文编码)
- “ASCII”
- “UTF-7” 其他 mbstring 支持的编码(如 “GBK”、”BIG5” 等,实际支持有限)
<
属于ASCII安全字符,在 Python标准库、RFC 2152标准下,<
和 ?
都是原样输出
只有在微软/Outlook/PHP mbstring等“变体”UTF-7实现下,< 可能会被编码为 +ADw-
,> 为 +AD4-
, php script_encoding 就是使用 mbstring 实现,在这里可以绕过 waf 对于 <?
绕过
如何修改特定的编码, 回到 apache 中重点关注配置, htaccess 配置可以覆盖
Options FollowSymLinks:
AllowOverride All:
只要在子目录htaccess 中进行配置,配置环境变量,使php 可以使用utf-7编码解析,绕过waf 检测
php_value zend.multibyte 1
php_value zend.script_encoding "UTF-7"
只要配置中有 .htaccess 就会 502
挑战1
apache 中配置 AccessFileName 来替代 .htaccess, 这里使用 ztaccess ,刚好绕过 waf
# security.
AccessFileName .ztaccess
挑战2
该配置会对当前目录及子目录解析都造成影响,使php 都只能使用utf-7 编码解析,影响正常功能使用
php_value zend.multibyte 1
php_value zend.script_encoding "UTF-7"
找到禅道根htdocs web路径
C:\zentao\xampp\htdocs
- 其中只有一个index.php 关键起效代码使 js 请求跳转到 /biz/ 目录
- 和项目代码属于两个目录,不影响关键代码运行,可以通过
.ztaccess
重复覆盖保证不会影响正常功能使用
在这里定义了最后上webshell 策略
- 覆盖子目录 .ztaccess,修改解析编码为utf-7
- 绕过waf,写入utf-7小马
- 访问小马:落地正常webshell
- 再次覆盖 .ztaccess, 修改编码为utf-8
- 连接webshell
挑战3
apache 配置中限定 其他目录下文件只能以txt进行解析
<DirectoryMatch "/opt/zbox/app/zentaoep/www/.+/.*">
<FilesMatch ".+\.ph(p[3457]?|t|tml)$">
SetHandler text/plain
</FilesMatch>
</DirectoryMatch>
使用 htaceess 覆盖策略
<Files "3.php">
SetHandler application/x-httpd-php
</Files>
webshell 落地上传截图
写入 .ztaccess
写webshell
webshell 上线