mirror of
https://github.com/ScuroNeko/mtg.git
synced 2026-08-31 18:34:02 +03:00
Fix android ping
This commit is contained in:
@@ -32,27 +32,24 @@ var serverHelloSuffix = []byte{
|
|||||||
0x00, 0x20, // 32 bytes of key
|
0x00, 0x20, // 32 bytes of key
|
||||||
}
|
}
|
||||||
|
|
||||||
func SendServerHello(w io.Writer, secret []byte, clientHello *ClientHello) ([]byte, error) {
|
func SendServerHello(w io.Writer, secret []byte, clientHello *ClientHello) error {
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
buf.Grow(tls.MaxRecordSize)
|
buf.Grow(tls.MaxRecordSize)
|
||||||
|
|
||||||
generateServerHello(buf, clientHello)
|
generateServerHello(buf, clientHello)
|
||||||
generateChangeCipherValue(buf)
|
generateChangeCipherValue(buf)
|
||||||
|
generateNoise(buf)
|
||||||
noise := &bytes.Buffer{}
|
|
||||||
generateNoise(noise)
|
|
||||||
|
|
||||||
packet := buf.Bytes()
|
packet := buf.Bytes()
|
||||||
digest := hmac.New(sha256.New, secret)
|
digest := hmac.New(sha256.New, secret)
|
||||||
|
|
||||||
digest.Write(clientHello.Random[:])
|
digest.Write(clientHello.Random[:])
|
||||||
digest.Write(packet)
|
digest.Write(packet)
|
||||||
digest.Write(noise.Bytes())
|
|
||||||
copy(packet[RandomOffset:], digest.Sum(nil))
|
copy(packet[RandomOffset:], digest.Sum(nil))
|
||||||
|
|
||||||
_, err := w.Write(packet)
|
_, err := w.Write(packet)
|
||||||
|
|
||||||
return noise.Bytes()[tls.SizeHeader:], err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateServerHello(buf *bytes.Buffer, hello *ClientHello) {
|
func generateServerHello(buf *bytes.Buffer, hello *ClientHello) {
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ func (suite *SendServerHelloTestSuite) SetupTest() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (suite *SendServerHelloTestSuite) TestRecordStructure() {
|
func (suite *SendServerHelloTestSuite) TestRecordStructure() {
|
||||||
noise, err := fake.SendServerHello(suite.buf, suite.secret.Key[:], suite.hello)
|
err := fake.SendServerHello(suite.buf, suite.secret.Key[:], suite.hello)
|
||||||
suite.NoError(err)
|
suite.NoError(err)
|
||||||
|
|
||||||
var rec bytes.Buffer
|
var rec bytes.Buffer
|
||||||
@@ -53,14 +53,18 @@ func (suite *SendServerHelloTestSuite) TestRecordStructure() {
|
|||||||
suite.NoError(err)
|
suite.NoError(err)
|
||||||
suite.Equal(byte(tls.TypeChangeCipherSpec), recordType)
|
suite.Equal(byte(tls.TypeChangeCipherSpec), recordType)
|
||||||
|
|
||||||
suite.Empty(suite.buf.Bytes())
|
rec.Reset()
|
||||||
|
|
||||||
// noise is raw payload without TLS record header
|
recordType, length, err := tls.ReadRecord(suite.buf, &rec)
|
||||||
suite.Len(noise, 1369)
|
suite.NoError(err)
|
||||||
|
suite.Equal(byte(tls.TypeApplicationData), recordType)
|
||||||
|
suite.Equal(int64(1369), length)
|
||||||
|
|
||||||
|
suite.Empty(suite.buf.Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *SendServerHelloTestSuite) TestHMAC() {
|
func (suite *SendServerHelloTestSuite) TestHMAC() {
|
||||||
noise, err := fake.SendServerHello(suite.buf, suite.secret.Key[:], suite.hello)
|
err := fake.SendServerHello(suite.buf, suite.secret.Key[:], suite.hello)
|
||||||
suite.NoError(err)
|
suite.NoError(err)
|
||||||
|
|
||||||
packet := make([]byte, suite.buf.Len())
|
packet := make([]byte, suite.buf.Len())
|
||||||
@@ -74,18 +78,11 @@ func (suite *SendServerHelloTestSuite) TestHMAC() {
|
|||||||
mac.Write(suite.hello.Random[:])
|
mac.Write(suite.hello.Random[:])
|
||||||
mac.Write(packet)
|
mac.Write(packet)
|
||||||
|
|
||||||
// HMAC is computed over the full noise TLS record (with header),
|
|
||||||
// but SendServerHello returns noise without the header,
|
|
||||||
// so we reconstruct the full record.
|
|
||||||
var fullNoise bytes.Buffer
|
|
||||||
tls.WriteRecord(&fullNoise, noise) //nolint: errcheck
|
|
||||||
mac.Write(fullNoise.Bytes())
|
|
||||||
|
|
||||||
suite.Equal(random, mac.Sum(nil))
|
suite.Equal(random, mac.Sum(nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *SendServerHelloTestSuite) TestHandshakePayload() {
|
func (suite *SendServerHelloTestSuite) TestHandshakePayload() {
|
||||||
_, err := fake.SendServerHello(suite.buf, suite.secret.Key[:], suite.hello)
|
err := fake.SendServerHello(suite.buf, suite.secret.Key[:], suite.hello)
|
||||||
suite.NoError(err)
|
suite.NoError(err)
|
||||||
|
|
||||||
packet := suite.buf.Bytes()
|
packet := suite.buf.Bytes()
|
||||||
@@ -107,7 +104,7 @@ func (suite *SendServerHelloTestSuite) TestHandshakePayload() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (suite *SendServerHelloTestSuite) TestChangeCipherSpec() {
|
func (suite *SendServerHelloTestSuite) TestChangeCipherSpec() {
|
||||||
_, err := fake.SendServerHello(suite.buf, suite.secret.Key[:], suite.hello)
|
err := fake.SendServerHello(suite.buf, suite.secret.Key[:], suite.hello)
|
||||||
suite.NoError(err)
|
suite.NoError(err)
|
||||||
|
|
||||||
// Skip first record
|
// Skip first record
|
||||||
|
|||||||
+7
-14
@@ -78,8 +78,7 @@ func (p *Proxy) ServeConn(conn essentials.Conn) {
|
|||||||
ctx.logger.Info("Stream has been finished")
|
ctx.logger.Info("Stream has been finished")
|
||||||
}()
|
}()
|
||||||
|
|
||||||
noise, ok := p.doFakeTLSHandshake(ctx)
|
if !p.doFakeTLSHandshake(ctx) {
|
||||||
if !ok {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,11 +89,6 @@ func (p *Proxy) ServeConn(conn essentials.Conn) {
|
|||||||
}
|
}
|
||||||
defer clientConn.Stop()
|
defer clientConn.Stop()
|
||||||
|
|
||||||
if _, err := clientConn.SyncWrite(noise); err != nil {
|
|
||||||
ctx.logger.InfoError("cannot send the first packet", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.clientConn = clientConn
|
ctx.clientConn = clientConn
|
||||||
|
|
||||||
if err := p.doObfuscatedHandshake(ctx); err != nil {
|
if err := p.doObfuscatedHandshake(ctx); err != nil {
|
||||||
@@ -176,7 +170,7 @@ func (p *Proxy) Shutdown() {
|
|||||||
p.blocklist.Shutdown()
|
p.blocklist.Shutdown()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Proxy) doFakeTLSHandshake(ctx *streamContext) ([]byte, bool) {
|
func (p *Proxy) doFakeTLSHandshake(ctx *streamContext) bool {
|
||||||
rewind := newConnRewind(ctx.clientConn)
|
rewind := newConnRewind(ctx.clientConn)
|
||||||
|
|
||||||
clientHello, err := fake.ReadClientHello(
|
clientHello, err := fake.ReadClientHello(
|
||||||
@@ -188,25 +182,24 @@ func (p *Proxy) doFakeTLSHandshake(ctx *streamContext) ([]byte, bool) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
p.logger.InfoError("cannot read client hello", err)
|
p.logger.InfoError("cannot read client hello", err)
|
||||||
p.doDomainFronting(ctx, rewind)
|
p.doDomainFronting(ctx, rewind)
|
||||||
return nil, false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.antiReplayCache.SeenBefore(clientHello.SessionID) {
|
if p.antiReplayCache.SeenBefore(clientHello.SessionID) {
|
||||||
p.logger.Warning("replay attack has been detected!")
|
p.logger.Warning("replay attack has been detected!")
|
||||||
p.eventStream.Send(p.ctx, NewEventReplayAttack(ctx.streamID))
|
p.eventStream.Send(p.ctx, NewEventReplayAttack(ctx.streamID))
|
||||||
p.doDomainFronting(ctx, rewind)
|
p.doDomainFronting(ctx, rewind)
|
||||||
return nil, false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
noise, err := fake.SendServerHello(ctx.clientConn, p.secret.Key[:], clientHello)
|
if err := fake.SendServerHello(ctx.clientConn, p.secret.Key[:], clientHello); err != nil {
|
||||||
if err != nil {
|
|
||||||
p.logger.InfoError("cannot send welcome packet", err)
|
p.logger.InfoError("cannot send welcome packet", err)
|
||||||
return nil, false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.clientConn = tls.New(ctx.clientConn, true, false)
|
ctx.clientConn = tls.New(ctx.clientConn, true, false)
|
||||||
|
|
||||||
return noise, true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Proxy) doObfuscatedHandshake(ctx *streamContext) error {
|
func (p *Proxy) doObfuscatedHandshake(ctx *streamContext) error {
|
||||||
|
|||||||
Reference in New Issue
Block a user