MCPcopy
hub / github.com/jtesta/ssh-audit / run

Method run

src/ssh_audit/gextest.py:127–214  ·  view source on GitHub ↗
(out: 'OutputBuffer', s: 'SSH_Socket', banner: Optional['Banner'], kex: 'SSH2_Kex')

Source from the content-addressed store, hash-verified

125 # Runs the DH moduli test against the specified target.
126 @staticmethod
127 def run(out: 'OutputBuffer', s: 'SSH_Socket', banner: Optional['Banner'], kex: 'SSH2_Kex') -> None:
128 GEX_ALGS = {
129 'diffie-hellman-group-exchange-sha1': KexGroupExchange_SHA1,
130 'diffie-hellman-group-exchange-sha256': KexGroupExchange_SHA256,
131 }
132
133 # The previous RSA tests put the server in a state we can't
134 # test. So we need a new connection to start with a clean
135 # slate.
136 if s.is_connected():
137 s.close()
138
139 # Check if the server supports any of the group-exchange
140 # algorithms. If so, test each one.
141 for gex_alg, kex_group_class in GEX_ALGS.items(): # pylint: disable=too-many-nested-blocks
142 if gex_alg in kex.kex_algorithms:
143 out.d('Preparing to perform DH group exchange using ' + gex_alg + ' with min, pref and max modulus sizes of 512 bits, 1024 bits and 1536 bits...', write_now=True)
144
145 kex_group = kex_group_class(out)
146 smallest_modulus, reconnect_failed = GEXTest._send_init(out, s, kex_group, kex, gex_alg, 512, 1024, 1536)
147 if reconnect_failed:
148 break
149
150 # Try an array of specific modulus sizes... one at a time.
151 reconnect_failed = False
152 for bits in [512, 768, 1024, 1536, 2048, 3072, 4096]:
153
154 # If we found one modulus size already, but we're about
155 # to test a larger one, don't bother.
156 if bits >= smallest_modulus > 0:
157 break
158
159 smallest_modulus, reconnect_failed = GEXTest._send_init(out, s, kex_group, kex, gex_alg, bits, bits, bits)
160
161 # If the smallest modulus is 2048 and the server is OpenSSH, then we may have triggered the fallback mechanism, which tends to happen in testing scenarios such as this but not in most real-world conditions (see X). To better test this condition, we will do an additional check to see if the server supports sizes between 2048 and 4096, and consider this the definitive result.
162 openssh_test_updated = False
163 if (smallest_modulus == 2048) and (banner is not None) and (banner.software is not None) and (banner.software.find('OpenSSH') != -1):
164 out.d('First pass found a minimum GEX modulus of 2048 against OpenSSH server. Performing a second pass to get a more accurate result...')
165 smallest_modulus, _ = GEXTest._send_init(out, s, kex_group, kex, gex_alg, 2048, 3072, 4096)
166 out.d('Modulus size returned by server during second pass: %d bits' % smallest_modulus, write_now=True)
167 openssh_test_updated = bool((smallest_modulus > 0) and (smallest_modulus != 2048))
168
169 if smallest_modulus > 0:
170 kex.set_dh_modulus_size(gex_alg, smallest_modulus)
171
172 lst = SSH2_KexDB.get_db()['kex'][gex_alg]
173
174 # We flag moduli smaller than 2048 as a failure.
175 if smallest_modulus < 2048:
176 text = 'using small %d-bit modulus' % smallest_modulus
177
178 # For 'diffie-hellman-group-exchange-sha256', add
179 # a failure reason.
180 if len(lst) == 1:
181 lst.append([text])
182 # For 'diffie-hellman-group-exchange-sha1', delete
183 # the existing failure reason (which is vague), and
184 # insert our own.

Callers

nothing calls this directly

Calls 7

is_connectedMethod · 0.80
closeMethod · 0.80
itemsMethod · 0.80
dMethod · 0.80
_send_initMethod · 0.80
set_dh_modulus_sizeMethod · 0.80
get_dbMethod · 0.45

Tested by

no test coverage detected