增加防探测功能,增加流量加密功能
This commit is contained in:
@ -42,11 +42,15 @@ func (c *Client) Start() {
|
||||
}
|
||||
|
||||
func handlerClient(conn net.Conn, serverAddress string, fakeAddressSNI string) {
|
||||
config := &tls.Config{
|
||||
ServerName: fakeAddressSNI,
|
||||
}
|
||||
if HandshakePassword != "" {
|
||||
config.Rand = RandReaderObj
|
||||
}
|
||||
dial, err := tls.DialWithDialer(&net.Dialer{
|
||||
Timeout: time.Second * 5,
|
||||
}, "tcp", serverAddress, &tls.Config{
|
||||
ServerName: fakeAddressSNI,
|
||||
})
|
||||
}, "tcp", serverAddress, config)
|
||||
if err != nil {
|
||||
fmt.Printf("[Client] Dial server error: %v\n", err)
|
||||
return
|
||||
|
@ -1,6 +1,8 @@
|
||||
package shadow
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net"
|
||||
@ -8,7 +10,7 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestName(t *testing.T) {
|
||||
func TestHandshake(t *testing.T) {
|
||||
dial, err := tls.DialWithDialer(&net.Dialer{
|
||||
Timeout: time.Second * 5,
|
||||
}, "tcp", "evan.run:443", &tls.Config{
|
||||
@ -22,15 +24,43 @@ func TestName(t *testing.T) {
|
||||
time.Sleep(time.Minute)
|
||||
}
|
||||
|
||||
func TestName2(t *testing.T) {
|
||||
b := []byte("ABC")
|
||||
encrypt, err := AesEncrypt(b, []byte("1234567812345678"))
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
func TestMd5(t *testing.T) {
|
||||
key := "Passwd"
|
||||
passwd := []byte(key)
|
||||
|
||||
buf := make([]byte, 32)
|
||||
srcCode := md5.Sum(RandomByte(16))
|
||||
copy(buf[0:], srcCode[0:])
|
||||
buffer := bytes.NewBuffer(srcCode[:])
|
||||
|
||||
sum := md5.Sum(passwd)
|
||||
buffer.Write(sum[:])
|
||||
|
||||
hash := md5.Sum(buffer.Bytes())
|
||||
copy(buf[16:], hash[0:])
|
||||
fmt.Println(buf)
|
||||
|
||||
vBuf := make([]byte, 32)
|
||||
copy(vBuf, buf[0:16])
|
||||
verifyBuf := bytes.NewBuffer(vBuf)
|
||||
verifyBuf.Write(sum[:])
|
||||
|
||||
verifyHash := md5.Sum(buffer.Bytes())
|
||||
if bytes.Equal(verifyHash[:], buf[16:32]) {
|
||||
fmt.Println("GOOD")
|
||||
}
|
||||
decrypt, err := AesDecrypt(encrypt, []byte("1234567812345678"))
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
if VerifyKey(buf, key) {
|
||||
fmt.Println("VerifyKey GOOD")
|
||||
}
|
||||
fmt.Println(string(decrypt))
|
||||
|
||||
}
|
||||
|
||||
func TestAes(t *testing.T) {
|
||||
key := []byte("1234567812345678")
|
||||
data := []byte("AVC")
|
||||
|
||||
e := AesEncryptCBC(data, key)
|
||||
d := AesDecryptCBC(e, key)
|
||||
|
||||
fmt.Println(string(d))
|
||||
}
|
||||
|
8
shadow/global.go
Normal file
8
shadow/global.go
Normal file
@ -0,0 +1,8 @@
|
||||
package shadow
|
||||
|
||||
var (
|
||||
HandshakePassword = ""
|
||||
RandReaderObj = &RandReader{}
|
||||
EncryptKey = []byte{}
|
||||
Key = ""
|
||||
)
|
@ -47,6 +47,12 @@ func (m PackAppData) Read(p []byte) (n int, err error) {
|
||||
copy(p[sum:], buf[HeaderLength+2+sum:HeaderLength+2+sum+r])
|
||||
sum += r
|
||||
}
|
||||
if len(EncryptKey) > 0 {
|
||||
encryptedData := p[0:sum]
|
||||
decrypted := AesDecryptCBC(encryptedData, EncryptKey)
|
||||
copy(p[0:], decrypted)
|
||||
sum = len(decrypted)
|
||||
}
|
||||
return sum, err
|
||||
} else {
|
||||
fmt.Printf("Invalid header")
|
||||
@ -55,15 +61,30 @@ func (m PackAppData) Read(p []byte) (n int, err error) {
|
||||
}
|
||||
|
||||
func (m PackAppData) Write(p []byte) (n int, err error) {
|
||||
var sendData []byte
|
||||
if len(EncryptKey) > 0 {
|
||||
sendData = AesEncryptCBC(p, EncryptKey)
|
||||
} else {
|
||||
sendData = p
|
||||
}
|
||||
|
||||
lenNum := make([]byte, 2)
|
||||
binary.BigEndian.PutUint16(lenNum, uint16(len(p)))
|
||||
binary.BigEndian.PutUint16(lenNum, uint16(len(sendData)))
|
||||
|
||||
packetBuf := bytes.NewBuffer(AppDataHeader)
|
||||
packetBuf.Write(lenNum)
|
||||
packetBuf.Write(p)
|
||||
packetBuf.Write(sendData)
|
||||
|
||||
write, err := m.Conn.Write(packetBuf.Bytes())
|
||||
write = write - HeaderLength - 2
|
||||
if len(EncryptKey) > 0 {
|
||||
if write != packetBuf.Len() {
|
||||
write = 0
|
||||
} else {
|
||||
write = len(p)
|
||||
}
|
||||
} else {
|
||||
write = write - HeaderLength - 2
|
||||
}
|
||||
return write, err
|
||||
}
|
||||
|
||||
|
49
shadow/rand.go
Normal file
49
shadow/rand.go
Normal file
@ -0,0 +1,49 @@
|
||||
package shadow
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
"io"
|
||||
"math/rand"
|
||||
)
|
||||
|
||||
type RandReader struct {
|
||||
io.Reader
|
||||
}
|
||||
|
||||
func (r RandReader) Read(p []byte) (n int, err error) {
|
||||
buf := make([]byte, 32)
|
||||
randBytes := md5.Sum(RandomByte(16))
|
||||
copy(buf[0:], randBytes[:])
|
||||
|
||||
preHashData := bytes.NewBuffer(randBytes[:])
|
||||
sum := md5.Sum([]byte(HandshakePassword))
|
||||
preHashData.Write(sum[:])
|
||||
hash := md5.Sum(preHashData.Bytes())
|
||||
copy(buf[16:], hash[:])
|
||||
copy(p, buf)
|
||||
return 32, nil
|
||||
}
|
||||
|
||||
func RandomByte(size int) []byte {
|
||||
buf := make([]byte, size)
|
||||
for i := 0; i < size; i++ {
|
||||
buf[i] = byte(rand.Intn(255))
|
||||
}
|
||||
return buf
|
||||
}
|
||||
|
||||
func VerifyKey(p []byte, key string) bool {
|
||||
if len(p) != 32 {
|
||||
return false
|
||||
}
|
||||
buf := make([]byte, 16)
|
||||
copy(buf, p[0:16])
|
||||
buffer := bytes.NewBuffer(buf)
|
||||
sum := md5.Sum([]byte(key))
|
||||
buffer.Write(sum[:])
|
||||
|
||||
hash := md5.Sum(buffer.Bytes())
|
||||
|
||||
return bytes.Equal(hash[:], p[16:])
|
||||
}
|
@ -79,62 +79,11 @@ func handler(conn net.Conn, targetAddress string, fakeAddress string) {
|
||||
go MyCopy(p, realConnection, exit)
|
||||
go MyCopy(realConnection, p, exit)
|
||||
<-exit
|
||||
|
||||
//go func() {
|
||||
// buf := make([]byte, 64*1024)
|
||||
// for {
|
||||
// nr, er := realConnection.Read(buf)
|
||||
// if er != nil {
|
||||
// if er == io.EOF {
|
||||
// continue
|
||||
// } else {
|
||||
// fmt.Println("read err:", er)
|
||||
// break
|
||||
// }
|
||||
// } else {
|
||||
// lenNum := make([]byte, 2)
|
||||
// binary.BigEndian.PutUint16(lenNum, uint16(nr))
|
||||
//
|
||||
// packetBuf := bytes.NewBuffer(AppDataHeader)
|
||||
// packetBuf.Write(lenNum)
|
||||
// packetBuf.Write(buf[0:nr])
|
||||
//
|
||||
// _, ew := conn.Write(packetBuf.Bytes())
|
||||
// if ew != nil {
|
||||
// fmt.Printf("err2:%v\n", ew)
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}()
|
||||
//
|
||||
//go func() {
|
||||
// result := bytes.NewBuffer(nil)
|
||||
// var buf [65542]byte // 由于 标识数据包长度 的只有两个字节 故数据包最大为 2^16+4(魔数)+2(长度标识)
|
||||
// for {
|
||||
// n, er := conn.Read(buf[0:])
|
||||
// result.Write(buf[0:n])
|
||||
// if er != nil {
|
||||
// if er == io.EOF {
|
||||
// continue
|
||||
// } else {
|
||||
// fmt.Println("read err:", er)
|
||||
// break
|
||||
// }
|
||||
// } else {
|
||||
// scanner := bufio.NewScanner(result)
|
||||
// scanner.Split(packetSlitFunc)
|
||||
// for scanner.Scan() {
|
||||
// realConnection.Write(scanner.Bytes()[HeaderLength+2:])
|
||||
// }
|
||||
// }
|
||||
// result.Reset()
|
||||
// }
|
||||
//}()
|
||||
}
|
||||
|
||||
func processHandshake(src net.Conn, dst net.Conn, waitCh chan int, srcType string) {
|
||||
buf := make([]byte, 32*1024)
|
||||
verifyPass := false
|
||||
for {
|
||||
nr, er := src.Read(buf)
|
||||
if nr > 0 {
|
||||
@ -142,10 +91,17 @@ func processHandshake(src net.Conn, dst net.Conn, waitCh chan int, srcType strin
|
||||
if srcType == "client" {
|
||||
header := ParseAndVerifyTLSHeader(buf[0:nr])
|
||||
if header != nil {
|
||||
if header != nil && header.Type == Handshake && header.HandshakeType == ClientHello && !verifyPass {
|
||||
verifyPass = VerifyKey(header.Rand, HandshakePassword)
|
||||
}
|
||||
if header.Type == ChangeCipherSpec {
|
||||
fmt.Println("[Server] handshake complete")
|
||||
waitCh <- 1
|
||||
break
|
||||
if HandshakePassword != "" && !verifyPass {
|
||||
fmt.Println("[Server] Probe detected,pass through all traffic.")
|
||||
} else {
|
||||
fmt.Println("[Server] handshake complete")
|
||||
waitCh <- 1
|
||||
break
|
||||
}
|
||||
}
|
||||
//fmt.Println(header.toString())
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ type TLSHeader struct {
|
||||
Length int
|
||||
HandshakeType uint8
|
||||
ChangeCipherSpecNext uint8
|
||||
Rand []byte
|
||||
}
|
||||
|
||||
func (t *TLSHeader) toString() string {
|
||||
@ -95,6 +96,9 @@ func ParseAndVerifyTLSHeader(data []byte) *TLSHeader {
|
||||
if header.HandshakeType != ServerHello && header.HandshakeType != ClientHello && header.HandshakeType != Certificate && header.HandshakeType != ServerKeyExchange && header.HandshakeType != ServerHelloDone {
|
||||
header.HandshakeType = EncryptedHandshake
|
||||
}
|
||||
if header.HandshakeType == ClientHello {
|
||||
header.Rand = data[11:43]
|
||||
}
|
||||
}
|
||||
if header.Type == ChangeCipherSpec {
|
||||
if len(data) > 6 {
|
||||
|
Reference in New Issue
Block a user