Zabbix 2.2.x, 3.0.x SQL注射漏洞

  • 发表于
  • Vulndb

zabbix1

0x01 背景

昨晚zabbix这个高危漏洞又在朋友圈炸开锅了,这篇是根据POC对zabbix3.0.3的源码进行了粗浅的分析。
注入产生的流程:

0x02 漏洞分析

根据网上提供的POC:

jsrpc.php?type=9
&method=screen.get
&timestamp=1471403798083
&pageFile=history.php
&profileIdx=web.item.graph
&profileIdx2=1+or+updatexml(1,md5(0x11),1)+or+1=1)%23
&updateProfile=true
&period=3600
&stime=20160817050632
&resourcetype=17

我们可以找到漏洞文件jsrpc.php,为了方便阅读,去掉了跟本次漏洞无关的代码:
/zabbix-3.0.3/frontends/php/jsrpc.php

然后我们看到是调用了CScreenBuilder类的getScreen($data)方法来处理$data数据,我们跟进,发现首先调用了个构造方法初始化数据
/zabbix-3.0.3/frontends/php/include/classes/screens/CScreenBuilder.php

这里就有对profileIdx2参数的操作了,但是还是没有insert注入语句,我们看到最后调用了CScreenBase类的calculateTime方法并把profileIdx2传进去了,跟进
/zabbix-3.0.3/frontends/php/include/classes/screens/CScreenBase.php

这里再次引入了一个类CProfile并调用update方法将profileIdx2带入到更新操作里了,没有insert语句没关系,我们先跟进CProfile类的update函数。
/zabbix-3.0.3/frontends/php/include/classes/user/CProfile.php

发现这里只是对$profiles变量做了更新操作,当然profileIdx2参数也赋值进去了,这里是没有insert注入操作的。我们再回到最开始的jsrpc.php,这里最后引入了page_footer.php

我们再跟进page_footer.php,发现调用了CProfile类的flush方法如下:

我们跟进flush方法:

发现执行了insert语句造成注入漏洞,至此粗浅的漏洞分析完了。

0x03 漏洞证明

@寂寞的瘦子 表弟搭建了zabbix3.0.3的测试环境,使用了XPATH注入,证明如下:

zabbix2

0x04 漏洞修复

暴力的修补方法是对CProfile类的flush方法中注入参数做强制整形转换即可

跟佳佳沟通了下,发现一个更好的修复方法就是使用zabbix自己的过滤函数zbx_dbstr,我们看下这个函数:

使用mysqli_real_escape_string对单引号等特殊字符进行转义,并且加上单引号保护保证万无一失~
所以这里更优的修复方法是将上面intval函数换为zbx_dbstr。

漏洞来源:http://seclists.org/fulldisclosure/2016/Aug/82
相关漏洞:https://www.exploit-db.com/exploits/40237/