Skip to content

Instantly share code, notes, and snippets.

@fuglede
Created April 25, 2018 06:14
Show Gist options
  • Save fuglede/c95432e47a05ceb6cfa1969d5cc259b8 to your computer and use it in GitHub Desktop.
Save fuglede/c95432e47a05ceb6cfa1969d5cc259b8 to your computer and use it in GitHub Desktop.
Waterwall
// Provides a proxy that strips SNI information from TLS packets, allowing
// you to circumvent SNI inspecting firewalls. Is implemented here for
// Slack's web hooks but can be used for any host that only uses SNI for
// certificate provision (as opposed to request handling).
// To use it, simply ship off the HTTP request intended for Slack to :9010
// instead.
package main
import (
"bytes"
"crypto/tls"
"io/ioutil"
"net"
"net/http"
)
// slackProxy acts as a proxy for hooks.slack.com, effectively stripping
// the SNI part of TLS packets.
func slackProxy(w http.ResponseWriter, r *http.Request) {
// Get IP for Slack
host := "hooks.slack.com"
h, _ := net.LookupHost(host)
ip := h[0]
// Create a request to Slack based on what was sent to us
url := "https://" + ip + string(r.URL.Path)
data, _ := ioutil.ReadAll(r.Body)
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(data))
req.Host = host
// Ignore bad certificates (since we're connecting without a host).
// Since we do get a perfectly fine certificate, we could also just
// verify that one by hand.
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
client := &http.Client{Transport: tr}
// Perform the request and send back the results to caller
resp, _ := client.Do(req)
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
w.Write(body)
}
func main() {
http.HandleFunc("/", slackProxy)
http.ListenAndServe(":9010", nil)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment