Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python SSL上的MITM代理挂起在客户端的wrap_套接字上_Python_Sockets_Ssl_Proxy_Pyopenssl - Fatal编程技术网

Python SSL上的MITM代理挂起在客户端的wrap_套接字上

Python SSL上的MITM代理挂起在客户端的wrap_套接字上,python,sockets,ssl,proxy,pyopenssl,Python,Sockets,Ssl,Proxy,Pyopenssl,我陷入了困境,你是我最后的希望。我开始做一个用ssl制作MITM代理的项目。我的程序使用httpconnect方法。为了保持简洁,我的程序如下图所示 Client Proxy Server + + + CONNECT | | | +------------> | |

我陷入了困境,你是我最后的希望。我开始做一个用ssl制作MITM代理的项目。我的程序使用
httpconnect
方法。为了保持简洁,我的程序如下图所示

      Client          Proxy             Server
           +              +             +
  CONNECT  |              |             |
           +------------> |             |
           |              |             |
           |    200 Established         |
           |  <-----------+             |
           |              |             |
           | <----------> |             |
           |  Handshake   |             |
           |              | <---------> |
           |              |  Handshake  |
           |              |             |
           |              |             |
           | <----------> | <---------> |
           | Data Exchange| Data Exchange
           |              |             |
我用Openssl模拟一个客户端

openssl s_client -proxy 127.0.0.1:8000 -connect www.google.com:443 -state -verify 1 -CAfile cacert.pem -verify_return_error
当客户端连接到代理时,它们都挂起。如果我杀了我收到的客户

Traceback (most recent call last):
  File "/mitm/mitm_proxy.py", line 100, in <module>
    run()
  File “/mitm/mitm_proxy.py", line 92, in run
    connection = ssl.wrap_socket(connection, keyfile='private.pem', certfile='cacert.pem', server_side=True)
  File "/usr/lib/python3.5/ssl.py", line 1069, in wrap_socket
    ciphers=ciphers)
  File "/usr/lib/python3.5/ssl.py", line 752, in __init__
    self.do_handshake()
  File "/usr/lib/python3.5/ssl.py", line 988, in do_handshake
    self._sslobj.do_handshake()
  File "/usr/lib/python3.5/ssl.py", line 633, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLEOFError: EOF occurred in violation of protocol (_ssl.c:645)

我将我的代码与其他可以工作的代码进行了比较,它们基本上是相同的,这就是为什么我在这里。我不知道出了什么问题。

我不确定这是否是您问题的主要原因,但这一个肯定是错误的:

服务器的正确响应应该是以
\r\n
结尾的状态行,可选的
键:值\r\n
对,然后是
\r\n
以标记HTTP头的结尾,即至少:

由于客户端没有接收到丢失的
\r\n\r\n
,它可能会等待它,而不会启动TLS握手(即发送ClientHello)。相反,服务器将等待客户端启动握手,这样双方将永远等待对方

除了您没有遵循标准之外,
openssl s_客户机-代理…
似乎也没有遵循标准。它实际上需要响应来包含“已建立”一词,正如OpenSSL 1.1.0c中apps/s_client.c中惰性HTTP解析代码的以下摘录所示:

case PROTO_CONNECT:
        ...
        BIO_printf(fbio, "CONNECT %s HTTP/1.0\r\n\r\n", connectstr);
        (void)BIO_flush(fbio);
        /* wait for multi-line response to end CONNECT response */
        do {
            mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
            if (strstr(mbuf, "200") != NULL
                && strstr(mbuf, "established") != NULL)
                foundit++;
        } while (mbuf_len > 3 && foundit == 0);
因此,请尝试使用以下行:


这会使客户机在尝试连接时立即产生上述相同的输出。代理还会产生与上述相同的EOF错误,表明客户端在接收到
HTTP/1.0 200 OK\r\n\r\n
@PeterKrasinski后正在退出:s_客户端似乎也存在错误。请参阅我编辑的答案。
CONNECTED(00000003)
s_client: HTTP CONNECT failed
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 140709212149056 bytes and written 39 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
---
    connection.send(b"HTTP/1.0 200 OK")
    connection.send(b"HTTP/1.0 200 OK\r\n\r\n")
case PROTO_CONNECT:
        ...
        BIO_printf(fbio, "CONNECT %s HTTP/1.0\r\n\r\n", connectstr);
        (void)BIO_flush(fbio);
        /* wait for multi-line response to end CONNECT response */
        do {
            mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
            if (strstr(mbuf, "200") != NULL
                && strstr(mbuf, "established") != NULL)
                foundit++;
        } while (mbuf_len > 3 && foundit == 0);
    connection.send(b"HTTP/1.0 200 established\r\n\r\n")