Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't recommend weaker crypto #166

Open
notramo opened this issue Mar 5, 2023 · 5 comments
Open

Don't recommend weaker crypto #166

notramo opened this issue Mar 5, 2023 · 5 comments

Comments

@notramo
Copy link

notramo commented Mar 5, 2023

If a server has AES 256 enabled, but not AES 128, don't indicate it as an error, despite AES 128 being considered as modern.
Similarly, if a server has sntrup761x25519-sha512@openssh.com enabled, but not curve25519-ssh, dont' indicate it as an error.

@jtesta
Copy link
Owner

jtesta commented Mar 14, 2023

Could you please paste the entire ssh-audit output of a scan that produced this output? That would help me understand what it did exactly, and why. Thanks!

@notramo
Copy link
Author

notramo commented Mar 20, 2023

sshd_config cryptography section:

HostKey /etc/ssh/ssh_host_ed25519_key
Ciphers chacha20-poly1305@openssh.com
KexAlgorithms sntrup761x25519-sha512@openssh.com
HostKeyAlgorithms ssh-ed25519
MACs hmac-sha2-512-etm@openssh.com

output:

# general
(gen) banner: SSH-2.0-OpenSSH_9.1
(gen) software: OpenSSH 9.1
(gen) compatibility: OpenSSH 8.5+
(gen) compression: enabled (zlib@openssh.com)

# key exchange algorithms
(kex) sntrup761x25519-sha512@openssh.com  -- [warn] using experimental algorithm
                                          `- [info] available since OpenSSH 8.5

# host-key algorithms
(key) ssh-ed25519                         -- [info] available since OpenSSH 6.5

# encryption algorithms (ciphers)
(enc) chacha20-poly1305@openssh.com       -- [info] available since OpenSSH 6.5
                                          `- [info] default cipher since OpenSSH 6.9.

# message authentication code algorithms
(mac) hmac-sha2-512-etm@openssh.com       -- [info] available since OpenSSH 6.2

# algorithm recommendations (for OpenSSH 9.1)
(rec) +aes128-ctr                         -- enc algorithm to append 
(rec) +aes128-gcm@openssh.com             -- enc algorithm to append 
(rec) +aes192-ctr                         -- enc algorithm to append 
(rec) +aes256-ctr                         -- enc algorithm to append 
(rec) +aes256-gcm@openssh.com             -- enc algorithm to append 
(rec) +curve25519-sha256                  -- kex algorithm to append 
(rec) +curve25519-sha256@libssh.org       -- kex algorithm to append 
(rec) +diffie-hellman-group-exchange-sha256-- kex algorithm to append 
(rec) +diffie-hellman-group14-sha256      -- kex algorithm to append 
(rec) +diffie-hellman-group16-sha512      -- kex algorithm to append 
(rec) +diffie-hellman-group18-sha512      -- kex algorithm to append 
(rec) +hmac-sha2-256-etm@openssh.com      -- mac algorithm to append 
(rec) +rsa-sha2-256                       -- key algorithm to append 
(rec) +rsa-sha2-512                       -- key algorithm to append 
(rec) +umac-128-etm@openssh.com           -- mac algorithm to append 
(rec) -sntrup761x25519-sha512@openssh.com -- kex algorithm to remove 

# additional info
(nfo) For hardening guides on common OSes, please see: <https://www.ssh-audit.com/hardening_guides.html>

@jtesta
Copy link
Owner

jtesta commented Mar 20, 2023

Thanks for posting the output. I see what you're referring to.

The tool's recommendations section is simply saying what safe additional algorithms could be enabled on the server. I suppose this messaging could be refined and made more clear. For example, the tool can recommend that unsafe algorithms are removed, then use another section to suggest additional safe algorithms.

If anyone wants to work on the PR for this functionality, its up for grabs!

@oam7575
Copy link

oam7575 commented Mar 17, 2024

I have had a look at this on and off for a little while and have made zero progress.

I did try to add a few checks in the area of the
def _get_cbc_ciphers_enabled(algs: Algorithms) -> List[str]:" ; and
def _get_etm_macs_enabled(algs: Algorithms) -> List[str]:

While these checks certainly suppressed any weaker recommendations they also suppressed removal prompts ( not good ) ; and were very fragile as they relied on "bit checking" in the cipher name ( eg : check 128 exists in aes128-ctr ).

This would of tend to break down whenever checking a something with different names; EG : Curve25519SHA256 vs diffie-hellman-group16-sha256

I had another go attempting to update the ssh2_kexdb.py file with a numerical value to each ENC / MAC / KEX and KEY.
Something like so:

'aes128-ctr': [['3.7,d0.52,l10.4.1'], [], [], [], [20]],
'aes192-ctr': [['3.7,l10.4.1'], [], [], [], [200]],
'aes256-ctr': [['3.7,d0.52,l10.4.1'], [], [], [], [2000]],

The thought was to then to
A) extract that value for ciphers / keys etc that the server is currently using. ( ValueA )
B) compare that value to can ciphers / keys that would be recommended. ( ValueB )

If (Value B) is smaller than (Value A) DONT recommend that cipher.

This is were I became stuck as (I am not a very well versed programmer ) and am having trouble following the code.

@oam7575
Copy link

oam7575 commented Mar 17, 2024

The spaghetti below attempts to explain my thoughts from my previous comment.

In the example code it uses the SSH2_KexDB as provided from the repo.
I have modified it with weight values as shown in my previous comment.

This version of the code returns two algorithm's with the largest weight numbers - it seemed safer than only returning 1x.

Notes:
all_algs and suggested_algs are place holder for easier testing.

aes64-ctr and others are garbage created for testing.

If I can manage to make something work that looks sensible I will create a pull request.

Feel free to use / modify / destroy as you see fit.

CAUTION : Might eat your cat.

from ssh2_kexdb import SSH2_KexDB


db = SSH2_KexDB.get_db()

all_algs = [('aes64-ctr', 5), ('aes128-ctr', 20), ('aes192-ctr', 200), ('aes256-ctr', 2000), ('aes256-gcm@openssh.com', 2500)]
suggest_algs = [('aes256-gcm@openssh.com', 2500), ('aes64-ctr', 5), ('aes128-ctr', 20), ('aes192-ctr', 200), ('aes256-ctr', 2000)]

enabled_algs = ['aes128-ctr', 'aes192-ctr']

check_list = []
check_list_weight = []
suggest_list = []

largest_suggest = None
second_largest_suggest = None

# Iterate through the SSH2_KEXDB 
# Format First (kex, key, enc, mac )
for format in db:
    # Iterate alg per format
    for algorithm_name in db[format]:
        # If we match an enabled alg vs a database record grab the details
        for alg in enabled_algs:
            if algorithm_name == alg:
                # Stuff everything into variables
                # weight is the new prefered_weight of an alg
                ver, fail, warn, info, weight = db[format][algorithm_name]

                # Convert the weight to an int so we can use it later.
                weight = int(weight[0])

                # append to a list of enabled algs
                # we will need seperate lists for each format key, kex, mac
                check_list.append((alg))

                # For this format put all weights into their own list.
                # will need seperate lists for each format
                check_list_weight.append(weight)

# Iterate over our list of potential algs to suggest
for suggested_alg in suggest_algs:
    # Extract their name and weight value
    suggested_name = suggested_alg[0]
    suggested_weight = suggested_alg[1]

    # Find the two largest values
    if largest_suggest is None or int(suggested_weight) > largest_suggest:
        second_largest_suggest = largest_suggest
        largest_suggest = suggested_weight
    elif (second_largest_suggest is None) or (int(suggested_weight) > second_largest_suggest and int(suggested_weight) != largest_suggest):
        second_largest_suggest = int(suggested_weight)

# Iterate the list a second time and if the alg weight matches either the 
# largest or second largest number then add to the suggested list.
for suggested_alg in suggest_algs:
    # Extract their name and weight value
    suggested_name = suggested_alg[0]
    suggested_weight = suggested_alg[1]

    if suggested_weight == second_largest_suggest and suggested_name not in suggest_list and suggested_name not in enabled_algs:
        suggest_list.append(suggested_name)
    elif suggested_weight == largest_suggest and suggested_name not in suggest_list and suggested_name not in enabled_algs:
        suggest_list.append(suggested_name)

print(suggest_list)

oam7575 added a commit to oam7575/ssh-audit that referenced this issue Mar 18, 2024
… exception of always suggesting a _second_ option.

jtesta#166
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants