Ideally I want to use pysslscan, but it is not available to me (neither is pyOpenSSL). I found a post doing part of what I want on superuser. So inspired by a blog post and another SO answer, I tried to set up a requests
object where I control the cipher suite:
#!/usr/bin/env python
import requests
import os, sys, subprocess
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.ssl_ import create_urllib3_context
hurl = "https://localhost:443/manage/health"
#get ciphers
openssl_ciphers = subprocess.check_output(["openssl", "ciphers","ALL:eNULL"])
cipherList=(openssl_ciphers.splitlines())[0].decode("utf-8").split(':')
class CustomAdapter(HTTPAdapter):
# This is the 2.11 Requests cipher string, containing 3DES.
CIPHERS = (
'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+HIGH:'
'DH+HIGH:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+HIGH:RSA+3DES:!aNULL:'
'!eNULL:!MD5'
)
def setCiphers(self, cipher):
self.CIPHERS = cipher
def init_poolmanager(self, *args, **kwargs):
context = create_urllib3_context(ciphers=self.CIPHERS)
kwargs['ssl_context'] = context
return super(CustomAdapter, self).init_poolmanager(*args, **kwargs)
def proxy_manager_for(self, *args, **kwargs):
context = create_urllib3_context(ciphers=self.CIPHERS)
kwargs['ssl_context'] = context
return super(CustomAdapter, self).proxy_manager_for(*args, **kwargs)
for cipher in cipherList:
x = CustomAdapter()
x.setCiphers(cipher)
s = requests.Session()
s.mount(hurl, x)
r = s.get(hurl)
print("%-*s\t%s" % (30, cipher, r.status_code))
But I get 200 on every single request...
I sense a flaw in my cipher-suite setting logic. Most likely I am setting it after the calls to the init_poolmanager
and proxy_manager_for
methods have been performed.
If I change the CIPHERS to this:
CIPHERS = (
'NULL-SHA:'
'!aNULL:'
'!eNULL:!MD5'
)
I get ssl.SSLError: ('No cipher can be selected.',)
which is essentially what I want.