mirror of
https://github.com/drwetter/testssl.sh.git
synced 2025-01-30 12:21:17 +01:00
Merge branch '3.2' into diffing_openssls
This commit is contained in:
commit
cbaa813a40
@ -12,6 +12,7 @@
|
||||
* Improved compatibility with Open/LibreSSL versions not supporting TLS 1.0-1.1 anymore
|
||||
* Renamed PFS/perfect forward secrecy --> FS/forward secrecy
|
||||
* Cipher list straightening
|
||||
* Support RFC 9150 cipher suites
|
||||
* Improved mass testing
|
||||
* Better align colors of ciphers with standard cipherlists
|
||||
* Save a few cycles for ROBOT
|
||||
@ -23,13 +24,16 @@
|
||||
* Test for STARTTLS injection vulnerabilities (SMTP, POP3, IMAP)
|
||||
* STARTTLS: XMPP server support, plus new set of OpenSSL-bad binaries
|
||||
* Several code improvements to STARTTLS, also better detection when no STARTTLS is offered
|
||||
* Renegotiation checks more reliable against different servers
|
||||
* STARTTLS on active directory service support
|
||||
* Security fixes: DNS and other input from servers
|
||||
* Don't penalize missing trust in rating when CA not in Java store
|
||||
* Added support for certificates with EdDSA signatures and public keys
|
||||
* Extract CA list shows supported certification authorities sent by the server
|
||||
* Wildcard certificates: detection and warning
|
||||
* TLS 1.2 and TLS 1.3 sig algs added
|
||||
* Check for ffdhe groups
|
||||
* Check for three KEMs in draft-kwiatkowski-tls-ecdhe-mlkem/draft-tls-westerbaan-xyber768d00
|
||||
* Show server supported signature algorithms
|
||||
* --add-ca can also now be a directory with \*.pem files
|
||||
* Warning of 398 day limit for certificates issued after 2020/9/1
|
||||
@ -41,6 +45,7 @@
|
||||
* DNS via proxy improvements
|
||||
* Client simulation runs in wide mode which is even better readable
|
||||
* Added --reqheader to support custom headers in HTTP requests
|
||||
* Search for more HTTP security headers on the server
|
||||
* Test for support for RFC 8879 certificate compression
|
||||
* Deprecating --fast and --ssl-native (warning but still av)
|
||||
* Compatible to GNU grep 3.8
|
||||
|
@ -1,21 +1,25 @@
|
||||
|
||||
### Contributions / participation
|
||||
### Contributing / participating
|
||||
|
||||
is always welcome, here @ github or via e-mail.
|
||||
Contributing / participating is always welcome!
|
||||
|
||||
Note please the following
|
||||
Please note the following:
|
||||
|
||||
* Please read at least the [coding convention](https://github.com/testssl/testssl.sh/Coding_Convention.md).
|
||||
* One PR per feature or bug fix or improvement. Please do not mix issues.
|
||||
* Document your PR, both in the PR and/or commit message and in the code.
|
||||
* Please read the [coding convention](https://github.com/testssl/testssl.sh/blob/3.2/Coding_Convention.md).
|
||||
* If you have something new and/or bigger which you like to contribute, better open an issue first before you get frustrated.
|
||||
* Please one pull request per feature or bug fix or improvement. Please do not mix issues.
|
||||
* Documentation pays off in the long run. So please your document your code and the pull request and/or commit message.
|
||||
* Please test your changes thoroughly as reliability is important for this project. You may want to check different servers with different settings.
|
||||
* Travis runs automatically when anything is committed/PR'd. You should check any complains from Travis. Beforehand you can check with `prove -v`.
|
||||
* If it's a new feature please consider writing a unit test for it. You can use e.g. `t/20_baseline_ipv4_http.t` as a template. The general documentation for [Test::More](https://perldoc.perl.org/Test/More.html) is a good start.
|
||||
* If it's a new feature it would need to be documented in the appropriate section in `help()` and in `~/doc/testssl.1.md`
|
||||
* GitHub actions are running automatically when anything is committed. You should see any complains. Beforehand you can check with `prove -v` from the "root dir" of this project.
|
||||
* If it's a new feature, please consider writing a unit test for it. You can use e.g. `t/10_baseline_ipv4_http.t` or `t/61_diff_testsslsh.t` as a template. The general documentation for [Test::More](https://perldoc.perl.org/Test/More.html) is a good start.
|
||||
* If it's a new feature, it would need to be documented in the appropriate section in `help()` and in `~/doc/testssl.1.md`
|
||||
|
||||
For questions just open an issue or feel free to send me an e-mail.
|
||||
If you're interested in contributing and wonder how you can help, you can search for different tags in the issues (somewhat increasing degree of difficulty):
|
||||
* [documentation](https://github.com/testssl/testssl.sh/issues?q=is:issue%20state:open%20label:documentation)
|
||||
* [good first issue](https://github.com/testssl/testssl.sh/issues?q=is:issue%20state:open%20label:%22good%20first%20issue%22)
|
||||
* [help wanted](https://github.com/testssl/testssl.sh/issues?q=is:issue%20state:open%20label:%22help%20wanted%22)
|
||||
* [for grabs](https://github.com/testssl/testssl.sh/issues?q=is:issue%20state:open%20label:%22good%20first%20issue%22)
|
||||
|
||||
For questions just open an issue. Thanks for reading this!
|
||||
|
||||
#### Patches via e-mail
|
||||
|
||||
Of course it is fine when you want to send in patches to use e-mail. For the address please grep for SWCONTACT in testssl.sh .
|
||||
Let me know how you like them to be attributed.
|
||||
|
@ -10,7 +10,7 @@ for some new / advanced cipher suites and/or features which are not in the
|
||||
official branch like (old version of the) CHACHA20+POLY1305 and CAMELLIA 256 bit ciphers.
|
||||
|
||||
The (stripped) binaries this directory are all compiled from my openssl snapshot
|
||||
(https://github.com/drwetter/openssl-1.0.2.bad) which adds a few bits to Peter
|
||||
(https://github.com/testssl/openssl-1.0.2.bad) which adds a few bits to Peter
|
||||
Mosman's openssl fork (https://github.com/PeterMosmans/openssl). Thx a bunch, Peter!
|
||||
The few bits are IPv6 support (except IPV6 proxy) and some STARTTLS backports.
|
||||
|
||||
@ -71,11 +71,11 @@ Compilation instructions
|
||||
If you want to compile OpenSSL yourself, here are the instructions:
|
||||
|
||||
1.)
|
||||
git git clone https://github.com/drwetter/openssl-1.0.2-bad
|
||||
git git clone https://github.com/testssl/openssl-1.0.2-bad
|
||||
cd openssl
|
||||
|
||||
|
||||
2.) configure the damned thing. Options I used (see https://github.com/drwetter/testssl.sh/blob/master/utils/make-openssl.sh)
|
||||
2.) configure the damned thing. Options I used (see https://github.com/testssl/testssl.sh/blob/master/utils/make-openssl.sh)
|
||||
|
||||
**for 64Bit including Kerberos ciphers:**
|
||||
|
||||
|
@ -607,4 +607,4 @@ All native Windows platforms emulating Linux are known to be slow\.
|
||||
.SH "BUGS"
|
||||
Probably\. Current known ones and interface for filing new ones: https://testssl\.sh/bugs/ \.
|
||||
.SH "SEE ALSO"
|
||||
\fBciphers\fR(1), \fBopenssl\fR(1), \fBs_client\fR(1), \fBx509\fR(1), \fBverify\fR(1), \fBocsp\fR(1), \fBcrl\fR(1), \fBbash\fR(1) and the websites https://testssl\.sh/ and https://github\.com/drwetter/testssl\.sh/ \.
|
||||
\fBciphers\fR(1), \fBopenssl\fR(1), \fBs_client\fR(1), \fBx509\fR(1), \fBverify\fR(1), \fBocsp\fR(1), \fBcrl\fR(1), \fBbash\fR(1) and the websites https://testssl\.sh/ and https://github\.com/testssl/testssl\.sh/ \.
|
||||
|
@ -681,7 +681,7 @@ from. That helps us to get bugfixes, other feedback and more contributions.</p>
|
||||
|
||||
<h2 id="SEE-ALSO">SEE ALSO</h2>
|
||||
|
||||
<p><span class="man-ref"><code>ciphers</code><span class="s">(1)</span></span>, <span class="man-ref"><code>openssl</code><span class="s">(1)</span></span>, <span class="man-ref"><code>s_client</code><span class="s">(1)</span></span>, <span class="man-ref"><code>x509</code><span class="s">(1)</span></span>, <span class="man-ref"><code>verify</code><span class="s">(1)</span></span>, <span class="man-ref"><code>ocsp</code><span class="s">(1)</span></span>, <span class="man-ref"><code>crl</code><span class="s">(1)</span></span>, <span class="man-ref"><code>bash</code><span class="s">(1)</span></span> and the websites https://testssl.sh/ and https://github.com/drwetter/testssl.sh/ .</p>
|
||||
<p><span class="man-ref"><code>ciphers</code><span class="s">(1)</span></span>, <span class="man-ref"><code>openssl</code><span class="s">(1)</span></span>, <span class="man-ref"><code>s_client</code><span class="s">(1)</span></span>, <span class="man-ref"><code>x509</code><span class="s">(1)</span></span>, <span class="man-ref"><code>verify</code><span class="s">(1)</span></span>, <span class="man-ref"><code>ocsp</code><span class="s">(1)</span></span>, <span class="man-ref"><code>crl</code><span class="s">(1)</span></span>, <span class="man-ref"><code>bash</code><span class="s">(1)</span></span> and the websites https://testssl.sh/ and https://github.com/testssl/testssl.sh/ .</p>
|
||||
|
||||
<ol class='man-decor man-foot man foot'>
|
||||
<li class='tl'></li>
|
||||
|
@ -587,4 +587,4 @@ Probably. Current known ones and interface for filing new ones: https://testssl.
|
||||
|
||||
## SEE ALSO
|
||||
|
||||
`ciphers`(1), `openssl`(1), `s_client`(1), `x509`(1), `verify`(1), `ocsp`(1), `crl`(1), `bash`(1) and the websites https://testssl.sh/ and https://github.com/drwetter/testssl.sh/ .
|
||||
`ciphers`(1), `openssl`(1), `s_client`(1), `x509`(1), `verify`(1), `ocsp`(1), `crl`(1), `bash`(1) and the websites https://testssl.sh/ and https://github.com/testssl/testssl.sh/ .
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
# data we need for socket based handshakes
|
||||
# see #807 and #806 (especially
|
||||
# https://github.com/drwetter/testssl.sh/issues/806#issuecomment-318686374)
|
||||
# https://github.com/testssl/testssl.sh/issues/806#issuecomment-318686374)
|
||||
|
||||
# 7 ciphers defined for TLS 1.3 in RFCs 8446 and 9150
|
||||
readonly TLS13_CIPHER="
|
||||
|
@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
# disabled as IPv6 is not supported by Travis, see https://github.com/drwetter/testssl.sh/issues/1177
|
||||
# disabled as IPv6 wasn't supported by Travis CI and isn't by GH action, see https://github.com/testssl/testssl.sh/issues/1177
|
||||
|
||||
# Just a functional test, whether there are any problems on the client side
|
||||
# Probably we could also inspect the JSON for any problems for
|
||||
|
@ -3,11 +3,10 @@
|
||||
# Baseline diff test against testssl.sh (csv output)
|
||||
#
|
||||
# We don't use a full run yet and only the certificate section.
|
||||
# There we would need to blacklist at least:
|
||||
# There we would need to blacklist more, like:
|
||||
# cert_serialNumber, cert_fingerprintSHA1, cert_fingerprintSHA256, cert
|
||||
# cert_expirationStatus, cert_notBefore, cert_notAfter, cert_caIssuers, intermediate_cert
|
||||
#
|
||||
# help is appreciated here
|
||||
|
||||
use strict;
|
||||
use Test::More;
|
||||
@ -16,55 +15,54 @@ use Text::Diff;
|
||||
|
||||
my $tests = 0;
|
||||
my $prg="./testssl.sh";
|
||||
my $master_socket_csv="./t/baseline_data/default_testssl.csvfile";
|
||||
my $socket_csv="tmp.csv";
|
||||
my $check2run="-p -s -P --fs -h -U -c -q --ip=one --color 0 --csvfile $socket_csv";
|
||||
#my $check2run="-p --color 0 --csvfile $socket_csv";
|
||||
my $baseline_csv="./t/baseline_data/default_testssl.csvfile";
|
||||
my $cat_csv="tmp.csv";
|
||||
my $check2run="-p -s -P --fs -h -U -c -q --ip=one --color 0 --csvfile $cat_csv";
|
||||
my $uri="testssl.sh";
|
||||
my $diff="";
|
||||
|
||||
die "Unable to open $prg" unless -f $prg;
|
||||
die "Unable to open $master_socket_csv" unless -f $master_socket_csv;
|
||||
|
||||
die "Unable to open $baseline_csv" unless -f $baseline_csv;
|
||||
|
||||
# Provide proper start conditions
|
||||
unlink "tmp.csv";
|
||||
unlink $cat_csv;
|
||||
|
||||
# Title
|
||||
printf "\n%s\n", "Diff unit test IPv4 against \"$uri\"";
|
||||
my @args=("$prg", "$check2run", "$uri", "2>&1");
|
||||
|
||||
#1 run
|
||||
`$prg $check2run $uri 2>&1`;
|
||||
printf "\n%s\n", "Diff unit test (IPv4) against \"$uri\"";
|
||||
printf "@args\n";
|
||||
system("@args") == 0
|
||||
or die ("FAILED: \"@args\" ");
|
||||
|
||||
$diff = diff $socket_csv, $master_socket_csv;
|
||||
|
||||
$socket_csv=`cat tmp.csv`;
|
||||
$master_socket_csv=`cat $master_socket_csv`;
|
||||
$cat_csv=`cat $cat_csv`;
|
||||
$baseline_csv=`cat $baseline_csv`;
|
||||
|
||||
# Filter for changes that are allowed to occur
|
||||
$socket_csv=~ s/HTTP_clock_skew.*\n//g;
|
||||
$master_socket_csv=~ s/HTTP_clock_skew.*\n//g;
|
||||
|
||||
# DROWN
|
||||
$socket_csv=~ s/censys.io.*\n//g;
|
||||
$master_socket_csv=~ s/censys.io.*\n//g;
|
||||
$cat_csv =~ s/HTTP_clock_skew.*\n//g;
|
||||
$baseline_csv =~ s/HTTP_clock_skew.*\n//g;
|
||||
|
||||
# HTTP time
|
||||
$socket_csv=~ s/HTTP_headerTime.*\n//g;
|
||||
$master_socket_csv=~ s/HTTP_headerTime.*\n//g;
|
||||
$cat_csv =~ s/HTTP_headerTime.*\n//g;
|
||||
$baseline_csv =~ s/HTTP_headerTime.*\n//g;
|
||||
|
||||
# Compare the differences to the master file -- and print differences if there were detected.
|
||||
# DROWN
|
||||
$cat_csv =~ s/censys.io.*\n//g;
|
||||
$baseline_csv =~ s/censys.io.*\n//g;
|
||||
|
||||
$diff = diff \$cat_csv, \$baseline_csv;
|
||||
|
||||
# Compare the differences to the baseline file -- and print differences if there were detected.
|
||||
#
|
||||
cmp_ok($socket_csv, "eq", $master_socket_csv, "Check whether CSV output matches master file from $uri") or
|
||||
ok($cat_csv eq $baseline_csv, "Check whether CSV output matches baseline file from $uri") or
|
||||
diag ("\n%s\n", "$diff");
|
||||
|
||||
$tests++;
|
||||
|
||||
unlink "tmp.csv";
|
||||
|
||||
$tests++;
|
||||
done_testing($tests);
|
||||
printf "\n";
|
||||
|
||||
|
||||
# vim:ts=5:sw=5:expandtab
|
||||
# vim:ts=5:sw=5:expandtab
|
||||
|
||||
|
@ -70,7 +70,7 @@
|
||||
"FS_TLS13_sig_algs","testssl.sh/81.169.166.184","443","INFO","RSA-PSS-RSAE+SHA256 RSA-PSS-RSAE+SHA384 RSA-PSS-RSAE+SHA512","",""
|
||||
"HTTP_status_code","testssl.sh/81.169.166.184","443","INFO","200 OK ('/')","",""
|
||||
"HTTP_clock_skew","testssl.sh/81.169.166.184","443","INFO","0 seconds from localtime","",""
|
||||
"HTTP_headerTime","testssl.sh/81.169.166.184","443","INFO","1654006271","",""
|
||||
"HTTP_headerTime","testssl.sh/81.169.166.184","443","INFO","1737570310","",""
|
||||
"HSTS_time","testssl.sh/81.169.166.184","443","OK","362 days (=31337000 seconds) > 15552000 seconds","",""
|
||||
"HSTS_subdomains","testssl.sh/81.169.166.184","443","INFO","only for this domain","",""
|
||||
"HSTS_preload","testssl.sh/81.169.166.184","443","INFO","domain is NOT marked for preloading","",""
|
||||
@ -81,6 +81,8 @@
|
||||
"X-Frame-Options","testssl.sh/81.169.166.184","443","OK","DENY","",""
|
||||
"X-Content-Type-Options","testssl.sh/81.169.166.184","443","OK","nosniff","",""
|
||||
"Content-Security-Policy","testssl.sh/81.169.166.184","443","OK","script-src 'unsafe-inline'; style-src 'unsafe-inline' 'self'; object-src 'self'; base-uri 'none'; form-action 'none'; img-src 'self' ; default-src 'self'; frame-ancestors 'self'; upgrade-insecure-requests;","",""
|
||||
"Cross-Origin-Opener-Policy","testssl.sh/81.169.166.184","443","INFO","same-origin-allow-popups","",""
|
||||
"Cross-Origin-Resource-Policy","testssl.sh/81.169.166.184","443","INFO","same-site","",""
|
||||
"banner_reverseproxy","testssl.sh/81.169.166.184","443","INFO","--","","CWE-200"
|
||||
"heartbleed","testssl.sh/81.169.166.184","443","OK","not vulnerable, no heartbeat extension","CVE-2014-0160","CWE-119"
|
||||
"CCS","testssl.sh/81.169.166.184","443","OK","not vulnerable","CVE-2014-0224","CWE-310"
|
||||
@ -95,7 +97,7 @@
|
||||
"SWEET32","testssl.sh/81.169.166.184","443","OK","not vulnerable","CVE-2016-2183 CVE-2016-6329","CWE-327"
|
||||
"FREAK","testssl.sh/81.169.166.184","443","OK","not vulnerable","CVE-2015-0204","CWE-310"
|
||||
"DROWN","testssl.sh/81.169.166.184","443","OK","not vulnerable on this host and port","CVE-2016-0800 CVE-2016-0703","CWE-310"
|
||||
"DROWN_hint","testssl.sh/81.169.166.184","443","INFO","Make sure you don't use this certificate elsewhere with SSLv2 enabled services, see https://search.censys.io/search?resource=hosts&virtual_hosts=INCLUDE&q=31B44391529821C6A77F3C78B02D716A07F99B8FDB342BF5A78F263C25375968","CVE-2016-0800 CVE-2016-0703","CWE-310"
|
||||
"DROWN_hint","testssl.sh/81.169.166.184","443","INFO","Make sure you don't use this certificate elsewhere with SSLv2 enabled services, see https://search.censys.io/search?resource=hosts&virtual_hosts=INCLUDE&q=5B4BC205947AED96ECB1879F2668F7F69D696C143BA8D1C69DBB4DC873C92AE9","CVE-2016-0800 CVE-2016-0703","CWE-310"
|
||||
"LOGJAM","testssl.sh/81.169.166.184","443","OK","not vulnerable, no DH EXPORT ciphers,","CVE-2015-4000","CWE-310"
|
||||
"LOGJAM-common_primes","testssl.sh/81.169.166.184","443","OK","--","CVE-2015-4000","CWE-310"
|
||||
"BEAST_CBC_TLS1","testssl.sh/81.169.166.184","443","MEDIUM","ECDHE-RSA-AES256-SHA ECDHE-RSA-AES128-SHA DHE-RSA-CAMELLIA256-SHA DHE-RSA-CAMELLIA128-SHA DHE-RSA-AES256-SHA DHE-RSA-AES128-SHA AES256-SHA","CVE-2011-3389","CWE-20"
|
||||
|
249
testssl.sh
249
testssl.sh
@ -122,7 +122,7 @@ trap "child_error" USR1
|
||||
|
||||
########### Internal definitions
|
||||
#
|
||||
declare -r VERSION="3.2rc3"
|
||||
declare -r VERSION="3.2rc4"
|
||||
declare -r SWCONTACT="dirk aet testssl dot sh"
|
||||
[[ "$VERSION" =~ dev|rc|beta ]] && \
|
||||
SWURL="https://testssl.sh/dev/" ||
|
||||
@ -248,6 +248,7 @@ OPENSSL2=${OPENSSL2:-/usr/bin/openssl} # This will be openssl version >=1.1.1 (
|
||||
OPENSSL2_HAS_TLS_1_3=false # If we run with supplied binary AND $OPENSSL2 supports TLS 1.3 this will be set to true
|
||||
OSSL_SHORTCUT=${OSSL_SHORTCUT:-true} # If you don't want automagically switch from $OPENSSL to $OPENSSL2 for TLS 1.3-only hosts, set this to false
|
||||
OPENSSL_LOCATION=""
|
||||
OPENSSL_NOTIMEOUT="" # Needed for renegotiation tests
|
||||
IKNOW_FNAME=false
|
||||
FIRST_FINDING=true # is this the first finding we are outputting to file?
|
||||
JSONHEADER=true # include JSON headers and footers in HTML file, if one is being created
|
||||
@ -582,8 +583,6 @@ tmln_out() { printf -- "%b" "$1\n"; }
|
||||
out() { printf -- "%b" "$1"; html_out "$(html_reserved "$1")"; }
|
||||
outln() { printf -- "%b" "$1\n"; html_out "$(html_reserved "$1")\n"; }
|
||||
|
||||
#TODO: Still no shell injection safe but if just run it from the cmd line: that's fine
|
||||
|
||||
# Color print functions, see also https://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x329.html
|
||||
tm_liteblue() { [[ "$COLOR" -ge 2 ]] && { "$COLORBLIND" && tm_out "\033[0;32m$1" || tm_out "\033[0;34m$1"; } || tm_out "$1"; tm_off; } # not yet used
|
||||
pr_liteblue() { tm_liteblue "$1"; [[ "$COLOR" -ge 2 ]] && { "$COLORBLIND" && html_out "<span style=\"color:#008817;\">$(html_reserved "$1")</span>" || html_out "<span style=\"color:#0000ee;\">$(html_reserved "$1")</span>"; } || html_out "$(html_reserved "$1")"; }
|
||||
@ -3127,11 +3126,13 @@ emphasize_stuff_in_headers(){
|
||||
-e "s/X-Powered-By/${yellow}X-Powered-By${off}/g" \
|
||||
-e "s/X-UA-Compatible/${yellow}X-UA-Compatible${off}/g" \
|
||||
-e "s/Link/${yellow}Link${off}/g" \
|
||||
-e "s/X-DNS-Prefetch-Control/${yellow}X-DNS-Prefetch-Control${off}/g" \
|
||||
-e "s/X-Rack-Cache/${yellow}X-Rack-Cache${off}/g" \
|
||||
-e "s/X-Runtime/${yellow}X-Runtime${off}/g" \
|
||||
-e "s/X-Pingback/${yellow}X-Pingback${off}/g" \
|
||||
-e "s/X-Permitted-Cross-Domain-Policies/${yellow}X-Permitted-Cross-Domain-Policies${off}/g" \
|
||||
-e "s/X-AspNet-Version/${yellow}X-AspNet-Version${off}/g" \
|
||||
-e "s/X-AspNetMvc-Version/${yellow}X-AspNetMvc-Version${off}/g" \
|
||||
-e "s/x-note/${yellow}x-note${off}/g" \
|
||||
-e "s/x-global-transaction-id/${yellow}x-global-transaction-id${off}/g" \
|
||||
-e "s/X-Global-Transaction-ID/${yellow}X-Global-Transaction-ID${off}/g" \
|
||||
@ -3141,7 +3142,7 @@ emphasize_stuff_in_headers(){
|
||||
if "$do_html"; then
|
||||
if [[ $COLOR -ge 2 ]]; then
|
||||
html_out "$(tm_out "$1" | sed -e 's/\&/\&/g' \
|
||||
-e 's/</\</g' -e 's/>/\>/g' -e 's/"/\"/g' -e "s/'/\'/g" \
|
||||
-e 's/</\</g' -e 's/>/\>/g' -e 's/\"/\"/g' -e "s/\'/\'/g" \
|
||||
-e "s/\([0-9]\)/${html_brown}\1${html_off}/g" \
|
||||
-e "s/Unix/${html_yellow}Unix${html_off}/g" \
|
||||
-e "s/Debian/${html_yellow}Debian${html_off}/g" \
|
||||
@ -3177,18 +3178,19 @@ emphasize_stuff_in_headers(){
|
||||
-e "s/Link/${html_yellow}Link${html_off}/g" \
|
||||
-e "s/X-Runtime/${html_yellow}X-Runtime${html_off}/g" \
|
||||
-e "s/X-Rack-Cache/${html_yellow}X-Rack-Cache${html_off}/g" \
|
||||
-e "s/X-DNS-Prefetch-Control/${html_yellow}X-DNS-Prefetch-Control${html_off}/g" \
|
||||
-e "s/X-Pingback/${html_yellow}X-Pingback${html_off}/g" \
|
||||
-e "s/X-Permitted-Cross-Domain-Policies/${html_yellow}X-Permitted-Cross-Domain-Policies${html_off}/g" \
|
||||
-e "s/X-AspNet-Version/${html_yellow}X-AspNet-Version${html_off}/g")" \
|
||||
-e "s/X-AspNet-Version/${html_yellow}X-AspNet-Version${html_off}/g" \
|
||||
-e "s/X-AspNetMvc-Version/${html_yellow}X-AspNetMvc-Version${html_off}/g" \
|
||||
-e "s/x-note/${html_yellow}x-note${html_off}/g" \
|
||||
-e "s/X-Global-Transaction-ID/${html_yellow}X-Global-Transaction-ID${html_off}/g" \
|
||||
-e "s/x-global-transaction-id/${html_yellow}x-global-transaction-id${html_off}/g" \
|
||||
-e "s/Alt-Svc/${html_yellow}Alt-Svc${html_off}/g" \
|
||||
-e "s/system-wsgw-management-loopback/${html_yellow}system-wsgw-management-loopback${html_off}/g"
|
||||
#FIXME: this is double code. The pattern to emphasize would fit better into
|
||||
# one function.
|
||||
# Also we need another function like run_other_header as otherwise "Link" "Alt-Svc" will never be found.
|
||||
# And: I matches case sensitive only which might not detect all banners. (sed ignorecase is not possible w/ BSD sed)
|
||||
-e "s/system-wsgw-management-loopback/${html_yellow}system-wsgw-management-loopback${html_off}/g" \
|
||||
)"
|
||||
#FIXME: this is double code. The pattern to emphasize headers should be better in one single function
|
||||
# And: It matches case sensitive headers only which won't detect all banners. (sed ignorecase is not a/v for OpenBSD sed)
|
||||
else
|
||||
html_out "$(html_reserved "$1")"
|
||||
fi
|
||||
@ -3435,16 +3437,22 @@ run_security_headers() {
|
||||
|
||||
pr_bold " Security headers "
|
||||
# X-XSS-Protection is useless and at worst harmful, see https://news.ycombinator.com/item?id=20472947
|
||||
# Expect-CT is deprecated, see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expect-CT
|
||||
for header_and_svrty in "X-Frame-Options OK" \
|
||||
"X-Content-Type-Options OK" \
|
||||
"Content-Security-Policy OK" \
|
||||
"X-Content-Security-Policy OK" \
|
||||
"X-WebKit-CSP OK" \
|
||||
"X-Content-Security-Policy INFO" \
|
||||
"X-WebKit-CSP INFO" \
|
||||
"Content-Security-Policy-Report-Only OK" \
|
||||
"Expect-CT OK" \
|
||||
"Expect-CT INFO" \
|
||||
"Permissions-Policy OK" \
|
||||
"Cross-Origin-Opener-Policy INFO" \
|
||||
"Cross-Origin-Resource-Policy INFO" \
|
||||
"Cross-Origin-Embedder-Policy INFO" \
|
||||
"X-XSS-Protection INFO" \
|
||||
"Access-Control-Allow-Origin INFO" \
|
||||
"Access-Control-Allow-Credentials INFO" \
|
||||
"Permissions-Policy INFO" \
|
||||
"Upgrade INFO" \
|
||||
"X-Served-By INFO" \
|
||||
"Referrer-Policy INFO" \
|
||||
@ -11250,6 +11258,12 @@ npn_pre(){
|
||||
fileout "NPN" "WARN" "not tested $OPENSSL doesn't support NPN/SPDY"
|
||||
return 7
|
||||
fi
|
||||
if "$TLS13_ONLY"; then
|
||||
# https://github.com/openssl/openssl/issues/3665
|
||||
pr_warning "There's no such thing as NPN on TLS 1.3-only hosts"
|
||||
fileout "NPN" "WARN" "not possible for TLS 1.3-only hosts"
|
||||
return 6
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
@ -11273,16 +11287,24 @@ alpn_pre(){
|
||||
run_npn() {
|
||||
local tmpstr
|
||||
local -i ret=0
|
||||
local proto=""
|
||||
local jsonID="NPN"
|
||||
|
||||
[[ -n "$STARTTLS" ]] && return 0
|
||||
"$FAST" && return 0
|
||||
pr_bold " NPN/SPDY "
|
||||
|
||||
if ! npn_pre; then
|
||||
outln
|
||||
return 0
|
||||
fi
|
||||
$OPENSSL s_client $(s_client_options "-connect $NODEIP:$PORT $BUGS $SNI -nextprotoneg "$NPN_PROTOs"") </dev/null 2>$ERRFILE >$TMPFILE
|
||||
|
||||
# TLS 1.3 s_client doesn't support -nextprotoneg when connecting with TLS 1.3. So we need to make sure it won't be used
|
||||
# TLS13_ONLY is tested here again, just to be sure, see npn_pre
|
||||
if "$HAS_TLS13" && ! $TLS13_ONLY ]] ; then
|
||||
proto="-no_tls1_3"
|
||||
fi
|
||||
$OPENSSL s_client $(s_client_options "$proto -connect $NODEIP:$PORT $BUGS $SNI -nextprotoneg "$NPN_PROTOs"") </dev/null 2>$ERRFILE >$TMPFILE
|
||||
[[ $? -ne 0 ]] && ret=1
|
||||
tmpstr="$(grep -a '^Protocols' $TMPFILE | sed 's/Protocols.*: //')"
|
||||
if [[ -z "$tmpstr" ]] || [[ "$tmpstr" == " " ]]; then
|
||||
@ -17152,7 +17174,7 @@ run_ticketbleed() {
|
||||
#
|
||||
run_renego() {
|
||||
local legacycmd="" proto="$OPTIMAL_PROTO"
|
||||
local sec_renego sec_client_renego
|
||||
local sec_renego
|
||||
local -i ret=0
|
||||
local cve=""
|
||||
local cwe="CWE-310"
|
||||
@ -17244,110 +17266,113 @@ run_renego() {
|
||||
elif [[ "$CLIENT_AUTH" == required ]] && [[ -z "$MTLS" ]]; then
|
||||
prln_warning "not having provided client certificate and private key file, the client x509-based authentication prevents this from being tested"
|
||||
fileout "$jsonID" "WARN" "not having provided client certificate and private key file, the client x509-based authentication prevents this from being tested"
|
||||
sec_client_renego=1
|
||||
else
|
||||
# We will need $ERRFILE for mitigation detection
|
||||
if [[ $ERRFILE =~ dev.null ]]; then
|
||||
ERRFILE=$TEMPDIR/errorfile.txt || exit $ERR_FCREATE
|
||||
# cleanup previous run if any (multiple IP)
|
||||
rm -f $ERRFILE
|
||||
restore_errfile=1
|
||||
else
|
||||
restore_errfile=0
|
||||
fi
|
||||
# We need up to two tries here, as some LiteSpeed servers don't answer on "R" and block. Thus first try in the background
|
||||
# msg enables us to look deeper into it while debugging
|
||||
echo R | $OPENSSL s_client $(s_client_options "$proto $BUGS $legacycmd $STARTTLS -connect $NODEIP:$PORT $PROXY $SNI") >$TMPFILE 2>>$ERRFILE &
|
||||
wait_kill $! $HEADER_MAXSLEEP
|
||||
if [[ $? -eq 3 ]]; then
|
||||
pr_svrty_good "likely not vulnerable (OK)"; outln ", timed out" # it hung
|
||||
fileout "$jsonID" "OK" "likely not vulnerable (timed out)" "$cve" "$cwe"
|
||||
sec_client_renego=1
|
||||
else
|
||||
# second try in the foreground as we are sure now it won't hang
|
||||
(echo R; sleep 1) | $OPENSSL s_client $(s_client_options "$proto $legacycmd $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI") >$TMPFILE 2>>$ERRFILE
|
||||
sec_client_renego=$?
|
||||
# 0 means client is renegotiating & doesn't return an error --> vuln!
|
||||
# 1 means client tried to renegotiating but the server side errored then. You still see RENEGOTIATING in the output
|
||||
if tail -5 $TMPFILE| grep -qa '^closed'; then
|
||||
# Exemption from above: server closed the connection but return value was zero
|
||||
# See https://github.com/testssl/testssl.sh/issues/1725 and referenced issue @haproxy
|
||||
sec_client_renego=1
|
||||
[[ "$SERVICE" != HTTP ]] && ssl_reneg_attempts=1
|
||||
# We try again if server is HTTP. This could be either a node.js server or something else.
|
||||
# Mitigations (default values) for:
|
||||
# - node.js allows 3x R and then blocks. So then 4x should be tested.
|
||||
# - F5 BIG-IP ADS allows 5x R and then blocks. So then 6x should be tested.
|
||||
# - Stormshield allows 9x and then blocks. So then 10x should be tested.
|
||||
# This way we save a couple seconds as we weeded out the ones which are more robust
|
||||
# Amount of times tested before breaking is set in SSL_RENEG_ATTEMPTS.
|
||||
|
||||
# Clear the log to not get the content of previous run before the execution of the new one.
|
||||
# (Used in the loop tests before s_client invocation)
|
||||
echo -n > $TMPFILE
|
||||
echo -n > $ERRFILE
|
||||
# RENEGOTIATING wait loop watchdog file
|
||||
touch $TEMPDIR/allowed_to_loop
|
||||
# If we dont wait for the session to be established on slow server, we will try to re-negotiate
|
||||
# too early losing all the attempts before the session establishment as OpenSSL will not buffer them
|
||||
# (only the first will be till the establishement of the session).
|
||||
(j=0; while [[ $(grep -ac '^SSL-Session:' $TMPFILE) -ne 1 ]] && [[ $j -lt 30 ]]; do sleep $ssl_reneg_wait; ((j++)); done; \
|
||||
# Connection could be closed by the server with 0 return value. We do one more iteration to not close
|
||||
# s_client STDIN too early as the close could come at any time and race with the tear down of s_client.
|
||||
# See https://github.com/drwetter/testssl.sh/issues/2590
|
||||
# In this case the added iteration is harmless as it will just spin in backgroup
|
||||
for ((i=0; i <= ssl_reneg_attempts; i++ )); do sleep $ssl_reneg_wait; echo R 2>/dev/null; k=0; \
|
||||
# 0 means client is renegotiating & doesn't return an error --> vuln!
|
||||
# 1 means client tried to renegotiating but the server side errored then. You still see RENEGOTIATING in the output
|
||||
# Exemption from above: server closed the connection but return value was zero
|
||||
# See https://github.com/drwetter/testssl.sh/issues/1725 and referenced issue @haproxy
|
||||
while [[ $(grep -ac '^RENEGOTIATING' $ERRFILE) -ne $((i+1)) ]] && [[ -f $TEMPDIR/allowed_to_loop ]] \
|
||||
&& [[ $(tail -1 $ERRFILE | grep -acE '^(RENEGOTIATING|depth|verify|notAfter)') -eq 1 ]] \
|
||||
&& [[ $k -lt 120 ]]; \
|
||||
do sleep $ssl_reneg_wait; ((k++)); if (tail -5 $TMPFILE| grep -qa '^closed'); then break; fi; done; \
|
||||
done) | \
|
||||
$OPENSSL_NOTIMEOUT s_client $(s_client_options "$proto $legacycmd $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI") >$TMPFILE 2>$ERRFILE &
|
||||
pid=$!
|
||||
( sleep $((ssl_reneg_attempts*3+3)) && kill $pid && touch $TEMPDIR/was_killed ) >&2 2>/dev/null &
|
||||
watcher=$!
|
||||
# Trick to get the return value of the openssl command, output redirection and a timeout.
|
||||
# Yes, some target hang/block after some tries (some LiteSpeed servers don't answer at all on "R" and block).
|
||||
wait $pid
|
||||
tmp_result=$?
|
||||
pkill -HUP -P $watcher
|
||||
wait $watcher
|
||||
# Stop any background wait loop
|
||||
rm -f $TEMPDIR/allowed_to_loop
|
||||
# If we are here, we have done the loop. Count the effective renego attempts.
|
||||
# It could be less than the numbers of "for" iterations (minus one) in case of late server close.
|
||||
loop_reneg=$(grep -ac '^RENEGOTIATING' $ERRFILE)
|
||||
# As above, some servers close the connection and return value is zero
|
||||
if (tail -5 $TMPFILE | grep -qa '^closed'); then
|
||||
tmp_result=1
|
||||
fi
|
||||
# timeout reached ?
|
||||
if [[ -f $TEMPDIR/was_killed ]]; then
|
||||
tmp_result=2
|
||||
rm -f $TEMPDIR/was_killed
|
||||
fi
|
||||
if [[ $tmp_result -eq 1 ]] && [[ loop_reneg -eq 1 ]]; then
|
||||
tmp_result=3
|
||||
fi
|
||||
if [[ $SERVICE != HTTP ]]; then
|
||||
# theoretic possible case
|
||||
if [[ $loop_reneg -eq 2 ]]; then
|
||||
tmp_result=0
|
||||
fi
|
||||
case "$sec_client_renego" in
|
||||
0) # We try again if server is HTTP. This could be either a node.js server or something else.
|
||||
# Mitigations (default values) for:
|
||||
# - node.js allows 3x R and then blocks. So then 4x should be tested.
|
||||
# - F5 BIG-IP ADS allows 5x R and then blocks. So then 6x should be tested.
|
||||
# - Stormshield allows 9x and then blocks. So then 10x should be tested.
|
||||
# This way we save a couple seconds as we weeded out the ones which are more robust
|
||||
# Amount of times tested before breaking is set in SSL_RENEG_ATTEMPTS.
|
||||
if [[ $SERVICE != HTTP ]]; then
|
||||
pr_svrty_medium "VULNERABLE (NOT ok)"; outln ", potential DoS threat"
|
||||
fileout "$jsonID" "MEDIUM" "VULNERABLE, potential DoS threat" "$cve" "$cwe" "$hint"
|
||||
else
|
||||
# Clear the log to not get the content of previous run before the execution of the new one.
|
||||
echo -n > $TMPFILE
|
||||
#RENEGOTIATING wait loop watchdog file
|
||||
touch $TEMPDIR/allowed_to_loop
|
||||
# If we dont wait for the session to be established on slow server, we will try to re-negotiate
|
||||
# too early losing all the attempts before the session establishment as OpenSSL will not buffer them
|
||||
# (only the first will be till the establishement of the session).
|
||||
(j=0; while [[ $(grep -ac '^SSL-Session:' $TMPFILE) -ne 1 ]] && [[ $j -lt 30 ]]; do sleep $ssl_reneg_wait; ((j++)); done; \
|
||||
for ((i=0; i < ssl_reneg_attempts; i++ )); do sleep $ssl_reneg_wait; echo R; k=0; \
|
||||
while [[ $(grep -ac '^RENEGOTIATING' $ERRFILE) -ne $((i+3)) ]] && [[ -f $TEMPDIR/allowed_to_loop ]] \
|
||||
&& [[ $(tail -n1 $ERRFILE |grep -acE '^(RENEGOTIATING|depth|verify|notAfter)') -eq 1 ]] \
|
||||
&& [[ $k -lt 120 ]]; \
|
||||
do sleep $ssl_reneg_wait; ((k++)); if (tail -5 $TMPFILE| grep -qa '^closed'); then sleep 1; break; fi; done; \
|
||||
done) | \
|
||||
$OPENSSL s_client $(s_client_options "$proto $legacycmd $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI") >$TMPFILE 2>>$ERRFILE &
|
||||
pid=$!
|
||||
( sleep $((ssl_reneg_attempts*3)) && kill $pid && touch $TEMPDIR/was_killed ) >&2 2>/dev/null &
|
||||
watcher=$!
|
||||
# Trick to get the return value of the openssl command, output redirection and a timeout.
|
||||
# Yes, some target hang/block after some tries.
|
||||
wait $pid
|
||||
tmp_result=$?
|
||||
pkill -HUP -P $watcher
|
||||
wait $watcher
|
||||
rm -f $TEMPDIR/allowed_to_loop
|
||||
# If we are here, we have done two successful renegotiation (-2) and do the loop
|
||||
loop_reneg=$(($(grep -ac '^RENEGOTIATING' $ERRFILE)-2))
|
||||
# As above, some servers close the connection and return value is zero
|
||||
if (tail -5 $TMPFILE| grep -qa '^closed'); then
|
||||
tmp_result=1
|
||||
fi
|
||||
if [[ -f $TEMPDIR/was_killed ]]; then
|
||||
tmp_result=2
|
||||
rm -f $TEMPDIR/was_killed
|
||||
fi
|
||||
case $tmp_result in
|
||||
0) pr_svrty_high "VULNERABLE (NOT ok)"; outln ", DoS threat ($ssl_reneg_attempts attempts)"
|
||||
fileout "$jsonID" "HIGH" "VULNERABLE, DoS threat" "$cve" "$cwe" "$hint"
|
||||
;;
|
||||
1) pr_svrty_good "not vulnerable (OK)"; outln " -- mitigated (disconnect after $loop_reneg/$ssl_reneg_attempts attempts)"
|
||||
fileout "$jsonID" "OK" "not vulnerable, mitigated" "$cve" "$cwe"
|
||||
;;
|
||||
2) pr_svrty_good "not vulnerable (OK)"; \
|
||||
outln " -- mitigated ($loop_reneg successful reneg within ${ssl_reneg_attempts} in $((${ssl_reneg_attempts}*3))s(timeout))"
|
||||
fileout "$jsonID" "OK" "not vulnerable, mitigated" "$cve" "$cwe"
|
||||
;;
|
||||
*) prln_warning "FIXME (bug): $sec_client_renego ($ssl_reneg_attempts tries)"
|
||||
fileout "$jsonID" "DEBUG" "FIXME (bug $ssl_reneg_attempts tries) $sec_client_renego" "$cve" "$cwe"
|
||||
ret=1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
1)
|
||||
prln_svrty_good "not vulnerable (OK)"
|
||||
fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe"
|
||||
;;
|
||||
*)
|
||||
prln_warning "FIXME (bug): $sec_client_renego"
|
||||
fileout "$jsonID" "DEBUG" "FIXME (bug) $sec_client_renego - Please report" "$cve" "$cwe"
|
||||
ret=1
|
||||
;;
|
||||
case $tmp_result in
|
||||
0) pr_svrty_medium "VULNERABLE (NOT ok)"; outln ", potential DoS threat"
|
||||
fileout "$jsonID" "MEDIUM" "VULNERABLE, potential DoS threat" "$cve" "$cwe" "$hint"
|
||||
;;
|
||||
1|3) prln_svrty_good "not vulnerable (OK)"
|
||||
fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe"
|
||||
;;
|
||||
2) pr_svrty_good "likely not vulnerable (OK)"; outln ", timed out ($((${ssl_reneg_attempts}*3+3))s)" # it hung
|
||||
fileout "$jsonID" "OK" "likely not vulnerable (timed out)" "$cve" "$cwe"
|
||||
;;
|
||||
*) prln_warning "FIXME (bug): $sec_client_renego"
|
||||
fileout "$jsonID" "DEBUG" "FIXME (bug) $sec_client_renego - Please report" "$cve" "$cwe"
|
||||
ret=1
|
||||
;;
|
||||
esac
|
||||
else
|
||||
case $tmp_result in
|
||||
0) pr_svrty_high "VULNERABLE (NOT ok)"; outln ", DoS threat ($ssl_reneg_attempts attempts)"
|
||||
fileout "$jsonID" "HIGH" "VULNERABLE, DoS threat" "$cve" "$cwe" "$hint"
|
||||
;;
|
||||
1) pr_svrty_good "not vulnerable (OK)"; outln " -- mitigated (disconnect after $loop_reneg/$ssl_reneg_attempts attempts)"
|
||||
fileout "$jsonID" "OK" "not vulnerable, mitigated" "$cve" "$cwe"
|
||||
;;
|
||||
3) prln_svrty_good "not vulnerable (OK)"
|
||||
fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe"
|
||||
;;
|
||||
2) pr_svrty_good "not vulnerable (OK)"; \
|
||||
outln " -- mitigated ($loop_reneg successful reneg within ${ssl_reneg_attempts} in $((${ssl_reneg_attempts}*3+3))s(timeout))"
|
||||
fileout "$jsonID" "OK" "not vulnerable, mitigated" "$cve" "$cwe"
|
||||
;;
|
||||
*) prln_warning "FIXME (bug): $sec_client_renego ($ssl_reneg_attempts tries)"
|
||||
fileout "$jsonID" "DEBUG" "FIXME (bug $ssl_reneg_attempts tries) $sec_client_renego" "$cve" "$cwe"
|
||||
ret=1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
@ -20523,6 +20548,8 @@ find_openssl_binary() {
|
||||
fi
|
||||
fi
|
||||
|
||||
OPENSSL_NOTIMEOUT=$OPENSSL
|
||||
|
||||
if ! "$do_mass_testing"; then
|
||||
if [[ -n $OPENSSL_TIMEOUT ]]; then
|
||||
OPENSSL="$TIMEOUT_CMD $OPENSSL_TIMEOUT $OPENSSL"
|
||||
@ -20685,7 +20712,7 @@ single check as <options> ("$PROG_NAME URI" does everything except -E and -g):
|
||||
-e, --each-cipher checks each local cipher remotely
|
||||
-E, --cipher-per-proto checks those per protocol
|
||||
-s, --std, --categories tests standard cipher categories by strength
|
||||
-f, --fs, --nsa checks forward secrecy settings
|
||||
-f, --fs, --forward-secrecy checks forward secrecy settings
|
||||
-p, --protocols checks TLS/SSL protocols (including SPDY/HTTP2)
|
||||
-g, --grease tests several server implementation bugs like GREASE and size limitations
|
||||
-S, --server-defaults displays the server's default picks and certificate info
|
||||
|
@ -69,7 +69,7 @@ testv6_patch() {
|
||||
else
|
||||
echo
|
||||
echo "no IPv6 patch (Fedora) detected!! -- Press ^C and dl & apply from"
|
||||
echo "https://github.com/drwetter/testssl.sh/blob/master/bin/fedora-dirk-ipv6.diff"
|
||||
echo "https://github.com/testssl/testssl.sh/blob/master/bin/fedora-dirk-ipv6.diff"
|
||||
echo "or press any key to ignore"
|
||||
echo
|
||||
read a
|
||||
|
Loading…
Reference in New Issue
Block a user