Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

routines:CONNECT_CR_SRVR_HELLO:wrong version number #2

Open
domyway opened this issue Aug 21, 2020 · 4 comments
Open

routines:CONNECT_CR_SRVR_HELLO:wrong version number #2

domyway opened this issue Aug 21, 2020 · 4 comments
Assignees

Comments

@domyway
Copy link

domyway commented Aug 21, 2020

HTTP proxy
OnRequest change the body . but get error info :

routines:CONNECT_CR_SRVR_HELLO:wrong version number

if I dont change anything, all fine.
need some help
thanks.

@ameshkov
Copy link
Member

Could you please show your code?

@domyway
Copy link
Author

domyway commented Aug 21, 2020

func main() {
	proxy := gomitmproxy.NewProxy(gomitmproxy.Config{
		// TLSConfig: tlsConfig,
		ListenAddr: &net.TCPAddr{
			IP:   net.IPv4(0, 0, 0, 0),
			Port: 8080,
		},
		OnRequest: func(session *gomitmproxy.Session) (request *http.Request, response *http.Response) {
			req := session.Request()

			log.Printf("onRequest: %s %s", req.Method, req.URL.String())

			body := strings.NewReader("<html><body><h1>Replaced response</h1></body></html>")
			res := proxyutil.NewResponse(http.StatusOK, body, req)
			log.Printf("onRequest: %s %s %+v", req.Method, req.URL.String(), res)

			if req.URL.Host == "www.google.com:443" {
				body := strings.NewReader("<html><body><h1>Replaced response</h1></body></html>")
				res := proxyutil.NewResponse(http.StatusOK, body, req)
				res.Header.Set("Content-Type", "text/html")

				// Use session props to pass the information about request being blocked
				// session.SetProp("blocked", true)
				return nil, res
			}

			return nil, nil
		},
		OnResponse: func(session *gomitmproxy.Session) *http.Response {
			log.Printf("onResponse: %s", session.Request().URL.String())

			if _, ok := session.GetProp("blocked"); ok {
				log.Printf("onResponse: was blocked")
			}

			res := session.Response()
			req := session.Request()

			if strings.Index(res.Header.Get("Content-Type"), "text/html") != 0 {
				// Do nothing with non-HTML responses
				return nil
			}

			b, err := proxyutil.ReadDecompressedBody(res)
			// Close the original body
			_ = res.Body.Close()
			if err != nil {
				return proxyutil.NewErrorResponse(req, err)
			}

			// Use latin1 before modifying the body
			// Using this 1-byte encoding will let us preserve all original characters
			// regardless of what exactly is the encoding
			body, err := proxyutil.DecodeLatin1(bytes.NewReader(b))
			if err != nil {
				return proxyutil.NewErrorResponse(session.Request(), err)
			}

			// Modifying the original body
			modifiedBody, err := proxyutil.EncodeLatin1(body + "<!-- EDITED -->")
			if err != nil {
				return proxyutil.NewErrorResponse(session.Request(), err)
			}

			res.Body = ioutil.NopCloser(bytes.NewReader(modifiedBody))
			res.Header.Del("Content-Encoding")
			// res.ContentLength = int64(len(modifiedBody))
			log.Printf("onResponse: %+v", res)
			return res
		},
	})
	err := proxy.Start()
	if err != nil {
		log.Fatal(err)
	}

	signalChannel := make(chan os.Signal, 1)
	signal.Notify(signalChannel, syscall.SIGINT, syscall.SIGTERM)
	<-signalChannel

	// Clean up
	proxy.Close()
}


export https_proxy=127.0.0.1:8080
export http_proxy=127.0.0.1:8080

curl -v https://www.google.com   
                                                                                                                                                                                              ````
* Uses proxy env variable https_proxy == 'http://127.0.0.1:8080'
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
* allocate connect buffer!
* Establish HTTP proxy tunnel to www.google.com:443
> CONNECT www.google.com:443 HTTP/1.1
> Host: www.google.com:443
> User-Agent: curl/7.64.1
> Proxy-Connection: Keep-Alive
>
< HTTP/1.1 200 OK
< Connection: close
< Content-Type: text/html
<
* Proxy replied 200 to CONNECT request
* CONNECT phase completed!
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/cert.pem
  CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* error:1400410B:SSL routines:CONNECT_CR_SRVR_HELLO:wrong version number
* Closing connection 0
curl: (35) error:1400410B:SSL routines:CONNECT_CR_SRVR_HELLO:wrong version number

@szolin
Copy link
Contributor

szolin commented Aug 21, 2020

CONNECT www.google.com:443 HTTP/1.1

curl sends a CONNECT method request to your app, then it sends TLS handshake data, but receives

body := strings.NewReader("<html><body><h1>Replaced response</h1></body></html>")

back. HTML data is not a valid TLS server handshake data!

@domyway
Copy link
Author

domyway commented Aug 21, 2020

how can i do to change the https response body ?

I trace the code
if I dont change the body, then app goes to handleConnect(session *Session) finally

session.res = proxyutil.NewResponse(http.StatusOK, nil, session.req)

then

err = p.writeResponse(session)

It looks like the same thing what the OnRequest Func do

body := strings.NewReader("<html><body><h1>Replaced response</h1></body></html>")
res := proxyutil.NewResponse(http.StatusOK, body, req)

// then go here
p.writeResponse(session)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants