diff options
Diffstat (limited to 'scripts/ssl-dh-params.nse')
-rw-r--r-- | scripts/ssl-dh-params.nse | 941 |
1 files changed, 941 insertions, 0 deletions
diff --git a/scripts/ssl-dh-params.nse b/scripts/ssl-dh-params.nse new file mode 100644 index 0000000..bf2bde5 --- /dev/null +++ b/scripts/ssl-dh-params.nse @@ -0,0 +1,941 @@ +local nmap = require "nmap" +local shortport = require "shortport" +local sslcert = require "sslcert" +local stdnse = require "stdnse" +local string = require "string" +local math = require "math" +local table = require "table" +local tls = require "tls" +local vulns = require "vulns" +local have_ssl, openssl = pcall(require, "openssl") + +description = [[ +Weak ephemeral Diffie-Hellman parameter detection for SSL/TLS services. + +This script simulates SSL/TLS handshakes using ciphersuites that have ephemeral +Diffie-Hellman as the key exchange algorithm. + +Diffie-Hellman MODP group parameters are extracted and analyzed for vulnerability +to Logjam (CVE 2015-4000) and other weaknesses. + +Opportunistic STARTTLS sessions are established on services that support them. +]] + +--- +-- @usage +-- nmap --script ssl-dh-params <target> +-- +-- @output +-- Host script results: +-- | ssl-dh-params: +-- | VULNERABLE: +-- | Transport Layer Security (TLS) Protocol DHE_EXPORT Ciphers Downgrade MitM (Logjam) +-- | State: VULNERABLE +-- | IDs: BID:74733 CVE:CVE-2015-4000 +-- | The Transport Layer Security (TLS) protocol contains a flaw that is triggered +-- | when handling Diffie-Hellman key exchanges defined with the DHE_EXPORT cipher. +-- | This may allow a man-in-the-middle attacker to downgrade the security of a TLS +-- | session to 512-bit export-grade cryptography, which is significantly weaker, +-- | allowing the attacker to more easily break the encryption and monitor or tamper +-- | with the encrypted stream. +-- | Disclosure date: 2015-5-19 +-- | Check results: +-- | EXPORT-GRADE DH GROUP 1 +-- | Ciphersuite: TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA +-- | Modulus Type: Non-safe prime +-- | Modulus Source: sun.security.provider/512-bit DSA group with 160-bit prime order subgroup +-- | Modulus Length: 512 bits +-- | Generator Length: 512 bits +-- | Public Key Length: 512 bits +-- | References: +-- | https://weakdh.org +-- | https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4000 +-- | https://www.securityfocus.com/bid/74733 +-- | +-- | Diffie-Hellman Key Exchange Insufficient Diffie-Hellman Group Strength +-- | State: VULNERABLE +-- | Transport Layer Security (TLS) services that use Diffie-Hellman groups of +-- | insuffficient strength, especially those using one of a few commonly shared +-- | groups, may be susceptible to passive eavesdropping attacks. +-- | Check results: +-- | WEAK DH GROUP 1 +-- | Ciphersuite: TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA +-- | Modulus Type: Safe prime +-- | Modulus Source: Unknown/Custom-generated +-- | Modulus Length: 512 bits +-- | Generator Length: 8 bits +-- | Public Key Length: 512 bits +-- | References: +-- | https://weakdh.org +-- | +-- | Diffie-Hellman Key Exchange Potentially Unsafe Group Parameters +-- | State: VULNERABLE +-- | This TLS service appears to be using a modulus that is not a safe prime and does +-- | not correspond to any well-known DSA group for Diffie-Hellman key exchange. +-- | These parameters MAY be secure if: +-- | - They were generated according to the procedure described in FIPS 186-4 for +-- | DSA Domain Parameter Generation, or +-- | - The generator g generates a subgroup of large prime order +-- | Additional testing may be required to verify the security of these parameters. +-- | Check results: +-- | NON-SAFE DH GROUP 1 +-- | Cipher Suite: TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA +-- | Modulus Type: Non-safe prime +-- | Modulus Source: Unknown/Custom-generated +-- | Modulus Length: 1024 bits +-- | Generator Length: 1024 bits +-- | Public Key Length: 1024 bits +-- | References: +-- |_ https://weakdh.org + +author = "Jacob Gajek" +license = "Same as Nmap--See https://nmap.org/book/man-legal.html" +categories = {"vuln", "safe"} +dependencies = {"https-redirect"} + +-- Anonymous Diffie-Hellman key exchange variants +local DH_anon_ALGORITHMS = { + ["DH_anon_EXPORT"] = 1, + ["DH_anon"] = 1 +} + +-- Full-strength ephemeral Diffie-Hellman key exchange variants +local DHE_ALGORITHMS = { + ["DHE_RSA"] = 1, + ["DHE_DSS"] = 1, + ["DHE_PSK"] = 1 +} + +-- Export-grade ephemeral Diffie-Hellman key exchange variants +local DHE_ALGORITHMS_EXPORT = { + ["DHE_RSA_EXPORT"] = 1, + ["DHE_DSS_EXPORT"] = 1, + ["DHE_DSS_EXPORT1024"] = 1 +} + +local fromhex = stdnse.fromhex + +-- Common Diffie-Hellman groups +-- +-- The primes from weakdh.org were harvested by: +-- 1) Scanning the IPv4 space +-- 2) Scanning Alexa Top 1 million (seen >100 times) +-- +-- The list from weakdh.org overlaps the original script source code, therefore those were removed. +-- The primes were not searchable on Google (hope for source code match) - they may belong to closed +-- source software. If someone happens to find/match it, send a pull request. +local DHE_PRIMES = { + [fromhex([[ + D4BCD524 06F69B35 994B88DE 5DB89682 C8157F62 D8F33633 EE5772F1 1F05AB22 + D6B5145B 9F241E5A CC31FF09 0A4BC711 48976F76 795094E7 1E790352 9F5A824B + ]])] = "mod_ssl 2.0.x/512-bit MODP group with safe prime modulus", + + [fromhex([[ + E6969D3D 495BE32C 7CF180C3 BDD4798E 91B78182 51BB055E 2A206490 4A79A770 + FA15A259 CBD523A6 A6EF09C4 3048D5A2 2F971F3C 20129B48 000E6EDD 061CBC05 + 3E371D79 4E5327DF 611EBBBE 1BAC9B5C 6044CF02 3D76E05E EA9BAD99 1B13A63C + 974E9EF1 839EB5DB 125136F7 262E56A8 871538DF D823C650 5085E21F 0DD5C86B + ]])] = "mod_ssl 2.0.x/1024-bit MODP group with safe prime modulus", + + [fromhex([[ + 9FDB8B8A 004544F0 045F1737 D0BA2E0B 274CDF1A 9F588218 FB435316 A16E3741 + 71FD19D8 D8F37C39 BF863FD6 0E3E3006 80A3030C 6E4C3757 D08F70E6 AA871033 + ]])] = "mod_ssl 2.2.x/512-bit MODP group with safe prime modulus", + + [fromhex([[ + D67DE440 CBBBDC19 36D693D3 4AFD0AD5 0C84D239 A45F520B B88174CB 98BCE951 + 849F912E 639C72FB 13B4B4D7 177E16D5 5AC179BA 420B2A29 FE324A46 7A635E81 + FF590137 7BEDDCFD 33168A46 1AAD3B72 DAE88600 78045B07 A7DBCA78 74087D15 + 10EA9FCC 9DDD3305 07DD62DB 88AEAA74 7DE0F4D6 E2BD68B0 E7393E0F 24218EB3 + ]])] = "mod_ssl 2.2.x/1024-bit MODP group with safe prime modulus", + + [fromhex([[ + BBBC2DCA D8467490 7C43FCF5 80E9CFDB D958A3F5 68B42D4B 08EED4EB 0FB3504C + 6C030276 E710800C 5CCBBAA8 922614C5 BEECA565 A5FDF1D2 87A2BC04 9BE67780 + 60E91A92 A757E304 8F68B076 F7D36CC8 F29BA5DF 81DC2CA7 25ECE662 70CC9A50 + 35D8CECE EF9EA027 4A63AB1E 58FAFD49 88D0F65D 146757DA 071DF045 CFE16B9B + ]])] = "nginx/1024-bit MODP group with safe prime modulus", + + [fromhex([[ + FCA682CE 8E12CABA 26EFCCF7 110E526D B078B05E DECBCD1E B4A208F3 AE1617AE + 01F35B91 A47E6DF6 3413C5E1 2ED0899B CD132ACD 50D99151 BDC43EE7 37592E17 + ]])] = "sun.security.provider/512-bit DSA group with 160-bit prime order subgroup", + + [fromhex([[ + E9E64259 9D355F37 C97FFD35 67120B8E 25C9CD43 E927B3A9 670FBEC5 D8901419 + 22D2C3B3 AD248009 3799869D 1E846AAB 49FAB0AD 26D2CE6A 22219D47 0BCE7D77 + 7D4A21FB E9C270B5 7F607002 F3CEF839 3694CF45 EE3688C1 1A8C56AB 127A3DAF + ]])] = "sun.security.provider/768-bit DSA group with 160-bit prime order subgroup", + + [fromhex([[ + FD7F5381 1D751229 52DF4A9C 2EECE4E7 F611B752 3CEF4400 C31E3F80 B6512669 + 455D4022 51FB593D 8D58FABF C5F5BA30 F6CB9B55 6CD7813B 801D346F F26660B7 + 6B9950A5 A49F9FE8 047B1022 C24FBBA9 D7FEB7C6 1BF83B57 E7C6A8A6 150F04FB + 83F6D3C5 1EC30235 54135A16 9132F675 F3AE2B61 D72AEFF2 2203199D D14801C7 + ]])] = "sun.security.provider/1024-bit DSA group with 160-bit prime order subgroup", + + [fromhex([[ + DA583C16 D9852289 D0E4AF75 6F4CCA92 DD4BE533 B804FB0F ED94EF9C 8A4403ED + 574650D3 6999DB29 D776276B A2D3D412 E218F4DD 1E084CF6 D8003E7C 4774E833 + ]])] = "openssl/512-bit MODP group with safe prime modulus", + + [fromhex([[ + 97F64261 CAB505DD 2828E13F 1D68B6D3 DBD0F313 047F40E8 56DA58CB 13B8A1BF + 2B783A4C 6D59D5F9 2AFC6CFF 3D693F78 B23D4F31 60A9502E 3EFAF7AB 5E1AD5A6 + 5E554313 828DA83B 9FF2D941 DEE95689 FADAEA09 36ADDF19 71FE635B 20AF4703 + 64603C2D E059F54B 650AD8FA 0CF70121 C74799D7 587132BE 9B999BB9 B787E8AB + ]])] = "openssl/1024-bit MODP group with safe prime modulus", + + [fromhex([[ + ED928935 824555CB 3BFBA276 5A690461 BF21F3AB 53D2CD21 DAFF7819 1152F10E + C1E255BD 686F6800 53B9226A 2FE49A34 1F65CC59 328ABDB1 DB49EDDF A71266C3 + FD210470 18F07FD6 F7585119 72827B22 A934181D 2FCB21CF 6D92AE43 B6A829C7 + 27A3CB00 C5F2E5FB 0AA45985 A2BDAD45 F0B3ADF9 E08135EE D983B3CC AEEAEB66 + E6A95766 B9F128A5 3F2280D7 0BA6F671 939B810E F85A90E6 CCCA6F66 5F7AC010 + 1A1EF0FC 2DB6080C 6228B0EC DB8928EE 0CA83D65 94691669 533C5360 13B02BA7 + D48287AD 1C729E41 35FCC27C E951DE61 85FC199B 76600F33 F86BB3CA 520E29C3 + 07E89016 CCCC0019 B6ADC3A4 308B33A1 AFD88C8D 9D01DBA4 C4DD7F0B BD6F38C3 + ]])] = "openssl/2048-bit MODP group with safe prime modulus", + + [fromhex([[ + AED037C3 BDF33FA2 EEDC4390 B70A2089 7B770175 E9B92EB2 0F8061CC D4B5A591 + 723C7934 FDA9F9F3 274490F8 50647283 5BE05927 1C4F2C03 5A4EE756 A36613F1 + 382DBD47 4DE8A4A0 322122E8 C730A83C 3E4800EE BD6F8548 A5181711 BA545231 + C843FAC4 175FFAF8 49C440DB 446D8462 C1C3451B 49EFA829 F5C48A4C 7BAC7F64 + 7EE00015 1AA9ED81 101B36AB 5C39AAFF EC54A3F8 F97C1B7B F406DCB4 2DC092A5 + BAA06259 EFEB3FAB 12B42698 2E8F3EF4 B3F7B4C3 302A24C8 AA4213D8 45035CE4 + A8ADD31F 816616F1 9E21A5C9 5080597F 8980AD6B 814E3585 5B79E684 4491527D + 552B72B7 C78D8D6B 993A736F 8486B305 88B8F1B8 7E89668A 8BD3F13D DC517D4B + ]])] = "openssl/2048-bit MODP group with safe prime modulus", + + [fromhex([[ + FEEAD19D BEAF90F6 1CFCA106 5D69DB08 839A2A2B 6AEF2488 ABD7531F BB3E462E + 7DCECEFB CEDCBBBD F56549EE 95153056 8188C3D9 7294166B 6AABA0AA 5CC8555F + 9125503A 180E9032 4C7F39C6 A3452F31 42EE72AB 7DFFC74C 528DB6DA 76D9C644 + F55D083E 9CDE74F7 E742413B 69476617 D2670F2B F6D59FFC D7C3BDDE ED41E2BD + 2CCDD9E6 12F1056C AB88C441 D7F9BA74 651ED1A8 4D407A27 D71895F7 77AB6C77 + 63CC00E6 F1C30B2F E7944692 7E74BC73 B8431B53 011AF5AD 1515E63D C1DE83CC + 802ECE7D FC71FBDF 179F8E41 D7F1B43E BA75D5A9 C3B11D4F 1B0B5A09 88A9AACB + CCC10512 26DC8410 E41693EC 8591E31E E2F5AFDF AEDE122D 1277FC27 0BE4D25C + 1137A58B E961EAC9 F27D4C71 E2391904 DD6AB27B ECE5BD6C 64C79B14 6C2D208C + D63A4B74 F8DAE638 DBE2C880 6BA10773 8A8DF5CF E214A4B7 3D03C912 75FBA572 + 8146CE5F EC01775B 74481ADF 86F4854D 65F5DA4B B67F882A 60CE0BCA 0ACD157A + A377F10B 091AD0B5 68893039 ECA33CDC B61BA8C9 E32A87A2 F5D8B7FD 26734D2F + 09679235 2D70ADE9 F4A51D84 88BC57D3 2A638E0B 14D6693F 6776FFFB 355FEDF6 + 52201FA7 0CB8DB34 FB549490 951A701E 04AD49D6 71B74D08 9CAA8C0E 5E833A21 + 291D6978 F918F25D 5C769BDB E4BB72A8 4A1AFE6A 0BBAD18D 3EACC7B4 54AF408D + 4F1CCB23 B9AE576F DAE2D1A6 8F43D275 741DB19E EDC3B81B 5E56964F 5F8C3363 + ]])] = "openssl/4096-bit MODP group with safe prime modulus", + + [fromhex([[ + FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 29024E08 8A67CC74 + 020BBEA6 3B139B22 514A0879 8E3404DD EF9519B3 CD3A431B 302B0A6D F25F1437 + 4FE1356D 6D51C245 E485B576 625E7EC6 F44C42E9 A63A3620 FFFFFFFF FFFFFFFF + ]])] = "RFC2409/Oakley Group 1", + + [fromhex([[ + FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 29024E08 8A67CC74 + 020BBEA6 3B139B22 514A0879 8E3404DD EF9519B3 CD3A431B 302B0A6D F25F1437 + 4FE1356D 6D51C245 E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED + EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381 FFFFFFFF FFFFFFFF + ]])] = "RFC2409/Oakley Group 2", + + [fromhex([[ + FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 29024E08 8A67CC74 + 020BBEA6 3B139B22 514A0879 8E3404DD EF9519B3 CD3A431B 302B0A6D F25F1437 + 4FE1356D 6D51C245 E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED + EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D C2007CB8 A163BF05 + 98DA4836 1C55D39A 69163FA8 FD24CF5F 83655D23 DCA3AD96 1C62F356 208552BB + 9ED52907 7096966D 670C354E 4ABC9804 F1746C08 CA237327 FFFFFFFF FFFFFFFF + ]])] = "RFC3526/Oakley Group 5", + + [fromhex([[ + FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 29024E08 8A67CC74 + 020BBEA6 3B139B22 514A0879 8E3404DD EF9519B3 CD3A431B 302B0A6D F25F1437 + 4FE1356D 6D51C245 E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED + EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D C2007CB8 A163BF05 + 98DA4836 1C55D39A 69163FA8 FD24CF5F 83655D23 DCA3AD96 1C62F356 208552BB + 9ED52907 7096966D 670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B + E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9 DE2BCBF6 95581718 + 3995497C EA956AE5 15D22618 98FA0510 15728E5A 8AACAA68 FFFFFFFF FFFFFFFF + ]])] = "RFC3526/Oakley Group 14", + + [fromhex([[ + FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 29024E08 8A67CC74 + 020BBEA6 3B139B22 514A0879 8E3404DD EF9519B3 CD3A431B 302B0A6D F25F1437 + 4FE1356D 6D51C245 E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED + EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D C2007CB8 A163BF05 + 98DA4836 1C55D39A 69163FA8 FD24CF5F 83655D23 DCA3AD96 1C62F356 208552BB + 9ED52907 7096966D 670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B + E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9 DE2BCBF6 95581718 + 3995497C EA956AE5 15D22618 98FA0510 15728E5A 8AAAC42D AD33170D 04507A33 + A85521AB DF1CBA64 ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7 + ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B F12FFA06 D98A0864 + D8760273 3EC86A64 521F2B18 177B200C BBE11757 7A615D6C 770988C0 BAD946E2 + 08E24FA0 74E5AB31 43DB5BFC E0FD108E 4B82D120 A93AD2CA FFFFFFFF FFFFFFFF + ]])] = "RFC3526/Oakley Group 15", + + [fromhex([[ + FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 29024E08 8A67CC74 + 020BBEA6 3B139B22 514A0879 8E3404DD EF9519B3 CD3A431B 302B0A6D F25F1437 + 4FE1356D 6D51C245 E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED + EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D C2007CB8 A163BF05 + 98DA4836 1C55D39A 69163FA8 FD24CF5F 83655D23 DCA3AD96 1C62F356 208552BB + 9ED52907 7096966D 670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B + E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9 DE2BCBF6 95581718 + 3995497C EA956AE5 15D22618 98FA0510 15728E5A 8AAAC42D AD33170D 04507A33 + A85521AB DF1CBA64 ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7 + ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B F12FFA06 D98A0864 + D8760273 3EC86A64 521F2B18 177B200C BBE11757 7A615D6C 770988C0 BAD946E2 + 08E24FA0 74E5AB31 43DB5BFC E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7 + 88719A10 BDBA5B26 99C32718 6AF4E23C 1A946834 B6150BDA 2583E9CA 2AD44CE8 + DBBBC2DB 04DE8EF9 2E8EFC14 1FBECAA6 287C5947 4E6BC05D 99B2964F A090C3A2 + 233BA186 515BE7ED 1F612970 CEE2D7AF B81BDD76 2170481C D0069127 D5B05AA9 + 93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34063199 FFFFFFFF FFFFFFFF + ]])] = "RFC3526/Oakley Group 16", + + [fromhex([[ + B10B8F96 A080E01D DE92DE5E AE5D54EC 52C99FBC FB06A3C6 9A6A9DCA 52D23B61 + 6073E286 75A23D18 9838EF1E 2EE652C0 13ECB4AE A9061123 24975C3C D49B83BF + ACCBDD7D 90C4BD70 98488E9C 219A7372 4EFFD6FA E5644738 FAA31A4F F55BCCC0 + A151AF5F 0DC8B4BD 45BF37DF 365C1A65 E68CFDA7 6D4DA708 DF1FB2BC 2E4A4371 + ]])] = "RFC5114/1024-bit DSA group with 160-bit prime order subgroup", + + [fromhex([[ + AD107E1E 9123A9D0 D660FAA7 9559C51F A20D64E5 683B9FD1 B54B1597 B61D0A75 + E6FA141D F95A56DB AF9A3C40 7BA1DF15 EB3D688A 309C180E 1DE6B85A 1274A0A6 + 6D3F8152 AD6AC212 9037C9ED EFDA4DF8 D91E8FEF 55B7394B 7AD5B7D0 B6C12207 + C9F98D11 ED34DBF6 C6BA0B2C 8BBC27BE 6A00E0A0 B9C49708 B3BF8A31 70918836 + 81286130 BC8985DB 1602E714 415D9330 278273C7 DE31EFDC 7310F712 1FD5A074 + 15987D9A DC0A486D CDF93ACC 44328387 315D75E1 98C641A4 80CD86A1 B9E587E8 + BE60E69C C928B2B9 C52172E4 13042E9B 23F10B0E 16E79763 C9B53DCF 4BA80A29 + E3FB73C1 6B8E75B9 7EF363E2 FFA31F71 CF9DE538 4E71B81C 0AC4DFFE 0C10E64F + ]])] = "RFC5114/2048-bit DSA group with 224-bit prime order subgroup", + + [fromhex([[ + 87A8E61D B4B6663C FFBBD19C 65195999 8CEEF608 660DD0F2 5D2CEED4 435E3B00 + E00DF8F1 D61957D4 FAF7DF45 61B2AA30 16C3D911 34096FAA 3BF4296D 830E9A7C + 209E0C64 97517ABD 5A8A9D30 6BCF67ED 91F9E672 5B4758C0 22E0B1EF 4275BF7B + 6C5BFC11 D45F9088 B941F54E B1E59BB8 BC39A0BF 12307F5C 4FDB70C5 81B23F76 + B63ACAE1 CAA6B790 2D525267 35488A0E F13C6D9A 51BFA4AB 3AD83477 96524D8E + F6A167B5 A41825D9 67E144E5 14056425 1CCACB83 E6B486F6 B3CA3F79 71506026 + C0B857F6 89962856 DED4010A BD0BE621 C3A3960A 54E710C3 75F26375 D7014103 + A4B54330 C198AF12 6116D227 6E11715F 693877FA D7EF09CA DB094AE9 1E1A1597 + ]])] = "RFC5114/2048-bit DSA group with 256-bit prime order subgroup", + + [fromhex([[ + D6C094AD 57F5374F 68D58C7B 096872D9 45CEE1F8 2664E059 4421E1D5 E3C8E98B + C3F0A6AF 8F92F19E 3FEF9337 B99B9C93 A055D55A 96E42573 4005A68E D47040FD + F00A5593 6EBA4B93 F64CBA1A 004E4513 611C9B21 7438A703 A2060C20 38D0CFAA + FFBBA48F B9DAC4B2 450DC58C B0320A03 17E2A31B 44A02787 C657FB0C 0CBEC11D + ]])] = "weakdh.org/1024-bit MODP group with non-safe prime modulus", + + [fromhex([[ + C9BBF5F7 74A8297B 0F97CDDA 3A3468C7 117B6BF7 99A13D9F 1F5DAC48 7B2241FE + 95EFB13C 2855DFD2 F898B3F9 9188E24E DF326DD6 8C76CC85 53728351 2D46F195 + 3129C693 364D8C71 202EABB3 EBC85C1D F53907FB D0B7EB49 0AD0BC99 28968680 + 0C46AB04 BF7CDD9A D425E6FB 25592EB6 258A0655 D75E93B2 671746AE 349E721B + ]])] = "weakdh.org/1024-bit MODP group with safe prime modulus", + + [fromhex([[ + 829FEBFC E3EE0434 862D3364 A62BDE7B 65F0C74A 3A53B555 291414FC AE5E86D7 + 34B16DBD CC952B1C 5EB443B1 54B3B466 62E811E1 1D8BC731 34018A5E A7B5B6A9 + 720D84BC 28B74822 C5AF24C9 04E5BB5A DABF8FF2 A5ED7B45 6688D6CA B82F8AF0 + 188A456C 3ED62D2F EACF6BD3 FD47337D 884DFA09 F0A3D696 75E35806 E3AE9593 + ]])] = "weakdh.org/1024-bit MODP group with safe prime modulus", + + [fromhex([[ + 92402435 C3A12E44 D3730D8E 78CADFA7 8E2F5B51 A956BFF4 DB8E5652 3E9695E6 + 3E32506C FEB912F2 A77D22E7 1BB54C86 80893B82 AD1BCF33 7F7F7796 D3FB9681 + 81D9BA1F 7034ABFB 1F97B310 4CF3203F 663E8199 0B7E090F 6C4C5EE1 A0E57EC1 + 74D3E84A D9E72E6A C7DA6AEA 12DF297C 131854FB F21AC4E8 79C23BBC 60B4F753 + ]])] = "weakdh.org/1024-bit MODP group with safe prime modulus", + + [fromhex([[ + A9A34811 446C7B69 A29FF999 7C2181EC FAAAD139 CCDE2455 755D42F4 2E700AFD + 86779D54 8A7C07CA 5DE42332 61117D0A 5773F245 9C331AF1 A1B08EF8 360A14DE + 4046F274 62DA36AA 47D9FDE2 92B8815D 598C3A9C 546E7ED3 95D22EC3 9119F5B9 + 22CC41B3 0AF220FF 47BDE1B8 8334AD29 81DDC5ED 923F11C3 DDD3B22C 949DC41B + ]])] = "weakdh.org/1024-bit MODP group with safe prime modulus", + + [fromhex([[ + CA6B8564 6DC21765 7605DACF E801FAD7 59845383 4AF126C8 CC765E0F 81014F24 + 93546AB7 DDE5C677 C32D5B06 05B1BBFA 4C5DBFA3 253ADB33 205B7D8C 67DF98C4 + BCE81C78 13F9FC26 15F1C332 F953AB39 CE8B7FE7 E3951FB7 3131407F 4D5489B6 + B17C6875 9A2EAF8B 195A8DE8 0A165E4E B7520774 B167A00F A5629FDC 5A9A25F3 + ]])] = "weakdh.org/1024-bit MODP group with safe prime modulus", + + [fromhex([[ + EB373E94 AB618DF8 20D233ED 93E3EBCB 319BDAC2 0994C1DF 003986A7 9FAFFF76 + 54151CC9 E0641314 92698B47 496F5FDC FAF12892 679D8BC3 1580D7D4 1CD83F81 + 529C7951 3D58EC67 2E0E87FC D008C137 E3E5861A B2D3A02F 4D372CEE 4F220FEB + 2C9039AC 997664A7 EBB75444 6AA69EB3 E0EF3C60 F91C2639 2B54EC35 A970A7BB + ]])] = "weakdh.org/1024-bit MODP group with safe prime modulus", + + [fromhex([[ + 80A68ADC 5327E05C AAD07C44 64B8ADEA 908432AF 9651B237 F47A7A8B F84D568F + DFDAFAB0 6621C0C4 28450F1C 55F7D4A8 ECE383F2 7D6055AD DF60C4B8 37DCC1E3 + B8374E37 99517929 39FDC3BB B4285112 C8B4A9F6 FCE4DD53 AA23F99E 2647C394 + CE4D8BB8 2E773F41 EB786CE8 4CD0C3DD 4C31D755 D1CF9E9B 70C45EE2 8ECDABAB + ]])] = "weakdh.org/1024-bit MODP group with safe prime modulus", + + [fromhex([[ + C0EB5F3A 4CB30A9F FE3786E8 4C038141 69B52030 5AD49F54 EFD8CAAC 31A69B29 + 73CC9F57 B4B8F80D 2C5FB68B 3913B617 2042D2E5 BD53381A 5E597696 C9E97BD6 + 488DB339 5581320D DD4AF9CD E4A4EBE2 9118C688 28E5B392 89C26728 0B4FDC25 + 10C288B2 174D77EE 0AAD9C1E 17EA5ED3 7CF971B6 B19A8711 8E529826 591CA14B + ]])] = "weakdh.org/1024-bit MODP group with safe prime modulus", + + [fromhex([[ + 8FC0E1E2 0574D6AB 3C76DDEA 64524C20 76446B67 98E5B6BD 2614F966 9A5061D6 + 99034DB4 819780EC 8EE28A4E 66B5C4E0 A634E47B F9C981A5 EC4908EE 1B83A410 + 813165AC 0AB6BDCF D3257188 AC49399D 541C16F2 960F9D64 B9C51EC0 85AD0BB4 + FE389013 18F0CD61 65D4B1B3 1C723953 B83217F8 B3EBF870 8160E82D 7911754B + ]])] = "weakdh.org/1024-bit MODP group with safe prime modulus", + + -- haproxy, postfix, and IronPort params courtesy Frank Bergmann + [fromhex([[ + EC86F870 A03316EC 051A7359 CD1F8BF8 29E4D2CF 52DDC224 8DB5389A FB5CA4E4 + B2DACE66 5074A685 4D4B1D30 B82BF310 E9A72D05 71E781DF 8B59523B 5F430B68 + F1DB07BE 086B1B23 EE4DCC9E 0E43A01E DF438CEC BEBE90B4 5154B92F 7B64764E + 5DD42EAE C29EAE51 4359C777 9C503C0E ED73045F F14C762A D8F8CFFC 3440D1B4 + 42618466 423904F8 68B262D7 55ED1B74 7591E0C5 69C1315C DB7B442E CE84580D + 1E660CC8 449EFD40 08675DFB A7768F00 1187E993 F97DC4BC 745520D4 4A412F43 + 421AC1F2 97174927 376B2F88 7E1CA0A1 899227D9 565A71C1 56377E3A 9D05E7EE + 5D8F8217 BCE9C293 3082F9F4 C9AE49DB D054B4D9 754DFA06 B8D63841 B71F77F3 + ]])] = "haproxy 1.5 builtin", + + [fromhex([[ + B0FEB4CF D45507E7 CC88590D 1726C50C A54A9223 8178DA88 AA4C1306 BF5D2F9E + BC96B851 009D0C0D 75ADFD3B B17E714F 3F915414 44B83025 1CEBDF72 9C4CF189 + 0D683F94 8EA4FB76 8918B291 16900199 668C5381 4E273D99 E75A7AAF D5ECE27E + FAED0118 C2782559 065C39F6 CD4954AF C1B1EA4A F953D0DF 6DAFD493 E7BAAE9B + ]])] = "postfix builtin", + + [fromhex([[ + F8D5CCE8 7A3961B5 F5CBC834 40C51856 E0E6FA6D 5AB28310 78C86762 1CA46CA8 + 7D7FA3B1 AF75B834 3C699374 D36920F2 E39A653D E8F0725A A6E2D297 7537558C + E27E784F 4B549BEF B558927B A30C8BD8 1DACDCAE 93027B5D CE1BC176 70AF7DEC + E81149AB D7D632D9 B80A6397 CEBCC7A9 619CCF38 288EA3D5 23287743 B04E6FB3 + ]])] = "IronPort SMTPD builtin", +} + + +-- DSA parameters +local DSA_PARAMS = { + -- sun.security.provider/512-bit DSA group with 160-bit prime order subgroup + [fromhex([[ + FCA682CE 8E12CABA 26EFCCF7 110E526D B078B05E DECBCD1E B4A208F3 AE1617AE + 01F35B91 A47E6DF6 3413C5E1 2ED0899B CD132ACD 50D99151 BDC43EE7 37592E17 + ]])] = + + fromhex([[ + 678471B2 7A9CF44E E91A49C5 147DB1A9 AAF244F0 5A434D64 86931D2D 14271B9E + 35030B71 FD73DA17 9069B32E 2935630E 1C206235 4D0DA20A 6C416E50 BE794CA4 + ]]), + + -- sun.security.provider/768-bit DSA group with 160-bit prime order subgroup + [fromhex([[ + E9E64259 9D355F37 C97FFD35 67120B8E 25C9CD43 E927B3A9 670FBEC5 D8901419 + 22D2C3B3 AD248009 3799869D 1E846AAB 49FAB0AD 26D2CE6A 22219D47 0BCE7D77 + 7D4A21FB E9C270B5 7F607002 F3CEF839 3694CF45 EE3688C1 1A8C56AB 127A3DAF + ]])] = + + fromhex([[ + 30470AD5 A005FB14 CE2D9DCD 87E38BC7 D1B1C5FA CBAECBE9 5F190AA7 A31D23C4 + DBBCBE06 17454440 1A5B2C02 0965D8C2 BD2171D3 66844577 1F74BA08 4D2029D8 + 3C1C1585 47F3A9F1 A2715BE2 3D51AE4D 3E5A1F6A 7064F316 933A346D 3F529252 + ]]), + + -- sun.security.provider/1024-bit DSA group with 160-bit prime order subgroup + [fromhex([[ + FD7F5381 1D751229 52DF4A9C 2EECE4E7 F611B752 3CEF4400 C31E3F80 B6512669 + 455D4022 51FB593D 8D58FABF C5F5BA30 F6CB9B55 6CD7813B 801D346F F26660B7 + 6B9950A5 A49F9FE8 047B1022 C24FBBA9 D7FEB7C6 1BF83B57 E7C6A8A6 150F04FB + 83F6D3C5 1EC30235 54135A16 9132F675 F3AE2B61 D72AEFF2 2203199D D14801C7 + ]])] = + + fromhex([[ + F7E1A085 D69B3DDE CBBCAB5C 36B857B9 7994AFBB FA3AEA82 F9574C0B 3D078267 + 5159578E BAD4594F E6710710 8180B449 167123E8 4C281613 B7CF0932 8CC8A6E1 + 3C167A8B 547C8D28 E0A3AE1E 2BB3A675 916EA37F 0BFA2135 62F1FB62 7A01243B + CCA4F1BE A8519089 A883DFE1 5AE59F06 928B665E 807B5525 64014C3B FECF492A + ]]), + + -- RFC5114/1024-bit DSA group with 160-bit prime order subgroup + [fromhex([[ + B10B8F96 A080E01D DE92DE5E AE5D54EC 52C99FBC FB06A3C6 9A6A9DCA 52D23B61 + 6073E286 75A23D18 9838EF1E 2EE652C0 13ECB4AE A9061123 24975C3C D49B83BF + ACCBDD7D 90C4BD70 98488E9C 219A7372 4EFFD6FA E5644738 FAA31A4F F55BCCC0 + A151AF5F 0DC8B4BD 45BF37DF 365C1A65 E68CFDA7 6D4DA708 DF1FB2BC 2E4A4371 + ]])] = + + fromhex([[ + A4D1CBD5 C3FD3412 6765A442 EFB99905 F8104DD2 58AC507F D6406CFF 14266D31 + 266FEA1E 5C41564B 777E690F 5504F213 160217B4 B01B886A 5E91547F 9E2749F4 + D7FBD7D3 B9A92EE1 909D0D22 63F80A76 A6A24C08 7A091F53 1DBF0A01 69B6A28A + D662A4D1 8E73AFA3 2D779D59 18D08BC8 858F4DCE F97C2A24 855E6EEB 22B3B2E5 + ]]), + + -- RFC5114/2048-bit DSA group with 224-bit prime order subgroup + [fromhex([[ + AD107E1E 9123A9D0 D660FAA7 9559C51F A20D64E5 683B9FD1 B54B1597 B61D0A75 + E6FA141D F95A56DB AF9A3C40 7BA1DF15 EB3D688A 309C180E 1DE6B85A 1274A0A6 + 6D3F8152 AD6AC212 9037C9ED EFDA4DF8 D91E8FEF 55B7394B 7AD5B7D0 B6C12207 + C9F98D11 ED34DBF6 C6BA0B2C 8BBC27BE 6A00E0A0 B9C49708 B3BF8A31 70918836 + 81286130 BC8985DB 1602E714 415D9330 278273C7 DE31EFDC 7310F712 1FD5A074 + 15987D9A DC0A486D CDF93ACC 44328387 315D75E1 98C641A4 80CD86A1 B9E587E8 + BE60E69C C928B2B9 C52172E4 13042E9B 23F10B0E 16E79763 C9B53DCF 4BA80A29 + E3FB73C1 6B8E75B9 7EF363E2 FFA31F71 CF9DE538 4E71B81C 0AC4DFFE 0C10E64F + ]])] = + + fromhex([[ + AC4032EF 4F2D9AE3 9DF30B5C 8FFDAC50 6CDEBE7B 89998CAF 74866A08 CFE4FFE3 + A6824A4E 10B9A6F0 DD921F01 A70C4AFA AB739D77 00C29F52 C57DB17C 620A8652 + BE5E9001 A8D66AD7 C1766910 1999024A F4D02727 5AC1348B B8A762D0 521BC98A + E2471504 22EA1ED4 09939D54 DA7460CD B5F6C6B2 50717CBE F180EB34 118E98D1 + 19529A45 D6F83456 6E3025E3 16A330EF BB77A86F 0C1AB15B 051AE3D4 28C8F8AC + B70A8137 150B8EEB 10E183ED D19963DD D9E263E4 770589EF 6AA21E7F 5F2FF381 + B539CCE3 409D13CD 566AFBB4 8D6C0191 81E1BCFE 94B30269 EDFE72FE 9B6AA4BD + 7B5A0F1C 71CFFF4C 19C418E1 F6EC0179 81BC087F 2A7065B3 84B890D3 191F2BFA + ]]), + + -- RFC5114/2048-bit DSA group with 256-bit prime order subgroup + [fromhex([[ + 87A8E61D B4B6663C FFBBD19C 65195999 8CEEF608 660DD0F2 5D2CEED4 435E3B00 + E00DF8F1 D61957D4 FAF7DF45 61B2AA30 16C3D911 34096FAA 3BF4296D 830E9A7C + 209E0C64 97517ABD 5A8A9D30 6BCF67ED 91F9E672 5B4758C0 22E0B1EF 4275BF7B + 6C5BFC11 D45F9088 B941F54E B1E59BB8 BC39A0BF 12307F5C 4FDB70C5 81B23F76 + B63ACAE1 CAA6B790 2D525267 35488A0E F13C6D9A 51BFA4AB 3AD83477 96524D8E + F6A167B5 A41825D9 67E144E5 14056425 1CCACB83 E6B486F6 B3CA3F79 71506026 + C0B857F6 89962856 DED4010A BD0BE621 C3A3960A 54E710C3 75F26375 D7014103 + A4B54330 C198AF12 6116D227 6E11715F 693877FA D7EF09CA DB094AE9 1E1A1597 + ]])] = + + fromhex([[ + 3FB32C9B 73134D0B 2E775066 60EDBD48 4CA7B18F 21EF2054 07F4793A 1A0BA125 + 10DBC150 77BE463F FF4FED4A AC0BB555 BE3A6C1B 0C6B47B1 BC3773BF 7E8C6F62 + 901228F8 C28CBB18 A55AE313 41000A65 0196F931 C77A57F2 DDF463E5 E9EC144B + 777DE62A AAB8A862 8AC376D2 82D6ED38 64E67982 428EBC83 1D14348F 6F2F9193 + B5045AF2 767164E1 DFC967C1 FB3F2E55 A4BD1BFF E83B9C80 D052B985 D182EA0A + DB2A3B73 13D3FE14 C8484B1E 052588B9 B7D2BBD2 DF016199 ECD06E15 57CD0915 + B3353BBB 64E0EC37 7FD02837 0DF92B52 C7891428 CDC67EB6 184B523D 1DB246C3 + 2F630784 90F00EF8 D647D148 D4795451 5E2327CF EF98C582 664B4C0F 6CC41659 + ]]) +} + + +-- Add additional context (protocol) to debug output +local function ctx_log(level, protocol, fmt, ...) + return stdnse.debug(level, "(%s) " .. fmt, protocol, ...) +end + + +-- returns a function that yields a new tls record each time it is called +local function get_record_iter(sock) + local buffer = "" + local i = 1 + local fragment + return function () + local record + i, record = tls.record_read(buffer, i, fragment) + if record == nil then + local status, err + status, buffer, err = tls.record_buffer(sock, buffer, i) + if not status then + return nil, err + end + i, record = tls.record_read(buffer, i, fragment) + if record == nil then + return nil, "done" + end + end + fragment = record.fragment + return record + end +end + + +local function get_server_response(host, port, t) + local timeout = stdnse.get_timeout(host, 10000, 5000) + + -- Create socket. + local status, sock, err + local starttls = sslcert.getPrepareTLSWithoutReconnect(port) + if starttls then + status, sock = starttls(host, port) + if not status then + ctx_log(1, t.protocol, "Can't connect: %s", sock) + return nil + end + else + sock = nmap.new_socket() + sock:set_timeout(timeout) + status, err = sock:connect(host, port) + if not status then + ctx_log(1, t.protocol, "Can't connect: %s", err) + sock:close() + return nil + end + end + + sock:set_timeout(timeout) + + -- Send request. + local req = tls.client_hello(t) + status, err = sock:send(req) + if not status then + ctx_log(1, t.protocol, "Can't send: %s", err) + sock:close() + return nil + end + + -- Read response. + local get_next_record = get_record_iter(sock) + local records = {} + while true do + local record + record, err = get_next_record() + if not record then + ctx_log(1, t.protocol, "Couldn't read a TLS record: %s", err) + sock:close() + return records + end + -- Collect message bodies into one record per type + records[record.type] = records[record.type] or record + local done = false + for j = 1, #record.body do -- no ipairs because we append below + local b = record.body[j] + done = ((record.type == "alert" and b.level == "fatal") or + (record.type == "handshake" and b.type == "server_hello_done")) + table.insert(records[record.type].body, b) + end + if done then + sock:close() + return records + end + end +end + +-- If protocol fails (i.e. no ciphers will ever succeed) then returns false +-- If no ciphers were supported, but the protocol is valid, then returns nil +-- else returns the cipher and dh params +local function get_dhe_params(host, port, protocol, ciphers) + local cipher, packed + local t = {} + local pos = 1 + t.protocol = protocol + local tlsname = tls.servername(host) + t.extensions = { + server_name = tlsname and tls.EXTENSION_HELPERS["server_name"](tlsname), + } + + -- Keep ClientHello record size below 255 bytes and the number of ciphersuites + -- to 64 or less in order to avoid implementation issues with some TLS servers + + -- Get handshake record size with just one cipher + t.ciphers = { "TLS_NULL_WITH_NULL_NULL" } + local len = #tls.client_hello(t) + local room = math.floor(math.max(0, (255 - len) / 2)) + + local function next_chunk(t, ciphers, pos) + + -- Compute number of ciphers to fit in next chunk + local last = math.min(#ciphers, pos + math.min(63, room)) + t.ciphers = {} + + for i = pos, last do + table.insert(t.ciphers, ciphers[i]) + end + + return last + 1 + end + + while pos <= #ciphers do + pos = next_chunk(t, ciphers, pos) + local records = get_server_response(host, port, t) + if not records then + stdnse.debug1("Connection failed") + return false + end + + local alert = records.alert + if alert then + for j = 1, #alert.body do + ctx_log(2, protocol, "Received alert: %s", alert.body[j].description) + if alert["protocol"] ~= protocol then + ctx_log(1, protocol, "Protocol rejected.") + return false + end + end + end + + -- Extract negotiated cipher suite and key exchange data + local handshake = records.handshake + if handshake then + for j = 1, #handshake.body do + if handshake.body[j].type == "server_hello" then + if handshake.body[j].protocol ~= protocol then + ctx_log(1, protocol, "Protocol rejected in server hello") + return false + end + cipher = handshake.body[j].cipher + elseif handshake.body[j].type == "server_key_exchange" then + packed = handshake.body[j].data + end + end + end + + -- Only try next chunk if current chunk was rejected + if cipher and packed then + local info = tls.cipher_info(cipher) + local data = tls.KEX_ALGORITHMS[info.kex].server_key_exchange(packed, protocol) + return cipher, data.dhparams + end + end + + return nil +end + + +local function get_dhe_ciphers() + local dh_anons = {} + local dhe_ciphers = {} + local dhe_exports = {} + + for cipher, _ in pairs(tls.CIPHERS) do + local info = tls.cipher_info(cipher) + if DH_anon_ALGORITHMS[info.kex] then + dh_anons[#dh_anons + 1] = cipher + end + if DHE_ALGORITHMS[info.kex] then + dhe_ciphers[#dhe_ciphers + 1] = cipher + end + if DHE_ALGORITHMS_EXPORT[info.kex] then + dhe_exports[#dhe_exports + 1] = cipher + end + end + + return dh_anons, dhe_ciphers, dhe_exports +end + +local fields_order = { + "Cipher Suite", + "Modulus Type", + "Modulus Source", + "Modulus Length", + "Generator Length", + "Public Key Length", +} +local group_metatable = { + __tostring = function(g) + local out = {} + for i=1, #fields_order do + local k = fields_order[i] + if g[k] then + out[#out+1] = (" %s: %s"):format(k, g[k]) + end + end + return table.concat(out, "\n") + end +} + +local function check_dhgroup(anondh, logjam, weakdh, nosafe, cipher, dhparams) + local source = DHE_PRIMES[dhparams.p] + local length = #dhparams.p * 8 + local genlen = #dhparams.g * 8 + local pubkeylen = #dhparams.y * 8 + local modulus = stdnse.tohex(dhparams.p) + local generator = stdnse.tohex(dhparams.g) + local pubkey = stdnse.tohex(dhparams.y) + local is_prime, is_safe + + local group = { + ["Cipher Suite"] = cipher, + ["Modulus Source"] = source or "Unknown/Custom-generated", + ["Modulus Length"] = length, + ["Modulus"] = modulus, + ["Generator Length"] = genlen, + ["Generator"] = generator, + ["Public Key Length"] = pubkeylen + } + setmetatable(group, group_metatable) + + if have_ssl then + local bn = openssl.bignum_bin2bn(dhparams.p) + is_safe, is_prime = openssl.bignum_is_safe_prime(bn) + group["Modulus Type"] = (is_safe and "Safe prime") or + (is_prime and "Non-safe prime") or + "Composite" + end + + if string.find(cipher, "DH_anon") then + anondh[#anondh + 1] = group + elseif string.find(cipher, "EXPORT") then + logjam[#logjam + 1] = group + elseif length <= 1024 then + weakdh[#weakdh + 1] = group + end + + -- The use of non-safe primes requires carefully generated parameters + -- in order to be secure. Do some rudimentary validation checks here. + if have_ssl and not is_safe and not DSA_PARAMS[dhparams.p] then + nosafe[#nosafe + 1] = group + elseif DSA_PARAMS[dhparams.p] and DSA_PARAMS[dhparams.p] ~= dhparams.g then + nosafe[#nosafe + 1] = group + end +end + + +portrule = function(host, port) + return shortport.ssl(host, port) or sslcert.getPrepareTLSWithoutReconnect(port) +end + +local function format_check(t, label) + local out = {} + for i, v in ipairs(t) do + out[i] = string.format("%s %d\n%s", label, i, v) + end + return out +end + +action = function(host, port) + local dh_anons, dhe_ciphers, dhe_exports = get_dhe_ciphers() + local cipher + local dhparams + local anondh = {} + local logjam = {} + local weakdh = {} + local nosafe = {} + local primes = {} + local anons = {} + + local vuln_table_anondh = { + title = "Anonymous Diffie-Hellman Key Exchange MitM Vulnerability", + description = [[ +Transport Layer Security (TLS) services that use anonymous +Diffie-Hellman key exchange only provide protection against passive +eavesdropping, and are vulnerable to active man-in-the-middle attacks +which could completely compromise the confidentiality and integrity +of any data exchanged over the resulting session.]], + state = vulns.STATE.NOT_VULN, + references = { + "https://www.ietf.org/rfc/rfc2246.txt" + } + } + + local vuln_table_logjam = { + title = "Transport Layer Security (TLS) Protocol DHE_EXPORT Ciphers Downgrade MitM (Logjam)", + description = [[ +The Transport Layer Security (TLS) protocol contains a flaw that is +triggered when handling Diffie-Hellman key exchanges defined with +the DHE_EXPORT cipher. This may allow a man-in-the-middle attacker +to downgrade the security of a TLS session to 512-bit export-grade +cryptography, which is significantly weaker, allowing the attacker +to more easily break the encryption and monitor or tamper with +the encrypted stream.]], + state = vulns.STATE.NOT_VULN, + IDS = { + CVE = 'CVE-2015-4000', + BID = '74733' + }, + SCORES = { + CVSSv2 = '4.3' + }, + dates = { + disclosure = { + year = 2015, month = 5, day = 19 + } + }, + references = { + "https://weakdh.org" + } + } + + local vuln_table_weakdh = { + title = "Diffie-Hellman Key Exchange Insufficient Group Strength", + description = [[ +Transport Layer Security (TLS) services that use Diffie-Hellman groups +of insufficient strength, especially those using one of a few commonly +shared groups, may be susceptible to passive eavesdropping attacks.]], + state = vulns.STATE.NOT_VULN, + references = { + "https://weakdh.org" + } + } + + local vuln_table_nosafe = { + title = "Diffie-Hellman Key Exchange Incorrectly Generated Group Parameters", + description = [[ +This TLS service appears to be using a modulus that is not a safe prime +and does not correspond to any well-known DSA group for Diffie-Hellman +key exchange. +These parameters MAY be secure if: +- They were generated according to the procedure described in + FIPS 186-4 for DSA Domain Parameter Generation, or +- The generator g generates a subgroup of large prime order +Additional testing may be required to verify the security of these +parameters.]], + state = vulns.STATE.NOT_VULN, + references = { + "https://weakdh.org" + } + } + + for protocol in pairs(tls.PROTOCOLS) do + if protocol == "TLSv1.3" then + -- TLSv1.3 does not allow anonymous key exchange and only allows specific + -- DHE groups named in RFC 7919 + goto NEXT_PROTOCOL + end + -- Try anonymous DH ciphersuites + cipher, dhparams = get_dhe_params(host, port, protocol, dh_anons) + -- Explicit test for false needed because nil just means no ciphers supported. + if cipher == false then goto NEXT_PROTOCOL end + if dhparams and not anons[dhparams.p] then + vuln_table_anondh.state = vulns.STATE.VULN + check_dhgroup(anondh, logjam, weakdh, nosafe, cipher, dhparams) + anons[dhparams.p] = 1 + end + + -- Try DHE_EXPORT ciphersuites + cipher, dhparams = get_dhe_params(host, port, protocol, dhe_exports) + if dhparams and not primes[dhparams.p] then + check_dhgroup(anondh, logjam, weakdh, nosafe, cipher, dhparams) + primes[dhparams.p] = 1 + end + + -- Try non-export DHE ciphersuites + cipher, dhparams = get_dhe_params(host, port, protocol, dhe_ciphers) + if dhparams and not primes[dhparams.p] then + check_dhgroup(anondh, logjam, weakdh, nosafe, cipher, dhparams) + primes[dhparams.p] = 1 + end + ::NEXT_PROTOCOL:: + end + + local report = vulns.Report:new(SCRIPT_NAME, host, port) + + vuln_table_anondh.check_results = format_check(anondh, "ANONYMOUS DH GROUP") + vuln_table_logjam.check_results = format_check(logjam, "EXPORT-GRADE DH GROUP") + vuln_table_weakdh.check_results = format_check(weakdh, "WEAK DH GROUP") + vuln_table_nosafe.check_results = format_check(nosafe, "NON-SAFE GROUP") + + if #anondh > 0 then + vuln_table_anondh.state = vulns.STATE.VULN + end + + if #logjam > 0 then + vuln_table_logjam.state = vulns.STATE.VULN + end + + if #weakdh > 0 then + vuln_table_weakdh.state = vulns.STATE.VULN + end + + if #nosafe > 0 then + vuln_table_nosafe.state = vulns.STATE.LIKELY_VULN + end + + return report:make_output(vuln_table_anondh, vuln_table_logjam, vuln_table_weakdh, vuln_table_nosafe) +end |