Sandertv / gophertunnel

General purpose library for Minecraft Bedrock Edition software written in Go
MIT License
422 stars 99 forks source link

dialer conn: decode packet 3: varint overflows integer #234

Open RestartFU opened 5 months ago

RestartFU commented 5 months ago

some servers (ex: skill-mine.ru:19133) send invalid varints on purpose, preventing anyone using gophertunnel to join their servers

when removing the panic:

2024/07/01 15:18:50 dialer conn: decode packet *packet.ServerToClientHandshake: 550 unread bytes left: 0x808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808
08080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080800065794a344e5855694f694a4e53466c335255465a53457476576b6c36616a42445156465a526b73305255564251306c45575764425
2566b335a32315154586c634c7a4e54596d6f776448523256337052566e4a4f566c7776597a4a795a7a6469517a424f6455466f646c525863334e4a556b6330627a5a4f4e446772555731634c7a427353304e7a593345784e484a7954575a5261465668596d6c616447513354305279656d5
63553473878566e4e5052306f354f537451645374754e554a4b57564e765430525455303830556c5234555570316157394565474a345a47704b566d3145496977695957786e496a6f6952564d7a4f44516966512e65794a7a59577830496a6f696431425153566878647a524d566a5674646
b4d784e5842574f4535705a7a3039496e302e585774556d685f722d586c4c4c766a7a5672762d6f553552574c5468445a77345a746b2d6c556a6e6c356870776b49626d4964644f4e734d69324b69315434557657454675334b34596f6448396649766b5935734269394b763445776d4877706b36704a4f536b6a446b68564e6b324a41735274696b34754456324f456f3375
Failed to connect to skill-mine.ru:19133: dial minecraft 192.168.2.157:51633->57.129.5.154:19133: use of closed network connection
Flonja commented 5 months ago

What's the entire buffer of ServerToClientHandshake? nvm

Sandertv commented 5 months ago

The entire 808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808 080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808000 fragment is part of the varint fyi .-.

Flonja commented 5 months ago

After some debugging in the Discord server, a "patch" got written: (of course this would have to be copied onto other types as well)

func (r *Reader) Varuint32(x *uint32) {
    var v uint32
+    var i int
-    for i := 0; i < 35; i += 7 {
+    for {
        b, err := r.r.ReadByte()
        if err != nil {
            r.panic(err)
        }

        v |= uint32(b&0x7f) << i
        if b&0x80 == 0 {
            *x = v
            return
        }
+        i += 7
    }
-    r.panic(errVarIntOverflow)
}

It turns out the client won't stop reading until it gets to the "end". This patch should be used temporarily though, since this is technically an issue on Bedrock's side where it doesn't have a strict limit on how much it should read.