Initial socks-logger code
parent
e75332964e
commit
9c6b4a8df9
45
README.md
45
README.md
|
@ -1,45 +1,10 @@
|
|||
go-socks5 [![Build Status](https://travis-ci.org/armon/go-socks5.png)](https://travis-ci.org/armon/go-socks5)
|
||||
=========
|
||||
|
||||
Provides the `socks5` package that implements a [SOCKS5 server](http://en.wikipedia.org/wiki/SOCKS).
|
||||
SOCKS (Secure Sockets) is used to route traffic between a client and server through
|
||||
an intermediate proxy layer. This can be used to bypass firewalls or NATs.
|
||||
# socks-logger
|
||||
|
||||
Feature
|
||||
=======
|
||||
A SOCKS5 proxy that logs the domains you visit. See [this article](https://www.evilsocket.net/2017/06/30/BetterCap-1-6-1-TLS-Server-Name-Indication-and-Why-We-Need-to-Encrypt-It/) for a summary on how.
|
||||
|
||||
The package has the following features:
|
||||
* "No Auth" mode
|
||||
* User/Password authentication
|
||||
* Support for the CONNECT command
|
||||
* Rules to do granular filtering of commands
|
||||
* Custom DNS resolution
|
||||
* Unit tests
|
||||
|
||||
TODO
|
||||
====
|
||||
|
||||
The package still needs the following:
|
||||
* Support for the BIND command
|
||||
* Support for the ASSOCIATE command
|
||||
|
||||
|
||||
Example
|
||||
=======
|
||||
|
||||
Below is a simple example of usage
|
||||
|
||||
```go
|
||||
// Create a SOCKS5 server
|
||||
conf := &socks5.Config{}
|
||||
server, err := socks5.New(conf)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Create SOCKS5 proxy on localhost port 8000
|
||||
if err := server.ListenAndServe("tcp", "127.0.0.1:8000"); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
```
|
||||
go get github.com/serverwentdown/socks-logger
|
||||
go run $GOPATH/src/github.com/serverwentdown/socks-logger/socks-logger/main.go
|
||||
```
|
||||
|
||||
|
|
130
request.go
130
request.go
|
@ -6,6 +6,8 @@ import (
|
|||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
"math/big"
|
||||
"bytes"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
@ -356,9 +358,135 @@ type closeWriter interface {
|
|||
// proxy is used to suffle data from src to destination, and sends errors
|
||||
// down a dedicated channel
|
||||
func proxy(dst io.Writer, src io.Reader, errCh chan error) {
|
||||
_, err := io.Copy(dst, src)
|
||||
//_, err := io.Copy(dst, src)
|
||||
_, err := copyAndModify(dst, src)
|
||||
if tcpConn, ok := dst.(closeWriter); ok {
|
||||
tcpConn.CloseWrite()
|
||||
}
|
||||
errCh <- err
|
||||
}
|
||||
|
||||
func copyAndModify(dst io.Writer, src io.Reader) (written int64, err error) {
|
||||
// based on copyBuffer in io.go
|
||||
buf := make([]byte, 32*1024)
|
||||
for {
|
||||
nr, er := src.Read(buf)
|
||||
if written == 0 && nr > 0 {
|
||||
if (buf[0] == 0x16 && buf[5] == 0x01) {// && buf[1] == 0x03 && buf[2] == 0x01) {
|
||||
modifyHello(buf);
|
||||
}
|
||||
}
|
||||
if nr > 0 {
|
||||
nw, ew := dst.Write(buf[0:nr])
|
||||
if nw > 0 {
|
||||
written += int64(nw)
|
||||
}
|
||||
if ew != nil {
|
||||
err = ew
|
||||
break
|
||||
}
|
||||
if nr != nw {
|
||||
err = io.ErrShortWrite
|
||||
break
|
||||
}
|
||||
}
|
||||
if er != nil {
|
||||
if er != io.EOF {
|
||||
err = er
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
return written, err
|
||||
}
|
||||
|
||||
func modifyHello(buf []byte) {
|
||||
|
||||
// 1 byte content type
|
||||
|
||||
// 2 byte tls version
|
||||
|
||||
// 2 byte tls frame length
|
||||
frameLength := big.NewInt(0)
|
||||
frameLength.SetBytes(buf[3:5])
|
||||
|
||||
// 1 byte handshake type
|
||||
|
||||
// 3 byte handshake length
|
||||
handshakeLength := big.NewInt(0)
|
||||
handshakeLength.SetBytes(buf[6:9])
|
||||
|
||||
// 2 byte version
|
||||
|
||||
// 32 byte random
|
||||
|
||||
// 1 byte session id length
|
||||
sessionLength := big.NewInt(0)
|
||||
sessionLength.SetBytes(buf[43:44])
|
||||
|
||||
// session id
|
||||
|
||||
// 2 byte cipher suites length (in bytes)
|
||||
suitesLength := big.NewInt(0)
|
||||
suitesLength.SetBytes(buf[44+sessionLength.Uint64():44+sessionLength.Uint64()+2])
|
||||
|
||||
// cipher suites
|
||||
|
||||
// 1 byte compression methods length
|
||||
|
||||
// 1 byte compression method
|
||||
|
||||
// 2 byte extensions length
|
||||
extensionsLength := big.NewInt(0)
|
||||
extensionsLength.SetBytes(buf[48+sessionLength.Uint64()+suitesLength.Uint64():48+sessionLength.Uint64()+suitesLength.Uint64()+2])
|
||||
|
||||
// extensions:
|
||||
|
||||
extensionsStart := 50 + sessionLength.Uint64() + suitesLength.Uint64()
|
||||
extensionsEnd := extensionsStart + extensionsLength.Uint64()
|
||||
cur := extensionsStart
|
||||
for cur + 4 < extensionsEnd {
|
||||
if (buf[cur] != 0x00 || buf[cur + 1] != 0x00) {
|
||||
extensionLength := big.NewInt(0)
|
||||
extensionLength.SetBytes(buf[cur+2:cur+4])
|
||||
cur += 4 + extensionLength.Uint64()
|
||||
continue
|
||||
}
|
||||
|
||||
// yay is sni header!
|
||||
extensionLength := big.NewInt(0)
|
||||
extensionLength.SetBytes(buf[cur+2:cur+4])
|
||||
|
||||
// 2 byte sni list length
|
||||
listLength := big.NewInt(0)
|
||||
listLength.SetBytes(buf[cur+4:cur+6])
|
||||
|
||||
var list []string
|
||||
|
||||
listStart := cur + 6
|
||||
listEnd := cur + 6 + listLength.Uint64()
|
||||
lcur := listStart
|
||||
for lcur + 3 < listEnd {
|
||||
// 1 byte type
|
||||
// 2 byte length
|
||||
nameLength := big.NewInt(0)
|
||||
nameLength.SetBytes(buf[lcur+1:lcur+3])
|
||||
//buf[lcur+3] = 'x'
|
||||
// name
|
||||
var name bytes.Buffer
|
||||
name.Write(buf[lcur+3:lcur+3+nameLength.Uint64()])
|
||||
name.WriteByte(0)
|
||||
// append to list
|
||||
list = append(list, name.String())
|
||||
lcur += 3 + nameLength.Uint64()
|
||||
}
|
||||
fmt.Println(list)
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
// 2 byte extension type
|
||||
// 2 byte extension length
|
||||
// extension data
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/serverwentdown/socks-logger"
|
||||
)
|
||||
|
||||
func main() {
|
||||
conf := &socks5.Config{}
|
||||
server, err := socks5.New(conf)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if err := server.ListenAndServe("tcp", "127.0.0.1:8000"); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue