CVE-2024-36412 SuiteCRM未授权sql注入分析

SuiteCRM是一个开源的客户关系管理(CRM)软件应用程序。在版本7.14.4和8.6.1之前存在未授权SQL注入漏洞,本文对CVE-2024-36412这个漏洞进行复现和分析,以及注入点的特殊性做了解释。

漏洞简介

SuiteCRM是一个开源的客户关系管理(CRM)软件应用程序。在版本7.14.4和8.6.1之前存在未授权SQL注入漏洞。

漏洞复现

下载SuiteCRM 7.14.3,解压放在web目录,访问/install.php进行安装,配置完mysql和web管理员账号密码,点击next安装完后会自动跳转登录页面。

image.png

发送下面poc

GET /SuiteCRM-7.14.3/index.php?entryPoint=responseEntryPoint&event=1&delegate=<"+UNION+SELECT+SLEEP(3);--+&type=c&response=accept HTTP/1.1
Host: 192.168.1.100
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0.3 Safari/605.1.15
Accept-Encoding: gzip
Connection: close
Cookie: XDEBUG_SESSION=XDEBUG_ECLIPSE
Conent-Length: 2

成功延时3秒后返回

image.png

漏洞分析

调用堆栈

MysqliManager.php:142, MysqliManager->query()
MysqlManager.php:285, MysqlManager->limitQuery()
DBManager.php:1659, DBManager->getOne()
responseEntryPoint.php:24, require_once()
SugarController.php:1017, SugarController->handleEntryPoint()
SugarController.php:465, SugarController->process()
SugarController.php:361, SugarController->execute()
SugarApplication.php:101, SugarApplication->execute()
index.php:52, {main}()

SugarController::process方法下断点,可以看到会遍历$process_tasks数组中的6个proccess进行处理,并通过$_processed判断是否处理完成。

image.png
遍历到handleEntryPoint,跟进对应方法,会根据传入的entryPoint参数从entry_point_registry中获取对应的php文件进行包含。

image.png
跟进包含的modules/FP_events/responseEntryPoint.php文件,可以看到将get请求获取到的delegate参数直接拼接到了sql语句并执行,这就导致了sql注入。

image.png

为什么需要<符号?

细心的同学会发现,POC中的sql语句前面有一个<字符,这是必须的吗?没错,是必须的

如果去掉<符号,用"+UNION+SELECT+SLEEP(3);--+这样的payload请求,并没有延时返回。

image.png
调试代码可以看到,responseEntryPoint.php文件中通过$_GET获取到的$delegate_id变成了&quot;,被html实体编码了,这就导致无法闭合sqli语句前面的双引号,导致sql注入失败。

image.png

为什么加上<之后,不会被html实体编码,而不加<却会被html实体编码?

这是由于系统的全局xss过滤机制在做怪!

访问index.php会包含entryPoint.phpentryPoint.php会调用utils.phpclean_incoming_data来清理所有的请求参数,包括xss的清理,堆栈如下

utils.php:2639, securexss()
utils.php:2520, array_map()
utils.php:2520, clean_incoming_data()
entryPoint.php:93, require_once()
index.php:47, {main}()

image.png

在securexss方法下断点,使用<"+UNION+SELECT+SLEEP(3);-- 请求,可以看到会通过$xss_cleanup这个数组来过滤xss的关键符号,经过过滤后的payload变成了&lt;&quot; UNION SELECT SLEEP(3);-- ,这时<都被html实体编码了。

image.png

如果到这里直接返回编码后的字符串$partialString,sql注入将不会存在,但是这里还交给了AntiXSS做进一步的过滤,看下再经过AntiXSS过滤后的结果。

image.png
&quot;又变回了,这就导致了单引号逃逸。

跟进xss_clean方法看看怎么回事儿,主要逻辑都在AntiXSS.php文件,处理路由在\\voku\\helper\\AntiXSS::_do,调用_decode_string会先html解码。

image.png

走到_sanitize_naughty_html会通过正则匹配标签开头如<、标签内容、标签结尾如>,然后将匹配的数组传入_close_html_callback

image.png

_close_html_callback把标签内容部分的<> html实体编码,标签内容部分是"+UNION+SELECT+SLEEP(3);--,前面再拼接一个&lt;

image.png
_do方法处理后,会比较xss处理前和处理后的字符串是否相等,如果不相等,则将_xss_found标记为true,否则为false

image.png

所以传入<” 经过str_replace后变成&lt;&quot; ,再经过_do方法会变成&lt;"并返回

如果传入不包含<,经过str_replace后变成&quot;,再经过_do方法处理后_xss_foundfalse,即处理前和处理后字符串没变化,则保留原有的&quot;返回。

image.png
这就解释了为什么传入<”能注入而注入不了。

流量对抗

前面提到AntiXSS的_decode_string方法会对参数做html解码,所以可以AntiXSS对参数解码的特性对payload做一些变形,html编码+url编码SELECT关键字效果如下

image.png

漏洞修复

对比最新版7.14.4,在responseEntryPoint.php中增加了$db->quote()来防止sql注入

image.png
官方7.14.4版本的更新公告中同时也修复了其他的漏洞,本次修复的其他sql注入漏洞利用方式跟本文分析的大同小异,就不做赘述。

  • 发表于 2024-08-08 09:40:45
  • 阅读 ( 1196 )
  • 分类:CMS
  • 举报

1 条评论

bmjoker
学到了