Skip to content

Commit 2073121

Browse files
committed
TeamCity: Raise ArgumentError, refactor Crypto as an included module
1 parent f82483b commit 2073121

File tree

1 file changed

+22
-7
lines changed

1 file changed

+22
-7
lines changed

lib/metasploit/framework/login_scanner/teamcity.rb

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ class Teamcity < HTTP
1212
module Crypto
1313
# https://github.com/openssl/openssl/blob/a08a145d4a7e663dd1e973f06a56e983a5e916f7/crypto/rsa/rsa_pk1.c#L125
1414
# https://datatracker.ietf.org/doc/html/rfc3447#section-7.2.1
15-
def self.pkcs1pad2(text, n)
15+
def pkcs1pad2(text, n)
16+
raise ArgumentError, "Cannot pad the text: '#{text.inspect}'" unless text.is_a?(String)
17+
raise ArgumentError, "Invalid message length: '#{n.inspect}'" unless n.is_a?(Integer)
18+
1619
if n < text.length + 11
1720
raise ArgumentError, 'Message too long'
1821
end
@@ -49,7 +52,7 @@ def self.pkcs1pad2(text, n)
4952
# @param [String] exponent
5053
# @param [String] text
5154
# @return [String]
52-
def self.rsa_encrypt(modulus, exponent, text)
55+
def rsa_encrypt(modulus, exponent, text)
5356
n = modulus.to_i(16)
5457
e = exponent.to_i(16)
5558

@@ -60,19 +63,26 @@ def self.rsa_encrypt(modulus, exponent, text)
6063
h.length.odd? ? h.prepend('0') : h
6164
end
6265

63-
def self.two_byte_chars?(str)
66+
def two_byte_chars?(str)
67+
raise ArgumentError, 'Unable to check char size for non-string value' unless str.is_a?(String)
68+
6469
str.bytesize > str.length
6570
end
6671

67-
def self.max_data_size(str)
72+
def max_data_size(str)
73+
raise ArgumentError, 'Unable to get maximum data size for non-string value' unless str.is_a?(String)
74+
6875
# Taken from TeamCity's login page JavaScript sources.
6976
two_byte_chars?(str) ? 58 : 116
7077
end
7178

7279
# @param [String] text The text to encrypt.
7380
# @param [String] public_key The hex representation of the public key to use.
7481
# @return [String] A string blob.
75-
def self.encrypt_data(text, public_key)
82+
def encrypt_data(text, public_key)
83+
raise ArgumentError, "Cannot encrypt the provided data: '#{text.inspect}'" unless text.is_a?(String)
84+
raise ArgumentError, "Cannot encrypt data with the public key: '#{public_key.inspect}'" unless public_key.is_a?(String)
85+
7686
exponent = '10001'
7787
e = []
7888
g = max_data_size(text)
@@ -92,6 +102,7 @@ def self.encrypt_data(text, public_key)
92102
end
93103
end
94104

105+
include Crypto
95106

96107
DEFAULT_PORT = 8111
97108
LIKELY_PORTS = [8111]
@@ -151,7 +162,7 @@ def create_login_request(username, password, public_key)
151162
_remember: '',
152163
submitLogin: 'Log in',
153164
publicKey: public_key,
154-
encryptedPassword: Crypto.encrypt_data(password, public_key)
165+
encryptedPassword: encrypt_data(password, public_key)
155166
}
156167
}
157168
end
@@ -205,7 +216,11 @@ def logout_with_headers(headers)
205216
'headers' => headers
206217
}
207218

208-
send_request(logout_params)
219+
begin
220+
send_request(logout_params)
221+
rescue Rex::ConnectionError => _e
222+
# ignore
223+
end
209224
end
210225

211226
def attempt_login(credential)

0 commit comments

Comments
 (0)