0

I've successfully made a request to a site on Postman, but when I copy the Python code and execute it, it gave me the following error

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 665, in urlopen
    httplib_response = self._make_request(
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 376, in _make_request
    self._validate_conn(conn)
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 996, in _validate_conn
    conn.connect()
  File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 366, in connect
    self.sock = ssl_wrap_socket(
  File "/usr/lib/python3/dist-packages/urllib3/util/ssl_.py", line 370, in ssl_wrap_socket
    return context.wrap_socket(sock, server_hostname=server_hostname)
  File "/usr/lib/python3/dist-packages/urllib3/contrib/pyopenssl.py", line 491, in wrap_socket
    raise ssl.SSLError("bad handshake: %r" % e)
ssl.SSLError: ("bad handshake: SysCallError(-1, 'Unexpected EOF')",)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/requests/adapters.py", line 439, in send
    resp = conn.urlopen(
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 719, in urlopen
    retries = retries.increment(
  File "/usr/lib/python3/dist-packages/urllib3/util/retry.py", line 436, in increment
    raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='...', port=443): Max retries exceeded with url: /dkmh/login.asp (Caused by SSLError(SSLError("bad handshake: SysCallError(-1, 'Unexpected EOF')")))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "test.py", line 23, in <module>
    response = requests.request("POST", url, headers=headers, data = payload, verify=False)
  File "/usr/lib/python3/dist-packages/requests/api.py", line 60, in request
    return session.request(method=method, url=url, **kwargs)
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 533, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 646, in send
    r = adapter.send(request, **kwargs)
  File "/usr/lib/python3/dist-packages/requests/adapters.py", line 514, in send
    raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='...', port=443): Max retries exceeded with url: /dkmh/login.asp (Caused by SSLError(SSLError("bad handshake: SysCallError(-1, 'Unexpected EOF')")))

Here is the full code (I have removed the original URL)

import requests

url = "https://xxx/login.asp"

payload = 'chkSubmit=ok&txtLoginId=19020055&txtPassword=qj28r8&txtSel=1'
headers = {
  'Connection': 'keep-alive',
  'Cache-Control': 'max-age=0',
  'Upgrade-Insecure-Requests': '1',
  'Origin': 'https://xxx',
  'Content-Type': 'application/x-www-form-urlencoded',
  'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36',
  'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
  'Sec-Fetch-Site': 'same-origin',
  'Sec-Fetch-Mode': 'navigate',
  'Sec-Fetch-User': '?1',
  'Sec-Fetch-Dest': 'document',
  'Referer': 'https://xxx/login.asp',
  'Accept-Language': 'vi-VN,vi;q=0.9,en-US;q=0.8,en;q=0.7',
  'Cookie': '_ga=GA1.3.1781562536.1609987797; ASPSESSIONIDAQDQQQSC=MDJHCACBKMNBFFLOGABMCGEA; UnivId=; intUserLogedin=92573; selab=intUserRef=92573; first=PortalModule%5F376; intUserLogedin=92573; selab=intUserRef=92573; UnivId=; first=PortalModule%5F376'
}

response = requests.request("POST", url, headers=headers, data = payload, verify=False)

print(response.text.encode('utf8'))

According to my check, the TLS version of the site is 1.0. I tried the script with python 3.6, 3.7, 3.8, tried to install requests[security], but none of the above actions worked!

The output of SSLLabs: https://www.ssllabs.com/ssltest/analyze.html?d=daotao.vnu.edu.vn

Hoàng Tùng
  • 100
  • 1
  • 2
  • 10
  • This can be anything. Server requiring weak ciphers like RC4 or 3DES, needing a client certificate, incompatibility with modern TLS stacks, ... - impossible to tell based on this information. If the server is public it would help to provide the URL or the full output of [SSLLabs](https://www.ssllabs.com/ssltest/analyze.html). If you are in control of the server look into the server side log files for hints what the problem might be. – Steffen Ullrich Feb 28 '21 at 15:56
  • I've add the link to the SSLLabs analysis at the end of the question. The website is my university's site – Hoàng Tùng Feb 28 '21 at 16:06

1 Answers1

0

Holy sh.t, the server is totally insecure and hopelessly broken:

enter image description here

The only cipher supported which is only weak and not already insecure is 3DES-CBC:

enter image description here

But, since this cipher is weak it is not supported by common builds of OpenSSL - which is the base for SSL in Python. Is is usable in older version of Python or with special builds of OpenSSL though if explicitly enabled.

See How to work with Python requests with hosts only supporting TLS 1.0 or Requests failing to connect to a TLS server on how to enable this cipher from Python - as long as it is build into the underlying OpenSSL library.

Steffen Ullrich
  • 114,247
  • 10
  • 131
  • 172
  • Thank you. It gave me "Caused by SSLError(SSLError('No cipher can be selected.',),)" after following the threads you have given. I'm using Ubuntu 20.04 LTS. In addition, could you specify a python version which supported 3DES-CBC cipher, or a link to where I can consult to create a "special build of OpenSSL"? – Hoàng Tùng Feb 28 '21 at 16:33
  • @HoàngTùng: There is no specific Python version, it is a question of OpenSSL build options and then compiling Python with this specific build of OpenSSL. Details depend on your OS. For example I have an older version of Anaconda Python 3.6.3 lying around which comes with OpenSSL 1.0.2 and which still supports 3DES. – Steffen Ullrich Feb 28 '21 at 16:58
  • I have followed the following [https://superuser.com/questions/1179309/how-to-enable-3des-ssl-ciphers-for-openssl-1-0-2k](guide) about enabling 3DES SSL Cipher on a custom OpenSSL build. Howerver, the same message "No cipher can be selected" still showed up – Hoàng Tùng Feb 28 '21 at 17:14
  • @HoàngTùng: not only do you need an OpenSSL with 3DES enabled but Python also needs to be compiled against it in order to use - see [here](https://www.google.com/search?q=python+compile+with+custom+openssl) for various instructions on how to do it. – Steffen Ullrich Feb 28 '21 at 18:03