CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/lib/metasploit/framework/credential_collection.rb
Views: 1904
require 'metasploit/framework/credential'12module Metasploit::Framework34class PrivateCredentialCollection5# @!attribute additional_privates6# Additional private values that should be tried7# @return [Array<String>]8attr_accessor :additional_privates910# @!attribute blank_passwords11# Whether each username should be tried with a blank password12# @return [Boolean]13attr_accessor :blank_passwords1415# @!attribute nil_passwords16# Whether each username should be tried with a nil password17# @return [Boolean]18attr_accessor :nil_passwords1920# @!attribute pass_file21# Path to a file containing passwords, one per line22# @return [String]23attr_accessor :pass_file2425# @!attribute password26# The password that should be tried27# @return [String]28attr_accessor :password2930# @!attribute prepended_creds31# List of credentials to be tried before any others32#33# @see #prepend_cred34# @return [Array<Credential>]35attr_accessor :prepended_creds3637# @!attribute realm38# The authentication realm associated with this password39# @return [String]40attr_accessor :realm4142# @!attribute filter43# A block that can be used to filter credential objects44attr_accessor :filter4546# @option opts [Boolean] :nil_passwords See {#nil_passwords}47# @option opts [Boolean] :blank_passwords See {#blank_passwords}48# @option opts [String] :pass_file See {#pass_file}49# @option opts [String] :password See {#password}50# @option opts [Array<Credential>] :prepended_creds ([]) See {#prepended_creds}51# @option opts [Boolean] :user_as_pass See {#user_as_pass}52# @option opts [String] :user_file See {#user_file}53# @option opts [String] :username See {#username}54# @option opts [String] :userpass_file See {#userpass_file}55# @option opts [String] :usernames_only See {#usernames_only}56def initialize(opts = {})57opts.each do |attribute, value|58public_send("#{attribute}=", value)59end60self.prepended_creds ||= []61self.additional_privates ||= []62self.filter = nil63end6465# Adds a string as an additional private credential66# to be combined in the collection.67#68# @param [String] private_str The string to use as a private credential69# @return [void]70def add_private(private_str='')71additional_privates << private_str72end7374# Add {Credential credentials} that will be yielded by {#each}75#76# @see prepended_creds77# @param [Credential] cred78# @return [self]79def prepend_cred(cred)80prepended_creds.unshift cred81self82end8384# Combines all the provided credential sources into a stream of {Credential}85# objects, yielding them one at a time86#87# @yieldparam credential [Metasploit::Framework::Credential]88# @return [void]89def each_filtered90each_unfiltered do |credential|91next unless self.filter.nil? || self.filter.call(credential)9293yield credential94end95end9697# Combines all the provided credential sources into a stream of {Credential}98# objects, yielding them one at a time99#100# @yieldparam credential [Metasploit::Framework::Credential]101# @return [void]102def each_unfiltered103if pass_file.present?104pass_fd = File.open(pass_file, 'r:binary')105end106107prepended_creds.each { |c| yield c }108109if password.present?110yield Metasploit::Framework::Credential.new(private: password, realm: realm, private_type: private_type(password))111end112if blank_passwords113yield Metasploit::Framework::Credential.new(private: "", realm: realm, private_type: :password)114end115if nil_passwords116yield Metasploit::Framework::Credential.new(private: nil, realm: realm, private_type: :password)117end118if pass_fd119pass_fd.each_line do |pass_from_file|120pass_from_file.chomp!121yield Metasploit::Framework::Credential.new(private: pass_from_file, realm: realm, private_type: private_type(pass_from_file))122end123pass_fd.seek(0)124end125additional_privates.each do |add_private|126yield Metasploit::Framework::Credential.new(private: add_private, realm: realm, private_type: private_type(add_private))127end128129ensure130pass_fd.close if pass_fd && !pass_fd.closed?131end132133# Returns true when #each will have no results to iterate134#135# @return [Boolean]136def empty?137prepended_creds.empty? && !has_privates?138end139140# Returns true when a filter is defined141#142# @return [Boolean]143def filtered?144!self.filter.nil?145end146147# Returns true when there are any private values set148#149# @return [Boolean]150def has_privates?151password.present? || pass_file.present? || !additional_privates.empty? || blank_passwords || nil_passwords152end153154alias each each_filtered155156protected157158# Analyze a private value to determine its type by checking it against a known list of regular expressions159#160# @param [String] private The string to analyze161# @return [Symbol]162def private_type(private)163if private =~ /[0-9a-f]{32}:[0-9a-f]{32}/164:ntlm_hash165elsif private =~ /^md5([a-f0-9]{32})$/166:postgres_md5167else168:password169end170end171end172173class CredentialCollection < PrivateCredentialCollection174# @!attribute password_spray175# Whether password spray is enabled. When true, each password is tried against each username first.176# Otherwise the default bruteforce logic will attempt all passwords against the first user, before177# continuing to the next user178#179# @return [Boolean]180attr_accessor :password_spray181182# @!attribute additional_publics183# Additional public values that should be tried184#185# @return [Array<String>]186attr_accessor :additional_publics187188# @!attribute user_as_pass189# Whether each username should be tried as a password for that user190# @return [Boolean]191attr_accessor :user_as_pass192193# @!attribute user_file194# Path to a file containing usernames, one per line195# @return [String]196attr_accessor :user_file197198# @!attribute username199# The username that should be tried200# @return [String]201attr_accessor :username202203# @!attribute userpass_file204# Path to a file containing usernames and passwords separated by a space,205# one pair per line206# @return [String]207attr_accessor :userpass_file208209# @!attribute anonymous_login210# Whether to attempt an anonymous login (blank user/pass)211# @return [Boolean]212attr_accessor :anonymous_login213214# @option opts [Boolean] :blank_passwords See {#blank_passwords}215# @option opts [String] :pass_file See {#pass_file}216# @option opts [String] :password See {#password}217# @option opts [Array<Credential>] :prepended_creds ([]) See {#prepended_creds}218# @option opts [Boolean] :user_as_pass See {#user_as_pass}219# @option opts [String] :user_file See {#user_file}220# @option opts [String] :username See {#username}221# @option opts [String] :userpass_file See {#userpass_file}222def initialize(opts = {})223super224self.additional_publics ||= []225end226227# Adds a string as an additional public credential228# to be combined in the collection.229#230# @param [String] public_str The string to use as a public credential231# @return [void]232def add_public(public_str='')233additional_publics << public_str234end235236# Combines all the provided credential sources into a stream of {Credential}237# objects, yielding them one at a time238#239# @yieldparam credential [Metasploit::Framework::Credential]240# @return [void]241def each_filtered242if password_spray243each_unfiltered_password_first do |credential|244next unless self.filter.nil? || self.filter.call(credential)245246yield credential247end248else249each_unfiltered_username_first do |credential|250next unless self.filter.nil? || self.filter.call(credential)251252yield credential253end254end255end256257alias each each_filtered258259# When password spraying is enabled, do first passwords then usernames260# i.e.261# username1:password1262# username2:password1263# username3:password1264# ...265# username1:password2266# username2:password2267# username3:password2268# ...269# @yieldparam credential [Metasploit::Framework::Credential]270# @return [void]271def each_unfiltered_password_first272if user_file.present?273user_fd = File.open(user_file, 'r:binary')274end275276prepended_creds.each { |c| yield c }277278if anonymous_login279yield Metasploit::Framework::Credential.new(public: '', private: '', realm: realm, private_type: :password)280end281282if password.present?283if nil_passwords284yield Metasploit::Framework::Credential.new(public: username, private: nil, realm: realm, private_type: :password)285end286if username.present?287yield Metasploit::Framework::Credential.new(public: username, private: password, realm: realm, private_type: private_type(password))288end289if user_as_pass290yield Metasploit::Framework::Credential.new(public: username, private: username, realm: realm, private_type: :password)291end292if blank_passwords293yield Metasploit::Framework::Credential.new(public: username, private: "", realm: realm, private_type: :password)294end295if user_fd296user_fd.each_line do |user_from_file|297user_from_file.chomp!298yield Metasploit::Framework::Credential.new(public: user_from_file, private: password, realm: realm, private_type: private_type(password))299end300user_fd.seek(0)301end302end303304if pass_file.present?305File.open(pass_file, 'r:binary') do |pass_fd|306pass_fd.each_line do |pass_from_file|307pass_from_file.chomp!308if username.present?309yield Metasploit::Framework::Credential.new(public: username, private: pass_from_file, realm: realm, private_type: :password)310end311if user_as_pass312yield Metasploit::Framework::Credential.new(public: pass_from_file, private: pass_from_file, realm: realm, private_type: :password)313end314next unless user_fd315316user_fd.each_line do |user_from_file|317user_from_file.chomp!318yield Metasploit::Framework::Credential.new(public: user_from_file, private: pass_from_file, realm: realm, private_type: private_type(pass_from_file))319end320user_fd.seek(0)321end322end323end324325if userpass_file.present?326File.open(userpass_file, 'r:binary') do |userpass_fd|327userpass_fd.each_line do |line|328user, pass = line.split(" ", 2)329if pass.blank?330pass = ''331else332pass.chomp!333end334yield Metasploit::Framework::Credential.new(public: user, private: pass, realm: realm)335end336end337end338339additional_privates.each do |add_private|340if username.present?341yield Metasploit::Framework::Credential.new(public: username, private: add_private, realm: realm, private_type: private_type(add_private))342end343user_fd.each_line do |user_from_file|344user_from_file.chomp!345yield Metasploit::Framework::Credential.new(public: user_from_file, private: add_private, realm: realm, private_type: private_type(add_private))346end347user_fd.seek(0)348end349350additional_publics.each do |add_public|351if password.present?352yield Metasploit::Framework::Credential.new(public: add_public, private: password, realm: realm, private_type: private_type(password) )353end354if user_as_pass355yield Metasploit::Framework::Credential.new(public: add_public, private: user_from_file, realm: realm, private_type: :password)356end357if blank_passwords358yield Metasploit::Framework::Credential.new(public: add_public, private: "", realm: realm, private_type: :password)359end360if nil_passwords361yield Metasploit::Framework::Credential.new(public: add_public, private: nil, realm: realm, private_type: :password)362end363if user_fd364user_fd.each_line do |user_from_file|365user_from_file.chomp!366yield Metasploit::Framework::Credential.new(public: add_public, private: user_from_file, realm: realm, private_type: private_type(user_from_file))367end368user_fd.seek(0)369end370additional_privates.each do |add_private|371yield Metasploit::Framework::Credential.new(public: add_public, private: add_private, realm: realm, private_type: private_type(add_private))372end373end374ensure375user_fd.close if user_fd && !user_fd.closed?376end377378# When password spraying is not enabled, do first usernames then passwords379# i.e.380# username1:password1381# username1:password2382# username1:password3383# ...384# username2:password1385# username2:password2386# username2:password3387# @yieldparam credential [Metasploit::Framework::Credential]388# @return [void]389def each_unfiltered_username_first390if pass_file.present?391pass_fd = File.open(pass_file, 'r:binary')392end393394prepended_creds.each { |c| yield c }395396if anonymous_login397yield Metasploit::Framework::Credential.new(public: '', private: '', realm: realm, private_type: :password)398end399400if username.present?401if nil_passwords402yield Metasploit::Framework::Credential.new(public: username, private: nil, realm: realm, private_type: :password)403end404if password.present?405yield Metasploit::Framework::Credential.new(public: username, private: password, realm: realm, private_type: private_type(password))406end407if user_as_pass408yield Metasploit::Framework::Credential.new(public: username, private: username, realm: realm, private_type: :password)409end410if blank_passwords411yield Metasploit::Framework::Credential.new(public: username, private: "", realm: realm, private_type: :password)412end413if pass_fd414pass_fd.each_line do |pass_from_file|415pass_from_file.chomp!416yield Metasploit::Framework::Credential.new(public: username, private: pass_from_file, realm: realm, private_type: private_type(pass_from_file))417end418pass_fd.seek(0)419end420additional_privates.each do |add_private|421yield Metasploit::Framework::Credential.new(public: username, private: add_private, realm: realm, private_type: private_type(add_private))422end423end424425if user_file.present?426File.open(user_file, 'r:binary') do |user_fd|427user_fd.each_line do |user_from_file|428user_from_file.chomp!429if nil_passwords430yield Metasploit::Framework::Credential.new(public: user_from_file, private: nil, realm: realm, private_type: :password)431end432if password.present?433yield Metasploit::Framework::Credential.new(public: user_from_file, private: password, realm: realm, private_type: private_type(password) )434end435if user_as_pass436yield Metasploit::Framework::Credential.new(public: user_from_file, private: user_from_file, realm: realm, private_type: :password)437end438if blank_passwords439yield Metasploit::Framework::Credential.new(public: user_from_file, private: "", realm: realm, private_type: :password)440end441if pass_fd442pass_fd.each_line do |pass_from_file|443pass_from_file.chomp!444yield Metasploit::Framework::Credential.new(public: user_from_file, private: pass_from_file, realm: realm, private_type: private_type(pass_from_file))445end446pass_fd.seek(0)447end448additional_privates.each do |add_private|449yield Metasploit::Framework::Credential.new(public: user_from_file, private: add_private, realm: realm, private_type: private_type(add_private))450end451end452end453end454455if userpass_file.present?456File.open(userpass_file, 'r:binary') do |userpass_fd|457userpass_fd.each_line do |line|458user, pass = line.split(" ", 2)459if pass.blank?460pass = ''461else462pass.chomp!463end464yield Metasploit::Framework::Credential.new(public: user, private: pass, realm: realm)465end466end467end468469additional_publics.each do |add_public|470if password.present?471yield Metasploit::Framework::Credential.new(public: add_public, private: password, realm: realm, private_type: private_type(password) )472end473if user_as_pass474yield Metasploit::Framework::Credential.new(public: add_public, private: user_from_file, realm: realm, private_type: :password)475end476if blank_passwords477yield Metasploit::Framework::Credential.new(public: add_public, private: "", realm: realm, private_type: :password)478end479if pass_fd480pass_fd.each_line do |pass_from_file|481pass_from_file.chomp!482yield Metasploit::Framework::Credential.new(public: add_public, private: pass_from_file, realm: realm, private_type: private_type(pass_from_file))483end484pass_fd.seek(0)485end486additional_privates.each do |add_private|487yield Metasploit::Framework::Credential.new(public: add_public, private: add_private, realm: realm, private_type: private_type(add_private))488end489end490ensure491pass_fd.close if pass_fd && !pass_fd.closed?492end493494# Returns true when #each will have no results to iterate495#496# @return [Boolean]497def empty?498prepended_creds.empty? && !has_users? && !anonymous_login || (has_users? && !has_privates?)499end500501# Returns true when there are any user values set502#503# @return [Boolean]504def has_users?505username.present? || user_file.present? || userpass_file.present? || !additional_publics.empty?506end507508# Returns true when there are any private values set509#510# @return [Boolean]511def has_privates?512super || userpass_file.present? || user_as_pass513end514515end516end517518519