Adds the new SNMP mixin, still not working perfectly, but a good start

git-svn-id: file:///home/svn/framework3/trunk@6530 4d416f70-5f16-0410-b530-b9f4589650da
unstable
HD Moore 2009-05-08 04:18:31 +00:00
parent 6b5893f1f0
commit 8f63fc27e3
4 changed files with 101 additions and 5 deletions

View File

@ -233,6 +233,7 @@ class Exploit < Msf::Module
require 'msf/core/exploit/dcerpc'
require 'msf/core/exploit/sunrpc'
require 'msf/core/exploit/mssql'
require 'msf/core/exploit/snmp'
require 'msf/core/exploit/arkeia'
require 'msf/core/exploit/ndmp'
require 'msf/core/exploit/imap'

View File

@ -0,0 +1,67 @@
require 'msf/core'
require 'snmp'
module Msf
###
#
# This module exposes methods for querying a SNMP service
#
###
module Exploit::Remote::SNMPClient
include Exploit::Remote::Udp
#
# Creates an instance of a SNMP exploit module.
#
def initialize(info = {})
super
# Register the options that all SNMP exploits may make use of.
register_options(
[
Opt::RHOST,
Opt::RPORT(161),
OptString.new('COMMUNITY', [ false, 'The snmp community to use', 'public' ])
], Msf::Exploit::Remote::SNMPClient)
end
#
# This method wraps the snmp library and passes in
# the Rex UDP socket
#
def connect_snmp(global=true, opts={})
s = connect_udp(false, opts)
snmp = ::SNMP::Manager.new(
:Host => rhost,
:Port => rport,
:Socket => s,
:Transport => ::SNMP::RexUDPTransport,
:Community => community
)
@snmp = snmp if global
snmp
end
def disconnect_snmp
@snmp.close if @snmp
@snmp = nil
end
def snmp
@snmp
end
def community
datastore['COMMUNITY'] || 'public'
end
protected
attr_accessor :snmp
end
end

View File

@ -76,7 +76,7 @@ module BER #:nodoc:all
class InvalidLength < RuntimeError; end
def assert_no_remainder(remainder)
raise ParseError, remainder.inspect if remainder != ""
raise ParseError, remainder.inspect if (remainder and remainder != "")
end
#

View File

@ -39,6 +39,28 @@ class UDPTransport
end
end
##
# Wrap socket in a Metasploit friendly Rex compatibility layer
#
class RexUDPTransport
def initialize(socket)
@socket = socket
end
def close
@socket.close
end
def send(data, host, port, flags=0)
@socket.sendto(data, host, port, flags)
end
def recv(max_bytes)
@socket.recvfrom(max_bytes)
end
end
##
# Manage a request-id in the range 1..2**31-1
#
@ -124,6 +146,7 @@ class Manager
:Host => 'localhost',
:Port => 161,
:TrapPort => 162,
:Socket => nil,
:Community => 'public',
:WriteCommunity => nil,
:Version => :SNMPv2c,
@ -154,13 +177,18 @@ class Manager
@config[:WriteCommunity] = @config[:WriteCommunity] || @config[:Community]
@host = @config[:Host]
@port = @config[:Port]
@socket = @config[:Socket]
@trap_port = @config[:TrapPort]
@community = @config[:Community]
@write_community = @config[:WriteCommunity]
@snmp_version = @config[:Version]
@timeout = @config[:Timeout]
@retries = @config[:Retries]
@transport = @config[:Transport].new
if(@socket)
@transport = @config[:Transport].new(@socket)
else
@transport = @config[:Transport].new
end
@max_bytes = @config[:MaxReceiveBytes]
@mib = MIB.new
load_modules(@config[:MibModules], @config[:MibDir])
@ -458,7 +486,7 @@ class Manager
end
def try_request(request, community=@community, host=@host, port=@port)
(@retries + 1).times do |n|
(@retries.to_i + 1).times do |n|
send_request(request, community, host, port)
begin
timeout(@timeout) do
@ -466,8 +494,8 @@ class Manager
end
rescue Timeout::Error
# no action - try again
rescue => e
warn e.to_s
rescue ::Interrupt
raise $!
end
end
raise RequestTimeout, "host #{@config[:Host]} not responding", caller