main
sheepbao 8 years ago
commit 570106c081
  1. 88
      gomitmproxy.go
  2. 35
      src/vendor/mitm/dump.go
  3. 41
      src/vendor/mitm/mitm.go

@ -0,0 +1,88 @@
// This example shows a proxy server that uses go-mitm to man-in-the-middle
// HTTPS connections opened with CONNECT requests
package main
import (
"flag"
"log"
"net/http"
"os"
"sync"
"time"
)
const (
Version = "1.1"
)
var (
wg sync.WaitGroup
)
var logFile *os.File
var logger *log.Logger
func main() {
var conf Cfg
conf.Port = flag.String("port", "8080", "Listen port")
conf.Raddr = flag.String("raddr", "", "Remote addr")
conf.Log = flag.String("log", "./error.log", "log file path")
conf.Monitor = flag.Bool("m", false, "monitor mode")
conf.Tls = flag.Bool("tls", false, "tls connect")
help := flag.Bool("h", false, "help")
flag.Parse()
if *help {
flag.PrintDefaults()
}
var err error
logFile, err = os.Create(*conf.Log)
if err != nil {
log.Fatalln("fail to create log file!")
}
logger = log.New(logFile, "[gomitmproxy]", log.LstdFlags|log.Llongfile)
wg.Add(1)
gomitmproxy(&conf)
wg.Wait()
}
func gomitmproxy(conf *Cfg) {
tlsConfig := NewTlsConfig("gomitmproxy-ca-pk.pem", "gomitmproxy-ca-cert.pem", "", "")
handler, err := InitConfig(conf, tlsConfig)
if err != nil {
logger.Fatalf("InitConfig error: %s", err)
}
server := &http.Server{
Addr: ":" + *conf.Port,
Handler: handler,
ReadTimeout: 1 * time.Hour,
WriteTimeout: 1 * time.Hour,
}
go func() {
log.Printf("proxy listening port:%s", *conf.Port)
if *conf.Tls {
log.Println("ListenAndServeTLS")
err = server.ListenAndServeTLS("gomitmproxy-ca-cert.pem", "gomitmproxy-ca-pk.pem")
} else {
log.Println("ListenAndServe")
err = server.ListenAndServe()
}
if err != nil {
logger.Fatalf("Unable to start HTTP proxy: %s", err)
}
wg.Done()
log.Printf("gomitmproxy stop!!!!")
}()
return
}

@ -7,6 +7,7 @@ import (
"compress/flate"
"compress/gzip"
"fmt"
"io"
"io/ioutil"
"math"
"mylog"
@ -14,7 +15,7 @@ import (
"strconv"
)
func httpDump(req *http.Request, resp *http.Response) {
func httpDump(reqDump []byte, resp *http.Response) {
defer resp.Body.Close()
var respStatusStr string
respStatus := resp.StatusCode
@ -29,18 +30,25 @@ func httpDump(req *http.Request, resp *http.Response) {
case 5:
respStatusStr = color.Red("<--" + strconv.Itoa(respStatus))
}
fmt.Println(color.Green("Request:"))
fmt.Printf("%s %s %s\n", color.Blue(req.Method), req.RequestURI, respStatusStr)
fmt.Println(color.Green("Request:"), respStatusStr)
req, _ := ParseReq(reqDump)
fmt.Printf("%s %s %s\n", color.Blue(req.Method), req.Host+req.RequestURI, respStatusStr)
fmt.Printf("%s %s\n", color.Blue("RemoteAddr:"), req.RemoteAddr)
for headerName, headerContext := range req.Header {
fmt.Printf("%s: %s\n", color.Blue(headerName), headerContext)
}
if req.Method == "POST" {
fmt.Println(color.Green("URLEncoded form"))
for k, v := range req.Form {
fmt.Printf("%s: %s\n", color.Blue(k), v)
if req.Method == "POST" {
fmt.Println(color.Green("POST Param:"))
err := req.ParseForm()
if err != nil {
mylog.Println("parseForm error:", err)
} else {
for k, v := range req.Form {
fmt.Printf("\t%s: %s\n", color.Blue(k), v)
}
}
}
fmt.Println(color.Green("Response:"))
for headerName, headerContext := range resp.Header {
@ -79,3 +87,14 @@ func httpDump(req *http.Request, resp *http.Response) {
fmt.Printf("%s%s%s\n", color.Black("####################"), color.Cyan("END"), color.Black("####################"))
}
func ParseReq(b []byte) (*http.Request, error) {
// func ReadRequest(b *bufio.Reader) (req *Request, err error) { return readRequest(b, deleteHostHeader) }
fmt.Println(string(b))
fmt.Println("-----------------------")
var buf io.ReadWriter
buf = new(bytes.Buffer)
buf.Write(b)
bufr := bufio.NewReader(buf)
return http.ReadRequest(bufr)
}

@ -110,13 +110,17 @@ func (hw *HandlerWrapper) FakeCertForName(name string) (cert *tls.Certificate, e
func (hw *HandlerWrapper) DumpHTTPAndHTTPs(resp http.ResponseWriter, req *http.Request) {
req.Header.Del("Proxy-Connection")
req.Header.Set("Connection", "Keep-Alive")
reqTmp := copyHTTPRequest(req)
err := reqTmp.ParseForm()
var reqDump []byte
var err error
ch := make(chan bool)
// handle connection
go func() {
reqDump, err = httputil.DumpRequestOut(req, true)
ch <- true
}()
if err != nil {
mylog.Println("parseForm error:", err)
mylog.Println("DumpRequest error ", err)
}
// handle connection
connIn, _, err := resp.(http.Hijacker).Hijack()
if err != nil {
mylog.Println("hijack error:", err)
@ -155,9 +159,8 @@ func (hw *HandlerWrapper) DumpHTTPAndHTTPs(resp http.ResponseWriter, req *http.R
}
connOut, err := tls.Dial("tcp", host, hw.tlsConfig.ServerTLSConfig)
if err != nil {
mylog.Panicln("tls dial to", host, "error:", err)
mylog.Println("tls dial to", host, "error:", err)
return
}
if err = req.Write(connOut); err != nil {
@ -188,7 +191,10 @@ func (hw *HandlerWrapper) DumpHTTPAndHTTPs(resp http.ResponseWriter, req *http.R
}
if *hw.MyConfig.Monitor {
go httpDump(reqTmp, respOut)
<-ch
go httpDump(reqDump, respOut)
} else {
<-ch
}
}
@ -361,3 +367,22 @@ func connectProxyServer(conn net.Conn, addr string) error {
}
return nil
}
/*func ReadNotDrain(r *http.Request) (content []byte, err error) {
content, err = ioutil.ReadAll(r.Body)
r.Body = io.ReadCloser(bytes.NewBuffer(content))
return
}
func ParsePostValues(req *http.Request) (url.Values, error) {
c, err := ReadNotDrain(req)
if err != nil {
return nil, err
}
values, err := url.ParseQuery(string(c))
if err != nil {
return nil, err
}
return values, nil
}
*/

Loading…
Cancel
Save