summaryrefslogtreecommitdiffstats
path: root/scripts/ssl-dh-params.nse
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/ssl-dh-params.nse')
-rw-r--r--scripts/ssl-dh-params.nse941
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