Path: blob/master/modules/auxiliary/scanner/mysql/mysql_schemadump.rb
19848 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45require 'yaml'67class MetasploitModule < Msf::Auxiliary8include Msf::Exploit::Remote::MYSQL9include Msf::Auxiliary::Report10include Msf::Auxiliary::Scanner11include Msf::OptionalSession::MySQL1213def initialize14super(15'Name' => 'MYSQL Schema Dump',16'Description' => %Q{17This module extracts the schema information from a18MySQL DB server.19},20'Author' => ['theLightCosine'],21'License' => MSF_LICENSE22)2324register_options([25OptBool.new('DISPLAY_RESULTS', [true, "Display the Results to the Screen", true])26])27end2829def run_host(ip)30# If we have a session make use of it31if session32print_status("Using existing session #{session.sid}")33self.mysql_conn = session.client34else35# otherwise fallback to attempting to login36return unless mysql_login_datastore37end3839mysql_schema = get_schema40mysql_schema.each do |db|41report_note(42:host => mysql_conn.peerhost,43:type => "mysql.db.schema",44:data => { :database => db },45:port => mysql_conn.peerport,46:proto => 'tcp',47:update => :unique_data48)49end50output = "MySQL Server Schema \n Host: #{mysql_conn.peerhost} \n Port: #{mysql_conn.peerport} \n ====================\n\n"51output << YAML.dump(mysql_schema)52this_service = report_service(53:host => mysql_conn.peerhost,54:port => mysql_conn.peerport,55:name => 'mysql',56:proto => 'tcp'57)58p = store_loot('mysql_schema', "text/plain", mysql_conn.peerhost, output, "#{mysql_conn.peerhost}_mysql_schema.txt", "MySQL Schema", this_service)59print_good("Schema stored in: #{p}")60print_good output if datastore['DISPLAY_RESULTS']61end6263def get_schema64mysql_schema = []65res = mysql_query("show databases")66if res.size > 067res.each do |row|68next if row[0].nil?69next if row[0].empty?70next if row[0] == "information_schema"71next if row[0] == "mysql"72next if row[0] == "performance_schema"73next if row[0] == "test"7475tmp_db = {}76tmp_db['DBName'] = row[0]77tmp_db['Tables'] = []78tmp_tblnames = get_tbl_names(row[0])79unless tmp_tblnames.nil? or tmp_tblnames.empty?80tmp_tblnames.each do |table_name|81tmp_tbl = {}82tmp_tbl['TableName'] = table_name83tmp_tbl['Columns'] = []84tmp_clmnames = get_columns(tmp_db['DBName'], table_name)85unless tmp_clmnames.nil? or tmp_clmnames.empty?86tmp_clmnames.each do |column|87tmp_column = {}88tmp_column['ColumnName'] = column[0]89tmp_column['ColumnType'] = column[1]90tmp_tbl['Columns'] << tmp_column91end92end93tmp_db['Tables'] << tmp_tbl94end95end96mysql_schema << tmp_db97end98end99return mysql_schema100end101102# Gets all of the Tables names inside the given Database103def get_tbl_names(dbname)104tables = []105res = mysql_query("SHOW tables from #{dbname}")106if res.size > 0107res.each do |row|108next if row[0].nil?109next if row[0].empty?110111tables << row[0]112end113end114return tables115end116117def get_columns(db_name, tbl_name)118tables = []119res = mysql_query("desc #{db_name}.#{tbl_name}")120if res.size > 0121res.each do |row|122next if row[0].nil?123next if row[0].empty?124125tables << [row[0], row[1]]126end127end128return tables129end130end131132133