0x00前言
MyBB是一种非常流行的开源论坛软件。然而,即使是一个流行的工具也可能包含可能导致整个系统崩溃的错误或错误链。在本文中,我们将介绍远程代码执行漏洞利用链。
0x01可视化编辑器持久XSS
(cve-2022-43707)
不久前,同事发表了一篇文章"通过嵌套解析器对XSS进行模糊测试"。在这篇文章中,他给出了多个XSS攻击的例子,其中一个在MyBB中。MyBB团队在1.8.25版本中修正了Igor给出的有效载荷。但我并没有止步于此——我继续开始模糊测试!
首先,具有低权限的注册用户在设置中编辑他的签名。在“View Source”模式下将以下有效负载插入编辑器:
[email][email= onpointerover=alert()//]text[/email]
(将带有xss的有效载荷插入到用户签名中)
在更新签名之后,链接有一个新的onpointer事件处理程序,值为alert();//。当您将鼠标光标悬停在呈现的文本上时,将执行嵌入的JavaScript代码。
(当鼠标悬停在用户签名上时,执行用户签名中嵌入的javascript代码)
因此,如果属于“Moderator”或“Administrator”组的用户在签名部分输入实现上述有效负载的用户的配置文件,那么,当该用户将鼠标光标悬停在呈现的文本上时,嵌入的JavaScript代码也将被执行。
(当管理员将鼠标悬停在鼠标光标上时编辑用户签名时执行嵌入的javascript代码)
属于“Administrator”组的用户在通过Admin CP: /admin/index.php?module=user-users&action=search搜索用户时,可以执行SQL注入。
默认情况下,自定义字段容易受到SQL注入的攻击:Location, Bio, Gender
(搜索用户时自定义字段)
为了演示该漏洞,将对自定义Bio字段执行搜索。为此,用户需要向自定义Bio字段添加文本,以便搜索至少返回一条记录。
在这里,“My biography”值将添加到“Administrator”组中的用户的自定义Bio字段。
(填写自定义生物字段)
通过带有My biography的自定义字段Bio发出搜索用户的请求,该请求使用代理(例如BurpSuite)拦截。
(通过自定义生物字段搜索用户)
用户搜索查询由自定义Bio字段拦截。
(通过代理截获的用户搜索请求)
SQL注入的一个脆弱位置是profile_fields数组的键。
profile_fields[fid2]=My biography
如果在fid2后添加单引号,服务器将返回错误“HTTP/1.1 503服务暂时不可用”。
(将单引号添加到通过代理截获的用户搜索请求中的自定义Bio字段的键中)
SQL注入的发生是由于从用户传输的数据没有完全控制/转义。问题的根源是admin/modules/user/users.php文件,即如何处理column变量的值。这个column变量的值应该用双引号框起来,或者检查是否为有效值。
(用户数据转义不足,导致SQL注入)
由于缺少检查column变量的哪些值是允许的,可以在不使用特殊字符的条件下实现SQL注入,这些特殊字符将由db->escape_string方法转义。
' AND '.$db->escape_string($column)."
将查询执行延迟5秒的SQL注入的有效负载:
profile_fields[(select pg_sleep(5))::text = $quote$$quote$ and fid2]=My biography
(SQL注入,这会导致执行SQL查询再休眠5秒)
在SQL注入发现的帮助下,可以升级这个问题。如果在安装MyBB时选择了支持多个查询的数据库引擎,就会发生这种情况。
安装时需要选择PostgreSQL。
(安装论坛引擎时,数据库配置中选择PostgreSQL)
当使用PostgreSQL数据库引擎时,发现的SQL注入将通过inc/db_pgsql.php文件中的原生pg_send_query函数执行。
(在使用Postgresql时调用本机函数pg_send_query)
根据PHP官方文档,pg_send_query函数可以一次执行多个查询。
(本机pg_send_query函数的官方文档)
现在让我们谈谈如何在MyBB中创建和编辑模板。
(模板编辑功能)
上图显示了模板member_profile_signature的编辑形式。
在创建或编辑模板时,也可以插入变量值,例如,{lang→users_signature}, {memprofile['signature']}。
模板保存在数据库的mybb_templates表中。在本例中,编辑的模板member_profile_signature的tid = 240。
(用户签名模板存储在数据库中)
在文件member.php中,模板member_profile_signature从数据库的第2158行中获取,并传递给eval函数。
(使用用户签名模板在服务器上执行代码)
有人可能会认为,在创建/编辑模板时,";${system('id')}结构可能被注入到eval函数中(member.php的第2158行),并表示一个单独的指令,该指令也将被执行。
然而,这是不可能的。在将模板保存到数据库之前,将在admin/modules/style/templates.php的536行中调用check_template函数。
(保存模板时,调用check_template函数)
check_template函数的目的是通过eval函数检查用户传递的模板中是否存在允许在系统中执行任意代码的结构。
(check_template函数是一个沙盒,可以防止在模板中引入危险结构)
如果check_template函数在检查时发现危险结构,则返回true并发生保存错误。
(结果是 check_template
函数是一个安全错误)
如果你设法以某种方式将结构";${system('id')}嵌入到模板中,绕过check_template函数,你将能够在服务器上执行任意代码。
现在我们回到MyBB中的SQL注入,它使用PostgreSQL进行多查询。在SQL注入期间使用单引号或双引号将导致它们的转义:
' AND '.$db->escape_string($column)."
将需要的构造重写为member_profile_signature模板而不使用单引号的SQL查询:
update mybb_templates set template = (select concat((select template from mybb_templates mt where mt.tid = 240),(select CHR(34)||CHR(59)||CHR(36)||CHR(123)||CHR(115)||CHR(121)||CHR(115)||CHR(116)||CHR(101)||CHR(109)||CHR(40)||CHR(39)||CHR(105)||CHR(100)||CHR(39)||CHR(41)||CHR(125)))) where tid = 240;
然后,最终的SQL注入将具有导致在系统中执行任意代码的表单。
(在多查询模式下执行SQL注入,第二次查询覆盖用户签名模板,注入恶意代码)
结果是执行system('id')命令。
(服务器上的RCE通过SQL注入绕过模板沙盒函数)
漏洞修复可以在MyBB官方网站上找到。
0x03参考链接
https://mybb.com/versions/1.8.32/
https://github.com/mybb/mybb/security/advisories/GHSA-ggp5-454p-867v
https://github.com/mybb/mybb/security/advisories/GHSA-6vpw-m83q-27px
推荐阅读: