jtesta / ssh-audit

SSH server & client security auditing (banner, key exchange, encryption, mac, compression, compatibility, security, etc)
MIT License
3.4k stars 175 forks source link

JSON output does not have a recommendations section #122

Closed VeNoMouS closed 1 year ago

VeNoMouS commented 3 years ago

looking at your code, you don't output it in your build_struct function...

VeNoMouS commented 3 years ago

Since no response... a hack can be done along the lines ..

def build_struct(
    target_host: str,
    banner: Optional['Banner'],
    kex: Optional['SSH2_Kex'] = None,
    pkm: Optional['SSH1_PublicKeyMessage'] = None,
    client_host: Optional[str] = None,
    software=None,
    algs=None
) -> Any:

    .....

    software, alg_rec = algs.get_recommendations(software, True)
    res['recommendations'] = {
        'critical': {},
        'warning': {}
    }

    for alg_type in ['kex', 'key', 'enc', 'mac']:
        if alg_type in alg_rec[2]:
            for action in ['del', 'add', 'chg']:
                if action in alg_rec[2][alg_type]:
                    for n in alg_rec[2][alg_type][action]:
                        level = 'critical' if alg_rec[2][alg_type][action][n] >= 10 else 'warning'

                        if action not in res['recommendations'][level]:
                            res['recommendations'][level][action] = {}

                        if alg_type not in res['recommendations'][level][action]:
                            res['recommendations'][level][action][alg_type] = []

                        res['recommendations'][level][action][alg_type].append(n)

    return res

....

def output(out: OutputBuffer, aconf: AuditConf, banner: Optional[Banner], header: List[str], client_host: Optional[str] = None, kex: Optional[SSH2_Kex] = None, pkm: Optional[SSH1_PublicKeyMessage] = None, print_target: bool = False) -> int:
    ......
    if aconf.json:
        out.reset()
        # Build & write the JSON struct.
        out.info(
            json.dumps(
                build_struct(
                    aconf.host,
                    banner,
                    kex=kex,
                    client_host=client_host,
                    software=software,
                    algs=algs
                ),
                indent=4 if aconf.json_print_indent else None, 
                sort_keys=True
            )
        )

which products the following appended output on a -jj...

    "recommendations": {
        "critical": {
            "del": {
                "enc": [
                    "3des-cbc",
                    "blowfish-cbc",
                    "cast128-cbc",
                    "arcfour",
                    "arcfour128",
                    "arcfour256",
                    "aes128-cbc",
                    "aes192-cbc",
                    "aes256-cbc",
                    "rijndael-cbc@lysator.liu.se"
                ],
                "kex": [
                    "diffie-hellman-group1-sha1",
                    "diffie-hellman-group-exchange-sha1",
                    "ecdh-sha2-nistp256",
                    "ecdh-sha2-nistp384",
                    "ecdh-sha2-nistp521"
                ],
                "key": [
                    "ssh-rsa",
                    "ssh-dss",
                    "ecdsa-sha2-nistp256"
                ],
                "mac": [
                    "hmac-sha1-96",
                    "hmac-sha2-256-96",
                    "hmac-sha2-512-96",
                    "hmac-md5",
                    "hmac-md5-96",
                    "hmac-ripemd160",
                    "hmac-ripemd160@openssh.com",
                    "hmac-sha1-96-etm@openssh.com",
                    "hmac-md5-etm@openssh.com",
                    "hmac-md5-96-etm@openssh.com",
                    "hmac-ripemd160-etm@openssh.com"
                ]
            }
        },
        "warning": {
            "del": {
                "kex": [
                    "diffie-hellman-group14-sha1"
                ],
                "mac": [
                    "hmac-sha1",
                    "hmac-sha2-256",
                    "hmac-sha2-512",
                    "umac-64@openssh.com",
                    "umac-128@openssh.com",
                    "hmac-sha1-etm@openssh.com",
                    "umac-64-etm@openssh.com"
                ]
            }
        }
    },

honestly , reading your code is a nightmare, if you're reformatting everything so much all over the place, change it at the source and structure it accordingly so you're not having to loop on everything in order to format it...

just my 2 cents.

VeNoMouS commented 3 years ago

Additionally, since you don't output in a logical structured manner to an object or structured dict as stated above, it makes it impossible / impractical using this as 3rd party python module ... as the end developer has to manually restructure everything your doing just to get structured output they can re-use in their own code.

jtesta commented 3 years ago

honestly , reading your code is a nightmare

I didn't write those parts, but I am responsible for maintaining them. I'll gladly accept a PR to fix it though!

As for the issue at hand, it seems like you did most of the work already. A PR would speed things up, if you're able to make one. Thanks!

mr-pmillz commented 1 year ago

Hey @VeNoMouS @jtesta @letiemble

I've implemented @VeNoMouS 's changes I also added the corresponding CVE results to the JSON output in a structured manner as well. Tested and appears to work.

Let me know what you think @jtesta Here is the PR: https://github.com/jtesta/ssh-audit/pull/160 Cheers 🍻

Thibaut833 commented 1 year ago

Hi,

@jtesta can you accept this pull request please ? I want to use the json format with recommendations.

Thanks a lot.

Best regards.

jtesta commented 1 year ago

@VeNoMouS : I just committed a patch to add recommendations and CVE information to the JSON output. Please give it a try!

CC: @Thibaut833