Просмотр исходного кода

Add obfuscated2 server handshake

tags/v2.0.0-rc1
9seconds 5 лет назад
Родитель
Сommit
66c45dc83b

+ 6
- 52
mtglib/conns.go Просмотреть файл

@@ -2,66 +2,20 @@ package mtglib
2 2
 
3 3
 import (
4 4
 	"context"
5
-	"fmt"
6 5
 	"net"
7 6
 	"time"
8 7
 )
9 8
 
10
-type connStandard struct {
11
-	conn        net.Conn
12
-	idleTimeout time.Duration
13
-}
14
-
15
-func (c connStandard) Read(b []byte) (int, error) {
16
-	if err := c.conn.SetReadDeadline(time.Now().Add(c.idleTimeout)); err != nil {
17
-		return 0, fmt.Errorf("cannot set read deadline: %w", err)
18
-	}
19
-
20
-	return c.conn.Read(b)
21
-}
22
-
23
-func (c connStandard) Write(b []byte) (int, error) {
24
-	if err := c.conn.SetWriteDeadline(time.Now().Add(c.idleTimeout)); err != nil {
25
-		return 0, fmt.Errorf("cannot set write deadline: %w", err)
26
-	}
27
-
28
-	return c.conn.Write(b)
29
-}
30
-
31
-func (c connStandard) Close() error {
32
-	return c.conn.Close()
33
-}
34
-
35
-func (c connStandard) LocalAddr() net.Addr {
36
-	return c.conn.LocalAddr()
37
-}
38
-
39
-func (c connStandard) RemoteAddr() net.Addr {
40
-	return c.conn.RemoteAddr()
41
-}
42
-
43
-func (c connStandard) SetDeadline(t time.Time) error {
44
-	return c.conn.SetDeadline(t)
45
-}
46
-
47
-func (c connStandard) SetReadDeadline(t time.Time) error {
48
-	return c.conn.SetReadDeadline(t)
49
-}
50
-
51
-func (c connStandard) SetWriteDeadline(t time.Time) error {
52
-	return c.conn.SetWriteDeadline(t)
53
-}
54
-
55
-type connEventTraffic struct {
56
-	connStandard
9
+type connTelegramTraffic struct {
10
+	net.Conn
57 11
 
58 12
 	connID string
59 13
 	stream EventStream
60 14
 	ctx    context.Context
61 15
 }
62 16
 
63
-func (c connEventTraffic) Read(b []byte) (int, error) {
64
-	n, err := c.connStandard.Read(b)
17
+func (c connTelegramTraffic) Read(b []byte) (int, error) {
18
+	n, err := c.Conn.Read(b)
65 19
 
66 20
 	if n > 0 {
67 21
 		c.stream.Send(c.ctx, EventTraffic{
@@ -75,8 +29,8 @@ func (c connEventTraffic) Read(b []byte) (int, error) {
75 29
 	return n, err
76 30
 }
77 31
 
78
-func (c connEventTraffic) Write(b []byte) (int, error) {
79
-	n, err := c.connStandard.Write(b)
32
+func (c connTelegramTraffic) Write(b []byte) (int, error) {
33
+	n, err := c.Conn.Write(b)
80 34
 
81 35
 	if n > 0 {
82 36
 		c.stream.Send(c.ctx, EventTraffic{

+ 27
- 0
mtglib/internal/obfuscated2/client_handshake.go Просмотреть файл

@@ -8,6 +8,33 @@ import (
8 8
 	"io"
9 9
 )
10 10
 
11
+type clientHandhakeFrame struct {
12
+	handshakeFrame
13
+}
14
+
15
+func (c *clientHandhakeFrame) decryptor(secret []byte) cipher.Stream {
16
+	hasher := acquireSha256Hasher()
17
+	defer releaseSha256Hasher(hasher)
18
+
19
+	hasher.Write(c.key()) // nolint: errcheck
20
+	hasher.Write(secret)  // nolint: errcheck
21
+
22
+	return makeAesCtr(hasher.Sum(nil), c.iv())
23
+}
24
+
25
+func (c *clientHandhakeFrame) encryptor(secret []byte) cipher.Stream {
26
+	arr := clientHandhakeFrame{}
27
+	invertByteSlices(arr.data[:], c.data[:])
28
+
29
+	hasher := acquireSha256Hasher()
30
+	defer releaseSha256Hasher(hasher)
31
+
32
+	hasher.Write(arr.key()) // nolint: errcheck
33
+	hasher.Write(secret)    // nolint: errcheck
34
+
35
+	return makeAesCtr(hasher.Sum(nil), arr.iv())
36
+}
37
+
11 38
 func ClientHandshake(secret []byte, reader io.Reader) (int, cipher.Stream, cipher.Stream, error) {
12 39
 	handshake := clientHandhakeFrame{}
13 40
 

+ 0
- 30
mtglib/internal/obfuscated2/client_handshake_frame.go Просмотреть файл

@@ -1,30 +0,0 @@
1
-package obfuscated2
2
-
3
-import "crypto/cipher"
4
-
5
-type clientHandhakeFrame struct {
6
-	handshakeFrame
7
-}
8
-
9
-func (c *clientHandhakeFrame) decryptor(secret []byte) cipher.Stream {
10
-	hasher := acquireSha256Hasher()
11
-	defer releaseSha256Hasher(hasher)
12
-
13
-	hasher.Write(c.key()) // nolint: errcheck
14
-	hasher.Write(secret)  // nolint: errcheck
15
-
16
-	return makeAesCtr(hasher.Sum(nil), c.iv())
17
-}
18
-
19
-func (c *clientHandhakeFrame) encryptor(secret []byte) cipher.Stream {
20
-	arr := clientHandhakeFrame{}
21
-	invertByteSlices(arr.data[:], c.data[:])
22
-
23
-	hasher := acquireSha256Hasher()
24
-	defer releaseSha256Hasher(hasher)
25
-
26
-	hasher.Write(arr.key()) // nolint: errcheck
27
-	hasher.Write(secret)    // nolint: errcheck
28
-
29
-	return makeAesCtr(hasher.Sum(nil), arr.iv())
30
-}

+ 3
- 3
mtglib/internal/obfuscated2/conn.go Просмотреть файл

@@ -14,7 +14,7 @@ type Conn struct {
14 14
 	writeBuf []byte
15 15
 }
16 16
 
17
-func (c Conn) Read(p []byte) (int, error) {
17
+func (c *Conn) Read(p []byte) (int, error) {
18 18
 	n, err := c.Conn.Read(p)
19 19
 	if err != nil {
20 20
 		return n, err // nolint: wrapcheck
@@ -25,9 +25,9 @@ func (c Conn) Read(p []byte) (int, error) {
25 25
 	return n, nil
26 26
 }
27 27
 
28
-func (c Conn) Write(p []byte) (int, error) {
28
+func (c *Conn) Write(p []byte) (int, error) {
29 29
 	c.writeBuf = append(c.writeBuf[:0], p...)
30
-	c.Encryptor.XORKeyStream(c.writeBuf, c.writeBuf)
30
+	c.Encryptor.XORKeyStream(c.writeBuf, p)
31 31
 
32 32
 	return c.Conn.Write(c.writeBuf)
33 33
 }

+ 68
- 0
mtglib/internal/obfuscated2/server_handshake.go Просмотреть файл

@@ -0,0 +1,68 @@
1
+package obfuscated2
2
+
3
+import (
4
+	"crypto/cipher"
5
+	"crypto/rand"
6
+	"encoding/binary"
7
+	"fmt"
8
+	"net"
9
+)
10
+
11
+type serverHandshakeFrame struct {
12
+	handshakeFrame
13
+}
14
+
15
+func (s *serverHandshakeFrame) decryptor() cipher.Stream {
16
+	return makeAesCtr(s.key(), s.iv())
17
+}
18
+
19
+func (s *serverHandshakeFrame) encryptor() cipher.Stream {
20
+	arr := serverHandshakeFrame{}
21
+	invertByteSlices(arr.data[:], s.data[:])
22
+
23
+	return makeAesCtr(arr.key(), arr.iv())
24
+}
25
+
26
+func ServerHandshake(conn net.Conn) (cipher.Stream, cipher.Stream, error) {
27
+	handshake := generateServerHanshakeFrame()
28
+	copyHandshake := handshake
29
+	encryptor := handshake.encryptor()
30
+	decryptor := handshake.decryptor()
31
+
32
+	encryptor.XORKeyStream(handshake.data[:], handshake.data[:])
33
+	copy(handshake.key(), copyHandshake.key())
34
+	copy(handshake.iv(), copyHandshake.iv())
35
+
36
+	if _, err := conn.Write(handshake.data[:]); err != nil {
37
+		return nil, nil, fmt.Errorf("cannot send a handshake frame to telegram: %w", err)
38
+	}
39
+
40
+	return encryptor, decryptor, nil
41
+}
42
+
43
+func generateServerHanshakeFrame() serverHandshakeFrame {
44
+	frame := serverHandshakeFrame{}
45
+
46
+	for {
47
+		if _, err := rand.Read(frame.data[:]); err != nil {
48
+			panic(err)
49
+		}
50
+
51
+		if frame.data[0] == 0xef {
52
+			continue
53
+		}
54
+
55
+		switch binary.LittleEndian.Uint32(frame.data[:4]) {
56
+		case 0x44414548, 0x54534f50, 0x20544547, 0x4954504f, 0xeeeeeeee:
57
+			continue
58
+		}
59
+
60
+		if (frame.data[4] | frame.data[5] | frame.data[6] | frame.data[7]) == 0 {
61
+			continue
62
+		}
63
+
64
+		copy(frame.connectionType(), handshakeConnectionType)
65
+
66
+		return frame
67
+	}
68
+}

+ 19
- 14
mtglib/proxy.go Просмотреть файл

@@ -111,13 +111,10 @@ func (p *Proxy) doObfuscated2Handshake(ctx *streamContext) error {
111 111
 
112 112
 	ctx.dc = dc
113 113
 	ctx.logger = ctx.logger.BindInt("dc", dc)
114
-	ctx.clientConn = connStandard{
115
-		conn: obfuscated2.Conn{
116
-			Conn:      ctx.clientConn,
117
-			Encryptor: encryptor,
118
-			Decryptor: decryptor,
119
-		},
120
-		idleTimeout: p.idleTimeout,
114
+	ctx.clientConn = &obfuscated2.Conn{
115
+		Conn:      ctx.clientConn,
116
+		Encryptor: encryptor,
117
+		Decryptor: decryptor,
121 118
 	}
122 119
 
123 120
 	return nil
@@ -129,14 +126,22 @@ func (p *Proxy) doTelegramCall(ctx *streamContext) error {
129 126
 		return fmt.Errorf("cannot dial to Telegram: %w", err)
130 127
 	}
131 128
 
132
-	ctx.telegramConn = connEventTraffic{
133
-		connStandard: connStandard{
134
-			conn:        conn,
135
-			idleTimeout: p.idleTimeout,
129
+	encryptor, decryptor, err := obfuscated2.ServerHandshake(conn)
130
+	if err != nil {
131
+		conn.Close()
132
+
133
+		return fmt.Errorf("cannot perform obfuscated2 handshake: %w", err)
134
+	}
135
+
136
+	ctx.telegramConn = &obfuscated2.Conn{
137
+		Conn: connTelegramTraffic{
138
+			Conn:   conn,
139
+			connID: ctx.connID,
140
+			stream: p.eventStream,
141
+			ctx:    ctx,
136 142
 		},
137
-		connID: ctx.connID,
138
-		stream: p.eventStream,
139
-		ctx:    ctx,
143
+		Encryptor: encryptor,
144
+		Decryptor: decryptor,
140 145
 	}
141 146
 
142 147
 	p.eventStream.Send(ctx, EventConnectedToDC{

Загрузка…
Отмена
Сохранить