commit ae64d58e60084b7fcb93c80f560888b8a33a8d04 Author: Ambrose Chua Date: Wed Feb 14 21:54:18 2018 +0800 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b917c9f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.DS_Store +scramble diff --git a/README.md b/README.md new file mode 100644 index 0000000..26e4c77 --- /dev/null +++ b/README.md @@ -0,0 +1,21 @@ + +# scramble + +A simple tool to perform XOR as a TCP proxy. + +## Usage + +``` +$ ./scramble -help +Usage of ./scramble: + -connect string + forward to ip and port + -key int + key to xor the data (default 170) + -listen string + listen on ip and port (default ":8000") +``` + +## Use with a SOCKS proxy + +This tool may come really useful when trying to bypass filters that perform packet inspection. After starting a SOCKS proxy listening on the server, `scramble` can connect to the proxy and listen on an exposed port to provide "obscured" SOCKS proxying if `scramble` is also run on the client. diff --git a/main.go b/main.go new file mode 100644 index 0000000..efb562d --- /dev/null +++ b/main.go @@ -0,0 +1,80 @@ +package main + +import ( + "flag" + "io" + "log" + "net" +) + +var key int +var listen string +var connect string + +func main() { + flag.IntVar(&key, "key", 170, "key to xor the data") + flag.StringVar(&listen, "listen", ":8000", "listen on ip and port") + flag.StringVar(&connect, "connect", "", "forward to ip and port") + flag.Parse() + + if key < 0 || key > 255 { + flag.PrintDefaults() + log.Fatal("key is not one byte") + } + + if len(connect) < 3 { + flag.PrintDefaults() + log.Fatal("no connection specified") + } + + ln, err := net.Listen("tcp", listen) + if err != nil { + flag.PrintDefaults() + log.Fatal(err) + } + log.Print("listening on " + listen) + log.Print("will connect to " + connect) + + for { + c, err := ln.Accept() + if err != nil { + log.Print(err) + continue + } + log.Print("Connection from "+c.RemoteAddr().String()) + + cn, err := net.Dial("tcp", connect) + if err != nil { + log.Print(err) + continue + } + + go pipe(c, cn, byte(key)) + go pipe(cn, c, byte(key)) + } +} + +func pipe(w io.WriteCloser, r io.ReadCloser, key byte) { + buff := make([]byte, 65535) + for { + n, rerr := r.Read(buff) + for i := 0; i < n; i++ { + buff[i] = buff[i] ^ key + } + wn, werr := w.Write(buff[:n]) + if n != wn { + log.Print("mismatch") + } + + if werr != nil { + r.Close() + log.Print(werr) + return + } + if rerr != nil { + w.Close() + log.Print(rerr) + return + } + } +} diff --git a/scramble b/scramble new file mode 100755 index 0000000..aba150a Binary files /dev/null and b/scramble differ