🔒
TLSのversionを確認して、特定のバージョンでの動作確認を行う
備忘録としてまとめておきます。
特定の SSL/TLS のバージョンがサポートされているかを確認しつつ、動作確認をする (e.g. HTTPS Request が 200 OK を返す) ようなケースを想定しています。
TLSのversionを確認する
nmap の ssl-enum-ciphers
のスクリプトを利用します。
❯ nmap -V
Nmap version 7.93 ( https://nmap.org )
Platform: arm-apple-darwin21.6.0
Compiled with: liblua-5.3.6 openssl-1.1.1s libssh2-1.10.0 libz-1.2.11 libpcre-8.45 libpcap-1.9.1 nmap-libdnet-1.12 ipv6
Compiled without:
Available nsock engines: kqueue poll select
❯ nmap -h | grep script
-sC: equivalent to --script=default
--script=<Lua scripts>: <Lua scripts> is a comma separated list of
directories, script-files or script-categories
--script-args=<n1=v1,[n2=v2,...]>: provide arguments to scripts
--script-args-file=filename: provide NSE script args in a file
--script-trace: Show all data sent and received
--script-updatedb: Update the script database.
--script-help=<Lua scripts>: Show help about scripts.
<Lua scripts> is a comma-separated list of script-files or
script-categories.
-A: Enable OS detection, version detection, script scanning, and traceroute
オプションにも記載のある通り、script は Lua で実装されています。
出力結果は下記のような感じになります。
❯ nmap -sV --script ssl-enum-ciphers -p 443 google.com
Starting Nmap 7.93 ( https://nmap.org ) at 2022-12-04 20:28 JST
Nmap scan report for google.com (142.250.196.110)
Host is up (0.0049s latency).
rDNS record for 142.250.196.110: nrt12s35-in-f14.1e100.net
PORT STATE SERVICE VERSION
443/tcp open ssl/https gws
| fingerprint-strings:
| GetRequest:
| HTTP/1.0 200 OK
| Date: Sun, 04 Dec 2022 11:28:15 GMT
| Expires: -1
| Cache-Control: private, max-age=0
| Content-Type: text/html; charset=ISO-8859-1
| Cross-Origin-Opener-Policy-Report-Only: same-origin-allow-popups; report-to="gws"
| Report-To: {"group":"gws","max_age":2592000,"endpoints":[{"url":"https://csp.withgoogle.com/csp/report-to/gws/other"}]}
| P3P: CP="This is not a P3P policy! See g.co/p3phelp for more info."
| Server: gws
| X-XSS-Protection: 0
| X-Frame-Options: SAMEORIGIN
| Set-Cookie: 1P_JAR=2022-12-04-11; expires=Tue, 03-Jan-2023 11:28:15 GMT; path=/; domain=.google.com; Secure
| Set-Cookie: AEC=AakniGNu2qVzUr8xeccGgO2VOlq7QNTuPkN62NtAm7yp3nnddi9bXXXSfl0; expires=Fri, 02-Jun-2023 11:28:15 GMT; path=/; domain=.google.com; Secure; HttpOnly; SameSite=lax
| Set-Cookie: NID=511=ZP4aD2RiDXlGS0q90MhKG8ZAtU6YoarsnKdhzytOoy7S2Shhgu65ErVZ9oyWpKCYrFvCDTX57whRhZI_uP--28blHmyKk6nHowwA8MaD6AU7gRF4
| HTTPOptions:
| HTTP/1.0 405 Method Not Allowed
| Allow: GET, HEAD
| Date: Sun, 04 Dec 2022 11:28:15 GMT
| Content-Type: text/html; charset=UTF-8
| Server: gws
| Content-Length: 1592
| X-XSS-Protection: 0
| X-Frame-Options: SAMEORIGIN
| Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"
| <!DOCTYPE html>
| <html lang=en>
| <meta charset=utf-8>
| <meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width">
| <title>Error 405 (Method Not Allowed)!!1</title>
| <style>
|_ *{margin:0;padding:0}html,code{font:15px/22px arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px}* > body{background:url(//www.google.com/images/errors/robot.png) 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22p
|_http-server-header: gws
| ssl-enum-ciphers:
| TLSv1.0:
| ciphers:
| TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (ecdh_x25519) - A
| TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (ecdh_x25519) - A
| TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (ecdh_x25519) - A
| TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (ecdh_x25519) - A
| TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
| TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
| TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
| compressors:
| NULL
| cipher preference: server
| warnings:
| 64-bit block cipher 3DES vulnerable to SWEET32 attack
| TLSv1.1:
| ciphers:
| TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (ecdh_x25519) - A
| TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (ecdh_x25519) - A
| TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (ecdh_x25519) - A
| TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (ecdh_x25519) - A
| TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
| TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
| TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
| compressors:
| NULL
| cipher preference: server
| warnings:
| 64-bit block cipher 3DES vulnerable to SWEET32 attack
| TLSv1.2:
| ciphers:
| TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (ecdh_x25519) - A
| TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (ecdh_x25519) - A
| TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (ecdh_x25519) - A
| TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (ecdh_x25519) - A
| TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (ecdh_x25519) - A
| TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (ecdh_x25519) - A
| TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (ecdh_x25519) - A
| TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (ecdh_x25519) - A
| TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (ecdh_x25519) - A
| TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (ecdh_x25519) - A
| TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
| TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
| TLS_RSA_WITH_AES_128_GCM_SHA256 (rsa 2048) - A
| TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
| TLS_RSA_WITH_AES_256_GCM_SHA384 (rsa 2048) - A
| compressors:
| NULL
| cipher preference: client
| warnings:
| 64-bit block cipher 3DES vulnerable to SWEET32 attack
| TLSv1.3:
| ciphers:
| TLS_AKE_WITH_AES_128_GCM_SHA256 (ecdh_x25519) - A
| TLS_AKE_WITH_AES_256_GCM_SHA384 (ecdh_x25519) - A
| TLS_AKE_WITH_CHACHA20_POLY1305_SHA256 (ecdh_x25519) - A
| cipher preference: client
|_ least strength: C
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port443-TCP:V=7.93%T=SSL%I=7%D=12/4%Time=638C844F%P=arm-apple-darwin21.
SF:6.0%r(GetRequest,1AEA,"HTTP/1\.0\x20200\x20OK\r\nDate:\x20Sun,\x2004\x2
SF:0Dec\x202022\x2011:28:15\x20GMT\r\nExpires:\x20-1\r\nCache-Control:\x20
SF:private,\x20max-age=0\r\nContent-Type:\x20text/html;\x20charset=ISO-885
SF:9-1\r\nCross-Origin-Opener-Policy-Report-Only:\x20same-origin-allow-pop
SF:ups;\x20report-to=\"gws\"\r\nReport-To:\x20{\"group\":\"gws\",\"max_age
SF:\":2592000,\"endpoints\":\[{\"url\":\"https://csp\.withgoogle\.com/csp/
SF:report-to/gws/other\"}\]}\r\nP3P:\x20CP=\"This\x20is\x20not\x20a\x20P3P
SF:\x20policy!\x20See\x20g\.co/p3phelp\x20for\x20more\x20info\.\"\r\nServe
SF:r:\x20gws\r\nX-XSS-Protection:\x200\r\nX-Frame-Options:\x20SAMEORIGIN\r
SF:\nSet-Cookie:\x201P_JAR=2022-12-04-11;\x20expires=Tue,\x2003-Jan-2023\x
SF:2011:28:15\x20GMT;\x20path=/;\x20domain=\.google\.com;\x20Secure\r\nSet
SF:-Cookie:\x20AEC=AakniGNu2qVzUr8xeccGgO2VOlq7QNTuPkN62NtAm7yp3nnddi9bXXX
SF:Sfl0;\x20expires=Fri,\x2002-Jun-2023\x2011:28:15\x20GMT;\x20path=/;\x20
SF:domain=\.google\.com;\x20Secure;\x20HttpOnly;\x20SameSite=lax\r\nSet-Co
SF:okie:\x20NID=511=ZP4aD2RiDXlGS0q90MhKG8ZAtU6YoarsnKdhzytOoy7S2Shhgu65Er
SF:VZ9oyWpKCYrFvCDTX57whRhZI_uP--28blHmyKk6nHowwA8MaD6AU7gRF4")%r(HTTPOpti
SF:ons,7BC,"HTTP/1\.0\x20405\x20Method\x20Not\x20Allowed\r\nAllow:\x20GET,
SF:\x20HEAD\r\nDate:\x20Sun,\x2004\x20Dec\x202022\x2011:28:15\x20GMT\r\nCo
SF:ntent-Type:\x20text/html;\x20charset=UTF-8\r\nServer:\x20gws\r\nContent
SF:-Length:\x201592\r\nX-XSS-Protection:\x200\r\nX-Frame-Options:\x20SAMEO
SF:RIGIN\r\nAlt-Svc:\x20h3=\":443\";\x20ma=2592000,h3-29=\":443\";\x20ma=2
SF:592000,h3-Q050=\":443\";\x20ma=2592000,h3-Q046=\":443\";\x20ma=2592000,
SF:h3-Q043=\":443\";\x20ma=2592000,quic=\":443\";\x20ma=2592000;\x20v=\"46
SF:,43\"\r\n\r\n<!DOCTYPE\x20html>\n<html\x20lang=en>\n\x20\x20<meta\x20ch
SF:arset=utf-8>\n\x20\x20<meta\x20name=viewport\x20content=\"initial-scale
SF:=1,\x20minimum-scale=1,\x20width=device-width\">\n\x20\x20<title>Error\
SF:x20405\x20\(Method\x20Not\x20Allowed\)!!1</title>\n\x20\x20<style>\n\x2
SF:0\x20\x20\x20\*{margin:0;padding:0}html,code{font:15px/22px\x20arial,sa
SF:ns-serif}html{background:#fff;color:#222;padding:15px}body{margin:7%\x2
SF:0auto\x200;max-width:390px;min-height:180px;padding:30px\x200\x2015px}\
SF:*\x20>\x20body{background:url\(//www\.google\.com/images/errors/robot\.
SF:png\)\x20100%\x205px\x20no-repeat;padding-right:205px}p{margin:11px\x20
SF:0\x2022p");
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 75.19 seconds
TLSの特定のバージョンでHTTPS requestを送信する
curl で --tls-max
、--tls
のオプションを利用して、TLS バージョンの上限・下限を設定して、HTTP Request を送信します。
--tlsv1.x
のオプションだけでは下限のバージョンのみ設定するので、SSL/TLS handshake の中で client, server の両方が対応している version の中で最も高い TLS バージョンが選択されてしまうことがあります。
❯ curl --help all | grep tls
--proxy-tls13-ciphers <ciphersuite list> TLS 1.3 proxy cipher suites
--proxy-tlsauthtype <type> TLS authentication type for HTTPS proxy
--proxy-tlspassword <string> TLS password for HTTPS proxy
--proxy-tlsuser <name> TLS username for HTTPS proxy
--proxy-tlsv1 Use TLSv1 for HTTPS proxy
--tls-max <VERSION> Set maximum allowed TLS version
--tls13-ciphers <ciphersuite list> TLS 1.3 cipher suites to use
--tlsauthtype <type> TLS authentication type
--tlspassword TLS password
--tlsuser <name> TLS user name
-1, --tlsv1 Use TLSv1.0 or greater
--tlsv1.0 Use TLSv1.0 or greater
--tlsv1.1 Use TLSv1.1 or greater
--tlsv1.2 Use TLSv1.2 or greater
--tlsv1.3 Use TLSv1.3 or greater
出力結果は下記のような感じになります。
❯ curl -s -v --tlsv1.0 --tls-max 1.0 -o /dev/null https://cloud.google.com
* Trying 142.250.207.46:443...
* Connected to cloud.google.com (142.250.207.46) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/cert.pem
* CApath: none
* TLSv1.0 (OUT), TLS handshake, Client hello (1):
} [152 bytes data]
* TLSv1.0 (IN), TLS handshake, Server hello (2):
{ [96 bytes data]
* TLSv1.0 (IN), TLS handshake, Certificate (11):
{ [6448 bytes data]
* TLSv1.0 (IN), TLS handshake, Server key exchange (12):
{ [112 bytes data]
* TLSv1.0 (IN), TLS handshake, Server finished (14):
{ [4 bytes data]
* TLSv1.0 (OUT), TLS handshake, Client key exchange (16):
} [37 bytes data]
* TLSv1.0 (OUT), TLS change cipher, Change cipher spec (1):
} [1 bytes data]
* TLSv1.0 (OUT), TLS handshake, Finished (20):
} [16 bytes data]
* TLSv1.0 (IN), TLS change cipher, Change cipher spec (1):
{ [1 bytes data]
* TLSv1.0 (IN), TLS handshake, Finished (20):
{ [16 bytes data]
* SSL connection using TLSv1 / ECDHE-ECDSA-AES128-SHA
* ALPN, server accepted to use h2
* Server certificate:
* subject: CN=*.google.com
* start date: Nov 2 13:43:09 2022 GMT
* expire date: Jan 25 13:43:08 2023 GMT
* subjectAltName: host "cloud.google.com" matched cert's "*.google.com"
* issuer: C=US; O=Google Trust Services LLC; CN=GTS CA 1C3
* SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x15900ca00)
> GET / HTTP/2
> Host: cloud.google.com
> user-agent: curl/7.77.0
> accept: */*
>
< HTTP/2 200
< last-modified: Thu, 01 Dec 2022 22:23:58 GMT
< content-type: text/html; charset=utf-8
< set-cookie: _ga_devsite=GA1.3.2610108273.1670154189; Expires=Tue, 03 Dec 2024 11:43:09 GMT; Max-Age=63072000; Path=/
< content-security-policy: base-uri 'self'; object-src 'none'; script-src 'strict-dynamic' 'unsafe-inline' https: http: 'nonce-3RcjSdfu/X9S9kfGL98ZUwnoovwgpD' 'unsafe-eval'; report-uri https://csp.withgoogle.com/csp/devsite/v2
< strict-transport-security: max-age=63072000; includeSubdomains; preload
< x-frame-options: SAMEORIGIN
< x-xss-protection: 0
< x-content-type-options: nosniff
< cache-control: no-cache, must-revalidate
< expires: 0
< pragma: no-cache
< x-cloud-trace-context: a33112136a275d094a5b5c0f1572055e
< date: Sun, 04 Dec 2022 11:43:09 GMT
< server: Google Frontend
< content-length: 914180
< alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"
<
{ [1350 bytes data]
* Connection #0 to host cloud.google.com left intact
Discussion